@bitrise/bitkit-v2 0.3.416 → 0.3.418

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.
@@ -57,7 +57,7 @@ var BitkitBreadcrumbRoot = forwardRef(({ children, ...rest }, ref) => {
57
57
  ref,
58
58
  ...rest,
59
59
  children: /* @__PURE__ */ jsx(Breadcrumb.List, { children: childArray.map((child, index) => /* @__PURE__ */ jsxs(Fragment, { children: [child, /* @__PURE__ */ jsx(Show, {
60
- when: index < childArray.length - 1,
60
+ when: index < childArray.length - 1 || child.type === BreadcrumbItem,
61
61
  children: /* @__PURE__ */ jsx(Breadcrumb.Separator, { children: /* @__PURE__ */ jsx(IconChevronRight, {}) })
62
62
  })] }, child.key)) })
63
63
  });
@@ -1 +1 @@
1
- {"version":3,"file":"BitkitBreadcrumb.js","names":[],"sources":["../../../lib/components/BitkitBreadcrumb/BitkitBreadcrumb.tsx"],"sourcesContent":["import { Breadcrumb, type BreadcrumbRootProps } from '@chakra-ui/react/breadcrumb';\nimport { useBreakpointValue } from '@chakra-ui/react/hooks';\nimport { Show } from '@chakra-ui/react/show';\nimport { forwardRef, Fragment, type ReactElement } from 'react';\n\nimport { IconChevronRight, IconMoreHorizontal } from '../../icons';\nimport { flattenChildren } from '../../utilities/flattenChildren';\nimport { withSubComponents } from '../../utilities/withSubComponents.ts';\nimport BitkitControlButton from '../BitkitControlButton/BitkitControlButton.tsx';\nimport BreadcrumbCurrentItem, { type CurrentItemProps } from './components/BreadcrumbCurrentItem.tsx';\nimport BreadcrumbItem from './components/BreadcrumbItem.tsx';\nimport OverflowMenu, { type OverflowMenuProps } from './components/OverflowMenu.tsx';\nimport OverflowMenuItem from './components/OverflowMenuItem.tsx';\nimport OverflowMenuTrigger from './components/OverflowMenuTrigger.tsx';\nimport { type ItemProps } from './types.ts';\n\ntype BitkitBreadcrumbChild = ReactElement<ItemProps> | ReactElement<CurrentItemProps> | ReactElement<OverflowMenuProps>;\n\nexport type BitkitBreadcrumbProps = Omit<BreadcrumbRootProps, 'children'> & {\n children: BitkitBreadcrumbChild | BitkitBreadcrumbChild[];\n};\n\n// The whole prop bag travels, not just `href`/`children`: the mobile layout rebuilds its items\n// from these, so picking two keys here would drop everything else a consumer put on a crumb — a\n// `data-*` hook, an `aria-*`, an `onClick` — on mobile only, and silently.\nconst flattenItemProps = (elements: ReactElement[]): ItemProps[] => {\n const props: ItemProps[] = [];\n\n for (const child of elements) {\n if (child.type === BreadcrumbItem) {\n props.push(child.props as ItemProps);\n } else if (child.type === OverflowMenu) {\n const { children: menuChildren } = child.props as OverflowMenuProps;\n const menuChildArray = flattenChildren(menuChildren);\n for (const menuChild of menuChildArray) {\n if (menuChild.type === OverflowMenuItem) {\n props.push(menuChild.props as ItemProps);\n }\n }\n }\n }\n\n return props;\n};\n\nconst BitkitBreadcrumbRoot = forwardRef<HTMLElement, BitkitBreadcrumbProps>(({ children, ...rest }, ref) => {\n const isMobile = useBreakpointValue({ base: true, tablet: false }, { fallback: 'tablet' });\n const childArray = flattenChildren(children);\n\n if (childArray.length === 0) {\n return null;\n }\n\n if (isMobile) {\n const links = flattenItemProps(childArray);\n if (links.length === 0) {\n return null;\n }\n\n const lastLink = links[links.length - 1];\n const overflowLinks = links.slice(0, -1).reverse();\n\n return (\n <Breadcrumb.Root ref={ref} {...rest}>\n <Breadcrumb.List>\n <Show when={overflowLinks.length > 0}>\n <OverflowMenu>\n <OverflowMenuTrigger>\n <BitkitControlButton icon={IconMoreHorizontal} label=\"Open breadcrumbs\" size=\"xs\" />\n </OverflowMenuTrigger>\n {overflowLinks.map((link) => (\n <OverflowMenuItem key={link.href} {...link} />\n ))}\n </OverflowMenu>\n <Breadcrumb.Separator>\n <IconChevronRight />\n </Breadcrumb.Separator>\n </Show>\n <BreadcrumbItem {...lastLink} />\n <Breadcrumb.Separator>\n <IconChevronRight />\n </Breadcrumb.Separator>\n </Breadcrumb.List>\n </Breadcrumb.Root>\n );\n }\n\n return (\n <Breadcrumb.Root ref={ref} {...rest}>\n <Breadcrumb.List>\n {childArray.map((child, index) => (\n <Fragment key={child.key}>\n {child}\n <Show when={index < childArray.length - 1}>\n <Breadcrumb.Separator>\n <IconChevronRight />\n </Breadcrumb.Separator>\n </Show>\n </Fragment>\n ))}\n </Breadcrumb.List>\n </Breadcrumb.Root>\n );\n});\n\nBitkitBreadcrumbRoot.displayName = 'BitkitBreadcrumb';\n\nconst BitkitBreadcrumb = withSubComponents(BitkitBreadcrumbRoot, {\n CurrentItem: BreadcrumbCurrentItem,\n Item: BreadcrumbItem,\n OverflowMenu,\n OverflowMenuItem,\n});\n\nexport default BitkitBreadcrumb;\n"],"mappings":";;;;;;;;;;;;;;;;AAyBA,IAAM,oBAAoB,aAA0C;CAClE,MAAM,QAAqB,CAAC;CAE5B,KAAK,MAAM,SAAS,UAClB,IAAI,MAAM,SAAS,gBACjB,MAAM,KAAK,MAAM,KAAkB;MAC9B,IAAI,MAAM,SAAS,cAAc;EACtC,MAAM,EAAE,UAAU,iBAAiB,MAAM;EACzC,MAAM,iBAAiB,gBAAgB,YAAY;EACnD,KAAK,MAAM,aAAa,gBACtB,IAAI,UAAU,SAAS,kBACrB,MAAM,KAAK,UAAU,KAAkB;CAG7C;CAGF,OAAO;AACT;AAEA,IAAM,uBAAuB,YAAgD,EAAE,UAAU,GAAG,QAAQ,QAAQ;CAC1G,MAAM,WAAW,mBAAmB;EAAE,MAAM;EAAM,QAAQ;CAAM,GAAG,EAAE,UAAU,SAAS,CAAC;CACzF,MAAM,aAAa,gBAAgB,QAAQ;CAE3C,IAAI,WAAW,WAAW,GACxB,OAAO;CAGT,IAAI,UAAU;EACZ,MAAM,QAAQ,iBAAiB,UAAU;EACzC,IAAI,MAAM,WAAW,GACnB,OAAO;EAGT,MAAM,WAAW,MAAM,MAAM,SAAS;EACtC,MAAM,gBAAgB,MAAM,MAAM,GAAG,EAAE,CAAC,CAAC,QAAQ;EAEjD,OACE,oBAAC,WAAW,MAAZ;GAAsB;GAAK,GAAI;GAC7B,UAAA,qBAAC,WAAW,MAAZ,EAAA,UAAA;IACE,qBAAC,MAAD;KAAM,MAAM,cAAc,SAAS;KAAnC,UAAA,CACE,qBAAC,cAAD,EAAA,UAAA,CACE,oBAAC,qBAAD,EAAA,UACE,oBAAC,qBAAD;MAAqB,MAAM;MAAoB,OAAM;MAAmB,MAAK;KAAM,CAAA,EAChE,CAAA,GACpB,cAAc,KAAK,SAClB,oBAAC,kBAAD,EAAkC,GAAI,KAAO,GAAtB,KAAK,IAAiB,CAC9C,CACW,EAAA,CAAA,GACd,oBAAC,WAAW,WAAZ,EAAA,UACE,oBAAC,kBAAD,CAAmB,CAAA,EACC,CAAA,CAClB;;IACN,oBAAC,gBAAD,EAAgB,GAAI,SAAW,CAAA;IAC/B,oBAAC,WAAW,WAAZ,EAAA,UACE,oBAAC,kBAAD,CAAmB,CAAA,EACC,CAAA;GACP,EAAA,CAAA;EACF,CAAA;CAErB;CAEA,OACE,oBAAC,WAAW,MAAZ;EAAsB;EAAK,GAAI;EAC7B,UAAA,oBAAC,WAAW,MAAZ,EAAA,UACG,WAAW,KAAK,OAAO,UACtB,qBAAC,UAAD,EAAA,UAAA,CACG,OACD,oBAAC,MAAD;GAAM,MAAM,QAAQ,WAAW,SAAS;GACtC,UAAA,oBAAC,WAAW,WAAZ,EAAA,UACE,oBAAC,kBAAD,CAAmB,CAAA,EACC,CAAA;EAClB,CAAA,CACE,EAAA,GAPK,MAAM,GAOX,CACX,EACc,CAAA;CACF,CAAA;AAErB,CAAC;AAED,qBAAqB,cAAc;AAEnC,IAAM,mBAAmB,kBAAkB,sBAAsB;CAC/D,aAAa;CACb,MAAM;CACN;CACA;AACF,CAAC"}
1
+ {"version":3,"file":"BitkitBreadcrumb.js","names":[],"sources":["../../../lib/components/BitkitBreadcrumb/BitkitBreadcrumb.tsx"],"sourcesContent":["import { Breadcrumb, type BreadcrumbRootProps } from '@chakra-ui/react/breadcrumb';\nimport { useBreakpointValue } from '@chakra-ui/react/hooks';\nimport { Show } from '@chakra-ui/react/show';\nimport { forwardRef, Fragment, type ReactElement } from 'react';\n\nimport { IconChevronRight, IconMoreHorizontal } from '../../icons';\nimport { flattenChildren } from '../../utilities/flattenChildren';\nimport { withSubComponents } from '../../utilities/withSubComponents.ts';\nimport BitkitControlButton from '../BitkitControlButton/BitkitControlButton.tsx';\nimport BreadcrumbCurrentItem, { type CurrentItemProps } from './components/BreadcrumbCurrentItem.tsx';\nimport BreadcrumbItem from './components/BreadcrumbItem.tsx';\nimport OverflowMenu, { type OverflowMenuProps } from './components/OverflowMenu.tsx';\nimport OverflowMenuItem from './components/OverflowMenuItem.tsx';\nimport OverflowMenuTrigger from './components/OverflowMenuTrigger.tsx';\nimport { type ItemProps } from './types.ts';\n\ntype BitkitBreadcrumbChild = ReactElement<ItemProps> | ReactElement<CurrentItemProps> | ReactElement<OverflowMenuProps>;\n\nexport type BitkitBreadcrumbProps = Omit<BreadcrumbRootProps, 'children'> & {\n children: BitkitBreadcrumbChild | BitkitBreadcrumbChild[];\n};\n\n// The whole prop bag travels, not just `href`/`children`: the mobile layout rebuilds its items\n// from these, so picking two keys here would drop everything else a consumer put on a crumb — a\n// `data-*` hook, an `aria-*`, an `onClick` — on mobile only, and silently.\nconst flattenItemProps = (elements: ReactElement[]): ItemProps[] => {\n const props: ItemProps[] = [];\n\n for (const child of elements) {\n if (child.type === BreadcrumbItem) {\n props.push(child.props as ItemProps);\n } else if (child.type === OverflowMenu) {\n const { children: menuChildren } = child.props as OverflowMenuProps;\n const menuChildArray = flattenChildren(menuChildren);\n for (const menuChild of menuChildArray) {\n if (menuChild.type === OverflowMenuItem) {\n props.push(menuChild.props as ItemProps);\n }\n }\n }\n }\n\n return props;\n};\n\nconst BitkitBreadcrumbRoot = forwardRef<HTMLElement, BitkitBreadcrumbProps>(({ children, ...rest }, ref) => {\n const isMobile = useBreakpointValue({ base: true, tablet: false }, { fallback: 'tablet' });\n const childArray = flattenChildren(children);\n\n if (childArray.length === 0) {\n return null;\n }\n\n if (isMobile) {\n const links = flattenItemProps(childArray);\n if (links.length === 0) {\n return null;\n }\n\n const lastLink = links[links.length - 1];\n const overflowLinks = links.slice(0, -1).reverse();\n\n return (\n <Breadcrumb.Root ref={ref} {...rest}>\n <Breadcrumb.List>\n <Show when={overflowLinks.length > 0}>\n <OverflowMenu>\n <OverflowMenuTrigger>\n <BitkitControlButton icon={IconMoreHorizontal} label=\"Open breadcrumbs\" size=\"xs\" />\n </OverflowMenuTrigger>\n {overflowLinks.map((link) => (\n <OverflowMenuItem key={link.href} {...link} />\n ))}\n </OverflowMenu>\n <Breadcrumb.Separator>\n <IconChevronRight />\n </Breadcrumb.Separator>\n </Show>\n <BreadcrumbItem {...lastLink} />\n <Breadcrumb.Separator>\n <IconChevronRight />\n </Breadcrumb.Separator>\n </Breadcrumb.List>\n </Breadcrumb.Root>\n );\n }\n\n return (\n <Breadcrumb.Root ref={ref} {...rest}>\n <Breadcrumb.List>\n {childArray.map((child, index) => (\n <Fragment key={child.key}>\n {child}\n {/* The trail ends with a chevron when the last crumb is a link -- it points at the page\n you are on, which is not in the trail. A `CurrentItem` IS that page, so nothing\n follows it. Mobile already ends this way: its last crumb is always a link. */}\n <Show when={index < childArray.length - 1 || child.type === BreadcrumbItem}>\n <Breadcrumb.Separator>\n <IconChevronRight />\n </Breadcrumb.Separator>\n </Show>\n </Fragment>\n ))}\n </Breadcrumb.List>\n </Breadcrumb.Root>\n );\n});\n\nBitkitBreadcrumbRoot.displayName = 'BitkitBreadcrumb';\n\nconst BitkitBreadcrumb = withSubComponents(BitkitBreadcrumbRoot, {\n CurrentItem: BreadcrumbCurrentItem,\n Item: BreadcrumbItem,\n OverflowMenu,\n OverflowMenuItem,\n});\n\nexport default BitkitBreadcrumb;\n"],"mappings":";;;;;;;;;;;;;;;;AAyBA,IAAM,oBAAoB,aAA0C;CAClE,MAAM,QAAqB,CAAC;CAE5B,KAAK,MAAM,SAAS,UAClB,IAAI,MAAM,SAAS,gBACjB,MAAM,KAAK,MAAM,KAAkB;MAC9B,IAAI,MAAM,SAAS,cAAc;EACtC,MAAM,EAAE,UAAU,iBAAiB,MAAM;EACzC,MAAM,iBAAiB,gBAAgB,YAAY;EACnD,KAAK,MAAM,aAAa,gBACtB,IAAI,UAAU,SAAS,kBACrB,MAAM,KAAK,UAAU,KAAkB;CAG7C;CAGF,OAAO;AACT;AAEA,IAAM,uBAAuB,YAAgD,EAAE,UAAU,GAAG,QAAQ,QAAQ;CAC1G,MAAM,WAAW,mBAAmB;EAAE,MAAM;EAAM,QAAQ;CAAM,GAAG,EAAE,UAAU,SAAS,CAAC;CACzF,MAAM,aAAa,gBAAgB,QAAQ;CAE3C,IAAI,WAAW,WAAW,GACxB,OAAO;CAGT,IAAI,UAAU;EACZ,MAAM,QAAQ,iBAAiB,UAAU;EACzC,IAAI,MAAM,WAAW,GACnB,OAAO;EAGT,MAAM,WAAW,MAAM,MAAM,SAAS;EACtC,MAAM,gBAAgB,MAAM,MAAM,GAAG,EAAE,CAAC,CAAC,QAAQ;EAEjD,OACE,oBAAC,WAAW,MAAZ;GAAsB;GAAK,GAAI;GAC7B,UAAA,qBAAC,WAAW,MAAZ,EAAA,UAAA;IACE,qBAAC,MAAD;KAAM,MAAM,cAAc,SAAS;KAAnC,UAAA,CACE,qBAAC,cAAD,EAAA,UAAA,CACE,oBAAC,qBAAD,EAAA,UACE,oBAAC,qBAAD;MAAqB,MAAM;MAAoB,OAAM;MAAmB,MAAK;KAAM,CAAA,EAChE,CAAA,GACpB,cAAc,KAAK,SAClB,oBAAC,kBAAD,EAAkC,GAAI,KAAO,GAAtB,KAAK,IAAiB,CAC9C,CACW,EAAA,CAAA,GACd,oBAAC,WAAW,WAAZ,EAAA,UACE,oBAAC,kBAAD,CAAmB,CAAA,EACC,CAAA,CAClB;;IACN,oBAAC,gBAAD,EAAgB,GAAI,SAAW,CAAA;IAC/B,oBAAC,WAAW,WAAZ,EAAA,UACE,oBAAC,kBAAD,CAAmB,CAAA,EACC,CAAA;GACP,EAAA,CAAA;EACF,CAAA;CAErB;CAEA,OACE,oBAAC,WAAW,MAAZ;EAAsB;EAAK,GAAI;EAC7B,UAAA,oBAAC,WAAW,MAAZ,EAAA,UACG,WAAW,KAAK,OAAO,UACtB,qBAAC,UAAD,EAAA,UAAA,CACG,OAID,oBAAC,MAAD;GAAM,MAAM,QAAQ,WAAW,SAAS,KAAK,MAAM,SAAS;GAC1D,UAAA,oBAAC,WAAW,WAAZ,EAAA,UACE,oBAAC,kBAAD,CAAmB,CAAA,EACC,CAAA;EAClB,CAAA,CACE,EAAA,GAVK,MAAM,GAUX,CACX,EACc,CAAA;CACF,CAAA;AAErB,CAAC;AAED,qBAAqB,cAAc;AAEnC,IAAM,mBAAmB,kBAAkB,sBAAsB;CAC/D,aAAa;CACb,MAAM;CACN;CACA;AACF,CAAC"}
@@ -1,10 +1,16 @@
1
1
  import { ComboboxRootProps } from '@chakra-ui/react/combobox';
