@plexui/ui 0.14.3 → 0.15.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/es/components/Menu/Menu.js +2 -2
- package/dist/es/components/Menu/Menu.js.map +1 -1
- package/dist/es/components/TagInput/TagInput.js +41 -10
- package/dist/es/components/TagInput/TagInput.js.map +1 -1
- package/dist/es/components/TagInput/TagInput.module.css +73 -7
- package/dist/es/styles/variables-components.css +1 -1
- package/dist/types/components/Menu/Menu.d.ts +7 -1
- package/dist/types/components/TagInput/TagInput.d.ts +8 -1
- package/package.json +1 -1
|
@@ -100,10 +100,10 @@ const Label = ({ className, children }) => {
|
|
|
100
100
|
const Group = ({ className, children, }) => {
|
|
101
101
|
return _jsx(DropdownMenu.Group, { className: className, children: children });
|
|
102
102
|
};
|
|
103
|
-
const Content = ({ children, side, sideOffset = 5, align, alignOffset, width, minWidth, maxHeight, layout = "vertical", size, }) => {
|
|
103
|
+
const Content = ({ children, side, sideOffset = 5, align, alignOffset, width, minWidth, maxHeight, layout = "vertical", size, onCloseAutoFocus, }) => {
|
|
104
104
|
const { open } = useMenuContext();
|
|
105
105
|
const isHorizontal = layout === "horizontal";
|
|
106
|
-
return (_jsx(DropdownMenu.Portal, { forceMount: true, children: _jsx(TransitionGroup, { className: s.Menu, enterDuration: 350, exitDuration: 200, disableAnimations: true, children: open && (_jsx(DropdownMenu.Content, { forceMount: true, className: s.MenuList, side: side, sideOffset: sideOffset, align: align, alignOffset: alignOffset ?? (align === "center" ? 0 : -5), avoidCollisions: true, collisionPadding: { bottom: 30, top: 30, left: 12, right: 12 }, onEscapeKeyDown: preventDefaultHandler, "data-layout": isHorizontal ? "horizontal" : undefined, "data-size": isHorizontal && size ? size : undefined, style: toCssVariables({
|
|
106
|
+
return (_jsx(DropdownMenu.Portal, { forceMount: true, children: _jsx(TransitionGroup, { className: s.Menu, enterDuration: 350, exitDuration: 200, disableAnimations: true, children: open && (_jsx(DropdownMenu.Content, { forceMount: true, className: s.MenuList, side: side, sideOffset: sideOffset, align: align, alignOffset: alignOffset ?? (align === "center" ? 0 : -5), avoidCollisions: true, collisionPadding: { bottom: 30, top: 30, left: 12, right: 12 }, onEscapeKeyDown: preventDefaultHandler, onCloseAutoFocus: onCloseAutoFocus, "data-layout": isHorizontal ? "horizontal" : undefined, "data-size": isHorizontal && size ? size : undefined, style: toCssVariables({
|
|
107
107
|
"menu-width": width,
|
|
108
108
|
"menu-min-width": isHorizontal ? "auto" : minWidth,
|
|
109
109
|
"menu-max-height": maxHeight,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Menu.js","sourceRoot":"","sources":["../../../../src/components/Menu/Menu.tsx"],"names":[],"mappings":"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","sourcesContent":["\"use client\"\n\nimport { DropdownMenu } from \"radix-ui\"\nimport React, {\n type ComponentProps,\n type ComponentType,\n createContext,\n type MouseEvent,\n type ReactNode,\n useCallback,\n useContext,\n useMemo,\n useRef,\n useState,\n} from \"react\"\n\nimport clsx from \"clsx\"\nimport { useEscCloseStack } from \"../../hooks/useEscCloseStack\"\nimport { useLatestValue } from \"../../hooks/useLatestValue\"\nimport { preventDefaultHandler, toCssVariables } from \"../../lib/helpers\"\nimport { Button } from \"../Button\"\nimport { Check, ChevronRight } from \"../Icon\"\nimport { useLinkComponent } from \"../PlexUIProvider/internal\"\nimport { TransitionGroup } from \"../Transition\"\nimport s from \"./Menu.module.css\"\n\ntype MenuContextValue = {\n open: boolean\n setOpen: (next: boolean) => void\n}\n\nconst MenuContext = createContext<MenuContextValue | null>(null)\n\nconst useMenuContext = () => {\n const context = useContext(MenuContext)\n\n if (!context) {\n throw new Error(\"Menu components must be wrapped in <Menu />\")\n }\n\n return context\n}\n\nexport type MenuProps = {\n children: React.ReactNode\n /** Force the menu to remain open or closed */\n forceOpen?: boolean\n /** Callback triggered when the modal is opened */\n onOpen?: () => void\n /** Callback triggered when the modal is closed */\n onClose?: () => void\n /**\n * When set to `true`, interaction with outside elements will be disabled and only menu content will be visible to screen readers.\n * @default false\n */\n modal?: boolean\n}\n\nexport const Menu = ({ children, forceOpen, onOpen, onClose, modal = false }: MenuProps) => {\n const [open, setOpen] = useState<boolean>(false)\n const isOpen = forceOpen ?? open\n\n const latestOnOpen = useLatestValue(onOpen)\n const latestOnClose = useLatestValue(onClose)\n\n const handleOpenChange = useCallback(\n (nextState: boolean) => {\n setOpen(nextState)\n if (nextState) {\n latestOnOpen.current?.()\n } else {\n latestOnClose.current?.()\n }\n },\n [latestOnOpen, latestOnClose],\n )\n\n useEscCloseStack(open, () => {\n handleOpenChange(false)\n })\n\n const store = useMemo<MenuContextValue>(\n () => ({\n open: isOpen,\n setOpen: handleOpenChange,\n }),\n [isOpen, handleOpenChange],\n )\n\n return (\n <MenuContext.Provider value={store}>\n <DropdownMenu.Root open={isOpen} onOpenChange={handleOpenChange} modal={modal}>\n {children}\n </DropdownMenu.Root>\n </MenuContext.Provider>\n )\n}\n\nexport type MenuItemProps = {\n className?: string\n children: React.ReactNode\n /** Callback triggered when the item is pressed */\n onSelect?: DropdownMenu.DropdownMenuItemProps[\"onSelect\"]\n /** Callback triggered when the item is clicked */\n onClick?: DropdownMenu.DropdownMenuItemProps[\"onClick\"]\n /** Disables the menu item */\n disabled?: boolean\n}\n\nconst Item = ({ className, children, disabled, onSelect, onClick }: MenuItemProps) => {\n const { open } = useMenuContext()\n\n // This handler patches over focus races with core Radix primitives\n // https://github.com/radix-ui/primitives/blob/main/packages/react/menu/src/Menu.tsx#L712-L734\n const handlePreventAfterClose = (evt: React.PointerEvent<HTMLDivElement>) => {\n // Prevent default behavior when we're always known to be closing\n if (!open) {\n evt.preventDefault()\n }\n }\n\n // Custom click handlers\n if (onSelect) {\n return (\n <DropdownMenu.Item\n className={clsx(s.MenuItem, className)}\n onSelect={onSelect}\n onClick={onClick}\n disabled={disabled}\n onPointerMove={handlePreventAfterClose}\n onPointerLeave={handlePreventAfterClose}\n >\n <div className={s.PressableInner}>{children}</div>\n </DropdownMenu.Item>\n )\n }\n\n // Read-only content - will not appear interactive.\n return <div className={clsx(s.MenuItemContent, className)}>{children}</div>\n}\n\nconst ItemActions = ({ className, children }: { className?: string; children: ReactNode }) => {\n return <div className={clsx(s.ItemActions, className)}>{children}</div>\n}\n\nconst ItemAction = ({\n children,\n onClick,\n}: {\n children: ReactNode\n onClick: (evt: MouseEvent) => void\n}) => {\n const { setOpen } = useMenuContext()\n\n return (\n <Button\n className=\"rounded-sm\"\n color=\"secondary\"\n size=\"xs\"\n uniform\n iconSize=\"sm\"\n variant=\"ghost\"\n onClick={(evt) => {\n evt.stopPropagation()\n setOpen(false)\n onClick(evt)\n }}\n >\n {children}\n </Button>\n )\n}\n\ntype MenuLinkProps = Omit<React.AnchorHTMLAttributes<HTMLAnchorElement>, \"href\" | \"children\"> & {\n /** Content rendered inside the Link */\n children: React.ReactNode\n /** Disables the menu item */\n disabled?: boolean\n}\n\ntype MenuLink = <\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n T extends ComponentType<any> | \"a\" = PlexUI.LinkComponent,\n>(\n props: Omit<React.AnchorHTMLAttributes<HTMLAnchorElement>, \"href\"> &\n MenuLinkProps & {\n /**\n * Override the default component used for the link. This is useful for\n * using a routing library, or SSR rendering.\n * purposes.\n *\n * @default 'a'\n */\n as?: T\n } & ComponentProps<T>,\n) => ReactNode\n\nconst Link = ((\n props: MenuLinkProps & { href?: string; to?: string; as?: PlexUI.LinkComponent },\n) => {\n const { className, children, href, to, disabled, as: OverrideComponent, ...restProps } = props\n const { open } = useMenuContext()\n\n const propPath = href || to\n // When a path is not provided, default to an anchor\n const isExternal = propPath ? /^https?:\\/\\//.test(propPath) : true\n const DefaultComponent = useLinkComponent()\n const Component = OverrideComponent || (isExternal ? \"a\" : DefaultComponent)\n\n // This handler patches over focus races with core Radix primitives\n // https://github.com/radix-ui/primitives/blob/main/packages/react/menu/src/Menu.tsx#L712-L734\n const handlePreventAfterClose = (evt: React.PointerEvent<HTMLDivElement>) => {\n // Prevent default behavior when we're always known to be closing\n if (!open) {\n evt.preventDefault()\n }\n }\n\n const linkProps = isExternal\n ? { target: \"_blank\", rel: \"noopener noreferrer\", href: href ?? to }\n : { href, to }\n\n return (\n <DropdownMenu.Item\n asChild\n className={clsx(s.MenuItem, className)}\n disabled={disabled}\n onPointerMove={isExternal ? undefined : handlePreventAfterClose}\n onPointerLeave={isExternal ? undefined : handlePreventAfterClose}\n >\n <Component {...linkProps} {...restProps}>\n <span className={s.PressableInner}>{children}</span>\n </Component>\n </DropdownMenu.Item>\n )\n}) as MenuLink\n\nconst Separator = ({ className }: { className?: string }) => {\n return <DropdownMenu.Separator className={clsx(s.Separator, className)} role=\"separator\" />\n}\n\n\nconst Label = ({ className, children }: { className?: string; children: ReactNode }) => {\n return (\n <DropdownMenu.Label className={clsx(s.MenuLabel, className)}>\n {children}\n </DropdownMenu.Label>\n )\n}\n\nconst Group = ({\n className,\n children,\n}: {\n className?: string\n children: ReactNode\n}) => {\n return <DropdownMenu.Group className={className}>{children}</DropdownMenu.Group>\n}\n\nexport type MenuContentProps = {\n children: React.ReactNode\n /**\n * The preferred side of the trigger to render against when open. Will be reversed when collisions occur.\n * @default bottom\n */\n side?: DropdownMenu.DropdownMenuContentProps[\"side\"]\n /**\n * The distance in pixels from the trigger.\n * @default 5\n */\n sideOffset?: DropdownMenu.DropdownMenuContentProps[\"sideOffset\"]\n /**\n * The preferred alignment against the trigger. May change when collisions occur.\n * @default center\n */\n align?: DropdownMenu.DropdownMenuContentProps[\"align\"]\n /**\n * An offset in pixels from the \"start\" or \"end\" alignment options.\n * @default 0\n */\n alignOffset?: DropdownMenu.DropdownMenuContentProps[\"alignOffset\"]\n /**\n * Defines the `width` property of the content\n * @default auto\n */\n width?: number | \"auto\"\n /**\n * Defines the `min-width` property of the content, in pixels.\n * @default 300\n */\n minWidth?: number | \"auto\"\n /**\n * Defines the `max-width` property of the content, in pixels.\n */\n maxHeight?: number\n /**\n * Layout direction of menu items.\n * Use `\"horizontal\"` for icon-based toolbars (iOS-style).\n * @default \"vertical\"\n */\n layout?: \"vertical\" | \"horizontal\"\n /**\n * Size of horizontal menu items. Controls icon size and padding.\n * Only applies when `layout=\"horizontal\"`.\n * @default \"md\"\n */\n size?: \"sm\" | \"md\" | \"lg\"\n}\n\nconst Content = ({\n children,\n side,\n sideOffset = 5,\n align,\n alignOffset,\n width,\n minWidth,\n maxHeight,\n layout = \"vertical\",\n size,\n}: MenuContentProps) => {\n const { open } = useMenuContext()\n const isHorizontal = layout === \"horizontal\"\n\n return (\n <DropdownMenu.Portal forceMount>\n <TransitionGroup className={s.Menu} enterDuration={350} exitDuration={200} disableAnimations>\n {open && (\n <DropdownMenu.Content\n key=\"dropdown\"\n forceMount\n className={s.MenuList}\n side={side}\n sideOffset={sideOffset}\n align={align}\n alignOffset={alignOffset ?? (align === \"center\" ? 0 : -5)}\n avoidCollisions\n collisionPadding={{ bottom: 30, top: 30, left: 12, right: 12 }}\n onEscapeKeyDown={preventDefaultHandler}\n data-layout={isHorizontal ? \"horizontal\" : undefined}\n data-size={isHorizontal && size ? size : undefined}\n style={toCssVariables({\n \"menu-width\": width,\n \"menu-min-width\": isHorizontal ? \"auto\" : minWidth,\n \"menu-max-height\": maxHeight,\n })}\n >\n {children}\n </DropdownMenu.Content>\n )}\n </TransitionGroup>\n </DropdownMenu.Portal>\n )\n}\n\nconst Trigger = ({ children, disabled }: DropdownMenu.DropdownMenuTriggerProps) => {\n return (\n <DropdownMenu.Trigger asChild disabled={disabled}>\n {children}\n </DropdownMenu.Trigger>\n )\n}\n\ntype SubmenuContextValue = {\n open: boolean\n setOpen: (next: boolean) => void\n triggerRef: React.RefObject<HTMLDivElement | null>\n}\n\nconst SubmenuContext = createContext<SubmenuContextValue | null>(null)\n\nconst useSubmenuContext = () => {\n const context = useContext(SubmenuContext)\n\n if (!context) {\n throw new Error(\"Submenu components must be wrapped in <Sub />\")\n }\n\n return context\n}\n\nexport type SubmenuProps = {\n children: React.ReactNode\n /** Force the menu to remain open or closed */\n forceOpen?: boolean\n /** Callback triggered when the modal is opened */\n onOpen?: () => void\n /** Callback triggered when the modal is closed */\n onClose?: () => void\n}\n\nconst Sub = ({ children, forceOpen, onOpen, onClose }: SubmenuProps) => {\n const [open, setOpen] = useState<boolean>(false)\n const triggerRef = useRef<HTMLDivElement>(null)\n const isOpen = forceOpen ?? open\n\n const latestOnOpen = useLatestValue(onOpen)\n const latestOnClose = useLatestValue(onClose)\n\n const handleOpenChange = useCallback(\n (nextState: boolean) => {\n setOpen(nextState)\n if (nextState) {\n latestOnOpen.current?.()\n } else {\n latestOnClose.current?.()\n }\n },\n [latestOnOpen, latestOnClose],\n )\n\n useEscCloseStack(open, () => {\n handleOpenChange(false)\n // Ensure trigger is focused\n triggerRef.current?.focus()\n })\n\n const store = useMemo<SubmenuContextValue>(\n () => ({\n open: isOpen,\n setOpen: handleOpenChange,\n triggerRef,\n }),\n [isOpen, handleOpenChange],\n )\n\n return (\n <SubmenuContext.Provider value={store}>\n <DropdownMenu.Sub open={isOpen} onOpenChange={handleOpenChange}>\n {children}\n </DropdownMenu.Sub>\n </SubmenuContext.Provider>\n )\n}\n\nconst SubTrigger = ({\n className,\n children,\n disabled,\n}: {\n className?: string\n children: ReactNode\n disabled?: boolean\n}) => {\n const { open } = useMenuContext()\n const { triggerRef } = useSubmenuContext()\n\n // This handler patches over focus races with core Radix primitives\n // https://github.com/radix-ui/primitives/blob/main/packages/react/menu/src/Menu.tsx#L712-L734\n const handlePreventAfterClose = (evt: React.PointerEvent<HTMLDivElement>) => {\n // Prevent default behavior when we know the outer menu is closing\n if (!open) {\n evt.preventDefault()\n }\n }\n\n return (\n <DropdownMenu.SubTrigger\n ref={triggerRef}\n className={clsx(s.MenuItem, s.SubMenuItem, className)}\n disabled={disabled}\n onPointerMove={handlePreventAfterClose}\n onPointerLeave={handlePreventAfterClose}\n >\n <div className={s.PressableInner}>\n {children}\n <ChevronRight width=\"16\" height=\"16\" className={s.SubTriggerIcon} />\n </div>\n </DropdownMenu.SubTrigger>\n )\n}\n\ntype SubContentProps = {\n children: ReactNode\n sideOffset?: DropdownMenu.DropdownMenuSubContentProps[\"sideOffset\"]\n alignOffset?: DropdownMenu.DropdownMenuSubContentProps[\"alignOffset\"]\n width?: number | \"auto\"\n minWidth?: number | \"auto\"\n maxHeight?: number\n}\n\nconst SubContent = ({\n children,\n sideOffset = 4,\n alignOffset = -6,\n width = \"auto\",\n minWidth = \"auto\",\n maxHeight,\n}: SubContentProps) => {\n const { open } = useSubmenuContext()\n\n return (\n <DropdownMenu.Portal forceMount>\n <TransitionGroup className={s.Menu} enterDuration={350} exitDuration={200} disableAnimations>\n {open && (\n <DropdownMenu.SubContent\n key=\"submenu\"\n className={s.MenuList}\n sideOffset={sideOffset}\n alignOffset={alignOffset}\n avoidCollisions\n collisionPadding={{ bottom: 30, top: 30, left: 12, right: 12 }}\n onEscapeKeyDown={preventDefaultHandler}\n style={toCssVariables({\n \"menu-width\": width,\n \"menu-min-width\": minWidth,\n \"menu-max-height\": maxHeight,\n })}\n >\n {children}\n </DropdownMenu.SubContent>\n )}\n </TransitionGroup>\n </DropdownMenu.Portal>\n )\n}\n\nexport type MenuRadioGroupProps<T extends string> = {\n /** Controlled value */\n value: T\n /** Fired when selection changes */\n onChange: (value: T) => void\n children: ReactNode\n /**\n * The orientation of the indicator within the radio item.\n * @default end\n */\n indicatorPosition?: \"start\" | \"end\"\n}\n\nconst RadioGroup = <T extends string>({\n children,\n value,\n onChange,\n indicatorPosition = \"end\",\n ...props\n}: MenuRadioGroupProps<T>) => (\n <DropdownMenu.RadioGroup\n {...props}\n value={value}\n onValueChange={(v: string) => onChange(v as T)}\n data-indicator-position={indicatorPosition}\n >\n {children}\n </DropdownMenu.RadioGroup>\n)\n\nexport type MenuRadioItemProps<T extends string> = {\n value: T\n /** Class applied to the radio item */\n className?: string\n children: ReactNode\n /** Callback triggered when the radio item is pressed */\n onSelect?: DropdownMenu.DropdownMenuItemProps[\"onSelect\"]\n /** Disables the radio item */\n disabled?: boolean\n}\n\nconst RadioItem = <T extends string>({ className, children, ...props }: MenuRadioItemProps<T>) => (\n <DropdownMenu.RadioItem className={clsx(s.MenuItem, s.RadioItem, className)} {...props}>\n <div className={s.PressableInner}>\n <div className={s.RadioIndicator}>\n <DropdownMenu.ItemIndicator className={s.RadioIndicatorActive} />\n </div>\n {children}\n </div>\n </DropdownMenu.RadioItem>\n)\n\nexport type MenuCheckboxItemProps = {\n /** Controlled checked state of the checkbox item */\n checked?: DropdownMenu.DropdownMenuCheckboxItemProps[\"checked\"]\n /** Event handler called when the checked state changes */\n onCheckedChange?: DropdownMenu.DropdownMenuCheckboxItemProps[\"onCheckedChange\"]\n /** Class applied to the checkbox item */\n className?: string\n children: ReactNode\n /** Callback triggered when the checkbox item is pressed */\n onSelect?: DropdownMenu.DropdownMenuItemProps[\"onSelect\"]\n /** Disables the checkbox item */\n disabled?: boolean\n /**\n * The orientation of the indicator within the checkbox item.\n * @default end\n */\n indicatorPosition?: \"start\" | \"end\"\n /**\n * Visual treatment for the checkbox indicator.\n * @default solid\n */\n indicatorVariant?: \"solid\" | \"ghost\"\n}\nconst CheckboxItem = ({\n className,\n children,\n indicatorPosition = \"end\",\n indicatorVariant = \"solid\",\n ...props\n}: MenuCheckboxItemProps) => (\n <DropdownMenu.CheckboxItem\n className={clsx(s.MenuItem, s.CheckboxItem, className)}\n {...props}\n data-indicator-position={indicatorPosition}\n data-indicator-variant={indicatorVariant}\n >\n <div className={s.PressableInner}>\n <div className={s.CheckboxIndicator}>\n <DropdownMenu.ItemIndicator>\n {indicatorVariant === \"ghost\" ? (\n <Check className=\"size-4\" />\n ) : (\n <div className={s.CheckboxCircle}>\n <Check className=\"size-4\" />\n </div>\n )}\n </DropdownMenu.ItemIndicator>\n </div>\n {children}\n </div>\n </DropdownMenu.CheckboxItem>\n)\n\nMenu.Content = Content\nMenu.Item = Item\nMenu.ItemActions = ItemActions\nMenu.ItemAction = ItemAction\nMenu.Link = Link\nMenu.Separator = Separator\nMenu.Trigger = Trigger\nMenu.Sub = Sub\nMenu.SubTrigger = SubTrigger\nMenu.SubContent = SubContent\nMenu.CheckboxItem = CheckboxItem\nMenu.RadioGroup = RadioGroup\nMenu.RadioItem = RadioItem\nMenu.Label = Label\nMenu.Group = Group\n"]}
|
|
1
|
+
{"version":3,"file":"Menu.js","sourceRoot":"","sources":["../../../../src/components/Menu/Menu.tsx"],"names":[],"mappings":"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","sourcesContent":["\"use client\"\n\nimport { DropdownMenu } from \"radix-ui\"\nimport React, {\n type ComponentProps,\n type ComponentType,\n createContext,\n type MouseEvent,\n type ReactNode,\n useCallback,\n useContext,\n useMemo,\n useRef,\n useState,\n} from \"react\"\n\nimport clsx from \"clsx\"\nimport { useEscCloseStack } from \"../../hooks/useEscCloseStack\"\nimport { useLatestValue } from \"../../hooks/useLatestValue\"\nimport { preventDefaultHandler, toCssVariables } from \"../../lib/helpers\"\nimport { Button } from \"../Button\"\nimport { Check, ChevronRight } from \"../Icon\"\nimport { useLinkComponent } from \"../PlexUIProvider/internal\"\nimport { TransitionGroup } from \"../Transition\"\nimport s from \"./Menu.module.css\"\n\ntype MenuContextValue = {\n open: boolean\n setOpen: (next: boolean) => void\n}\n\nconst MenuContext = createContext<MenuContextValue | null>(null)\n\nconst useMenuContext = () => {\n const context = useContext(MenuContext)\n\n if (!context) {\n throw new Error(\"Menu components must be wrapped in <Menu />\")\n }\n\n return context\n}\n\nexport type MenuProps = {\n children: React.ReactNode\n /** Force the menu to remain open or closed */\n forceOpen?: boolean\n /** Callback triggered when the modal is opened */\n onOpen?: () => void\n /** Callback triggered when the modal is closed */\n onClose?: () => void\n /**\n * When set to `true`, interaction with outside elements will be disabled and only menu content will be visible to screen readers.\n * @default false\n */\n modal?: boolean\n}\n\nexport const Menu = ({ children, forceOpen, onOpen, onClose, modal = false }: MenuProps) => {\n const [open, setOpen] = useState<boolean>(false)\n const isOpen = forceOpen ?? open\n\n const latestOnOpen = useLatestValue(onOpen)\n const latestOnClose = useLatestValue(onClose)\n\n const handleOpenChange = useCallback(\n (nextState: boolean) => {\n setOpen(nextState)\n if (nextState) {\n latestOnOpen.current?.()\n } else {\n latestOnClose.current?.()\n }\n },\n [latestOnOpen, latestOnClose],\n )\n\n useEscCloseStack(open, () => {\n handleOpenChange(false)\n })\n\n const store = useMemo<MenuContextValue>(\n () => ({\n open: isOpen,\n setOpen: handleOpenChange,\n }),\n [isOpen, handleOpenChange],\n )\n\n return (\n <MenuContext.Provider value={store}>\n <DropdownMenu.Root open={isOpen} onOpenChange={handleOpenChange} modal={modal}>\n {children}\n </DropdownMenu.Root>\n </MenuContext.Provider>\n )\n}\n\nexport type MenuItemProps = {\n className?: string\n children: React.ReactNode\n /** Callback triggered when the item is pressed */\n onSelect?: DropdownMenu.DropdownMenuItemProps[\"onSelect\"]\n /** Callback triggered when the item is clicked */\n onClick?: DropdownMenu.DropdownMenuItemProps[\"onClick\"]\n /** Disables the menu item */\n disabled?: boolean\n}\n\nconst Item = ({ className, children, disabled, onSelect, onClick }: MenuItemProps) => {\n const { open } = useMenuContext()\n\n // This handler patches over focus races with core Radix primitives\n // https://github.com/radix-ui/primitives/blob/main/packages/react/menu/src/Menu.tsx#L712-L734\n const handlePreventAfterClose = (evt: React.PointerEvent<HTMLDivElement>) => {\n // Prevent default behavior when we're always known to be closing\n if (!open) {\n evt.preventDefault()\n }\n }\n\n // Custom click handlers\n if (onSelect) {\n return (\n <DropdownMenu.Item\n className={clsx(s.MenuItem, className)}\n onSelect={onSelect}\n onClick={onClick}\n disabled={disabled}\n onPointerMove={handlePreventAfterClose}\n onPointerLeave={handlePreventAfterClose}\n >\n <div className={s.PressableInner}>{children}</div>\n </DropdownMenu.Item>\n )\n }\n\n // Read-only content - will not appear interactive.\n return <div className={clsx(s.MenuItemContent, className)}>{children}</div>\n}\n\nconst ItemActions = ({ className, children }: { className?: string; children: ReactNode }) => {\n return <div className={clsx(s.ItemActions, className)}>{children}</div>\n}\n\nconst ItemAction = ({\n children,\n onClick,\n}: {\n children: ReactNode\n onClick: (evt: MouseEvent) => void\n}) => {\n const { setOpen } = useMenuContext()\n\n return (\n <Button\n className=\"rounded-sm\"\n color=\"secondary\"\n size=\"xs\"\n uniform\n iconSize=\"sm\"\n variant=\"ghost\"\n onClick={(evt) => {\n evt.stopPropagation()\n setOpen(false)\n onClick(evt)\n }}\n >\n {children}\n </Button>\n )\n}\n\ntype MenuLinkProps = Omit<React.AnchorHTMLAttributes<HTMLAnchorElement>, \"href\" | \"children\"> & {\n /** Content rendered inside the Link */\n children: React.ReactNode\n /** Disables the menu item */\n disabled?: boolean\n}\n\ntype MenuLink = <\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n T extends ComponentType<any> | \"a\" = PlexUI.LinkComponent,\n>(\n props: Omit<React.AnchorHTMLAttributes<HTMLAnchorElement>, \"href\"> &\n MenuLinkProps & {\n /**\n * Override the default component used for the link. This is useful for\n * using a routing library, or SSR rendering.\n * purposes.\n *\n * @default 'a'\n */\n as?: T\n } & ComponentProps<T>,\n) => ReactNode\n\nconst Link = ((\n props: MenuLinkProps & { href?: string; to?: string; as?: PlexUI.LinkComponent },\n) => {\n const { className, children, href, to, disabled, as: OverrideComponent, ...restProps } = props\n const { open } = useMenuContext()\n\n const propPath = href || to\n // When a path is not provided, default to an anchor\n const isExternal = propPath ? /^https?:\\/\\//.test(propPath) : true\n const DefaultComponent = useLinkComponent()\n const Component = OverrideComponent || (isExternal ? \"a\" : DefaultComponent)\n\n // This handler patches over focus races with core Radix primitives\n // https://github.com/radix-ui/primitives/blob/main/packages/react/menu/src/Menu.tsx#L712-L734\n const handlePreventAfterClose = (evt: React.PointerEvent<HTMLDivElement>) => {\n // Prevent default behavior when we're always known to be closing\n if (!open) {\n evt.preventDefault()\n }\n }\n\n const linkProps = isExternal\n ? { target: \"_blank\", rel: \"noopener noreferrer\", href: href ?? to }\n : { href, to }\n\n return (\n <DropdownMenu.Item\n asChild\n className={clsx(s.MenuItem, className)}\n disabled={disabled}\n onPointerMove={isExternal ? undefined : handlePreventAfterClose}\n onPointerLeave={isExternal ? undefined : handlePreventAfterClose}\n >\n <Component {...linkProps} {...restProps}>\n <span className={s.PressableInner}>{children}</span>\n </Component>\n </DropdownMenu.Item>\n )\n}) as MenuLink\n\nconst Separator = ({ className }: { className?: string }) => {\n return <DropdownMenu.Separator className={clsx(s.Separator, className)} role=\"separator\" />\n}\n\n\nconst Label = ({ className, children }: { className?: string; children: ReactNode }) => {\n return (\n <DropdownMenu.Label className={clsx(s.MenuLabel, className)}>\n {children}\n </DropdownMenu.Label>\n )\n}\n\nconst Group = ({\n className,\n children,\n}: {\n className?: string\n children: ReactNode\n}) => {\n return <DropdownMenu.Group className={className}>{children}</DropdownMenu.Group>\n}\n\nexport type MenuContentProps = {\n children: React.ReactNode\n /**\n * The preferred side of the trigger to render against when open. Will be reversed when collisions occur.\n * @default bottom\n */\n side?: DropdownMenu.DropdownMenuContentProps[\"side\"]\n /**\n * The distance in pixels from the trigger.\n * @default 5\n */\n sideOffset?: DropdownMenu.DropdownMenuContentProps[\"sideOffset\"]\n /**\n * The preferred alignment against the trigger. May change when collisions occur.\n * @default center\n */\n align?: DropdownMenu.DropdownMenuContentProps[\"align\"]\n /**\n * An offset in pixels from the \"start\" or \"end\" alignment options.\n * @default 0\n */\n alignOffset?: DropdownMenu.DropdownMenuContentProps[\"alignOffset\"]\n /**\n * Defines the `width` property of the content\n * @default auto\n */\n width?: number | \"auto\"\n /**\n * Defines the `min-width` property of the content, in pixels.\n * @default 300\n */\n minWidth?: number | \"auto\"\n /**\n * Defines the `max-width` property of the content, in pixels.\n */\n maxHeight?: number\n /**\n * Layout direction of menu items.\n * Use `\"horizontal\"` for icon-based toolbars (iOS-style).\n * @default \"vertical\"\n */\n layout?: \"vertical\" | \"horizontal\"\n /**\n * Size of horizontal menu items. Controls icon size and padding.\n * Only applies when `layout=\"horizontal\"`.\n * @default \"md\"\n */\n size?: \"sm\" | \"md\" | \"lg\"\n /**\n * Event handler called when auto-focus tries to return to the trigger\n * after the menu closes. Call `event.preventDefault()` to prevent the\n * trigger from regaining focus (and its focus-visible ring).\n */\n onCloseAutoFocus?: DropdownMenu.DropdownMenuContentProps[\"onCloseAutoFocus\"]\n}\n\nconst Content = ({\n children,\n side,\n sideOffset = 5,\n align,\n alignOffset,\n width,\n minWidth,\n maxHeight,\n layout = \"vertical\",\n size,\n onCloseAutoFocus,\n}: MenuContentProps) => {\n const { open } = useMenuContext()\n const isHorizontal = layout === \"horizontal\"\n\n return (\n <DropdownMenu.Portal forceMount>\n <TransitionGroup className={s.Menu} enterDuration={350} exitDuration={200} disableAnimations>\n {open && (\n <DropdownMenu.Content\n key=\"dropdown\"\n forceMount\n className={s.MenuList}\n side={side}\n sideOffset={sideOffset}\n align={align}\n alignOffset={alignOffset ?? (align === \"center\" ? 0 : -5)}\n avoidCollisions\n collisionPadding={{ bottom: 30, top: 30, left: 12, right: 12 }}\n onEscapeKeyDown={preventDefaultHandler}\n onCloseAutoFocus={onCloseAutoFocus}\n data-layout={isHorizontal ? \"horizontal\" : undefined}\n data-size={isHorizontal && size ? size : undefined}\n style={toCssVariables({\n \"menu-width\": width,\n \"menu-min-width\": isHorizontal ? \"auto\" : minWidth,\n \"menu-max-height\": maxHeight,\n })}\n >\n {children}\n </DropdownMenu.Content>\n )}\n </TransitionGroup>\n </DropdownMenu.Portal>\n )\n}\n\nconst Trigger = ({ children, disabled }: DropdownMenu.DropdownMenuTriggerProps) => {\n return (\n <DropdownMenu.Trigger asChild disabled={disabled}>\n {children}\n </DropdownMenu.Trigger>\n )\n}\n\ntype SubmenuContextValue = {\n open: boolean\n setOpen: (next: boolean) => void\n triggerRef: React.RefObject<HTMLDivElement | null>\n}\n\nconst SubmenuContext = createContext<SubmenuContextValue | null>(null)\n\nconst useSubmenuContext = () => {\n const context = useContext(SubmenuContext)\n\n if (!context) {\n throw new Error(\"Submenu components must be wrapped in <Sub />\")\n }\n\n return context\n}\n\nexport type SubmenuProps = {\n children: React.ReactNode\n /** Force the menu to remain open or closed */\n forceOpen?: boolean\n /** Callback triggered when the modal is opened */\n onOpen?: () => void\n /** Callback triggered when the modal is closed */\n onClose?: () => void\n}\n\nconst Sub = ({ children, forceOpen, onOpen, onClose }: SubmenuProps) => {\n const [open, setOpen] = useState<boolean>(false)\n const triggerRef = useRef<HTMLDivElement>(null)\n const isOpen = forceOpen ?? open\n\n const latestOnOpen = useLatestValue(onOpen)\n const latestOnClose = useLatestValue(onClose)\n\n const handleOpenChange = useCallback(\n (nextState: boolean) => {\n setOpen(nextState)\n if (nextState) {\n latestOnOpen.current?.()\n } else {\n latestOnClose.current?.()\n }\n },\n [latestOnOpen, latestOnClose],\n )\n\n useEscCloseStack(open, () => {\n handleOpenChange(false)\n // Ensure trigger is focused\n triggerRef.current?.focus()\n })\n\n const store = useMemo<SubmenuContextValue>(\n () => ({\n open: isOpen,\n setOpen: handleOpenChange,\n triggerRef,\n }),\n [isOpen, handleOpenChange],\n )\n\n return (\n <SubmenuContext.Provider value={store}>\n <DropdownMenu.Sub open={isOpen} onOpenChange={handleOpenChange}>\n {children}\n </DropdownMenu.Sub>\n </SubmenuContext.Provider>\n )\n}\n\nconst SubTrigger = ({\n className,\n children,\n disabled,\n}: {\n className?: string\n children: ReactNode\n disabled?: boolean\n}) => {\n const { open } = useMenuContext()\n const { triggerRef } = useSubmenuContext()\n\n // This handler patches over focus races with core Radix primitives\n // https://github.com/radix-ui/primitives/blob/main/packages/react/menu/src/Menu.tsx#L712-L734\n const handlePreventAfterClose = (evt: React.PointerEvent<HTMLDivElement>) => {\n // Prevent default behavior when we know the outer menu is closing\n if (!open) {\n evt.preventDefault()\n }\n }\n\n return (\n <DropdownMenu.SubTrigger\n ref={triggerRef}\n className={clsx(s.MenuItem, s.SubMenuItem, className)}\n disabled={disabled}\n onPointerMove={handlePreventAfterClose}\n onPointerLeave={handlePreventAfterClose}\n >\n <div className={s.PressableInner}>\n {children}\n <ChevronRight width=\"16\" height=\"16\" className={s.SubTriggerIcon} />\n </div>\n </DropdownMenu.SubTrigger>\n )\n}\n\ntype SubContentProps = {\n children: ReactNode\n sideOffset?: DropdownMenu.DropdownMenuSubContentProps[\"sideOffset\"]\n alignOffset?: DropdownMenu.DropdownMenuSubContentProps[\"alignOffset\"]\n width?: number | \"auto\"\n minWidth?: number | \"auto\"\n maxHeight?: number\n}\n\nconst SubContent = ({\n children,\n sideOffset = 4,\n alignOffset = -6,\n width = \"auto\",\n minWidth = \"auto\",\n maxHeight,\n}: SubContentProps) => {\n const { open } = useSubmenuContext()\n\n return (\n <DropdownMenu.Portal forceMount>\n <TransitionGroup className={s.Menu} enterDuration={350} exitDuration={200} disableAnimations>\n {open && (\n <DropdownMenu.SubContent\n key=\"submenu\"\n className={s.MenuList}\n sideOffset={sideOffset}\n alignOffset={alignOffset}\n avoidCollisions\n collisionPadding={{ bottom: 30, top: 30, left: 12, right: 12 }}\n onEscapeKeyDown={preventDefaultHandler}\n style={toCssVariables({\n \"menu-width\": width,\n \"menu-min-width\": minWidth,\n \"menu-max-height\": maxHeight,\n })}\n >\n {children}\n </DropdownMenu.SubContent>\n )}\n </TransitionGroup>\n </DropdownMenu.Portal>\n )\n}\n\nexport type MenuRadioGroupProps<T extends string> = {\n /** Controlled value */\n value: T\n /** Fired when selection changes */\n onChange: (value: T) => void\n children: ReactNode\n /**\n * The orientation of the indicator within the radio item.\n * @default end\n */\n indicatorPosition?: \"start\" | \"end\"\n}\n\nconst RadioGroup = <T extends string>({\n children,\n value,\n onChange,\n indicatorPosition = \"end\",\n ...props\n}: MenuRadioGroupProps<T>) => (\n <DropdownMenu.RadioGroup\n {...props}\n value={value}\n onValueChange={(v: string) => onChange(v as T)}\n data-indicator-position={indicatorPosition}\n >\n {children}\n </DropdownMenu.RadioGroup>\n)\n\nexport type MenuRadioItemProps<T extends string> = {\n value: T\n /** Class applied to the radio item */\n className?: string\n children: ReactNode\n /** Callback triggered when the radio item is pressed */\n onSelect?: DropdownMenu.DropdownMenuItemProps[\"onSelect\"]\n /** Disables the radio item */\n disabled?: boolean\n}\n\nconst RadioItem = <T extends string>({ className, children, ...props }: MenuRadioItemProps<T>) => (\n <DropdownMenu.RadioItem className={clsx(s.MenuItem, s.RadioItem, className)} {...props}>\n <div className={s.PressableInner}>\n <div className={s.RadioIndicator}>\n <DropdownMenu.ItemIndicator className={s.RadioIndicatorActive} />\n </div>\n {children}\n </div>\n </DropdownMenu.RadioItem>\n)\n\nexport type MenuCheckboxItemProps = {\n /** Controlled checked state of the checkbox item */\n checked?: DropdownMenu.DropdownMenuCheckboxItemProps[\"checked\"]\n /** Event handler called when the checked state changes */\n onCheckedChange?: DropdownMenu.DropdownMenuCheckboxItemProps[\"onCheckedChange\"]\n /** Class applied to the checkbox item */\n className?: string\n children: ReactNode\n /** Callback triggered when the checkbox item is pressed */\n onSelect?: DropdownMenu.DropdownMenuItemProps[\"onSelect\"]\n /** Disables the checkbox item */\n disabled?: boolean\n /**\n * The orientation of the indicator within the checkbox item.\n * @default end\n */\n indicatorPosition?: \"start\" | \"end\"\n /**\n * Visual treatment for the checkbox indicator.\n * @default solid\n */\n indicatorVariant?: \"solid\" | \"ghost\"\n}\nconst CheckboxItem = ({\n className,\n children,\n indicatorPosition = \"end\",\n indicatorVariant = \"solid\",\n ...props\n}: MenuCheckboxItemProps) => (\n <DropdownMenu.CheckboxItem\n className={clsx(s.MenuItem, s.CheckboxItem, className)}\n {...props}\n data-indicator-position={indicatorPosition}\n data-indicator-variant={indicatorVariant}\n >\n <div className={s.PressableInner}>\n <div className={s.CheckboxIndicator}>\n <DropdownMenu.ItemIndicator>\n {indicatorVariant === \"ghost\" ? (\n <Check className=\"size-4\" />\n ) : (\n <div className={s.CheckboxCircle}>\n <Check className=\"size-4\" />\n </div>\n )}\n </DropdownMenu.ItemIndicator>\n </div>\n {children}\n </div>\n </DropdownMenu.CheckboxItem>\n)\n\nMenu.Content = Content\nMenu.Item = Item\nMenu.ItemActions = ItemActions\nMenu.ItemAction = ItemAction\nMenu.Link = Link\nMenu.Separator = Separator\nMenu.Trigger = Trigger\nMenu.Sub = Sub\nMenu.SubTrigger = SubTrigger\nMenu.SubContent = SubContent\nMenu.CheckboxItem = CheckboxItem\nMenu.RadioGroup = RadioGroup\nMenu.RadioItem = RadioItem\nMenu.Label = Label\nMenu.Group = Group\n"]}
|
|
@@ -12,7 +12,7 @@ const INPUT_CURSOR_TOLERANCE_PX = 10;
|
|
|
12
12
|
const CONTAINER_PADDING_PX = 24;
|
|
13
13
|
const SHAKE_ANIMATION_DURATION_MS = 500;
|
|
14
14
|
export const TagInput = (props) => {
|
|
15
|
-
const { defaultValue: defaultValueProp = [], value: controlledValue, size = "xl", onChange, validator, maxTags, placeholder = "", autoFocus = false, rows = 1, delimiters = [",", " "], disabled, id, } = props;
|
|
15
|
+
const { defaultValue: defaultValueProp = [], value: controlledValue, size = "xl", onChange, validator, maxTags, placeholder = "", autoFocus = false, rows = 1, delimiters = [",", " "], disabled, pill = false, id, } = props;
|
|
16
16
|
const [internalTags, setInternalTags] = useState(defaultValueProp);
|
|
17
17
|
const value = controlledValue ?? internalTags;
|
|
18
18
|
const isControlled = controlledValue !== undefined;
|
|
@@ -48,20 +48,38 @@ export const TagInput = (props) => {
|
|
|
48
48
|
}
|
|
49
49
|
}, [focused, selectedTag, showInput]); // Include showInput so we focus the container when we hide the input
|
|
50
50
|
const placeholderText = tags.size === 0 ? placeholder : undefined;
|
|
51
|
-
// Handle positioning the real input inside of the container
|
|
52
|
-
//
|
|
51
|
+
// Handle positioning the real input inside of the container.
|
|
52
|
+
//
|
|
53
|
+
// Reasons we need to recompute input width:
|
|
54
|
+
// 1. Tags added / removed → last-tag right edge changes
|
|
55
|
+
// 2. User typing into input → measured text width changes
|
|
56
|
+
// 3. Container or chip dimensions change for any other reason —
|
|
57
|
+
// window resize, font load, parent layout shift, OR a `size`/
|
|
58
|
+
// `pill` prop flip that re-tunes chip height + font + gutter via
|
|
59
|
+
// CSS variables. Without watching for (3), `inputWidth` stays
|
|
60
|
+
// stale and the next typing flushes a one-off layout jump
|
|
61
|
+
// (visible as an extra wrap row right after toggling size).
|
|
62
|
+
//
|
|
63
|
+
// ResizeObserver covers (3) — it fires whenever the container or any
|
|
64
|
+
// chip changes box-size, including the synchronous CSS-var-driven
|
|
65
|
+
// reflow on a `size` toggle.
|
|
53
66
|
useLayoutEffect(() => {
|
|
54
|
-
if (containerRef.current
|
|
55
|
-
|
|
56
|
-
|
|
67
|
+
if (!containerRef.current || !measureRef.current) {
|
|
68
|
+
return;
|
|
69
|
+
}
|
|
70
|
+
const container = containerRef.current;
|
|
71
|
+
const measure = measureRef.current;
|
|
72
|
+
const recompute = () => {
|
|
73
|
+
const containerRect = container.getBoundingClientRect();
|
|
74
|
+
const tagElements = Array.from(container.querySelectorAll("[data-tag]"));
|
|
57
75
|
// Grab the right edge of the last tag if it exists, otherwise the left edge of the container
|
|
58
76
|
const leftBound = tagElements.length > 0
|
|
59
77
|
? tagElements[tagElements.length - 1].getBoundingClientRect().right
|
|
60
78
|
: containerRect.left;
|
|
61
|
-
|
|
79
|
+
measure.textContent = currentInput || placeholderText || "";
|
|
62
80
|
// By padding the text width, we ensure the input wraps to the next line
|
|
63
81
|
// before we get to the point where we start to overflow
|
|
64
|
-
const textWidth =
|
|
82
|
+
const textWidth = measure.getBoundingClientRect().width + INPUT_CURSOR_TOLERANCE_PX;
|
|
65
83
|
// Calculate the remaining space based on the last tag's right edge (or container's left if no tags)
|
|
66
84
|
const remainingSpace = containerRect.right - leftBound - CONTAINER_PADDING_PX;
|
|
67
85
|
if (textWidth <= remainingSpace) {
|
|
@@ -72,7 +90,20 @@ export const TagInput = (props) => {
|
|
|
72
90
|
const width = containerRect.right - containerRect.left - CONTAINER_PADDING_PX;
|
|
73
91
|
setInputWidth(width);
|
|
74
92
|
}
|
|
75
|
-
}
|
|
93
|
+
};
|
|
94
|
+
// Initial measurement (covers tags-array changes and typing).
|
|
95
|
+
recompute();
|
|
96
|
+
// Watch the container + every chip for any layout change. When `size`
|
|
97
|
+
// changes the container itself usually keeps the same width (it's
|
|
98
|
+
// `width: 100%`), but each chip's box does change — observing both
|
|
99
|
+
// is the cheapest way to catch every relevant reflow.
|
|
100
|
+
const observer = new ResizeObserver(recompute);
|
|
101
|
+
observer.observe(container);
|
|
102
|
+
const chips = container.querySelectorAll("[data-tag]");
|
|
103
|
+
chips.forEach((chip) => observer.observe(chip));
|
|
104
|
+
return () => {
|
|
105
|
+
observer.disconnect();
|
|
106
|
+
};
|
|
76
107
|
}, [currentInput, placeholderText, tags]); // Include tags so we reflow the container when we delete a tag
|
|
77
108
|
// ============================================
|
|
78
109
|
// Tag lifecycle functions
|
|
@@ -279,7 +310,7 @@ export const TagInput = (props) => {
|
|
|
279
310
|
};
|
|
280
311
|
// @ts-expect-error - Fix once usehooks-ts is updated https://github.com/juliencrn/usehooks-ts/pull/675
|
|
281
312
|
useOnClickOutside(containerRef, handleContainerBlur);
|
|
282
|
-
return (_jsxs(_Fragment, { children: [_jsx("div", { className: s.Container, ref: containerRef, onKeyDown: handleContainerKeyDown, onMouseDown: handleContainerMouseDown, onFocus: handleFocus, onBlur: handleBlur, "data-size": size, "data-focused": focused ? "" : undefined, "data-empty": tags.size === 0 ? "" : undefined, tabIndex: -1, style: toCssVariables({ "min-rows": String(rows) }), "data-disabled": disabled ? "" : undefined, children: _jsxs("div", { className: s.TagInput, children: [Array.from(tags.values()).map((tag) => (_jsxs("div", { className: s.Tag, tabIndex: -1, onClick: () => setSelectedTag(tag.value), "data-tag": tag.value, "data-invalid": !tag.valid ? "" : undefined, "data-duplicate": duplicateTags.has(tag.value) ? "" : undefined, children: [_jsx("span", { className: "overflow-hidden text-ellipsis", title: tag.value, children: _jsx("span", { className: s.TagValue, children: tag.value }) }), _jsx("div", { className: s.TagRemove, onClick: () => removeTag(tag.value), role: "button", "aria-label": "Remove item", children: _jsx(X, {}) })] }, tag.value))), showInput && (_jsxs("div", { className: s.InputContainer, children: [_jsx("span", { ref: measureRef, className: s.InputMeasure }), _jsx("div", { className: s.InputWrapper, children: _jsx("input", { id: id, className: s.Input, ref: inputRef, value: currentInput, onChange: (e) => {
|
|
313
|
+
return (_jsxs(_Fragment, { children: [_jsx("div", { className: s.Container, ref: containerRef, onKeyDown: handleContainerKeyDown, onMouseDown: handleContainerMouseDown, onFocus: handleFocus, onBlur: handleBlur, "data-size": size, "data-focused": focused ? "" : undefined, "data-empty": tags.size === 0 ? "" : undefined, "data-pill": pill ? "" : undefined, tabIndex: -1, style: toCssVariables({ "min-rows": String(rows) }), "data-disabled": disabled ? "" : undefined, children: _jsxs("div", { className: s.TagInput, children: [Array.from(tags.values()).map((tag) => (_jsxs("div", { className: s.Tag, tabIndex: -1, onClick: () => setSelectedTag(tag.value), "data-tag": tag.value, "data-invalid": !tag.valid ? "" : undefined, "data-duplicate": duplicateTags.has(tag.value) ? "" : undefined, children: [_jsx("span", { className: "overflow-hidden text-ellipsis", title: tag.value, children: _jsx("span", { className: s.TagValue, children: tag.value }) }), _jsx("div", { className: s.TagRemove, onClick: () => removeTag(tag.value), role: "button", "aria-label": "Remove item", children: _jsx(X, {}) })] }, tag.value))), showInput && (_jsxs("div", { className: s.InputContainer, children: [_jsx("span", { ref: measureRef, className: s.InputMeasure }), _jsx("div", { className: s.InputWrapper, children: _jsx("input", { id: id, className: s.Input, ref: inputRef, value: currentInput, onChange: (e) => {
|
|
283
314
|
setCurrentInput(e.target.value);
|
|
284
315
|
}, onPaste: handlePaste, onKeyDown: handleInputKeyDown, placeholder: placeholderText, style: { width: inputWidth }, disabled: disabled }) })] }))] }) }), maxTags && (_jsxs("div", { className: s.Limit, children: [tags.size, _jsx("span", { className: "mx-px", children: "/" }), maxTags] }))] }));
|
|
285
316
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"TagInput.js","sourceRoot":"","sources":["../../../../src/components/TagInput/TagInput.tsx"],"names":[],"mappings":"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","sourcesContent":["\"use client\"\n\nimport React, { useEffect, useLayoutEffect, useMemo, useRef, useState } from \"react\"\nimport { useOnClickOutside } from \"usehooks-ts\"\nimport { useLatestValue } from \"../../hooks/useLatestValue\"\nimport { toCssVariables } from \"../../lib/helpers\"\nimport type { Sizes } from \"../../types\"\nimport { X } from \"../Icon\"\nimport s from \"./TagInput.module.css\"\n\nexport type Tag = {\n value: string\n valid: boolean\n}\n\nexport type TagInputProps = {\n /**\n * The state of the tag input when it is initially rendered, used when uncontrolled\n */\n defaultValue?: Tag[]\n /**\n * The value of the tag input, used to control the tag input\n */\n value?: Tag[]\n /**\n * Allows the tag input to be targeted with htmlFor\n */\n id?: string\n /**\n * Corresponds with Input height when rows=1\n * @default xl\n */\n size?: Sizes<\"md\" | \"lg\" | \"xl\" | \"2xl\" | \"3xl\">\n /**\n * Callback function invoked when the tag list changes\n */\n onChange?: (tags: Tag[]) => void\n /**\n * Placeholder text for the input\n */\n placeholder?: string\n /**\n * A function that returns whether a given value is a valid tag.\n * Invalid tags are highlighted in red.\n * Tags are evaluated for validity only on creation; changing the validator function later has no effect\n */\n validator?: (value: string) => boolean\n /**\n * The maximum number of tags allowed before the input is disabled; displays a counter below the input\n */\n maxTags?: number\n /**\n * Whether to focus this input on mount\n * @default false\n */\n autoFocus?: boolean\n /**\n * The minimum number of rows for the tag input\n * @default 1\n */\n rows?: number\n /**\n * Controls what characters will count towards creating a new tag\n * @default [\",\", \" \"]\n */\n delimiters?: string[]\n /**\n * Disables the tag input visually and from interactions\n */\n disabled?: boolean\n}\n\n// How many pixels to reserve on the right of the input as a buffer before wrapping to the next line\nconst INPUT_CURSOR_TOLERANCE_PX = 10\n// The total space reserved on either side of the input for padding\nconst CONTAINER_PADDING_PX = 24\nconst SHAKE_ANIMATION_DURATION_MS = 500\n\nexport const TagInput = (props: TagInputProps) => {\n const {\n defaultValue: defaultValueProp = [],\n value: controlledValue,\n size = \"xl\",\n onChange,\n validator,\n maxTags,\n placeholder = \"\",\n autoFocus = false,\n rows = 1,\n delimiters = [\",\", \" \"],\n disabled,\n id,\n } = props\n\n const [internalTags, setInternalTags] = useState(defaultValueProp)\n\n const value = controlledValue ?? internalTags\n const isControlled = controlledValue !== undefined\n\n const tags = useMemo(() => new Map(value.map((tag) => [tag.value, tag])), [value])\n\n const [currentInput, setCurrentInput] = useState(\"\")\n const [focused, setFocused] = useState(autoFocus)\n const [selectedTag, setSelectedTag] = useState<string | null>(null)\n const [duplicateTags, setDuplicateTags] = useState<Set<string>>(new Set())\n const [inputWidth, setInputWidth] = useState<number>(0)\n const validatorLatest = useLatestValue(validator)\n const onChangeLatest = useLatestValue(onChange)\n\n const inputRef = useRef<HTMLInputElement>(null)\n const containerRef = useRef<HTMLDivElement>(null)\n const measureRef = useRef<HTMLSpanElement>(null)\n\n const showInput = !maxTags || tags.size < maxTags\n\n // Handle focusing the correct part of the tag input\n useEffect(() => {\n if (!focused || !containerRef.current) {\n return\n }\n const defaultFocusEl = inputRef.current ?? containerRef.current\n if (selectedTag === null) {\n defaultFocusEl.focus()\n } else {\n const selectedTagElement = containerRef.current.querySelector(\n `[data-tag=\"${selectedTag}\"]`,\n ) as HTMLElement | null\n if (selectedTagElement) {\n selectedTagElement.focus()\n } else {\n defaultFocusEl.focus()\n }\n }\n }, [focused, selectedTag, showInput]) // Include showInput so we focus the container when we hide the input\n\n const placeholderText = tags.size === 0 ? placeholder : undefined\n\n // Handle positioning the real input inside of the container\n // Use useLayoutEffect to avoid flashing during width calculation\n useLayoutEffect(() => {\n if (containerRef.current && measureRef.current) {\n const containerRect = containerRef.current.getBoundingClientRect()\n const tagElements = Array.from(\n containerRef.current.querySelectorAll(\"[data-tag]\"),\n ) as HTMLDivElement[]\n\n // Grab the right edge of the last tag if it exists, otherwise the left edge of the container\n const leftBound =\n tagElements.length > 0\n ? tagElements[tagElements.length - 1].getBoundingClientRect().right\n : containerRect.left\n\n measureRef.current.textContent = currentInput || placeholderText || \"\"\n\n // By padding the text width, we ensure the input wraps to the next line\n // before we get to the point where we start to overflow\n const textWidth = measureRef.current.getBoundingClientRect().width + INPUT_CURSOR_TOLERANCE_PX\n\n // Calculate the remaining space based on the last tag's right edge (or container's left if no tags)\n const remainingSpace = containerRect.right - leftBound - CONTAINER_PADDING_PX\n\n if (textWidth <= remainingSpace) {\n setInputWidth(remainingSpace)\n } else {\n // We are going to flow to a new line, so recalculate remaining space based on the container size\n const width = containerRect.right - containerRect.left - CONTAINER_PADDING_PX\n setInputWidth(width)\n }\n }\n }, [currentInput, placeholderText, tags]) // Include tags so we reflow the container when we delete a tag\n\n // ============================================\n // Tag lifecycle functions\n // ============================================\n\n const addTag = (tagValue: string) => {\n const trimmed = tagValue.trim()\n if (!trimmed) {\n return\n }\n if (tags.has(trimmed)) {\n setDuplicateTags((prevTags) => new Set(prevTags).add(trimmed))\n setTimeout(\n () =>\n setDuplicateTags((prevTags) => {\n const newTags = new Set(prevTags)\n newTags.delete(trimmed)\n return newTags\n }),\n SHAKE_ANIMATION_DURATION_MS,\n )\n return\n }\n const validTag = validatorLatest.current?.(trimmed) ?? true\n const newSet = new Map(tags)\n newSet.set(trimmed, { value: trimmed, valid: validTag })\n const newTags = Array.from(newSet.values())\n onChangeLatest.current?.(newTags)\n\n if (!isControlled) {\n setInternalTags(newTags)\n }\n }\n\n const removeTag = (tag: string) => {\n const newSet = new Map(tags)\n newSet.delete(tag)\n const newTags = Array.from(newSet.values())\n onChangeLatest.current?.(newTags)\n if (!isControlled) {\n setInternalTags(newTags)\n }\n if (selectedTag === tag) {\n setSelectedTag(null)\n }\n }\n\n const selectPreviousTag = () => {\n if (tags.size === 0) {\n return\n }\n const tagList = Array.from(tags.keys())\n if (selectedTag === null) {\n setSelectedTag(tagList[tagList.length - 1])\n } else {\n const prevIndex = tagList.indexOf(selectedTag)\n const index = Math.max(0, prevIndex - 1)\n setSelectedTag(tagList[index])\n }\n }\n\n const selectNextTag = () => {\n if (selectedTag === null) {\n return\n }\n const tagList = Array.from(tags.keys())\n const prevIndex = tagList.indexOf(selectedTag)\n const index = prevIndex + 1\n if (index < tagList.length) {\n setSelectedTag(tagList[index])\n } else {\n setSelectedTag(null)\n }\n }\n\n // ============================================\n // Helper functions\n // ============================================\n\n const isEmptyStartingSelection = () => {\n const input = inputRef.current\n if (!input) {\n return true\n }\n return input.selectionStart === 0 && input.selectionEnd === 0\n }\n\n const handleContainerBlur = () => {\n setFocused(false)\n setSelectedTag(null)\n if (currentInput) {\n addTag(currentInput)\n setCurrentInput(\"\")\n }\n }\n\n // ============================================\n // Event handlers\n // ============================================\n\n const handleContainerKeyDown = (e: React.KeyboardEvent<HTMLInputElement>) => {\n if (e.key === \"ArrowLeft\" || e.key === \"ArrowUp\") {\n if (isEmptyStartingSelection()) {\n e.preventDefault()\n selectPreviousTag()\n }\n } else if (e.key === \"ArrowRight\" || e.key === \"ArrowDown\") {\n if (selectedTag !== null) {\n e.preventDefault()\n selectNextTag()\n }\n } else if (e.key === \"Backspace\") {\n if (selectedTag !== null) {\n removeTag(selectedTag)\n } else if (isEmptyStartingSelection()) {\n selectPreviousTag()\n }\n }\n }\n\n const handleInputKeyDown = (e: React.KeyboardEvent<HTMLInputElement>) => {\n if (e.key === \"Enter\" || delimiters.includes(e.key)) {\n e.preventDefault()\n if (currentInput) {\n addTag(currentInput)\n setCurrentInput(\"\")\n }\n } else if (e.key === \"Tab\") {\n if (currentInput) {\n e.preventDefault()\n addTag(currentInput)\n setCurrentInput(\"\")\n }\n }\n }\n\n const handlePaste = (e: React.ClipboardEvent<HTMLInputElement>) => {\n const text = e.clipboardData.getData(\"Text\")\n let parts = [text]\n\n // Split by all delimiters\n for (const delimiter of delimiters) {\n const newParts = []\n for (const segment of parts) {\n newParts.push(...segment.split(delimiter))\n }\n parts = newParts\n }\n\n // Remove empty parts\n parts = parts.filter(Boolean)\n\n if (parts.length > 1) {\n e.preventDefault()\n parts.forEach((part) => addTag(part))\n }\n }\n\n const handleContainerMouseDown = (e: React.MouseEvent) => {\n // All clicks in the container focus the container\n setFocused(true)\n\n // If the click is on a tag pill, we are done. The click handler\n // for the specific tag will handle focusing it\n if (e.target && e.target instanceof Element && e.target.closest(\"[data-tag]\")) {\n return\n }\n\n // Since we know we didn't click a tag, clear any selected tag\n setSelectedTag(null)\n\n // If this click is outside of the input, prevent it from \"stealing\" focus from the input\n if (\n e.target &&\n e.target instanceof Element &&\n inputRef.current &&\n !inputRef.current.contains(e.target)\n ) {\n e.preventDefault()\n\n const { left, right, top, bottom } = inputRef.current.getBoundingClientRect()\n const { clientX, clientY } = e\n\n // If this is the first click, clear the selection. Otherwise, select the input contents\n if (e.detail === 1) {\n if (clientY < top || clientX < left) {\n // \"Before\" the input: top/left\n inputRef.current.setSelectionRange(0, 0)\n } else if (clientY > bottom || clientX > right) {\n // \"After\" the input: bottom/right\n const length = inputRef.current.value.length\n inputRef.current.setSelectionRange(length, length)\n }\n } else {\n inputRef.current.select()\n }\n }\n }\n\n const handleFocus = (e: React.FocusEvent) => {\n // If the focus is on a tag pill, do not trigger input focus logic\n // The click handler for the specific tag will handle it instead\n if (e.target && e.target instanceof Element && e.target.closest(\"[data-tag]\")) {\n return\n }\n setFocused(true)\n }\n\n const handleBlur = (e: React.FocusEvent) => {\n // If there is no related target, don't remove focus.\n // This occurs on a click inside the container but not on any element.\n // The handleClickOutside handler handles other cases\n if (!e.relatedTarget || !(e.relatedTarget instanceof Node)) {\n return\n }\n // Don't clear focus if focus is only moved elsewhere within the container\n if (containerRef.current && containerRef.current.contains(e.relatedTarget)) {\n // If we just tabbed into the input, clear the selected tag\n if (inputRef.current && inputRef.current.contains(e.relatedTarget)) {\n setSelectedTag(null)\n }\n return\n }\n handleContainerBlur()\n }\n\n // @ts-expect-error - Fix once usehooks-ts is updated https://github.com/juliencrn/usehooks-ts/pull/675\n useOnClickOutside(containerRef, handleContainerBlur)\n\n return (\n <>\n <div\n className={s.Container}\n ref={containerRef}\n onKeyDown={handleContainerKeyDown}\n onMouseDown={handleContainerMouseDown}\n onFocus={handleFocus}\n onBlur={handleBlur}\n data-size={size}\n data-focused={focused ? \"\" : undefined}\n data-empty={tags.size === 0 ? \"\" : undefined}\n tabIndex={-1}\n style={toCssVariables({ \"min-rows\": String(rows) })}\n data-disabled={disabled ? \"\" : undefined}\n >\n <div className={s.TagInput}>\n {Array.from(tags.values()).map((tag) => (\n <div\n key={tag.value}\n className={s.Tag}\n tabIndex={-1}\n onClick={() => setSelectedTag(tag.value)}\n data-tag={tag.value}\n data-invalid={!tag.valid ? \"\" : undefined}\n data-duplicate={duplicateTags.has(tag.value) ? \"\" : undefined}\n >\n <span className=\"overflow-hidden text-ellipsis\" title={tag.value}>\n <span className={s.TagValue}>{tag.value}</span>\n </span>\n <div\n className={s.TagRemove}\n onClick={() => removeTag(tag.value)}\n role=\"button\"\n aria-label=\"Remove item\"\n >\n <X />\n </div>\n </div>\n ))}\n {showInput && (\n <div className={s.InputContainer}>\n {/* Hidden element to measure input width */}\n <span ref={measureRef} className={s.InputMeasure} />\n <div className={s.InputWrapper}>\n <input\n id={id}\n className={s.Input}\n ref={inputRef}\n value={currentInput}\n onChange={(e) => {\n setCurrentInput(e.target.value)\n }}\n onPaste={handlePaste}\n onKeyDown={handleInputKeyDown}\n placeholder={placeholderText}\n style={{ width: inputWidth }}\n disabled={disabled}\n />\n </div>\n </div>\n )}\n </div>\n </div>\n {maxTags && (\n <div className={s.Limit}>\n {tags.size}\n <span className=\"mx-px\">/</span>\n {maxTags}\n </div>\n )}\n </>\n )\n}\n"]}
|
|
1
|
+
{"version":3,"file":"TagInput.js","sourceRoot":"","sources":["../../../../src/components/TagInput/TagInput.tsx"],"names":[],"mappings":"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","sourcesContent":["\"use client\"\n\nimport React, { useEffect, useLayoutEffect, useMemo, useRef, useState } from \"react\"\nimport { useOnClickOutside } from \"usehooks-ts\"\nimport { useLatestValue } from \"../../hooks/useLatestValue\"\nimport { toCssVariables } from \"../../lib/helpers\"\nimport type { Sizes } from \"../../types\"\nimport { X } from \"../Icon\"\nimport s from \"./TagInput.module.css\"\n\nexport type Tag = {\n value: string\n valid: boolean\n}\n\nexport type TagInputProps = {\n /**\n * The state of the tag input when it is initially rendered, used when uncontrolled\n */\n defaultValue?: Tag[]\n /**\n * The value of the tag input, used to control the tag input\n */\n value?: Tag[]\n /**\n * Allows the tag input to be targeted with htmlFor\n */\n id?: string\n /**\n * Corresponds with Input height when rows=1\n * @default xl\n */\n size?: Sizes<\"sm\" | \"md\" | \"lg\" | \"xl\" | \"2xl\" | \"3xl\">\n /**\n * Callback function invoked when the tag list changes\n */\n onChange?: (tags: Tag[]) => void\n /**\n * Placeholder text for the input\n */\n placeholder?: string\n /**\n * A function that returns whether a given value is a valid tag.\n * Invalid tags are highlighted in red.\n * Tags are evaluated for validity only on creation; changing the validator function later has no effect\n */\n validator?: (value: string) => boolean\n /**\n * The maximum number of tags allowed before the input is disabled; displays a counter below the input\n */\n maxTags?: number\n /**\n * Whether to focus this input on mount\n * @default false\n */\n autoFocus?: boolean\n /**\n * The minimum number of rows for the tag input\n * @default 1\n */\n rows?: number\n /**\n * Controls what characters will count towards creating a new tag\n * @default [\",\", \" \"]\n */\n delimiters?: string[]\n /**\n * Disables the tag input visually and from interactions\n */\n disabled?: boolean\n /**\n * Renders the container (and inner chips) with a fully-rounded radius,\n * matching `<Input pill />` and `<SelectControl pill />` for horizontal\n * filter rows that mix all three controls.\n * @default false\n */\n pill?: boolean\n}\n\n// How many pixels to reserve on the right of the input as a buffer before wrapping to the next line\nconst INPUT_CURSOR_TOLERANCE_PX = 10\n// The total space reserved on either side of the input for padding\nconst CONTAINER_PADDING_PX = 24\nconst SHAKE_ANIMATION_DURATION_MS = 500\n\nexport const TagInput = (props: TagInputProps) => {\n const {\n defaultValue: defaultValueProp = [],\n value: controlledValue,\n size = \"xl\",\n onChange,\n validator,\n maxTags,\n placeholder = \"\",\n autoFocus = false,\n rows = 1,\n delimiters = [\",\", \" \"],\n disabled,\n pill = false,\n id,\n } = props\n\n const [internalTags, setInternalTags] = useState(defaultValueProp)\n\n const value = controlledValue ?? internalTags\n const isControlled = controlledValue !== undefined\n\n const tags = useMemo(() => new Map(value.map((tag) => [tag.value, tag])), [value])\n\n const [currentInput, setCurrentInput] = useState(\"\")\n const [focused, setFocused] = useState(autoFocus)\n const [selectedTag, setSelectedTag] = useState<string | null>(null)\n const [duplicateTags, setDuplicateTags] = useState<Set<string>>(new Set())\n const [inputWidth, setInputWidth] = useState<number>(0)\n const validatorLatest = useLatestValue(validator)\n const onChangeLatest = useLatestValue(onChange)\n\n const inputRef = useRef<HTMLInputElement>(null)\n const containerRef = useRef<HTMLDivElement>(null)\n const measureRef = useRef<HTMLSpanElement>(null)\n\n const showInput = !maxTags || tags.size < maxTags\n\n // Handle focusing the correct part of the tag input\n useEffect(() => {\n if (!focused || !containerRef.current) {\n return\n }\n const defaultFocusEl = inputRef.current ?? containerRef.current\n if (selectedTag === null) {\n defaultFocusEl.focus()\n } else {\n const selectedTagElement = containerRef.current.querySelector(\n `[data-tag=\"${selectedTag}\"]`,\n ) as HTMLElement | null\n if (selectedTagElement) {\n selectedTagElement.focus()\n } else {\n defaultFocusEl.focus()\n }\n }\n }, [focused, selectedTag, showInput]) // Include showInput so we focus the container when we hide the input\n\n const placeholderText = tags.size === 0 ? placeholder : undefined\n\n // Handle positioning the real input inside of the container.\n //\n // Reasons we need to recompute input width:\n // 1. Tags added / removed → last-tag right edge changes\n // 2. User typing into input → measured text width changes\n // 3. Container or chip dimensions change for any other reason —\n // window resize, font load, parent layout shift, OR a `size`/\n // `pill` prop flip that re-tunes chip height + font + gutter via\n // CSS variables. Without watching for (3), `inputWidth` stays\n // stale and the next typing flushes a one-off layout jump\n // (visible as an extra wrap row right after toggling size).\n //\n // ResizeObserver covers (3) — it fires whenever the container or any\n // chip changes box-size, including the synchronous CSS-var-driven\n // reflow on a `size` toggle.\n useLayoutEffect(() => {\n if (!containerRef.current || !measureRef.current) {\n return\n }\n const container = containerRef.current\n const measure = measureRef.current\n\n const recompute = () => {\n const containerRect = container.getBoundingClientRect()\n const tagElements = Array.from(\n container.querySelectorAll(\"[data-tag]\"),\n ) as HTMLDivElement[]\n\n // Grab the right edge of the last tag if it exists, otherwise the left edge of the container\n const leftBound =\n tagElements.length > 0\n ? tagElements[tagElements.length - 1].getBoundingClientRect().right\n : containerRect.left\n\n measure.textContent = currentInput || placeholderText || \"\"\n\n // By padding the text width, we ensure the input wraps to the next line\n // before we get to the point where we start to overflow\n const textWidth = measure.getBoundingClientRect().width + INPUT_CURSOR_TOLERANCE_PX\n\n // Calculate the remaining space based on the last tag's right edge (or container's left if no tags)\n const remainingSpace = containerRect.right - leftBound - CONTAINER_PADDING_PX\n\n if (textWidth <= remainingSpace) {\n setInputWidth(remainingSpace)\n } else {\n // We are going to flow to a new line, so recalculate remaining space based on the container size\n const width = containerRect.right - containerRect.left - CONTAINER_PADDING_PX\n setInputWidth(width)\n }\n }\n\n // Initial measurement (covers tags-array changes and typing).\n recompute()\n\n // Watch the container + every chip for any layout change. When `size`\n // changes the container itself usually keeps the same width (it's\n // `width: 100%`), but each chip's box does change — observing both\n // is the cheapest way to catch every relevant reflow.\n const observer = new ResizeObserver(recompute)\n observer.observe(container)\n const chips = container.querySelectorAll(\"[data-tag]\")\n chips.forEach((chip) => observer.observe(chip))\n\n return () => {\n observer.disconnect()\n }\n }, [currentInput, placeholderText, tags]) // Include tags so we reflow the container when we delete a tag\n\n // ============================================\n // Tag lifecycle functions\n // ============================================\n\n const addTag = (tagValue: string) => {\n const trimmed = tagValue.trim()\n if (!trimmed) {\n return\n }\n if (tags.has(trimmed)) {\n setDuplicateTags((prevTags) => new Set(prevTags).add(trimmed))\n setTimeout(\n () =>\n setDuplicateTags((prevTags) => {\n const newTags = new Set(prevTags)\n newTags.delete(trimmed)\n return newTags\n }),\n SHAKE_ANIMATION_DURATION_MS,\n )\n return\n }\n const validTag = validatorLatest.current?.(trimmed) ?? true\n const newSet = new Map(tags)\n newSet.set(trimmed, { value: trimmed, valid: validTag })\n const newTags = Array.from(newSet.values())\n onChangeLatest.current?.(newTags)\n\n if (!isControlled) {\n setInternalTags(newTags)\n }\n }\n\n const removeTag = (tag: string) => {\n const newSet = new Map(tags)\n newSet.delete(tag)\n const newTags = Array.from(newSet.values())\n onChangeLatest.current?.(newTags)\n if (!isControlled) {\n setInternalTags(newTags)\n }\n if (selectedTag === tag) {\n setSelectedTag(null)\n }\n }\n\n const selectPreviousTag = () => {\n if (tags.size === 0) {\n return\n }\n const tagList = Array.from(tags.keys())\n if (selectedTag === null) {\n setSelectedTag(tagList[tagList.length - 1])\n } else {\n const prevIndex = tagList.indexOf(selectedTag)\n const index = Math.max(0, prevIndex - 1)\n setSelectedTag(tagList[index])\n }\n }\n\n const selectNextTag = () => {\n if (selectedTag === null) {\n return\n }\n const tagList = Array.from(tags.keys())\n const prevIndex = tagList.indexOf(selectedTag)\n const index = prevIndex + 1\n if (index < tagList.length) {\n setSelectedTag(tagList[index])\n } else {\n setSelectedTag(null)\n }\n }\n\n // ============================================\n // Helper functions\n // ============================================\n\n const isEmptyStartingSelection = () => {\n const input = inputRef.current\n if (!input) {\n return true\n }\n return input.selectionStart === 0 && input.selectionEnd === 0\n }\n\n const handleContainerBlur = () => {\n setFocused(false)\n setSelectedTag(null)\n if (currentInput) {\n addTag(currentInput)\n setCurrentInput(\"\")\n }\n }\n\n // ============================================\n // Event handlers\n // ============================================\n\n const handleContainerKeyDown = (e: React.KeyboardEvent<HTMLInputElement>) => {\n if (e.key === \"ArrowLeft\" || e.key === \"ArrowUp\") {\n if (isEmptyStartingSelection()) {\n e.preventDefault()\n selectPreviousTag()\n }\n } else if (e.key === \"ArrowRight\" || e.key === \"ArrowDown\") {\n if (selectedTag !== null) {\n e.preventDefault()\n selectNextTag()\n }\n } else if (e.key === \"Backspace\") {\n if (selectedTag !== null) {\n removeTag(selectedTag)\n } else if (isEmptyStartingSelection()) {\n selectPreviousTag()\n }\n }\n }\n\n const handleInputKeyDown = (e: React.KeyboardEvent<HTMLInputElement>) => {\n if (e.key === \"Enter\" || delimiters.includes(e.key)) {\n e.preventDefault()\n if (currentInput) {\n addTag(currentInput)\n setCurrentInput(\"\")\n }\n } else if (e.key === \"Tab\") {\n if (currentInput) {\n e.preventDefault()\n addTag(currentInput)\n setCurrentInput(\"\")\n }\n }\n }\n\n const handlePaste = (e: React.ClipboardEvent<HTMLInputElement>) => {\n const text = e.clipboardData.getData(\"Text\")\n let parts = [text]\n\n // Split by all delimiters\n for (const delimiter of delimiters) {\n const newParts = []\n for (const segment of parts) {\n newParts.push(...segment.split(delimiter))\n }\n parts = newParts\n }\n\n // Remove empty parts\n parts = parts.filter(Boolean)\n\n if (parts.length > 1) {\n e.preventDefault()\n parts.forEach((part) => addTag(part))\n }\n }\n\n const handleContainerMouseDown = (e: React.MouseEvent) => {\n // All clicks in the container focus the container\n setFocused(true)\n\n // If the click is on a tag pill, we are done. The click handler\n // for the specific tag will handle focusing it\n if (e.target && e.target instanceof Element && e.target.closest(\"[data-tag]\")) {\n return\n }\n\n // Since we know we didn't click a tag, clear any selected tag\n setSelectedTag(null)\n\n // If this click is outside of the input, prevent it from \"stealing\" focus from the input\n if (\n e.target &&\n e.target instanceof Element &&\n inputRef.current &&\n !inputRef.current.contains(e.target)\n ) {\n e.preventDefault()\n\n const { left, right, top, bottom } = inputRef.current.getBoundingClientRect()\n const { clientX, clientY } = e\n\n // If this is the first click, clear the selection. Otherwise, select the input contents\n if (e.detail === 1) {\n if (clientY < top || clientX < left) {\n // \"Before\" the input: top/left\n inputRef.current.setSelectionRange(0, 0)\n } else if (clientY > bottom || clientX > right) {\n // \"After\" the input: bottom/right\n const length = inputRef.current.value.length\n inputRef.current.setSelectionRange(length, length)\n }\n } else {\n inputRef.current.select()\n }\n }\n }\n\n const handleFocus = (e: React.FocusEvent) => {\n // If the focus is on a tag pill, do not trigger input focus logic\n // The click handler for the specific tag will handle it instead\n if (e.target && e.target instanceof Element && e.target.closest(\"[data-tag]\")) {\n return\n }\n setFocused(true)\n }\n\n const handleBlur = (e: React.FocusEvent) => {\n // If there is no related target, don't remove focus.\n // This occurs on a click inside the container but not on any element.\n // The handleClickOutside handler handles other cases\n if (!e.relatedTarget || !(e.relatedTarget instanceof Node)) {\n return\n }\n // Don't clear focus if focus is only moved elsewhere within the container\n if (containerRef.current && containerRef.current.contains(e.relatedTarget)) {\n // If we just tabbed into the input, clear the selected tag\n if (inputRef.current && inputRef.current.contains(e.relatedTarget)) {\n setSelectedTag(null)\n }\n return\n }\n handleContainerBlur()\n }\n\n // @ts-expect-error - Fix once usehooks-ts is updated https://github.com/juliencrn/usehooks-ts/pull/675\n useOnClickOutside(containerRef, handleContainerBlur)\n\n return (\n <>\n <div\n className={s.Container}\n ref={containerRef}\n onKeyDown={handleContainerKeyDown}\n onMouseDown={handleContainerMouseDown}\n onFocus={handleFocus}\n onBlur={handleBlur}\n data-size={size}\n data-focused={focused ? \"\" : undefined}\n data-empty={tags.size === 0 ? \"\" : undefined}\n data-pill={pill ? \"\" : undefined}\n tabIndex={-1}\n style={toCssVariables({ \"min-rows\": String(rows) })}\n data-disabled={disabled ? \"\" : undefined}\n >\n <div className={s.TagInput}>\n {Array.from(tags.values()).map((tag) => (\n <div\n key={tag.value}\n className={s.Tag}\n tabIndex={-1}\n onClick={() => setSelectedTag(tag.value)}\n data-tag={tag.value}\n data-invalid={!tag.valid ? \"\" : undefined}\n data-duplicate={duplicateTags.has(tag.value) ? \"\" : undefined}\n >\n <span className=\"overflow-hidden text-ellipsis\" title={tag.value}>\n <span className={s.TagValue}>{tag.value}</span>\n </span>\n <div\n className={s.TagRemove}\n onClick={() => removeTag(tag.value)}\n role=\"button\"\n aria-label=\"Remove item\"\n >\n <X />\n </div>\n </div>\n ))}\n {showInput && (\n <div className={s.InputContainer}>\n {/* Hidden element to measure input width */}\n <span ref={measureRef} className={s.InputMeasure} />\n <div className={s.InputWrapper}>\n <input\n id={id}\n className={s.Input}\n ref={inputRef}\n value={currentInput}\n onChange={(e) => {\n setCurrentInput(e.target.value)\n }}\n onPaste={handlePaste}\n onKeyDown={handleInputKeyDown}\n placeholder={placeholderText}\n style={{ width: inputWidth }}\n disabled={disabled}\n />\n </div>\n </div>\n )}\n </div>\n </div>\n {maxTags && (\n <div className={s.Limit}>\n {tags.size}\n <span className=\"mx-px\">/</span>\n {maxTags}\n </div>\n )}\n </>\n )\n}\n"]}
|
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
(var(--min-rows) * var(--tag-input-height)) + ((var(--min-rows) + 1) * var(--tag-input-tag-spacing))
|
|
10
10
|
);
|
|
11
11
|
padding: var(--tag-input-tag-spacing);
|
|
12
|
-
border-radius: var(--radius-md);
|
|
12
|
+
border-radius: var(--tag-input-radius, var(--radius-md));
|
|
13
13
|
box-shadow: 0 0 0 1px var(--input-outline-border-color) inset;
|
|
14
14
|
cursor: text;
|
|
15
15
|
outline: 0;
|
|
@@ -17,6 +17,17 @@
|
|
|
17
17
|
|
|
18
18
|
/* =============================================
|
|
19
19
|
Sizes
|
|
20
|
+
-----------------------------------------------
|
|
21
|
+
Each size sets the inner input height + the
|
|
22
|
+
container padding/gap (`--tag-input-tag-spacing`).
|
|
23
|
+
The sum `(rows × tag-input-height) + ((rows + 1) × tag-input-tag-spacing)`
|
|
24
|
+
equals the matching Input size when rows=1, so a
|
|
25
|
+
TagInput[size=md] sits flush next to an Input[size=md]
|
|
26
|
+
in a horizontal layout.
|
|
27
|
+
|
|
28
|
+
Sizes also re-tune the chip itself via
|
|
29
|
+
`--tag-input-tag-{height,gutter,font-size}` so the
|
|
30
|
+
inner pills stay proportional to the container.
|
|
20
31
|
============================================= */
|
|
21
32
|
}
|
|
22
33
|
|
|
@@ -38,11 +49,42 @@ box-shadow: 0 0 0 1px var(--gray-500) inset;
|
|
|
38
49
|
padding: var(--tag-input-tag-spacing) 12px;
|
|
39
50
|
}
|
|
40
51
|
|
|
52
|
+
/* =============================================
|
|
53
|
+
Pill — fully-rounded for the single-row state.
|
|
54
|
+
----------------------------------------------
|
|
55
|
+
The radius is locked to half of a single-row
|
|
56
|
+
container height (= half of `--control-size-*`).
|
|
57
|
+
With `radius-full` the container would stay an
|
|
58
|
+
ellipse when the chip list wraps to a second/third
|
|
59
|
+
row, which looks bad. Computing it from the
|
|
60
|
+
single-row height keeps the corners visually pill
|
|
61
|
+
on row 1 and stays sane on multi-row.
|
|
62
|
+
============================================= */
|
|
63
|
+
.Container[data-pill] {
|
|
64
|
+
border-radius: calc(
|
|
65
|
+
(var(--tag-input-height) + 2 * var(--tag-input-tag-spacing)) / 2
|
|
66
|
+
);
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
.Container[data-pill][data-empty] {
|
|
70
|
+
padding: var(--tag-input-tag-spacing) 16px;
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
/* 20 + 4 + 4 = 28 */
|
|
74
|
+
.Container:where([data-size="sm"]) {
|
|
75
|
+
--tag-input-font-size: var(--control-font-size-md);
|
|
76
|
+
--tag-input-height: 20px;
|
|
77
|
+
--tag-input-tag-spacing: 4px;
|
|
78
|
+
--tag-input-tag-gutter: var(--control-gutter-2xs);
|
|
79
|
+
--tag-input-radius: var(--control-radius-sm);
|
|
80
|
+
}
|
|
81
|
+
|
|
41
82
|
/* 20 + 6 + 6 = 32 */
|
|
42
83
|
.Container:where([data-size="md"]) {
|
|
43
84
|
--tag-input-font-size: var(--control-font-size-md);
|
|
44
85
|
--tag-input-height: 20px;
|
|
45
86
|
--tag-input-tag-spacing: 6px;
|
|
87
|
+
--tag-input-radius: var(--control-radius-md);
|
|
46
88
|
}
|
|
47
89
|
|
|
48
90
|
/* 24 + 6 + 6 = 36 */
|
|
@@ -50,13 +92,17 @@ box-shadow: 0 0 0 1px var(--gray-500) inset;
|
|
|
50
92
|
--tag-input-font-size: var(--control-font-size-md);
|
|
51
93
|
--tag-input-height: 24px;
|
|
52
94
|
--tag-input-tag-spacing: 6px;
|
|
95
|
+
--tag-input-radius: var(--control-radius-lg);
|
|
53
96
|
}
|
|
54
97
|
|
|
55
98
|
/* 24 + 8 + 8 = 40 */
|
|
56
99
|
.Container:where([data-size="xl"]) {
|
|
57
|
-
|
|
100
|
+
/* SelectControl xl uses control-font-size-md (not -lg), so the chip + input
|
|
101
|
+
text inside TagInput xl matches Select xl. */
|
|
102
|
+
--tag-input-font-size: var(--control-font-size-md);
|
|
58
103
|
--tag-input-height: 24px;
|
|
59
104
|
--tag-input-tag-spacing: 8px;
|
|
105
|
+
--tag-input-radius: var(--control-radius-xl);
|
|
60
106
|
}
|
|
61
107
|
|
|
62
108
|
/* 28 + 8 + 8 = 44 */
|
|
@@ -64,6 +110,7 @@ box-shadow: 0 0 0 1px var(--gray-500) inset;
|
|
|
64
110
|
--tag-input-font-size: var(--control-font-size-lg);
|
|
65
111
|
--tag-input-height: 28px;
|
|
66
112
|
--tag-input-tag-spacing: 8px;
|
|
113
|
+
--tag-input-radius: var(--control-radius-xl);
|
|
67
114
|
}
|
|
68
115
|
|
|
69
116
|
/* 32 + 8 + 8 = 48 */
|
|
@@ -71,6 +118,7 @@ box-shadow: 0 0 0 1px var(--gray-500) inset;
|
|
|
71
118
|
--tag-input-font-size: var(--control-font-size-lg);
|
|
72
119
|
--tag-input-height: 32px;
|
|
73
120
|
--tag-input-tag-spacing: 8px;
|
|
121
|
+
--tag-input-radius: var(--control-radius-xl);
|
|
74
122
|
}.TagInput {
|
|
75
123
|
display: flex;
|
|
76
124
|
flex-wrap: wrap;
|
|
@@ -80,12 +128,31 @@ box-shadow: 0 0 0 1px var(--gray-500) inset;
|
|
|
80
128
|
display: inline-flex;
|
|
81
129
|
align-items: center;
|
|
82
130
|
gap: calc(var(--spacing) * 1);
|
|
83
|
-
height
|
|
84
|
-
|
|
85
|
-
|
|
131
|
+
/* Match the inner input height so a chip-filled container is exactly
|
|
132
|
+
the same height as an empty one (= matching Input[size] of the same size).
|
|
133
|
+
Override per-size via `--tag-input-tag-height` if a non-square chip is needed. */
|
|
134
|
+
height: var(--tag-input-tag-height, var(--tag-input-height));
|
|
135
|
+
/* Right padding equals the chip's vertical padding so the close button
|
|
136
|
+
sits with equal whitespace on top, bottom, and right. */
|
|
137
|
+
padding: 0 calc((var(--tag-input-tag-height, var(--tag-input-height)) - var(--control-icon-size-sm)) / 2) 0
|
|
138
|
+
var(--tag-input-tag-gutter, var(--control-gutter-xs));
|
|
139
|
+
/* Concentric with the container: chip radius = container radius − inner padding.
|
|
140
|
+
Falls through every size automatically because both vars are set per-size. */
|
|
141
|
+
border-radius: var(--tag-input-tag-radius, calc(var(--tag-input-radius) - var(--tag-input-tag-spacing)));
|
|
142
|
+
/* Match SelectControl text-size for the same `size` (md/lg=14, xl/2xl/3xl=16);
|
|
143
|
+
`--tag-input-font-size` is set per-size to the same token Select uses. */
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
.Container[data-pill] .Tag {
|
|
147
|
+
/* Chip height is fixed (single row) so half of it gives a true pill,
|
|
148
|
+
same idea as the container's pill rule above. */
|
|
149
|
+
border-radius: calc(var(--tag-input-tag-height, var(--tag-input-height)) / 2);
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
.Tag {
|
|
86
153
|
background-color: var(--color-background-secondary-soft-alpha);
|
|
87
154
|
color: var(--color-text-secondary-soft);
|
|
88
|
-
font-size: var(--
|
|
155
|
+
font-size: var(--tag-input-tag-font-size, var(--tag-input-font-size));
|
|
89
156
|
font-weight: var(--button-font-weight);
|
|
90
157
|
cursor: pointer;
|
|
91
158
|
white-space: nowrap;
|
|
@@ -137,7 +204,6 @@ box-shadow: 0 0 0 1px var(--gray-500) inset;
|
|
|
137
204
|
}.TagRemove {
|
|
138
205
|
display: flex;
|
|
139
206
|
align-items: center;
|
|
140
|
-
margin-right: -1px;
|
|
141
207
|
color: inherit;
|
|
142
208
|
opacity: 0.5;
|
|
143
209
|
transition: opacity 0.15s ease;
|
|
@@ -330,7 +330,7 @@
|
|
|
330
330
|
/* =============================================
|
|
331
331
|
SelectControl
|
|
332
332
|
============================================= */
|
|
333
|
-
--select-control-font-weight: var(--font-weight-
|
|
333
|
+
--select-control-font-weight: var(--font-weight-normal);
|
|
334
334
|
|
|
335
335
|
/* =============================================
|
|
336
336
|
Slider
|
|
@@ -16,7 +16,7 @@ export type MenuProps = {
|
|
|
16
16
|
};
|
|
17
17
|
export declare const Menu: {
|
|
18
18
|
({ children, forceOpen, onOpen, onClose, modal }: MenuProps): import("react/jsx-runtime").JSX.Element;
|
|
19
|
-
Content: ({ children, side, sideOffset, align, alignOffset, width, minWidth, maxHeight, layout, size, }: MenuContentProps) => import("react/jsx-runtime").JSX.Element;
|
|
19
|
+
Content: ({ children, side, sideOffset, align, alignOffset, width, minWidth, maxHeight, layout, size, onCloseAutoFocus, }: MenuContentProps) => import("react/jsx-runtime").JSX.Element;
|
|
20
20
|
Item: ({ className, children, disabled, onSelect, onClick }: MenuItemProps) => import("react/jsx-runtime").JSX.Element;
|
|
21
21
|
ItemActions: ({ className, children }: {
|
|
22
22
|
className?: string;
|
|
@@ -124,6 +124,12 @@ export type MenuContentProps = {
|
|
|
124
124
|
* @default "md"
|
|
125
125
|
*/
|
|
126
126
|
size?: "sm" | "md" | "lg";
|
|
127
|
+
/**
|
|
128
|
+
* Event handler called when auto-focus tries to return to the trigger
|
|
129
|
+
* after the menu closes. Call `event.preventDefault()` to prevent the
|
|
130
|
+
* trigger from regaining focus (and its focus-visible ring).
|
|
131
|
+
*/
|
|
132
|
+
onCloseAutoFocus?: DropdownMenu.DropdownMenuContentProps["onCloseAutoFocus"];
|
|
127
133
|
};
|
|
128
134
|
export type SubmenuProps = {
|
|
129
135
|
children: React.ReactNode;
|
|
@@ -20,7 +20,7 @@ export type TagInputProps = {
|
|
|
20
20
|
* Corresponds with Input height when rows=1
|
|
21
21
|
* @default xl
|
|
22
22
|
*/
|
|
23
|
-
size?: Sizes<"md" | "lg" | "xl" | "2xl" | "3xl">;
|
|
23
|
+
size?: Sizes<"sm" | "md" | "lg" | "xl" | "2xl" | "3xl">;
|
|
24
24
|
/**
|
|
25
25
|
* Callback function invoked when the tag list changes
|
|
26
26
|
*/
|
|
@@ -58,5 +58,12 @@ export type TagInputProps = {
|
|
|
58
58
|
* Disables the tag input visually and from interactions
|
|
59
59
|
*/
|
|
60
60
|
disabled?: boolean;
|
|
61
|
+
/**
|
|
62
|
+
* Renders the container (and inner chips) with a fully-rounded radius,
|
|
63
|
+
* matching `<Input pill />` and `<SelectControl pill />` for horizontal
|
|
64
|
+
* filter rows that mix all three controls.
|
|
65
|
+
* @default false
|
|
66
|
+
*/
|
|
67
|
+
pill?: boolean;
|
|
61
68
|
};
|
|
62
69
|
export declare const TagInput: (props: TagInputProps) => import("react/jsx-runtime").JSX.Element;
|