{"version":3,"file":"InputGroup.mjs","sources":["../../src/inputs/InputGroup.tsx"],"sourcesContent":["import { clsx } from 'clsx';\nimport { createContext, useContext, useMemo, useRef, useState } from 'react';\n\nimport { useResizeObserver } from '../common/hooks/useResizeObserver';\nimport { cssValueWithUnit } from '../utilities/cssValueWithUnit';\nimport {\n  FieldLabelContextProvider,\n  InputDescribedByProvider,\n  InputIdContextProvider,\n  InputInvalidProvider,\n} from './contexts';\n\ntype InputPaddingContextType = [\n  number | string | undefined,\n  React.Dispatch<React.SetStateAction<number | string | undefined>>,\n];\n\nconst InputPaddingStartContext = createContext<InputPaddingContextType>([undefined, () => {}]);\n\nconst InputPaddingEndContext = createContext<InputPaddingContextType>([undefined, () => {}]);\n\nexport function useInputPaddings() {\n  const [paddingStart] = useContext(InputPaddingStartContext);\n  const [paddingEnd] = useContext(InputPaddingEndContext);\n\n  return {\n    paddingInlineStart: paddingStart,\n    paddingInlineEnd: paddingEnd,\n  } satisfies React.CSSProperties;\n}\n\ninterface InputGroupAddon {\n  content: React.ReactNode;\n  initialContentWidth?: number | string;\n  interactive?: boolean;\n  padding?: 'none' | 'sm' | 'md';\n}\n\nexport interface InputGroupProps {\n  addonStart?: InputGroupAddon;\n  addonEnd?: InputGroupAddon;\n  disabled?: boolean;\n  className?: string;\n  children?: React.ReactNode;\n}\n\nfunction inputPaddingInitialState({\n  initialContentWidth,\n  padding = inputAddonDefaultPadding,\n}: Pick<\n  InputGroupAddon,\n  'initialContentWidth' | 'padding'\n> = {}): () => InputPaddingContextType[0] {\n  return () =>\n    initialContentWidth != null\n      ? `calc(${cssValueWithUnit(initialContentWidth)} + ${cssValueWithUnit(\n          inputAddonContentWidthAddendByPadding[padding],\n        )})`\n      : undefined;\n}\n\nexport function InputGroup({\n  addonStart,\n  addonEnd,\n  disabled,\n  className,\n  children,\n}: InputGroupProps) {\n  const [paddingStart, setPaddingStart] = useState(inputPaddingInitialState(addonStart));\n  const [paddingEnd, setPaddingEnd] = useState(inputPaddingInitialState(addonEnd));\n\n  return (\n    <InputPaddingStartContext.Provider\n      value={useMemo(() => [paddingStart, setPaddingStart], [paddingStart])}\n    >\n      <InputPaddingEndContext.Provider\n        value={useMemo(() => [paddingEnd, setPaddingEnd], [paddingEnd])}\n      >\n        <fieldset disabled={disabled} className={clsx(className, 'np-input-group')}>\n          {addonStart != null ? <InputAddon placement=\"start\" {...addonStart} /> : null}\n          {children}\n          {addonEnd != null ? <InputAddon placement=\"end\" {...addonEnd} /> : null}\n        </fieldset>\n      </InputPaddingEndContext.Provider>\n    </InputPaddingStartContext.Provider>\n  );\n}\n\ninterface InputAddonProps extends Omit<InputGroupAddon, 'initialContentWidth'> {\n  placement: 'start' | 'end';\n}\n\nconst inputAddonContentWidthAddendByPadding = {\n  none: 0,\n  sm: '1rem',\n  md: '1.5rem',\n} satisfies {\n  [key in NonNullable<InputAddonProps['padding']>]: InputPaddingContextType[0];\n};\n\nconst inputAddonDefaultPadding = 'md' satisfies InputAddonProps['padding'];\n\nfunction InputAddon({\n  placement,\n  content,\n  interactive,\n  padding = inputAddonDefaultPadding,\n}: InputAddonProps) {\n  const [, setInputPadding] = useContext(\n    placement === 'start' ? InputPaddingStartContext : InputPaddingEndContext,\n  );\n\n  const ref = useRef<HTMLSpanElement>(null);\n  useResizeObserver(ref, (entry) => {\n    // TODO: Remove fallback once most browsers support `borderBoxSize`\n    const inlineSize = entry.borderBoxSize?.[0]?.inlineSize;\n    if (inlineSize != null) {\n      setInputPadding(inlineSize);\n    } else {\n      const targetStyle = getComputedStyle(entry.target);\n      setInputPadding(\n        entry.contentRect.width +\n          Number.parseFloat(targetStyle.paddingInlineStart) +\n          Number.parseFloat(targetStyle.paddingInlineEnd),\n      );\n    }\n  });\n\n  const isAvatarView = (node: unknown): boolean => {\n    if (!node || typeof node !== 'object') return false;\n    const { type } = node as { type?: { displayName?: string; name?: string } };\n    if (!type || (typeof type !== 'function' && typeof type !== 'object')) return false;\n    return type.displayName === 'AvatarView' || type.name === 'AvatarView';\n  };\n\n  const hasAvatarView = Array.isArray(content) ? content.some(isAvatarView) : isAvatarView(content);\n\n  return (\n    /* Prevent nested controls from being labeled redundantly */\n    <FieldLabelContextProvider value={undefined}>\n      <InputIdContextProvider value={undefined}>\n        <InputDescribedByProvider value={undefined}>\n          <InputInvalidProvider value={undefined}>\n            <span\n              ref={ref}\n              className={clsx(\n                'np-input-addon',\n                {\n                  'np-input-addon--placement-start': placement === 'start',\n                  'np-input-addon--placement-end': placement === 'end',\n                },\n                interactive && 'np-input-addon--interactive',\n                {\n                  'np-input-addon--padding-sm': padding === 'sm',\n                  'np-input-addon--padding-md': padding === 'md',\n                },\n                hasAvatarView && 'np-input-addon--avatar',\n              )}\n            >\n              {content}\n            </span>\n          </InputInvalidProvider>\n        </InputDescribedByProvider>\n      </InputIdContextProvider>\n    </FieldLabelContextProvider>\n  );\n}\n"],"names":["InputPaddingStartContext","createContext","undefined","InputPaddingEndContext","useInputPaddings","paddingStart","useContext","paddingEnd","paddingInlineStart","paddingInlineEnd","inputPaddingInitialState","initialContentWidth","padding","inputAddonDefaultPadding","cssValueWithUnit","inputAddonContentWidthAddendByPadding","InputGroup","addonStart","addonEnd","disabled","className","children","setPaddingStart","useState","setPaddingEnd","_jsx","Provider","value","useMemo","_jsxs","clsx","InputAddon","placement","none","sm","md","content","interactive","setInputPadding","ref","useRef","useResizeObserver","entry","inlineSize","borderBoxSize","targetStyle","getComputedStyle","target","contentRect","width","Number","parseFloat","isAvatarView","node","type","displayName","name","hasAvatarView","Array","isArray","some","FieldLabelContextProvider","InputIdContextProvider","InputDescribedByProvider","InputInvalidProvider"],"mappings":"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"}