2
2
  import { BitkitFieldProps } from '../BitkitField/BitkitField';
3
- import { BitkitSelectMenuEmptyStateProps, BitkitSelectMenuItemProps, BitkitSelectMenuScrollProps, BitkitSelectMenuSearchProps } from '../BitkitSelectMenu/BitkitSelectMenu';
3
+ import { BitkitSelectMenuEmptyStateProps, BitkitSelectMenuItemProps, BitkitSelectMenuScrollProps } from '../BitkitSelectMenu/BitkitSelectMenu';
4
4
  import { BitkitSelectMenuActionChild } from '../BitkitSelectMenu/BitkitSelectMenuAction';
5
5
  export type BitkitComboboxProps = Omit<BitkitFieldProps, 'children' | 'onChange' | 'state'> & {
6
+ /**
7
+ * Accept text that matches no option. `onValueChange` then fires with the typed text when the
8
+ * user commits it (closing the menu or leaving the field), and with the option's `value` when
9
+ * they pick one from the list.
10
+ */
11
+ allowCustomValue?: boolean;
6
12
  children?: BitkitSelectMenuActionChild;
7
- comboboxProps?: Omit<ComboboxRootProps, 'collection' | 'defaultValue' | 'onValueChange' | 'value'>;
13
+ comboboxProps?: Omit<ComboboxRootProps, 'allowCustomValue' | 'collection' | 'defaultInputValue' | 'defaultValue' | 'ids' | 'inputValue' | 'onInputValueChange' | 'onOpenChange' | 'onValueChange' | 'open' | 'openOnClick' | 'value'>;
8
14
  defaultValue?: string;
9
15
  disablePortal?: boolean;
10
16
  isLoading?: boolean;
@@ -14,10 +20,16 @@ export type BitkitComboboxProps = Omit<BitkitFieldProps, 'children' | 'onChange'
14
20
  size?: 'md' | 'lg';
15
21
  state?: 'disabled' | 'error' | 'readOnly' | 'warning';
16
22
  value?: string;
17
- } & BitkitSelectMenuSearchProps & BitkitSelectMenuScrollProps & BitkitSelectMenuEmptyStateProps;
23
+ } & BitkitSelectMenuScrollProps & BitkitSelectMenuEmptyStateProps;
18
24
  declare const _default: import('react').ForwardRefExoticComponent<Omit<BitkitFieldProps, "children" | "onChange" | "state"> & {
25
+ /**
26
+ * Accept text that matches no option. `onValueChange` then fires with the typed text when the
27
+ * user commits it (closing the menu or leaving the field), and with the option's `value` when
28
+ * they pick one from the list.
29
+ */
30
+ allowCustomValue?: boolean;
19
31
  children?: BitkitSelectMenuActionChild;
20
- comboboxProps?: Omit<ComboboxRootProps, "collection" | "defaultValue" | "onValueChange" | "value">;
32
+ comboboxProps?: Omit<ComboboxRootProps, "allowCustomValue" | "collection" | "defaultInputValue" | "defaultValue" | "ids" | "inputValue" | "onInputValueChange" | "onOpenChange" | "onValueChange" | "open" | "openOnClick" | "value">;
21
33
  defaultValue?: string;
22
34
  disablePortal?: boolean;
23
35
  isLoading?: boolean;
@@ -27,7 +39,7 @@ declare const _default: import('react').ForwardRefExoticComponent<Omit<BitkitFie
27
39
  size?: "md" | "lg";
28
40
  state?: "disabled" | "error" | "readOnly" | "warning";
29
41
  value?: string;
30
- } & BitkitSelectMenuSearchProps & BitkitSelectMenuScrollProps & BitkitSelectMenuEmptyStateProps & import('react').RefAttributes<HTMLDivElement>> & {
42
+ } & BitkitSelectMenuScrollProps & BitkitSelectMenuEmptyStateProps & import('react').RefAttributes<HTMLDivElement>> & {
31
43
  Action: {
32
44
  (props: import('..').BitkitSelectMenuActionProps): import("react").JSX.Element;
33
45
  displayName: string;
@@ -7,21 +7,57 @@ import BitkitCloseButton from "../BitkitCloseButton/BitkitCloseButton.js";
7
7
  import BitkitSelectMenuAction from "../BitkitSelectMenu/BitkitSelectMenuAction.js";
8
8
  import BitkitSelectMenu from "../BitkitSelectMenu/BitkitSelectMenu.js";
9
9
  import BitkitField from "../BitkitField/BitkitField.js";
10
- import { forwardRef, useContext, useState } from "react";
10
+ import { forwardRef, useContext, useRef, useState } from "react";
11
11
  import { jsx, jsxs } from "react/jsx-runtime";
12
12
  import { Portal } from "@chakra-ui/react/portal";
13
13
  import { createListCollection } from "@chakra-ui/react/collection";
14
14
  import { Combobox } from "@chakra-ui/react/combobox";
15
+ import { useFieldContext } from "@chakra-ui/react/field";
15
16
  import { useFilter } from "@chakra-ui/react/locale";
16
17
  //#region lib/components/BitkitCombobox/BitkitCombobox.tsx
18
+ /**
19
+ * A text input that filters a list of options as you type. The menu opens on focus with every
20
+ * option, narrows to the ones matching the input, and shows an empty state when nothing matches.
21
+ * Unlike BitkitSelect's menu it has no separate search field — the input itself is the filter.
22
+ */
17
23
  var BitkitCombobox = forwardRef((props, ref) => {
18
- const { children, comboboxProps, defaultValue, disablePortal, emptyHelperText, emptyLabel, isLoading, items, onScrolledToBottom, onSearchChange, onValueChange, placeholder = "Enter a value or select", searchValue, size = "lg", state, value, ...fieldProps } = props;
24
+ const { allowCustomValue, children, comboboxProps, defaultValue, disablePortal, emptyHelperText, emptyLabel, isLoading, items, onScrolledToBottom, onValueChange, placeholder = "Enter value or select", size = "lg", state, value, ...fieldProps } = props;
25
+ return /* @__PURE__ */ jsx(BitkitField, {
26
+ ref,
27
+ state,
28
+ ...fieldProps,
29
+ children: /* @__PURE__ */ jsx(ComboboxControl, {
30
+ allowCustomValue,
31
+ comboboxProps,
32
+ defaultValue,
33
+ disablePortal,
34
+ emptyHelperText: emptyHelperText ?? (allowCustomValue ? "Enter custom value." : void 0),
35
+ emptyLabel,
36
+ hasWarning: state === "warning" || !!fieldProps.warningText,
37
+ isInvalid: state === "error" || !!fieldProps.errorText,
38
+ isLoading,
39
+ items,
40
+ onScrolledToBottom,
41
+ onValueChange,
42
+ placeholder,
43
+ size,
44
+ state,
45
+ value,
46
+ children
47
+ })
48
+ });
49
+ });
50
+ BitkitCombobox.displayName = "BitkitCombobox";
51
+ /** Rendered inside BitkitField so it can read the field's ids and wire them to the input. */
52
+ var ComboboxControl = ({ allowCustomValue, children, comboboxProps, defaultValue, disablePortal, emptyHelperText, emptyLabel, hasWarning, isInvalid, isLoading, items, onScrolledToBottom, onValueChange, placeholder, size, state, value }) => {
19
53
  const { disablePortal: disablePortalFromContext } = useContext(BitkitPortalContext);
54
+ const field = useFieldContext();
20
55
  const { contains } = useFilter({ sensitivity: "base" });
21
56
  const [filterText, setFilterText] = useState("");
22
57
  const visibleItems = filterText ? items.filter((item) => contains(item.label, filterText)) : items;
23
58
  const collection = createListCollection({
24
59
  items: visibleItems,
60
+ groupBy: (item) => item.group || "",
25
61
  isItemDisabled: (item) => !!item.disabled
26
62
  });
27
63
  const itemValues = items.map((item) => item.value);
@@ -33,8 +69,30 @@ var BitkitCombobox = forwardRef((props, ref) => {
33
69
  setPrevItemsKey(itemsKey);
34
70
  if (!isAppend) setFilterText("");
35
71
  }
36
- const hasWarning = state === "warning" || !!fieldProps.warningText;
37
- const isInvalid = state === "error" || !!fieldProps.errorText;
72
+ const [initialInputValue] = useState(() => {
73
+ const initialValue = value ?? defaultValue;
74
+ if (!initialValue) return "";
75
+ return items.find((item) => item.value === initialValue)?.label ?? (allowCustomValue ? initialValue : "");
76
+ });
77
+ const [inputValue, setInputValue] = useState(initialInputValue);
78
+ const [isOpen, setIsOpen] = useState(false);
79
+ const [prevValue, setPrevValue] = useState(value);
80
+ if (value !== prevValue) {
81
+ setPrevValue(value);
82
+ if (allowCustomValue) setInputValue(value ? items.find((item) => item.value === value)?.label ?? value : "");
83
+ }
84
+ const lastEmittedValue = useRef(null);
85
+ const skipFocusOpen = useRef(false);
86
+ const isInteractive = state !== "disabled" && state !== "readOnly";
87
+ const commitCustomValue = () => {
88
+ const text = inputValue.trim();
89
+ if (!allowCustomValue || !text) return;
90
+ const match = items.find((item) => item.label.toLowerCase() === text.toLowerCase());
91
+ const committed = match ? match.value : text;
92
+ if (lastEmittedValue.current === committed) return;
93
+ lastEmittedValue.current = committed;
94
+ onValueChange?.(committed);
95
+ };
38
96
  const iconSize = size === "md" ? "16" : "24";
39
97
  let statusIcon;
40
98
  if (isInvalid) statusIcon = /* @__PURE__ */ jsx(IconErrorCircleFilled, {
@@ -42,57 +100,94 @@ var BitkitCombobox = forwardRef((props, ref) => {
42
100
  color: "icon/negative"
43
101
  });
44
102
  else if (hasWarning) statusIcon = /* @__PURE__ */ jsx(IconWarningYellow, { size: iconSize });
45
- return /* @__PURE__ */ jsx(BitkitField, {
46
- ref,
47
- state,
48
- ...fieldProps,
49
- children: /* @__PURE__ */ jsxs(Combobox.Root, {
50
- ...comboboxProps,
51
- collection,
52
- defaultValue: defaultValue ? [defaultValue] : void 0,
53
- disabled: state === "disabled",
54
- hasStatusIcon: !!statusIcon,
55
- invalid: isInvalid,
56
- onInputValueChange: (e) => {
57
- setFilterText(e.inputValue);
58
- },
59
- onValueChange: (details) => onValueChange?.(details.value[0]),
60
- readOnly: state === "readOnly",
61
- scrollToIndexFn: ({ getElement }) => getElement()?.scrollIntoView({ block: "nearest" }),
62
- size,
63
- value: value === void 0 ? void 0 : value ? [value] : [],
64
- children: [/* @__PURE__ */ jsxs(Combobox.Control, {
65
- className: "group",
66
- children: [/* @__PURE__ */ jsx(Combobox.Input, { placeholder }), /* @__PURE__ */ jsxs(Combobox.IndicatorGroup, { children: [
67
- /* @__PURE__ */ jsx(Combobox.ClearTrigger, {
68
- asChild: true,
69
- children: /* @__PURE__ */ jsx(BitkitCloseButton, { size: "sm" })
70
- }),
71
- statusIcon,
72
- /* @__PURE__ */ jsx(Combobox.Trigger, {
73
- asChild: true,
74
- children: /* @__PURE__ */ jsx(AssetSelectChevron, {})
75
- })
76
- ] })]
77
- }), /* @__PURE__ */ jsx(Portal, {
78
- disabled: disablePortal || disablePortalFromContext,
79
- children: /* @__PURE__ */ jsx(Combobox.Positioner, { children: /* @__PURE__ */ jsx(BitkitSelectMenu, {
80
- collection,
81
- emptyHelperText,
82
- emptyLabel,
83
- isLoading,
84
- onScrolledToBottom,
85
- onSearchChange,
86
- searchValue,
87
- size,
88
- variant: "combobox",
89
- children
90
- }) })
91
- })]
92
- })
103
+ return /* @__PURE__ */ jsxs(Combobox.Root, {
104
+ ...comboboxProps,
105
+ allowCustomValue,
106
+ collection,
107
+ defaultInputValue: initialInputValue,
108
+ defaultValue: defaultValue ? [defaultValue] : void 0,
109
+ disabled: state === "disabled",
110
+ hasStatusIcon: !!statusIcon,
111
+ ids: field ? {
112
+ input: field.ids.control,
113
+ label: field.ids.label
114
+ } : void 0,
115
+ invalid: isInvalid,
116
+ inputValue: allowCustomValue ? inputValue : void 0,
117
+ onInputValueChange: ({ inputValue: nextInputValue, reason }) => {
118
+ setInputValue(nextInputValue);
119
+ if (reason === "clear-trigger" && lastEmittedValue.current !== null) {
120
+ lastEmittedValue.current = null;
121
+ onValueChange?.(void 0);
122
+ }
123
+ setFilterText(reason === "input-change" ? nextInputValue : "");
124
+ },
125
+ onOpenChange: ({ open }) => {
126
+ setIsOpen(open);
127
+ if (!open) commitCustomValue();
128
+ },
129
+ onValueChange: (details) => {
130
+ const next = details.value[0];
131
+ if (allowCustomValue) setInputValue(next ? items.find((item) => item.value === next)?.label ?? next : "");
132
+ if (next === void 0 && lastEmittedValue.current === null) return;
133
+ lastEmittedValue.current = next ?? null;
134
+ onValueChange?.(next);
135
+ },
136
+ open: isOpen,
137
+ openOnClick: true,
138
+ readOnly: state === "readOnly",
139
+ scrollToIndexFn: ({ getElement }) => getElement()?.scrollIntoView({ block: "nearest" }),
140
+ selectionBehavior: allowCustomValue ? "preserve" : void 0,
141
+ size,
142
+ value: value === void 0 ? void 0 : value ? [value] : [],
143
+ children: [/* @__PURE__ */ jsxs(Combobox.Control, {
144
+ className: "group",
145
+ children: [/* @__PURE__ */ jsx(Combobox.Input, {
146
+ onBlur: commitCustomValue,
147
+ onKeyDown: (event) => {
148
+ if (!allowCustomValue || event.key !== "Enter") return;
149
+ if (event.currentTarget.getAttribute("aria-activedescendant")) return;
150
+ commitCustomValue();
151
+ setIsOpen(false);
152
+ },
153
+ onFocus: () => {
154
+ if (skipFocusOpen.current || !isInteractive) return;
155
+ setIsOpen(true);
156
+ },
157
+ placeholder
158
+ }), /* @__PURE__ */ jsxs(Combobox.IndicatorGroup, { children: [
159
+ /* @__PURE__ */ jsx(Combobox.ClearTrigger, {
160
+ asChild: true,
161
+ hidden: !isInteractive || !inputValue && !value,
162
+ children: /* @__PURE__ */ jsx(BitkitCloseButton, { size: "sm" })
163
+ }),
164
+ statusIcon,
165
+ /* @__PURE__ */ jsx(Combobox.Trigger, {
166
+ asChild: true,
167
+ onPointerDown: () => {
168
+ skipFocusOpen.current = true;
169
+ requestAnimationFrame(() => {
170
+ skipFocusOpen.current = false;
171
+ });
172
+ },
173
+ children: /* @__PURE__ */ jsx(AssetSelectChevron, {})
174
+ })
175
+ ] })]
176
+ }), /* @__PURE__ */ jsx(Portal, {
177
+ disabled: disablePortal || disablePortalFromContext,
178
+ children: /* @__PURE__ */ jsx(Combobox.Positioner, { children: /* @__PURE__ */ jsx(BitkitSelectMenu, {
179
+ collection,
180
+ emptyHelperText,
181
+ emptyLabel,
182
+ isLoading,
183
+ onScrolledToBottom,
184
+ size,
185
+ variant: "combobox",
186
+ children
187
+ }) })
188
+ })]
93
189
  });
94
- });
95
- BitkitCombobox.displayName = "BitkitCombobox";
190
+ };
96
191
  var BitkitCombobox_default = withSubComponents(BitkitCombobox, { Action: BitkitSelectMenuAction });
97
192
  //#endregion
98
193
  export { BitkitCombobox_default as default };
@@ -1 +1 @@
1
- {"version":3,"file":"BitkitCombobox.js","names":[],"sources":["../../../lib/components/BitkitCombobox/BitkitCombobox.tsx"],"sourcesContent":["import { createListCollection } from '@chakra-ui/react/collection';\nimport { Combobox, type ComboboxRootProps } from '@chakra-ui/react/combobox';\nimport { useFilter } from '@chakra-ui/react/locale';\nimport { Portal } from '@chakra-ui/react/portal';\nimport { forwardRef, useContext, useState } from 'react';\n\nimport IconErrorCircleFilled from '../../icons/IconErrorCircleFilled';\nimport IconWarningYellow from '../../icons/IconWarningYellow';\nimport AssetSelectChevron from '../../utilities/AssetSelectChevron';\nimport BitkitPortalContext from '../../utilities/BitkitPortalContext';\nimport { withSubComponents } from '../../utilities/withSubComponents';\nimport BitkitCloseButton from '../BitkitCloseButton/BitkitCloseButton';\nimport BitkitField, { type BitkitFieldProps } from '../BitkitField/BitkitField';\nimport BitkitSelectMenu, {\n type BitkitSelectMenuEmptyStateProps,\n type BitkitSelectMenuItemProps,\n type BitkitSelectMenuScrollProps,\n type BitkitSelectMenuSearchProps,\n} from '../BitkitSelectMenu/BitkitSelectMenu';\nimport BitkitSelectMenuAction, { type BitkitSelectMenuActionChild } from '../BitkitSelectMenu/BitkitSelectMenuAction';\n\nexport type BitkitComboboxProps = Omit<BitkitFieldProps, 'children' | 'onChange' | 'state'> & {\n children?: BitkitSelectMenuActionChild;\n comboboxProps?: Omit<ComboboxRootProps, 'collection' | 'defaultValue' | 'onValueChange' | 'value'>;\n defaultValue?: string;\n disablePortal?: boolean;\n isLoading?: boolean;\n items: Array<BitkitSelectMenuItemProps>;\n onValueChange?: (newVal: string | undefined) => void;\n placeholder?: string;\n size?: 'md' | 'lg';\n state?: 'disabled' | 'error' | 'readOnly' | 'warning';\n value?: string;\n} & BitkitSelectMenuSearchProps &\n BitkitSelectMenuScrollProps &\n BitkitSelectMenuEmptyStateProps;\n\nconst BitkitCombobox = forwardRef<HTMLDivElement, BitkitComboboxProps>((props: BitkitComboboxProps, ref) => {\n const {\n children,\n comboboxProps,\n defaultValue,\n disablePortal,\n emptyHelperText,\n emptyLabel,\n isLoading,\n items,\n onScrolledToBottom,\n onSearchChange,\n onValueChange,\n placeholder = 'Enter a value or select',\n searchValue,\n size = 'lg',\n state,\n value,\n ...fieldProps\n } = props;\n\n const { disablePortal: disablePortalFromContext } = useContext(BitkitPortalContext);\n\n const { contains } = useFilter({ sensitivity: 'base' });\n\n // Derive the collection on every render rather than using useListCollection, which snapshots\n // `items` into state as `initialItems` and never syncs it again, so changing `items` actually reaches the menu.\n // Deriving also keeps callers that pass an inline array literal safe, since nothing here is keyed on items identity.\n const [filterText, setFilterText] = useState('');\n const visibleItems = filterText ? items.filter((item) => contains(item.label, filterText)) : items;\n const collection = createListCollection<BitkitSelectMenuItemProps>({\n items: visibleItems,\n isItemDisabled: (item) => !!item.disabled,\n });\n\n // A new set of items invalidates whatever the old ones were filtered by — otherwise leftover\n // filter text (which Zag also sets from the selected item's label) can hide every new item and\n // leave the menu empty. Keyed on item values, not array identity, so an inline `items={[…]}`\n // literal doesn't wipe the filter on every keystroke. Matches what useListCollection's `set()`\n // used to do for us.\n const itemValues = items.map((item) => item.value);\n const itemsKey = JSON.stringify(itemValues);\n const [prevItemsKey, setPrevItemsKey] = useState(itemsKey);\n if (prevItemsKey !== itemsKey) {\n const prevValues = JSON.parse(prevItemsKey) as Array<string>;\n const isAppend = itemValues.length > prevValues.length && prevValues.every((v, i) => v === itemValues[i]);\n setPrevItemsKey(itemsKey);\n if (!isAppend) {\n setFilterText('');\n }\n }\n\n const hasWarning = state === 'warning' || !!fieldProps.warningText;\n const isInvalid = state === 'error' || !!fieldProps.errorText;\n const iconSize = size === 'md' ? '16' : '24';\n\n let statusIcon;\n if (isInvalid) {\n statusIcon = <IconErrorCircleFilled size={iconSize} color=\"icon/negative\" />;\n } else if (hasWarning) {\n statusIcon = <IconWarningYellow size={iconSize} />;\n }\n\n return (\n <BitkitField ref={ref} state={state} {...fieldProps}>\n <Combobox.Root\n {...comboboxProps}\n collection={collection}\n defaultValue={defaultValue ? [defaultValue] : undefined}\n disabled={state === 'disabled'}\n hasStatusIcon={!!statusIcon}\n invalid={isInvalid}\n onInputValueChange={(e) => {\n setFilterText(e.inputValue);\n }}\n onValueChange={(details) => onValueChange?.(details.value[0])}\n readOnly={state === 'readOnly'}\n // Bypass Zag's isScrollable(contentEl) gate — our Content is overflow:hidden flex\n // column, so the real scroll container is itemList. See BitkitMultiselect for why.\n scrollToIndexFn={({ getElement }) => getElement()?.scrollIntoView({ block: 'nearest' })}\n size={size}\n // Stay controlled whenever `value` is provided — including `''` (\"nothing selected\"). A\n // truthiness check (`value ? … : undefined`) passes `undefined` for `''`, which flips\n // Combobox.Root to uncontrolled: it then ignores `value`, so resets don't take and\n // onValueChange stops firing when the same option is re-selected.\n value={value === undefined ? undefined : value ? [value] : []}\n >\n <Combobox.Control className=\"group\">\n <Combobox.Input placeholder={placeholder} />\n <Combobox.IndicatorGroup>\n <Combobox.ClearTrigger asChild>\n <BitkitCloseButton size=\"sm\" />\n </Combobox.ClearTrigger>\n {statusIcon}\n <Combobox.Trigger asChild>\n <AssetSelectChevron />\n </Combobox.Trigger>\n </Combobox.IndicatorGroup>\n </Combobox.Control>\n <Portal disabled={disablePortal || disablePortalFromContext}>\n <Combobox.Positioner>\n <BitkitSelectMenu\n collection={collection}\n emptyHelperText={emptyHelperText}\n emptyLabel={emptyLabel}\n isLoading={isLoading}\n onScrolledToBottom={onScrolledToBottom}\n onSearchChange={onSearchChange}\n searchValue={searchValue}\n size={size}\n variant=\"combobox\"\n >\n {children}\n </BitkitSelectMenu>\n </Combobox.Positioner>\n </Portal>\n </Combobox.Root>\n </BitkitField>\n );\n});\n\nBitkitCombobox.displayName = 'BitkitCombobox';\n\nexport default withSubComponents(BitkitCombobox, { Action: BitkitSelectMenuAction });\n"],"mappings":";;;;;;;;;;;;;;;;AAqCA,IAAM,iBAAiB,YAAiD,OAA4B,QAAQ;CAC1G,MAAM,EACJ,UACA,eACA,cACA,eACA,iBACA,YACA,WACA,OACA,oBACA,gBACA,eACA,cAAc,2BACd,aACA,OAAO,MACP,OACA,OACA,GAAG,eACD;CAEJ,MAAM,EAAE,eAAe,6BAA6B,WAAW,mBAAmB;CAElF,MAAM,EAAE,aAAa,UAAU,EAAE,aAAa,OAAO,CAAC;CAKtD,MAAM,CAAC,YAAY,iBAAiB,SAAS,EAAE;CAC/C,MAAM,eAAe,aAAa,MAAM,QAAQ,SAAS,SAAS,KAAK,OAAO,UAAU,CAAC,IAAI;CAC7F,MAAM,aAAa,qBAAgD;EACjE,OAAO;EACP,iBAAiB,SAAS,CAAC,CAAC,KAAK;CACnC,CAAC;CAOD,MAAM,aAAa,MAAM,KAAK,SAAS,KAAK,KAAK;CACjD,MAAM,WAAW,KAAK,UAAU,UAAU;CAC1C,MAAM,CAAC,cAAc,mBAAmB,SAAS,QAAQ;CACzD,IAAI,iBAAiB,UAAU;EAC7B,MAAM,aAAa,KAAK,MAAM,YAAY;EAC1C,MAAM,WAAW,WAAW,SAAS,WAAW,UAAU,WAAW,OAAO,GAAG,MAAM,MAAM,WAAW,EAAE;EACxG,gBAAgB,QAAQ;EACxB,IAAI,CAAC,UACH,cAAc,EAAE;CAEpB;CAEA,MAAM,aAAa,UAAU,aAAa,CAAC,CAAC,WAAW;CACvD,MAAM,YAAY,UAAU,WAAW,CAAC,CAAC,WAAW;CACpD,MAAM,WAAW,SAAS,OAAO,OAAO;CAExC,IAAI;CACJ,IAAI,WACF,aAAa,oBAAC,uBAAD;EAAuB,MAAM;EAAU,OAAM;CAAiB,CAAA;MACtE,IAAI,YACT,aAAa,oBAAC,mBAAD,EAAmB,MAAM,SAAW,CAAA;CAGnD,OACE,oBAAC,aAAD;EAAkB;EAAY;EAAO,GAAI;EACvC,UAAA,qBAAC,SAAS,MAAV;GACE,GAAI;GACQ;GACZ,cAAc,eAAe,CAAC,YAAY,IAAI,KAAA;GAC9C,UAAU,UAAU;GACpB,eAAe,CAAC,CAAC;GACjB,SAAS;GACT,qBAAqB,MAAM;IACzB,cAAc,EAAE,UAAU;GAC5B;GACA,gBAAgB,YAAY,gBAAgB,QAAQ,MAAM,EAAE;GAC5D,UAAU,UAAU;GAGpB,kBAAkB,EAAE,iBAAiB,WAAW,CAAC,EAAE,eAAe,EAAE,OAAO,UAAU,CAAC;GAChF;GAKN,OAAO,UAAU,KAAA,IAAY,KAAA,IAAY,QAAQ,CAAC,KAAK,IAAI,CAAC;GApB9D,UAAA,CAsBE,qBAAC,SAAS,SAAV;IAAkB,WAAU;IAA5B,UAAA,CACE,oBAAC,SAAS,OAAV,EAA6B,YAAc,CAAA,GAC3C,qBAAC,SAAS,gBAAV,EAAA,UAAA;KACE,oBAAC,SAAS,cAAV;MAAuB,SAAA;MACrB,UAAA,oBAAC,mBAAD,EAAmB,MAAK,KAAM,CAAA;KACT,CAAA;KACtB;KACD,oBAAC,SAAS,SAAV;MAAkB,SAAA;MAChB,UAAA,oBAAC,oBAAD,CAAqB,CAAA;KACL,CAAA;IACK,EAAA,CAAA,CACT;GAClB,CAAA,GAAA,oBAAC,QAAD;IAAQ,UAAU,iBAAiB;IACjC,UAAA,oBAAC,SAAS,YAAV,EAAA,UACE,oBAAC,kBAAD;KACc;KACK;KACL;KACD;KACS;KACJ;KACH;KACP;KACN,SAAQ;KAEP;IACe,CAAA,EACC,CAAA;GACf,CAAA,CACK;;CACJ,CAAA;AAEjB,CAAC;AAED,eAAe,cAAc;AAE7B,IAAA,yBAAe,kBAAkB,gBAAgB,EAAE,QAAQ,uBAAuB,CAAC"}
1
+ {"version":3,"file":"BitkitCombobox.js","names":[],"sources":["../../../lib/components/BitkitCombobox/BitkitCombobox.tsx"],"sourcesContent":["import { createListCollection } from '@chakra-ui/react/collection';\nimport { Combobox, type ComboboxRootProps } from '@chakra-ui/react/combobox';\nimport { useFieldContext } from '@chakra-ui/react/field';\nimport { useFilter } from '@chakra-ui/react/locale';\nimport { Portal } from '@chakra-ui/react/portal';\nimport { forwardRef, useContext, useRef, useState } from 'react';\n\nimport IconErrorCircleFilled from '../../icons/IconErrorCircleFilled';\nimport IconWarningYellow from '../../icons/IconWarningYellow';\nimport AssetSelectChevron from '../../utilities/AssetSelectChevron';\nimport BitkitPortalContext from '../../utilities/BitkitPortalContext';\nimport { withSubComponents } from '../../utilities/withSubComponents';\nimport BitkitCloseButton from '../BitkitCloseButton/BitkitCloseButton';\nimport BitkitField, { type BitkitFieldProps } from '../BitkitField/BitkitField';\nimport BitkitSelectMenu, {\n type BitkitSelectMenuEmptyStateProps,\n type BitkitSelectMenuItemProps,\n type BitkitSelectMenuScrollProps,\n} from '../BitkitSelectMenu/BitkitSelectMenu';\nimport BitkitSelectMenuAction, { type BitkitSelectMenuActionChild } from '../BitkitSelectMenu/BitkitSelectMenuAction';\n\nexport type BitkitComboboxProps = Omit<BitkitFieldProps, 'children' | 'onChange' | 'state'> & {\n /**\n * Accept text that matches no option. `onValueChange` then fires with the typed text when the\n * user commits it (closing the menu or leaving the field), and with the option's `value` when\n * they pick one from the list.\n */\n allowCustomValue?: boolean;\n children?: BitkitSelectMenuActionChild;\n comboboxProps?: Omit<\n ComboboxRootProps,\n | 'allowCustomValue'\n | 'collection'\n | 'defaultInputValue'\n | 'defaultValue'\n | 'ids'\n | 'inputValue'\n | 'onInputValueChange'\n | 'onOpenChange'\n | 'onValueChange'\n | 'open'\n | 'openOnClick'\n | 'value'\n >;\n defaultValue?: string;\n disablePortal?: boolean;\n isLoading?: boolean;\n items: Array<BitkitSelectMenuItemProps>;\n onValueChange?: (newVal: string | undefined) => void;\n placeholder?: string;\n size?: 'md' | 'lg';\n state?: 'disabled' | 'error' | 'readOnly' | 'warning';\n value?: string;\n} & BitkitSelectMenuScrollProps &\n BitkitSelectMenuEmptyStateProps;\n\n/**\n * A text input that filters a list of options as you type. The menu opens on focus with every\n * option, narrows to the ones matching the input, and shows an empty state when nothing matches.\n * Unlike BitkitSelect's menu it has no separate search field — the input itself is the filter.\n */\nconst BitkitCombobox = forwardRef<HTMLDivElement, BitkitComboboxProps>((props: BitkitComboboxProps, ref) => {\n const {\n allowCustomValue,\n children,\n comboboxProps,\n defaultValue,\n disablePortal,\n emptyHelperText,\n emptyLabel,\n isLoading,\n items,\n onScrolledToBottom,\n onValueChange,\n placeholder = 'Enter value or select',\n size = 'lg',\n state,\n value,\n ...fieldProps\n } = props;\n\n return (\n <BitkitField ref={ref} state={state} {...fieldProps}>\n <ComboboxControl\n allowCustomValue={allowCustomValue}\n comboboxProps={comboboxProps}\n defaultValue={defaultValue}\n disablePortal={disablePortal}\n emptyHelperText={emptyHelperText ?? (allowCustomValue ? 'Enter custom value.' : undefined)}\n emptyLabel={emptyLabel}\n hasWarning={state === 'warning' || !!fieldProps.warningText}\n isInvalid={state === 'error' || !!fieldProps.errorText}\n isLoading={isLoading}\n items={items}\n onScrolledToBottom={onScrolledToBottom}\n onValueChange={onValueChange}\n placeholder={placeholder}\n size={size}\n state={state}\n value={value}\n >\n {children}\n </ComboboxControl>\n </BitkitField>\n );\n});\n\nBitkitCombobox.displayName = 'BitkitCombobox';\n\ntype ComboboxControlProps = Pick<\n BitkitComboboxProps,\n | 'allowCustomValue'\n | 'children'\n | 'comboboxProps'\n | 'defaultValue'\n | 'disablePortal'\n | 'emptyHelperText'\n | 'emptyLabel'\n | 'isLoading'\n | 'items'\n | 'onScrolledToBottom'\n | 'onValueChange'\n | 'state'\n | 'value'\n> &\n Required<Pick<BitkitComboboxProps, 'placeholder' | 'size'>> & {\n hasWarning: boolean;\n isInvalid: boolean;\n };\n\n/** Rendered inside BitkitField so it can read the field's ids and wire them to the input. */\nconst ComboboxControl = ({\n allowCustomValue,\n children,\n comboboxProps,\n defaultValue,\n disablePortal,\n emptyHelperText,\n emptyLabel,\n hasWarning,\n isInvalid,\n isLoading,\n items,\n onScrolledToBottom,\n onValueChange,\n placeholder,\n size,\n state,\n value,\n}: ComboboxControlProps) => {\n const { disablePortal: disablePortalFromContext } = useContext(BitkitPortalContext);\n const field = useFieldContext();\n\n const { contains } = useFilter({ sensitivity: 'base' });\n\n // Derive the collection on every render rather than using useListCollection, which snapshots\n // `items` into state as `initialItems` and never syncs it again, so changing `items` actually reaches the menu.\n // Deriving also keeps callers that pass an inline array literal safe, since nothing here is keyed on items identity.\n const [filterText, setFilterText] = useState('');\n const visibleItems = filterText ? items.filter((item) => contains(item.label, filterText)) : items;\n const collection = createListCollection<BitkitSelectMenuItemProps>({\n items: visibleItems,\n groupBy: (item) => item.group || '',\n isItemDisabled: (item) => !!item.disabled,\n });\n\n // A new set of items invalidates whatever the old ones were filtered by — otherwise leftover\n // filter text can hide every new item and leave the menu empty. Keyed on item values, not array\n // identity, so an inline `items={[…]}` literal doesn't wipe the filter on every keystroke; an\n // append (the next page of results) keeps it, so paging doesn't drop what the user typed.\n const itemValues = items.map((item) => item.value);\n const itemsKey = JSON.stringify(itemValues);\n const [prevItemsKey, setPrevItemsKey] = useState(itemsKey);\n if (prevItemsKey !== itemsKey) {\n const prevValues = JSON.parse(prevItemsKey) as Array<string>;\n const isAppend = itemValues.length > prevValues.length && prevValues.every((v, i) => v === itemValues[i]);\n setPrevItemsKey(itemsKey);\n if (!isAppend) {\n setFilterText('');\n }\n }\n\n // Zag only reports the input text once it changes, so mirror what it starts with — otherwise the\n // clear button stays hidden next to a pre-selected value.\n const [initialInputValue] = useState(() => {\n const initialValue = value ?? defaultValue;\n if (!initialValue) return '';\n return items.find((item) => item.value === initialValue)?.label ?? (allowCustomValue ? initialValue : '');\n });\n const [inputValue, setInputValue] = useState(initialInputValue);\n const [isOpen, setIsOpen] = useState(false);\n // A controlled `value` that no option carries can only live in the input, so follow it there.\n const [prevValue, setPrevValue] = useState(value);\n if (value !== prevValue) {\n setPrevValue(value);\n if (allowCustomValue) {\n setInputValue(value ? (items.find((item) => item.value === value)?.label ?? value) : '');\n }\n }\n const lastEmittedValue = useRef<string | null>(null);\n // Clicking the chevron focuses the input first, so without this the focus handler would open the\n // menu just before the trigger's own click closes it again.\n const skipFocusOpen = useRef(false);\n\n const isInteractive = state !== 'disabled' && state !== 'readOnly';\n\n const commitCustomValue = () => {\n const text = inputValue.trim();\n if (!allowCustomValue || !text) return;\n // Match the filter's case-insensitivity: typing \"react\" means the React option, not a custom\n // value that happens to read the same.\n const match = items.find((item) => item.label.toLowerCase() === text.toLowerCase());\n const committed = match ? match.value : text;\n if (lastEmittedValue.current === committed) return;\n lastEmittedValue.current = committed;\n onValueChange?.(committed);\n };\n\n const iconSize = size === 'md' ? '16' : '24';\n\n let statusIcon;\n if (isInvalid) {\n statusIcon = <IconErrorCircleFilled size={iconSize} color=\"icon/negative\" />;\n } else if (hasWarning) {\n statusIcon = <IconWarningYellow size={iconSize} />;\n }\n\n return (\n <Combobox.Root\n {...comboboxProps}\n allowCustomValue={allowCustomValue}\n collection={collection}\n defaultInputValue={initialInputValue}\n defaultValue={defaultValue ? [defaultValue] : undefined}\n disabled={state === 'disabled'}\n hasStatusIcon={!!statusIcon}\n // Chakra's Combobox doesn't take its input id from the surrounding Field, so the field\n // label's `htmlFor` would point at an element that doesn't exist. Hand it the field's ids\n // instead, and the label both labels and focuses the input.\n ids={field ? { input: field.ids.control, label: field.ids.label } : undefined}\n invalid={isInvalid}\n // Custom values live only in the input: Zag rewrites it from the collection on every value\n // change, which would blank text no option carries, so we own it and keep Zag off it.\n inputValue={allowCustomValue ? inputValue : undefined}\n onInputValueChange={({ inputValue: nextInputValue, reason }) => {\n setInputValue(nextInputValue);\n // The clear button empties `value` too, but a custom value never reached it, so Zag has\n // nothing to report — tell the consumer the field is empty now.\n if (reason === 'clear-trigger' && lastEmittedValue.current !== null) {\n lastEmittedValue.current = null;\n onValueChange?.(undefined);\n }\n // Only what the user types filters the list. Zag also writes the selected item's label\n // into the input, which would otherwise narrow the menu to that one item.\n setFilterText(reason === 'input-change' ? nextInputValue : '');\n }}\n onOpenChange={({ open }) => {\n setIsOpen(open);\n if (!open) commitCustomValue();\n }}\n onValueChange={(details) => {\n const next = details.value[0];\n // `selectionBehavior=\"preserve\"` leaves the input alone, so put the option's label there.\n if (allowCustomValue) setInputValue(next ? (items.find((item) => item.value === next)?.label ?? next) : '');\n // The clear path above already reported the empty field.\n if (next === undefined && lastEmittedValue.current === null) return;\n lastEmittedValue.current = next ?? null;\n onValueChange?.(next);\n }}\n open={isOpen}\n openOnClick\n readOnly={state === 'readOnly'}\n // Bypass Zag's isScrollable(contentEl) gate — our Content is overflow:hidden flex\n // column, so the real scroll container is itemList. See BitkitMultiselect for why.\n scrollToIndexFn={({ getElement }) => getElement()?.scrollIntoView({ block: 'nearest' })}\n selectionBehavior={allowCustomValue ? 'preserve' : undefined}\n size={size}\n // Stay controlled whenever `value` is provided — including `''` (\"nothing selected\"). A\n // truthiness check (`value ? … : undefined`) passes `undefined` for `''`, which flips\n // Combobox.Root to uncontrolled: it then ignores `value`, so resets don't take and\n // onValueChange stops firing when the same option is re-selected.\n value={value === undefined ? undefined : value ? [value] : []}\n >\n <Combobox.Control className=\"group\">\n <Combobox.Input\n onBlur={commitCustomValue}\n onKeyDown={(event) => {\n // Zag's Enter selects the highlighted item and does nothing when there is none, so\n // free text would just sit in an open menu. Commit it and close.\n if (!allowCustomValue || event.key !== 'Enter') return;\n if (event.currentTarget.getAttribute('aria-activedescendant')) return;\n commitCustomValue();\n setIsOpen(false);\n }}\n onFocus={() => {\n if (skipFocusOpen.current || !isInteractive) return;\n setIsOpen(true);\n }}\n placeholder={placeholder}\n />\n <Combobox.IndicatorGroup>\n {/* Zag hides the clear button until an option is selected; the design shows it for\n anything the field holds, including text that matches nothing yet. */}\n <Combobox.ClearTrigger asChild hidden={!isInteractive || (!inputValue && !value)}>\n <BitkitCloseButton size=\"sm\" />\n </Combobox.ClearTrigger>\n {statusIcon}\n <Combobox.Trigger\n asChild\n onPointerDown={() => {\n skipFocusOpen.current = true;\n requestAnimationFrame(() => {\n skipFocusOpen.current = false;\n });\n }}\n >\n <AssetSelectChevron />\n </Combobox.Trigger>\n </Combobox.IndicatorGroup>\n </Combobox.Control>\n <Portal disabled={disablePortal || disablePortalFromContext}>\n <Combobox.Positioner>\n <BitkitSelectMenu\n collection={collection}\n emptyHelperText={emptyHelperText}\n emptyLabel={emptyLabel}\n isLoading={isLoading}\n onScrolledToBottom={onScrolledToBottom}\n size={size}\n variant=\"combobox\"\n >\n {children}\n </BitkitSelectMenu>\n </Combobox.Positioner>\n </Portal>\n </Combobox.Root>\n );\n};\n\nexport default withSubComponents(BitkitCombobox, { Action: BitkitSelectMenuAction });\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;AA6DA,IAAM,iBAAiB,YAAiD,OAA4B,QAAQ;CAC1G,MAAM,EACJ,kBACA,UACA,eACA,cACA,eACA,iBACA,YACA,WACA,OACA,oBACA,eACA,cAAc,yBACd,OAAO,MACP,OACA,OACA,GAAG,eACD;CAEJ,OACE,oBAAC,aAAD;EAAkB;EAAY;EAAO,GAAI;EACvC,UAAA,oBAAC,iBAAD;GACoB;GACH;GACD;GACC;GACf,iBAAiB,oBAAoB,mBAAmB,wBAAwB,KAAA;GACpE;GACZ,YAAY,UAAU,aAAa,CAAC,CAAC,WAAW;GAChD,WAAW,UAAU,WAAW,CAAC,CAAC,WAAW;GAClC;GACJ;GACa;GACL;GACF;GACP;GACC;GACA;GAEN;EACc,CAAA;CACN,CAAA;AAEjB,CAAC;AAED,eAAe,cAAc;;AAwB7B,IAAM,mBAAmB,EACvB,kBACA,UACA,eACA,cACA,eACA,iBACA,YACA,YACA,WACA,WACA,OACA,oBACA,eACA,aACA,MACA,OACA,YAC0B;CAC1B,MAAM,EAAE,eAAe,6BAA6B,WAAW,mBAAmB;CAClF,MAAM,QAAQ,gBAAgB;CAE9B,MAAM,EAAE,aAAa,UAAU,EAAE,aAAa,OAAO,CAAC;CAKtD,MAAM,CAAC,YAAY,iBAAiB,SAAS,EAAE;CAC/C,MAAM,eAAe,aAAa,MAAM,QAAQ,SAAS,SAAS,KAAK,OAAO,UAAU,CAAC,IAAI;CAC7F,MAAM,aAAa,qBAAgD;EACjE,OAAO;EACP,UAAU,SAAS,KAAK,SAAS;EACjC,iBAAiB,SAAS,CAAC,CAAC,KAAK;CACnC,CAAC;CAMD,MAAM,aAAa,MAAM,KAAK,SAAS,KAAK,KAAK;CACjD,MAAM,WAAW,KAAK,UAAU,UAAU;CAC1C,MAAM,CAAC,cAAc,mBAAmB,SAAS,QAAQ;CACzD,IAAI,iBAAiB,UAAU;EAC7B,MAAM,aAAa,KAAK,MAAM,YAAY;EAC1C,MAAM,WAAW,WAAW,SAAS,WAAW,UAAU,WAAW,OAAO,GAAG,MAAM,MAAM,WAAW,EAAE;EACxG,gBAAgB,QAAQ;EACxB,IAAI,CAAC,UACH,cAAc,EAAE;CAEpB;CAIA,MAAM,CAAC,qBAAqB,eAAe;EACzC,MAAM,eAAe,SAAS;EAC9B,IAAI,CAAC,cAAc,OAAO;EAC1B,OAAO,MAAM,MAAM,SAAS,KAAK,UAAU,YAAY,CAAC,EAAE,UAAU,mBAAmB,eAAe;CACxG,CAAC;CACD,MAAM,CAAC,YAAY,iBAAiB,SAAS,iBAAiB;CAC9D,MAAM,CAAC,QAAQ,aAAa,SAAS,KAAK;CAE1C,MAAM,CAAC,WAAW,gBAAgB,SAAS,KAAK;CAChD,IAAI,UAAU,WAAW;EACvB,aAAa,KAAK;EAClB,IAAI,kBACF,cAAc,QAAS,MAAM,MAAM,SAAS,KAAK,UAAU,KAAK,CAAC,EAAE,SAAS,QAAS,EAAE;CAE3F;CACA,MAAM,mBAAmB,OAAsB,IAAI;CAGnD,MAAM,gBAAgB,OAAO,KAAK;CAElC,MAAM,gBAAgB,UAAU,cAAc,UAAU;CAExD,MAAM,0BAA0B;EAC9B,MAAM,OAAO,WAAW,KAAK;EAC7B,IAAI,CAAC,oBAAoB,CAAC,MAAM;EAGhC,MAAM,QAAQ,MAAM,MAAM,SAAS,KAAK,MAAM,YAAY,MAAM,KAAK,YAAY,CAAC;EAClF,MAAM,YAAY,QAAQ,MAAM,QAAQ;EACxC,IAAI,iBAAiB,YAAY,WAAW;EAC5C,iBAAiB,UAAU;EAC3B,gBAAgB,SAAS;CAC3B;CAEA,MAAM,WAAW,SAAS,OAAO,OAAO;CAExC,IAAI;CACJ,IAAI,WACF,aAAa,oBAAC,uBAAD;EAAuB,MAAM;EAAU,OAAM;CAAiB,CAAA;MACtE,IAAI,YACT,aAAa,oBAAC,mBAAD,EAAmB,MAAM,SAAW,CAAA;CAGnD,OACE,qBAAC,SAAS,MAAV;EACE,GAAI;EACc;EACN;EACZ,mBAAmB;EACnB,cAAc,eAAe,CAAC,YAAY,IAAI,KAAA;EAC9C,UAAU,UAAU;EACpB,eAAe,CAAC,CAAC;EAIjB,KAAK,QAAQ;GAAE,OAAO,MAAM,IAAI;GAAS,OAAO,MAAM,IAAI;EAAM,IAAI,KAAA;EACpE,SAAS;EAGT,YAAY,mBAAmB,aAAa,KAAA;EAC5C,qBAAqB,EAAE,YAAY,gBAAgB,aAAa;GAC9D,cAAc,cAAc;GAG5B,IAAI,WAAW,mBAAmB,iBAAiB,YAAY,MAAM;IACnE,iBAAiB,UAAU;IAC3B,gBAAgB,KAAA,CAAS;GAC3B;GAGA,cAAc,WAAW,iBAAiB,iBAAiB,EAAE;EAC/D;EACA,eAAe,EAAE,WAAW;GAC1B,UAAU,IAAI;GACd,IAAI,CAAC,MAAM,kBAAkB;EAC/B;EACA,gBAAgB,YAAY;GAC1B,MAAM,OAAO,QAAQ,MAAM;GAE3B,IAAI,kBAAkB,cAAc,OAAQ,MAAM,MAAM,SAAS,KAAK,UAAU,IAAI,CAAC,EAAE,SAAS,OAAQ,EAAE;GAE1G,IAAI,SAAS,KAAA,KAAa,iBAAiB,YAAY,MAAM;GAC7D,iBAAiB,UAAU,QAAQ;GACnC,gBAAgB,IAAI;EACtB;EACA,MAAM;EACN,aAAA;EACA,UAAU,UAAU;EAGpB,kBAAkB,EAAE,iBAAiB,WAAW,CAAC,EAAE,eAAe,EAAE,OAAO,UAAU,CAAC;EACtF,mBAAmB,mBAAmB,aAAa,KAAA;EAC7C;EAKN,OAAO,UAAU,KAAA,IAAY,KAAA,IAAY,QAAQ,CAAC,KAAK,IAAI,CAAC;EArD9D,UAAA,CAuDE,qBAAC,SAAS,SAAV;GAAkB,WAAU;GAA5B,UAAA,CACE,oBAAC,SAAS,OAAV;IACE,QAAQ;IACR,YAAY,UAAU;KAGpB,IAAI,CAAC,oBAAoB,MAAM,QAAQ,SAAS;KAChD,IAAI,MAAM,cAAc,aAAa,uBAAuB,GAAG;KAC/D,kBAAkB;KAClB,UAAU,KAAK;IACjB;IACA,eAAe;KACb,IAAI,cAAc,WAAW,CAAC,eAAe;KAC7C,UAAU,IAAI;IAChB;IACa;GACd,CAAA,GACD,qBAAC,SAAS,gBAAV,EAAA,UAAA;IAGE,oBAAC,SAAS,cAAV;KAAuB,SAAA;KAAQ,QAAQ,CAAC,iBAAkB,CAAC,cAAc,CAAC;KACxE,UAAA,oBAAC,mBAAD,EAAmB,MAAK,KAAM,CAAA;IACT,CAAA;IACtB;IACD,oBAAC,SAAS,SAAV;KACE,SAAA;KACA,qBAAqB;MACnB,cAAc,UAAU;MACxB,4BAA4B;OAC1B,cAAc,UAAU;MAC1B,CAAC;KACH;KAEA,UAAA,oBAAC,oBAAD,CAAqB,CAAA;IACL,CAAA;GACK,EAAA,CAAA,CACT;EAClB,CAAA,GAAA,oBAAC,QAAD;GAAQ,UAAU,iBAAiB;GACjC,UAAA,oBAAC,SAAS,YAAV,EAAA,UACE,oBAAC,kBAAD;IACc;IACK;IACL;IACD;IACS;IACd;IACN,SAAQ;IAEP;GACe,CAAA,EACC,CAAA;EACf,CAAA,CACK;;AAEnB;AAEA,IAAA,yBAAe,kBAAkB,gBAAgB,EAAE,QAAQ,uBAAuB,CAAC"}
@@ -1,4 +1,4 @@
1
- declare const comboboxSlotRecipe: import('@chakra-ui/react').SlotRecipeDefinition<"content" | "input" | "label" | "list" | "root" | "item" | "itemIndicator" | "trigger" | "positioner" | "itemGroup" | "itemGroupLabel" | "itemText" | "clearTrigger" | "control" | "emptyHelperText" | "indicatorGroup" | "empty", {
1
+ declare const comboboxSlotRecipe: import('@chakra-ui/react').SlotRecipeDefinition<"content" | "input" | "label" | "list" | "root" | "item" | "itemIndicator" | "trigger" | "positioner" | "itemGroup" | "itemGroupLabel" | "itemText" | "clearTrigger" | "control" | "indicatorGroup" | "empty", {
2
2
  size: {
3
3
  md: {
4
4
  item: {
@@ -5,7 +5,7 @@ import { comboboxAnatomy } from "@chakra-ui/react/anatomy";
5
5
  //#region lib/theme/slot-recipes/Combobox.recipe.ts
6
6
  var comboboxSlotRecipe = defineSlotRecipe({
7
7
  className: "combobox",
8
- slots: [...comboboxAnatomy.keys(), "emptyHelperText"],
8
+ slots: comboboxAnatomy.keys(),
9
9
  base: {
10
10
  control: {
11
11
  display: "flex",
@@ -18,15 +18,6 @@ var comboboxSlotRecipe = defineSlotRecipe({
18
18
  height: "var(--input-height)",
19
19
  textOverflow: "ellipsis"
20
20
  },
21
- empty: {
22
- paddingInline: "16",
23
- paddingBlock: "8",
24
- textStyle: "body/lg/regular"
25
- },
26
- emptyHelperText: {
27
- color: "text/helper",
28
- textStyle: "body/sm/regular"
29
- },
30
21
  ...base$1,
31
22
  indicatorGroup: {
32
23
  display: "flex",
@@ -1 +1 @@
1
- {"version":3,"file":"Combobox.recipe.js","names":[],"sources":["../../../lib/theme/slot-recipes/Combobox.recipe.ts"],"sourcesContent":["import { comboboxAnatomy } from '@chakra-ui/react/anatomy';\nimport { defineSlotRecipe } from '@chakra-ui/react/styled-system';\n\nimport { base, variants } from '../common/ComboboxAndSelect.common';\nimport * as inputStyle from '../common/InputAndTextarea.common';\n\nconst comboboxSlotRecipe = defineSlotRecipe({\n className: 'combobox',\n slots: [...comboboxAnatomy.keys(), 'emptyHelperText'],\n base: {\n control: {\n display: 'flex',\n alignItems: 'center',\n position: 'relative',\n },\n input: {\n ...inputStyle.base,\n ...inputStyle.singleLineInputOverrides,\n height: 'var(--input-height)',\n textOverflow: 'ellipsis',\n },\n empty: {\n paddingInline: '16',\n paddingBlock: '8',\n textStyle: 'body/lg/regular',\n },\n emptyHelperText: {\n color: 'text/helper',\n textStyle: 'body/sm/regular',\n },\n ...base,\n indicatorGroup: {\n display: 'flex',\n alignItems: 'center',\n gap: '8',\n position: 'absolute',\n right: '16',\n top: '50%',\n transform: 'translateY(-50%)',\n },\n },\n variants: {\n size: {\n md: {\n input: {\n ...inputStyle.variants.size.md,\n ...inputStyle.singleLineInputOverrides,\n paddingInlineEnd: '96',\n },\n ...variants.size.md,\n },\n lg: {\n input: {\n ...inputStyle.variants.size.lg,\n ...inputStyle.singleLineInputOverrides,\n paddingInlineEnd: '96',\n },\n ...variants.size.lg,\n },\n },\n hasStatusIcon: {\n true: {\n input: {\n paddingInlineEnd: '128',\n },\n },\n false: {},\n },\n },\n defaultVariants: {\n size: 'lg',\n },\n});\n\nexport default comboboxSlotRecipe;\n"],"mappings":";;;;;AAMA,IAAM,qBAAqB,iBAAiB;CAC1C,WAAW;CACX,OAAO,CAAC,GAAG,gBAAgB,KAAK,GAAG,iBAAiB;CACpD,MAAM;EACJ,SAAS;GACP,SAAS;GACT,YAAY;GACZ,UAAU;EACZ;EACA,OAAO;GACL,GAAG;GACH,GAAG;GACH,QAAQ;GACR,cAAc;EAChB;EACA,OAAO;GACL,eAAe;GACf,cAAc;GACd,WAAW;EACb;EACA,iBAAiB;GACf,OAAO;GACP,WAAW;EACb;EACA,GAAG;EACH,gBAAgB;GACd,SAAS;GACT,YAAY;GACZ,KAAK;GACL,UAAU;GACV,OAAO;GACP,KAAK;GACL,WAAW;EACb;CACF;CACA,UAAU;EACR,MAAM;GACJ,IAAI;IACF,OAAO;KACL,GAAA,SAAuB,KAAK;KAC5B,GAAG;KACH,kBAAkB;IACpB;IACA,GAAG,WAAS,KAAK;GACnB;GACA,IAAI;IACF,OAAO;KACL,GAAA,SAAuB,KAAK;KAC5B,GAAG;KACH,kBAAkB;IACpB;IACA,GAAG,WAAS,KAAK;GACnB;EACF;EACA,eAAe;GACb,MAAM,EACJ,OAAO,EACL,kBAAkB,MACpB,EACF;GACA,OAAO,CAAC;EACV;CACF;CACA,iBAAiB,EACf,MAAM,KACR;AACF,CAAC"}
1
+ {"version":3,"file":"Combobox.recipe.js","names":[],"sources":["../../../lib/theme/slot-recipes/Combobox.recipe.ts"],"sourcesContent":["import { comboboxAnatomy } from '@chakra-ui/react/anatomy';\nimport { defineSlotRecipe } from '@chakra-ui/react/styled-system';\n\nimport { base, variants } from '../common/ComboboxAndSelect.common';\nimport * as inputStyle from '../common/InputAndTextarea.common';\n\nconst comboboxSlotRecipe = defineSlotRecipe({\n className: 'combobox',\n slots: comboboxAnatomy.keys(),\n base: {\n control: {\n display: 'flex',\n alignItems: 'center',\n position: 'relative',\n },\n input: {\n ...inputStyle.base,\n ...inputStyle.singleLineInputOverrides,\n height: 'var(--input-height)',\n textOverflow: 'ellipsis',\n },\n ...base,\n indicatorGroup: {\n display: 'flex',\n alignItems: 'center',\n gap: '8',\n position: 'absolute',\n right: '16',\n top: '50%',\n transform: 'translateY(-50%)',\n },\n },\n variants: {\n size: {\n md: {\n input: {\n ...inputStyle.variants.size.md,\n ...inputStyle.singleLineInputOverrides,\n paddingInlineEnd: '96',\n },\n ...variants.size.md,\n },\n lg: {\n input: {\n ...inputStyle.variants.size.lg,\n ...inputStyle.singleLineInputOverrides,\n paddingInlineEnd: '96',\n },\n ...variants.size.lg,\n },\n },\n hasStatusIcon: {\n true: {\n input: {\n paddingInlineEnd: '128',\n },\n },\n false: {},\n },\n },\n defaultVariants: {\n size: 'lg',\n },\n});\n\nexport default comboboxSlotRecipe;\n"],"mappings":";;;;;AAMA,IAAM,qBAAqB,iBAAiB;CAC1C,WAAW;CACX,OAAO,gBAAgB,KAAK;CAC5B,MAAM;EACJ,SAAS;GACP,SAAS;GACT,YAAY;GACZ,UAAU;EACZ;EACA,OAAO;GACL,GAAG;GACH,GAAG;GACH,QAAQ;GACR,cAAc;EAChB;EACA,GAAG;EACH,gBAAgB;GACd,SAAS;GACT,YAAY;GACZ,KAAK;GACL,UAAU;GACV,OAAO;GACP,KAAK;GACL,WAAW;EACb;CACF;CACA,UAAU;EACR,MAAM;GACJ,IAAI;IACF,OAAO;KACL,GAAA,SAAuB,KAAK;KAC5B,GAAG;KACH,kBAAkB;IACpB;IACA,GAAG,WAAS,KAAK;GACnB;GACA,IAAI;IACF,OAAO;KACL,GAAA,SAAuB,KAAK;KAC5B,GAAG;KACH,kBAAkB;IACpB;IACA,GAAG,WAAS,KAAK;GACnB;EACF;EACA,eAAe;GACb,MAAM,EACJ,OAAO,EACL,kBAAkB,MACpB,EACF;GACA,OAAO,CAAC;EACV;CACF;CACA,iBAAiB,EACf,MAAM,KACR;AACF,CAAC"}
@@ -509,7 +509,7 @@ declare const slotRecipes: {
509
509
  };
510
510
  }>;
511
511
  collapsible: import('@chakra-ui/react').SlotRecipeDefinition<"content" | "root" | "trigger" | "indicator", import('@chakra-ui/react').SlotRecipeVariantRecord<"content" | "root" | "trigger" | "indicator">>;
512
- combobox: import('@chakra-ui/react').SlotRecipeDefinition<"content" | "input" | "label" | "list" | "root" | "item" | "itemIndicator" | "trigger" | "positioner" | "itemGroup" | "itemGroupLabel" | "itemText" | "clearTrigger" | "control" | "emptyHelperText" | "indicatorGroup" | "empty", {
512
+ combobox: import('@chakra-ui/react').SlotRecipeDefinition<"content" | "input" | "label" | "list" | "root" | "item" | "itemIndicator" | "trigger" | "positioner" | "itemGroup" | "itemGroupLabel" | "itemText" | "clearTrigger" | "control" | "indicatorGroup" | "empty", {
513
513
  size: {
514
514
  md: {
515
515
  item: {
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@bitrise/bitkit-v2",
3
3
  "private": false,
4
- "version": "0.3.416",
4
+ "version": "0.3.418",
5
5
  "description": "Bitrise Design System Components built with Chakra UI V3",
6
6
  "keywords": [
7
7
  "react",