@bitrise/bitkit-v2 0.3.200 → 0.3.202

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.
Files changed (33) hide show
  1. package/dist/components/BitkitCodeSnippet/BitkitCodeSnippet.js +11 -4
  2. package/dist/components/BitkitCodeSnippet/BitkitCodeSnippet.js.map +1 -1
  3. package/dist/components/BitkitCombobox/BitkitCombobox.d.ts +6 -4
  4. package/dist/components/BitkitCombobox/BitkitCombobox.js +13 -14
  5. package/dist/components/BitkitCombobox/BitkitCombobox.js.map +1 -1
  6. package/dist/components/BitkitMultiselect/BitkitMultiselect.d.ts +19 -0
  7. package/dist/components/BitkitMultiselect/BitkitMultiselect.js +184 -0
  8. package/dist/components/BitkitMultiselect/BitkitMultiselect.js.map +1 -0
  9. package/dist/components/BitkitSelect/BitkitSelect.d.ts +2 -3
  10. package/dist/components/BitkitSelect/BitkitSelect.js +12 -6
  11. package/dist/components/BitkitSelect/BitkitSelect.js.map +1 -1
  12. package/dist/components/BitkitSelectMenu/BitkitSelectMenu.d.ts +18 -7
  13. package/dist/components/BitkitSelectMenu/BitkitSelectMenu.js +155 -61
  14. package/dist/components/BitkitSelectMenu/BitkitSelectMenu.js.map +1 -1
  15. package/dist/components/index.d.ts +1 -0
  16. package/dist/main.js +3 -2
  17. package/dist/theme/slot-recipes/CodeSnippet.recipe.d.ts +6 -1
  18. package/dist/theme/slot-recipes/CodeSnippet.recipe.js +9 -3
  19. package/dist/theme/slot-recipes/CodeSnippet.recipe.js.map +1 -1
  20. package/dist/theme/slot-recipes/Combobox.recipe.d.ts +1 -1
  21. package/dist/theme/slot-recipes/Multiselect.recipe.d.ts +48 -0
  22. package/dist/theme/slot-recipes/Multiselect.recipe.js +150 -0
  23. package/dist/theme/slot-recipes/Multiselect.recipe.js.map +1 -0
  24. package/dist/theme/slot-recipes/Select.recipe.js +191 -18
  25. package/dist/theme/slot-recipes/Select.recipe.js.map +1 -1
  26. package/dist/theme/slot-recipes/Sidebar.recipe.d.ts +1 -1
  27. package/dist/theme/slot-recipes/TagsInput.recipe.d.ts +1 -1
  28. package/dist/theme/slot-recipes/index.js +2 -0
  29. package/dist/theme/slot-recipes/index.js.map +1 -1
  30. package/package.json +1 -1
  31. package/dist/theme/slot-recipes/DatePickerSelect.recipe.d.ts +0 -27
  32. package/dist/theme/slot-recipes/Select.recipe.d.ts +0 -21
  33. package/dist/theme/slot-recipes/index.d.ts +0 -2039
@@ -81,16 +81,23 @@ var BitkitCodeSnippet = forwardRef((props, ref) => {
81
81
  tabIndex: -1,
82
82
  children
83
83
  }),
84
- /* @__PURE__ */ jsx(BitkitTooltip, {
85
- text: COPY_TOOLTIP,
86
- children: copyButton
84
+ /* @__PURE__ */ jsx(chakra.div, {
85
+ css: styles.copyButtonWrapper,
86
+ children: /* @__PURE__ */ jsx(BitkitTooltip, {
87
+ text: COPY_TOOLTIP,
88
+ children: copyButton
89
+ })
87
90
  }),
88
91
  hasShowMore && /* @__PURE__ */ jsxs(chakra.div, {
89
92
  css: styles.showMoreContainer,
90
93
  children: [!isExpanded && /* @__PURE__ */ jsx(chakra.div, { css: styles.showMoreGradient }), /* @__PURE__ */ jsxs(chakra.button, {
91
94
  onClick: handleToggleExpand,
92
95
  css: styles.showMoreButton,
93
- children: [isExpanded ? "Show less" : "Show more", /* @__PURE__ */ jsx(AssetSelectChevron, { "data-state": isExpanded ? "open" : "closed" })]
96
+ children: [isExpanded ? "Show less" : "Show more", /* @__PURE__ */ jsx(AssetSelectChevron, {
97
+ "data-state": isExpanded ? "open" : "closed",
98
+ height: "16",
99
+ width: "16"
100
+ })]
94
101
  })]
95
102
  })
96
103
  ]
@@ -1 +1 @@
1
- {"version":3,"file":"BitkitCodeSnippet.js","names":[],"sources":["../../../lib/components/BitkitCodeSnippet/BitkitCodeSnippet.tsx"],"sourcesContent":["import { useClipboard } from '@ark-ui/react/clipboard';\nimport { chakra, useSlotRecipe } from '@chakra-ui/react/styled-system';\nimport { forwardRef, type KeyboardEvent, useState } from 'react';\n\nimport { IconCheck, IconCopy } from '../../icons';\nimport AssetSelectChevron from '../../utilities/AssetSelectChevron';\nimport BitkitTooltip from '../BitkitTooltip/BitkitTooltip';\n\nconst COPY_TOOLTIP = 'Copy to clipboard';\n\ninterface BaseProps {\n children: string;\n size?: 'md' | 'lg';\n textToCopy?: string;\n}\n\ninterface InlineProps extends BaseProps {\n interactive?: boolean;\n startingHeight?: never;\n variant: 'inline';\n}\n\ninterface BlockProps extends BaseProps {\n interactive?: never;\n startingHeight?: number;\n variant: 'multi' | 'single';\n}\n\nexport type BitkitCodeSnippetProps = InlineProps | BlockProps;\n\nconst BitkitCodeSnippet = forwardRef<HTMLElement, BitkitCodeSnippetProps>((props, ref) => {\n const { children, interactive, size = 'lg', startingHeight, textToCopy, variant } = props;\n\n const hasShowMore = startingHeight !== undefined;\n const [isExpanded, setIsExpanded] = useState(false);\n\n const { copied, copy } = useClipboard({ timeout: 2000, value: textToCopy ?? children });\n\n const recipe = useSlotRecipe({ key: 'codeSnippet' });\n const styles = recipe({ size, variant, hasShowMore, isExpanded, interactive });\n\n const handleToggleExpand = () => {\n setIsExpanded((prev) => !prev);\n };\n\n const handleKeyDown = (e: KeyboardEvent) => {\n if (e.key === 'Enter' || e.key === ' ') {\n e.preventDefault();\n copy();\n }\n };\n\n const copyButton = (\n <chakra.button aria-label={COPY_TOOLTIP} css={styles.copyButton} onClick={copy} type=\"button\">\n {copied ? <IconCheck size=\"16\" /> : <IconCopy size=\"16\" />}\n </chakra.button>\n );\n\n if (variant === 'inline') {\n if (!interactive) {\n return (\n <chakra.code ref={ref} css={styles.root}>\n {children}\n </chakra.code>\n );\n }\n\n return (\n <BitkitTooltip text={COPY_TOOLTIP}>\n <chakra.code ref={ref} css={styles.root} onClick={copy} onKeyDown={handleKeyDown} role=\"button\" tabIndex={0}>\n {children}\n </chakra.code>\n </BitkitTooltip>\n );\n }\n\n if (variant === 'single') {\n return (\n <chakra.div ref={ref} css={styles.root}>\n <chakra.code css={styles.content} tabIndex={-1}>\n {children}\n </chakra.code>\n <BitkitTooltip text={COPY_TOOLTIP}>{copyButton}</BitkitTooltip>\n </chakra.div>\n );\n }\n\n const contentMaxHeight = hasShowMore && !isExpanded ? startingHeight : undefined;\n\n return (\n <chakra.div ref={ref} css={styles.root}>\n <chakra.code css={styles.content} maxHeight={contentMaxHeight} tabIndex={-1}>\n {children}\n </chakra.code>\n <BitkitTooltip text={COPY_TOOLTIP}>{copyButton}</BitkitTooltip>\n {hasShowMore && (\n <chakra.div css={styles.showMoreContainer}>\n {!isExpanded && <chakra.div css={styles.showMoreGradient} />}\n <chakra.button onClick={handleToggleExpand} css={styles.showMoreButton}>\n {isExpanded ? 'Show less' : 'Show more'}\n <AssetSelectChevron data-state={isExpanded ? 'open' : 'closed'} />\n </chakra.button>\n </chakra.div>\n )}\n </chakra.div>\n );\n});\n\nBitkitCodeSnippet.displayName = 'BitkitCodeSnippet';\n\nexport default BitkitCodeSnippet;\n"],"mappings":";;;;;;;;;AAQA,IAAM,eAAe;AAsBrB,IAAM,oBAAoB,YAAiD,OAAO,QAAQ;CACxF,MAAM,EAAE,UAAU,aAAa,OAAO,MAAM,gBAAgB,YAAY,YAAY;CAEpF,MAAM,cAAc,mBAAmB,KAAA;CACvC,MAAM,CAAC,YAAY,iBAAiB,SAAS,MAAM;CAEnD,MAAM,EAAE,QAAQ,SAAS,aAAa;EAAE,SAAS;EAAM,OAAO,cAAc;EAAU,CAAC;CAGvF,MAAM,SADS,cAAc,EAAE,KAAK,eAAe,CAAC,CAC9B;EAAE;EAAM;EAAS;EAAa;EAAY;EAAa,CAAC;CAE9E,MAAM,2BAA2B;AAC/B,iBAAe,SAAS,CAAC,KAAK;;CAGhC,MAAM,iBAAiB,MAAqB;AAC1C,MAAI,EAAE,QAAQ,WAAW,EAAE,QAAQ,KAAK;AACtC,KAAE,gBAAgB;AAClB,SAAM;;;CAIV,MAAM,aACJ,oBAAC,OAAO,QAAR;EAAe,cAAY;EAAc,KAAK,OAAO;EAAY,SAAS;EAAM,MAAK;YAClF,SAAS,oBAAC,WAAD,EAAW,MAAK,MAAO,CAAA,GAAG,oBAAC,UAAD,EAAU,MAAK,MAAO,CAAA;EAC5C,CAAA;AAGlB,KAAI,YAAY,UAAU;AACxB,MAAI,CAAC,YACH,QACE,oBAAC,OAAO,MAAR;GAAkB;GAAK,KAAK,OAAO;GAChC;GACW,CAAA;AAIlB,SACE,oBAAC,eAAD;GAAe,MAAM;aACnB,oBAAC,OAAO,MAAR;IAAkB;IAAK,KAAK,OAAO;IAAM,SAAS;IAAM,WAAW;IAAe,MAAK;IAAS,UAAU;IACvG;IACW,CAAA;GACA,CAAA;;AAIpB,KAAI,YAAY,SACd,QACE,qBAAC,OAAO,KAAR;EAAiB;EAAK,KAAK,OAAO;YAAlC,CACE,oBAAC,OAAO,MAAR;GAAa,KAAK,OAAO;GAAS,UAAU;GACzC;GACW,CAAA,EACd,oBAAC,eAAD;GAAe,MAAM;aAAe;GAA2B,CAAA,CACpD;;CAIjB,MAAM,mBAAmB,eAAe,CAAC,aAAa,iBAAiB,KAAA;AAEvE,QACE,qBAAC,OAAO,KAAR;EAAiB;EAAK,KAAK,OAAO;YAAlC;GACE,oBAAC,OAAO,MAAR;IAAa,KAAK,OAAO;IAAS,WAAW;IAAkB,UAAU;IACtE;IACW,CAAA;GACd,oBAAC,eAAD;IAAe,MAAM;cAAe;IAA2B,CAAA;GAC9D,eACC,qBAAC,OAAO,KAAR;IAAY,KAAK,OAAO;cAAxB,CACG,CAAC,cAAc,oBAAC,OAAO,KAAR,EAAY,KAAK,OAAO,kBAAoB,CAAA,EAC5D,qBAAC,OAAO,QAAR;KAAe,SAAS;KAAoB,KAAK,OAAO;eAAxD,CACG,aAAa,cAAc,aAC5B,oBAAC,oBAAD,EAAoB,cAAY,aAAa,SAAS,UAAY,CAAA,CACpD;OACL;;GAEJ;;EAEf;AAEF,kBAAkB,cAAc"}
1
+ {"version":3,"file":"BitkitCodeSnippet.js","names":[],"sources":["../../../lib/components/BitkitCodeSnippet/BitkitCodeSnippet.tsx"],"sourcesContent":["import { useClipboard } from '@ark-ui/react/clipboard';\nimport { chakra, useSlotRecipe } from '@chakra-ui/react/styled-system';\nimport { forwardRef, type KeyboardEvent, useState } from 'react';\n\nimport { IconCheck, IconCopy } from '../../icons';\nimport AssetSelectChevron from '../../utilities/AssetSelectChevron';\nimport BitkitTooltip from '../BitkitTooltip/BitkitTooltip';\n\nconst COPY_TOOLTIP = 'Copy to clipboard';\n\ninterface BaseProps {\n children: string;\n size?: 'md' | 'lg';\n textToCopy?: string;\n}\n\ninterface InlineProps extends BaseProps {\n interactive?: boolean;\n startingHeight?: never;\n variant: 'inline';\n}\n\ninterface BlockProps extends BaseProps {\n interactive?: never;\n startingHeight?: number;\n variant: 'multi' | 'single';\n}\n\nexport type BitkitCodeSnippetProps = InlineProps | BlockProps;\n\nconst BitkitCodeSnippet = forwardRef<HTMLElement, BitkitCodeSnippetProps>((props, ref) => {\n const { children, interactive, size = 'lg', startingHeight, textToCopy, variant } = props;\n\n const hasShowMore = startingHeight !== undefined;\n const [isExpanded, setIsExpanded] = useState(false);\n\n const { copied, copy } = useClipboard({ timeout: 2000, value: textToCopy ?? children });\n\n const recipe = useSlotRecipe({ key: 'codeSnippet' });\n const styles = recipe({ size, variant, hasShowMore, isExpanded, interactive });\n\n const handleToggleExpand = () => {\n setIsExpanded((prev) => !prev);\n };\n\n const handleKeyDown = (e: KeyboardEvent) => {\n if (e.key === 'Enter' || e.key === ' ') {\n e.preventDefault();\n copy();\n }\n };\n\n const copyButton = (\n <chakra.button aria-label={COPY_TOOLTIP} css={styles.copyButton} onClick={copy} type=\"button\">\n {copied ? <IconCheck size=\"16\" /> : <IconCopy size=\"16\" />}\n </chakra.button>\n );\n\n if (variant === 'inline') {\n if (!interactive) {\n return (\n <chakra.code ref={ref} css={styles.root}>\n {children}\n </chakra.code>\n );\n }\n\n return (\n <BitkitTooltip text={COPY_TOOLTIP}>\n <chakra.code ref={ref} css={styles.root} onClick={copy} onKeyDown={handleKeyDown} role=\"button\" tabIndex={0}>\n {children}\n </chakra.code>\n </BitkitTooltip>\n );\n }\n\n if (variant === 'single') {\n return (\n <chakra.div ref={ref} css={styles.root}>\n <chakra.code css={styles.content} tabIndex={-1}>\n {children}\n </chakra.code>\n <BitkitTooltip text={COPY_TOOLTIP}>{copyButton}</BitkitTooltip>\n </chakra.div>\n );\n }\n\n const contentMaxHeight = hasShowMore && !isExpanded ? startingHeight : undefined;\n\n return (\n <chakra.div ref={ref} css={styles.root}>\n <chakra.code css={styles.content} maxHeight={contentMaxHeight} tabIndex={-1}>\n {children}\n </chakra.code>\n <chakra.div css={styles.copyButtonWrapper}>\n <BitkitTooltip text={COPY_TOOLTIP}>{copyButton}</BitkitTooltip>\n </chakra.div>\n {hasShowMore && (\n <chakra.div css={styles.showMoreContainer}>\n {!isExpanded && <chakra.div css={styles.showMoreGradient} />}\n <chakra.button onClick={handleToggleExpand} css={styles.showMoreButton}>\n {isExpanded ? 'Show less' : 'Show more'}\n <AssetSelectChevron data-state={isExpanded ? 'open' : 'closed'} height=\"16\" width=\"16\" />\n </chakra.button>\n </chakra.div>\n )}\n </chakra.div>\n );\n});\n\nBitkitCodeSnippet.displayName = 'BitkitCodeSnippet';\n\nexport default BitkitCodeSnippet;\n"],"mappings":";;;;;;;;;AAQA,IAAM,eAAe;AAsBrB,IAAM,oBAAoB,YAAiD,OAAO,QAAQ;CACxF,MAAM,EAAE,UAAU,aAAa,OAAO,MAAM,gBAAgB,YAAY,YAAY;CAEpF,MAAM,cAAc,mBAAmB,KAAA;CACvC,MAAM,CAAC,YAAY,iBAAiB,SAAS,MAAM;CAEnD,MAAM,EAAE,QAAQ,SAAS,aAAa;EAAE,SAAS;EAAM,OAAO,cAAc;EAAU,CAAC;CAGvF,MAAM,SADS,cAAc,EAAE,KAAK,eAAe,CAAC,CAC9B;EAAE;EAAM;EAAS;EAAa;EAAY;EAAa,CAAC;CAE9E,MAAM,2BAA2B;AAC/B,iBAAe,SAAS,CAAC,KAAK;;CAGhC,MAAM,iBAAiB,MAAqB;AAC1C,MAAI,EAAE,QAAQ,WAAW,EAAE,QAAQ,KAAK;AACtC,KAAE,gBAAgB;AAClB,SAAM;;;CAIV,MAAM,aACJ,oBAAC,OAAO,QAAR;EAAe,cAAY;EAAc,KAAK,OAAO;EAAY,SAAS;EAAM,MAAK;YAClF,SAAS,oBAAC,WAAD,EAAW,MAAK,MAAO,CAAA,GAAG,oBAAC,UAAD,EAAU,MAAK,MAAO,CAAA;EAC5C,CAAA;AAGlB,KAAI,YAAY,UAAU;AACxB,MAAI,CAAC,YACH,QACE,oBAAC,OAAO,MAAR;GAAkB;GAAK,KAAK,OAAO;GAChC;GACW,CAAA;AAIlB,SACE,oBAAC,eAAD;GAAe,MAAM;aACnB,oBAAC,OAAO,MAAR;IAAkB;IAAK,KAAK,OAAO;IAAM,SAAS;IAAM,WAAW;IAAe,MAAK;IAAS,UAAU;IACvG;IACW,CAAA;GACA,CAAA;;AAIpB,KAAI,YAAY,SACd,QACE,qBAAC,OAAO,KAAR;EAAiB;EAAK,KAAK,OAAO;YAAlC,CACE,oBAAC,OAAO,MAAR;GAAa,KAAK,OAAO;GAAS,UAAU;GACzC;GACW,CAAA,EACd,oBAAC,eAAD;GAAe,MAAM;aAAe;GAA2B,CAAA,CACpD;;CAIjB,MAAM,mBAAmB,eAAe,CAAC,aAAa,iBAAiB,KAAA;AAEvE,QACE,qBAAC,OAAO,KAAR;EAAiB;EAAK,KAAK,OAAO;YAAlC;GACE,oBAAC,OAAO,MAAR;IAAa,KAAK,OAAO;IAAS,WAAW;IAAkB,UAAU;IACtE;IACW,CAAA;GACd,oBAAC,OAAO,KAAR;IAAY,KAAK,OAAO;cACtB,oBAAC,eAAD;KAAe,MAAM;eAAe;KAA2B,CAAA;IACpD,CAAA;GACZ,eACC,qBAAC,OAAO,KAAR;IAAY,KAAK,OAAO;cAAxB,CACG,CAAC,cAAc,oBAAC,OAAO,KAAR,EAAY,KAAK,OAAO,kBAAoB,CAAA,EAC5D,qBAAC,OAAO,QAAR;KAAe,SAAS;KAAoB,KAAK,OAAO;eAAxD,CACG,aAAa,cAAc,aAC5B,oBAAC,oBAAD;MAAoB,cAAY,aAAa,SAAS;MAAU,QAAO;MAAK,OAAM;MAAO,CAAA,CAC3E;OACL;;GAEJ;;EAEf;AAEF,kBAAkB,cAAc"}
@@ -1,14 +1,16 @@
1
1
  import { ComboboxRootProps } from '@chakra-ui/react/combobox';
2
2
  import { BitkitFieldProps } from '../BitkitField/BitkitField';
3
- import { BitkitSelectContentProps, BitkitSelectMenuCreateItemProps, BitkitSelectMenuItemProps, BitkitSelectMenuSearchProps } from '../BitkitSelectMenu/BitkitSelectMenu';
3
+ import { BitkitSelectMenuCreateItemProps, BitkitSelectMenuEmptyStateProps, BitkitSelectMenuItemProps, BitkitSelectMenuSearchProps } from '../BitkitSelectMenu/BitkitSelectMenu';
4
4
  export type BitkitComboboxProps = Omit<BitkitFieldProps, 'children' | 'state'> & {
5
- comboboxProps?: ComboboxRootProps;
6
- contentProps?: BitkitSelectContentProps;
5
+ comboboxProps?: Omit<ComboboxRootProps, 'collection' | 'defaultValue' | 'onValueChange' | 'value'>;
6
+ defaultValue?: string;
7
7
  isLoading?: boolean;
8
8
  items: Array<BitkitSelectMenuItemProps>;
9
+ onValueChange?: (newVal: string | undefined) => void;
9
10
  placeholder?: string;
10
11
  size?: 'md' | 'lg';
11
12
  state?: 'disabled' | 'error' | 'readOnly' | 'warning';
12
- } & BitkitSelectMenuCreateItemProps & BitkitSelectMenuSearchProps;
13
+ value?: string;
14
+ } & BitkitSelectMenuCreateItemProps & BitkitSelectMenuSearchProps & BitkitSelectMenuEmptyStateProps;
13
15
  declare const BitkitCombobox: import('react').ForwardRefExoticComponent<BitkitComboboxProps & import('react').RefAttributes<HTMLDivElement>>;
14
16
  export default BitkitCombobox;
@@ -4,8 +4,6 @@ import IconWarningYellow from "../../icons/IconWarningYellow.js";
4
4
  import BitkitCloseButton from "../BitkitCloseButton/BitkitCloseButton.js";
5
5
  import BitkitSelectMenu from "../BitkitSelectMenu/BitkitSelectMenu.js";
6
6
  import BitkitField from "../BitkitField/BitkitField.js";
7
- import { useSlotRecipe } from "@chakra-ui/react/styled-system";
8
- import { Text } from "@chakra-ui/react/text";
9
7
  import { forwardRef } from "react";
10
8
  import { jsx, jsxs } from "react/jsx-runtime";
11
9
  import { Portal } from "@chakra-ui/react/portal";
@@ -14,13 +12,13 @@ import { useListCollection } from "@chakra-ui/react/hooks";
14
12
  import { useFilter } from "@chakra-ui/react/locale";
15
13
  //#region lib/components/BitkitCombobox/BitkitCombobox.tsx
16
14
  var BitkitCombobox = forwardRef((props, ref) => {
17
- const { comboboxProps, contentProps, createItemHref, createItemLabel, createItemProps, hasSearch, isLoading, items, onCreateItem, onSearchChange, placeholder = "Enter a value or select", size, state, ...fieldProps } = props;
15
+ const { comboboxProps, createItemLabel, defaultValue, emptyHelperText, emptyLabel, hasSearch, isLoading, items, onCreateItem, onSearchChange, onValueChange, placeholder = "Enter a value or select", searchValue, size, state, value, ...fieldProps } = props;
18
16
  const { contains } = useFilter({ sensitivity: "base" });
19
17
  const { collection, filter } = useListCollection({
20
18
  initialItems: items,
21
- filter: (_itemText, filterText, item) => contains(item.label, filterText)
19
+ filter: (_itemText, filterText, item) => contains(item.label, filterText),
20
+ isItemDisabled: (item) => !!item.disabled
22
21
  });
23
- const styles = useSlotRecipe({ key: "combobox" })({ size });
24
22
  const hasWarning = state === "warning" || !!fieldProps.warningText;
25
23
  const isInvalid = state === "error" || !!fieldProps.errorText;
26
24
  const iconSize = size === "md" ? "16" : "24";
@@ -37,13 +35,17 @@ var BitkitCombobox = forwardRef((props, ref) => {
37
35
  children: /* @__PURE__ */ jsxs(Combobox.Root, {
38
36
  ...comboboxProps,
39
37
  collection,
38
+ defaultValue: defaultValue ? [defaultValue] : void 0,
40
39
  disabled: state === "disabled",
41
40
  invalid: isInvalid,
42
41
  onInputValueChange: (e) => {
43
42
  filter(e.inputValue);
44
43
  },
44
+ onValueChange: (details) => onValueChange?.(details.value[0]),
45
45
  readOnly: state === "readOnly",
46
+ scrollToIndexFn: ({ getElement }) => getElement()?.scrollIntoView({ block: "nearest" }),
46
47
  size,
48
+ value: value ? [value] : void 0,
47
49
  children: [/* @__PURE__ */ jsxs(Combobox.Control, {
48
50
  className: "group",
49
51
  children: [/* @__PURE__ */ jsx(Combobox.Input, { placeholder }), /* @__PURE__ */ jsxs(Combobox.IndicatorGroup, { children: [
@@ -57,24 +59,21 @@ var BitkitCombobox = forwardRef((props, ref) => {
57
59
  children: /* @__PURE__ */ jsx(AssetSelectChevron, {})
58
60
  })
59
61
  ] })]
60
- }), /* @__PURE__ */ jsx(Portal, { children: /* @__PURE__ */ jsx(Combobox.Positioner, { children: /* @__PURE__ */ jsxs(Combobox.Content, { children: [/* @__PURE__ */ jsxs(Combobox.Empty, { children: ["No items found ", /* @__PURE__ */ jsx(Text, {
61
- css: styles.emptyHelperText,
62
- children: "Enter custom value"
63
- })] }), /* @__PURE__ */ jsx(BitkitSelectMenu, {
62
+ }), /* @__PURE__ */ jsx(Portal, { children: /* @__PURE__ */ jsx(Combobox.Positioner, { children: /* @__PURE__ */ jsx(BitkitSelectMenu, {
64
63
  collection,
65
- createItemHref,
66
64
  createItemLabel,
67
- createItemProps,
68
- contentProps,
65
+ emptyHelperText,
66
+ emptyLabel,
69
67
  isLoading,
70
68
  onCreateItem,
71
69
  size,
72
70
  variant: "combobox",
73
71
  ...hasSearch ? {
74
72
  hasSearch: true,
75
- onSearchChange
73
+ onSearchChange,
74
+ searchValue
76
75
  } : { hasSearch: false }
77
- })] }) }) })]
76
+ }) }) })]
78
77
  })
79
78
  });
80
79
  });
@@ -1 +1 @@
1
- {"version":3,"file":"BitkitCombobox.js","names":[],"sources":["../../../lib/components/BitkitCombobox/BitkitCombobox.tsx"],"sourcesContent":["import { Combobox, type ComboboxRootProps } from '@chakra-ui/react/combobox';\nimport { useListCollection } from '@chakra-ui/react/hooks';\nimport { useFilter } from '@chakra-ui/react/locale';\nimport { Portal } from '@chakra-ui/react/portal';\nimport { useSlotRecipe } from '@chakra-ui/react/styled-system';\nimport { Text } from '@chakra-ui/react/text';\nimport { forwardRef } from 'react';\n\nimport IconErrorCircleFilled from '../../icons/IconErrorCircleFilled';\nimport IconWarningYellow from '../../icons/IconWarningYellow';\nimport AssetSelectChevron from '../../utilities/AssetSelectChevron';\nimport BitkitCloseButton from '../BitkitCloseButton/BitkitCloseButton';\nimport BitkitField, { type BitkitFieldProps } from '../BitkitField/BitkitField';\nimport BitkitSelectMenu, {\n type BitkitSelectContentProps,\n type BitkitSelectMenuCreateItemProps,\n type BitkitSelectMenuItemProps,\n type BitkitSelectMenuSearchProps,\n} from '../BitkitSelectMenu/BitkitSelectMenu';\n\nexport type BitkitComboboxProps = Omit<BitkitFieldProps, 'children' | 'state'> & {\n comboboxProps?: ComboboxRootProps;\n contentProps?: BitkitSelectContentProps;\n isLoading?: boolean;\n items: Array<BitkitSelectMenuItemProps>;\n placeholder?: string;\n size?: 'md' | 'lg';\n state?: 'disabled' | 'error' | 'readOnly' | 'warning';\n} & BitkitSelectMenuCreateItemProps &\n BitkitSelectMenuSearchProps;\n\nconst BitkitCombobox = forwardRef<HTMLDivElement, BitkitComboboxProps>((props: BitkitComboboxProps, ref) => {\n const {\n comboboxProps,\n contentProps,\n createItemHref,\n createItemLabel,\n createItemProps,\n hasSearch,\n isLoading,\n items,\n onCreateItem,\n onSearchChange,\n placeholder = 'Enter a value or select',\n size,\n state,\n ...fieldProps\n } = props;\n\n const { contains } = useFilter({ sensitivity: 'base' });\n const { collection, filter } = useListCollection<BitkitSelectMenuItemProps>({\n initialItems: items,\n filter: (_itemText, filterText, item) => contains(item.label, filterText),\n });\n\n const comboboxRecipe = useSlotRecipe({ key: 'combobox' });\n const styles = comboboxRecipe({ size });\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 disabled={state === 'disabled'}\n invalid={isInvalid}\n onInputValueChange={(e) => {\n filter(e.inputValue);\n }}\n readOnly={state === 'readOnly'}\n size={size}\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>\n <Combobox.Positioner>\n <Combobox.Content>\n <Combobox.Empty>\n No items found <Text css={styles.emptyHelperText}>Enter custom value</Text>\n </Combobox.Empty>\n <BitkitSelectMenu\n collection={collection}\n createItemHref={createItemHref}\n createItemLabel={createItemLabel}\n createItemProps={createItemProps}\n contentProps={contentProps}\n isLoading={isLoading}\n onCreateItem={onCreateItem}\n size={size}\n variant=\"combobox\"\n {...(hasSearch ? { hasSearch: true, onSearchChange } : { hasSearch: false as const })}\n />\n </Combobox.Content>\n </Combobox.Positioner>\n </Portal>\n </Combobox.Root>\n </BitkitField>\n );\n});\n\nBitkitCombobox.displayName = 'BitkitCombobox';\n\nexport default BitkitCombobox;\n"],"mappings":";;;;;;;;;;;;;;;AA+BA,IAAM,iBAAiB,YAAiD,OAA4B,QAAQ;CAC1G,MAAM,EACJ,eACA,cACA,gBACA,iBACA,iBACA,WACA,WACA,OACA,cACA,gBACA,cAAc,2BACd,MACA,OACA,GAAG,eACD;CAEJ,MAAM,EAAE,aAAa,UAAU,EAAE,aAAa,QAAQ,CAAC;CACvD,MAAM,EAAE,YAAY,WAAW,kBAA6C;EAC1E,cAAc;EACd,SAAS,WAAW,YAAY,SAAS,SAAS,KAAK,OAAO,WAAW;EAC1E,CAAC;CAGF,MAAM,SADiB,cAAc,EAAE,KAAK,YAAY,CAAC,CAC3B,EAAE,MAAM,CAAC;CAEvC,MAAM,aAAa,UAAU,aAAa,CAAC,CAAC,WAAW;CACvD,MAAM,YAAY,UAAU,WAAW,CAAC,CAAC,WAAW;CACpD,MAAM,WAAW,SAAS,OAAO,OAAO;CAExC,IAAI;AACJ,KAAI,UACF,cAAa,oBAAC,uBAAD;EAAuB,MAAM;EAAU,OAAM;EAAkB,CAAA;UACnE,WACT,cAAa,oBAAC,mBAAD,EAAmB,MAAM,UAAY,CAAA;AAGpD,QACE,oBAAC,aAAD;EAAkB;EAAY;EAAO,GAAI;YACvC,qBAAC,SAAS,MAAV;GACE,GAAI;GACQ;GACZ,UAAU,UAAU;GACpB,SAAS;GACT,qBAAqB,MAAM;AACzB,WAAO,EAAE,WAAW;;GAEtB,UAAU,UAAU;GACd;aATR,CAWE,qBAAC,SAAS,SAAV;IAAkB,WAAU;cAA5B,CACE,oBAAC,SAAS,OAAV,EAA6B,aAAe,CAAA,EAC5C,qBAAC,SAAS,gBAAV,EAAA,UAAA;KACE,oBAAC,SAAS,cAAV;MAAuB,SAAA;gBACrB,oBAAC,mBAAD,EAAmB,MAAK,MAAO,CAAA;MACT,CAAA;KACvB;KACD,oBAAC,SAAS,SAAV;MAAkB,SAAA;gBAChB,oBAAC,oBAAD,EAAsB,CAAA;MACL,CAAA;KACK,EAAA,CAAA,CACT;OACnB,oBAAC,QAAD,EAAA,UACE,oBAAC,SAAS,YAAV,EAAA,UACE,qBAAC,SAAS,SAAV,EAAA,UAAA,CACE,qBAAC,SAAS,OAAV,EAAA,UAAA,CAAgB,mBACC,oBAAC,MAAD;IAAM,KAAK,OAAO;cAAiB;IAAyB,CAAA,CAC5D,EAAA,CAAA,EACjB,oBAAC,kBAAD;IACc;IACI;IACC;IACA;IACH;IACH;IACG;IACR;IACN,SAAQ;IACR,GAAK,YAAY;KAAE,WAAW;KAAM;KAAgB,GAAG,EAAE,WAAW,OAAgB;IACpF,CAAA,CACe,EAAA,CAAA,EACC,CAAA,EACf,CAAA,CACK;;EACJ,CAAA;EAEhB;AAEF,eAAe,cAAc"}
1
+ {"version":3,"file":"BitkitCombobox.js","names":[],"sources":["../../../lib/components/BitkitCombobox/BitkitCombobox.tsx"],"sourcesContent":["import { Combobox, type ComboboxRootProps } from '@chakra-ui/react/combobox';\nimport { useListCollection } from '@chakra-ui/react/hooks';\nimport { useFilter } from '@chakra-ui/react/locale';\nimport { Portal } from '@chakra-ui/react/portal';\nimport { forwardRef } from 'react';\n\nimport IconErrorCircleFilled from '../../icons/IconErrorCircleFilled';\nimport IconWarningYellow from '../../icons/IconWarningYellow';\nimport AssetSelectChevron from '../../utilities/AssetSelectChevron';\nimport BitkitCloseButton from '../BitkitCloseButton/BitkitCloseButton';\nimport BitkitField, { type BitkitFieldProps } from '../BitkitField/BitkitField';\nimport BitkitSelectMenu, {\n type BitkitSelectMenuCreateItemProps,\n type BitkitSelectMenuEmptyStateProps,\n type BitkitSelectMenuItemProps,\n type BitkitSelectMenuSearchProps,\n} from '../BitkitSelectMenu/BitkitSelectMenu';\n\nexport type BitkitComboboxProps = Omit<BitkitFieldProps, 'children' | 'state'> & {\n comboboxProps?: Omit<ComboboxRootProps, 'collection' | 'defaultValue' | 'onValueChange' | 'value'>;\n defaultValue?: string;\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} & BitkitSelectMenuCreateItemProps &\n BitkitSelectMenuSearchProps &\n BitkitSelectMenuEmptyStateProps;\n\nconst BitkitCombobox = forwardRef<HTMLDivElement, BitkitComboboxProps>((props: BitkitComboboxProps, ref) => {\n const {\n comboboxProps,\n createItemLabel,\n defaultValue,\n emptyHelperText,\n emptyLabel,\n hasSearch,\n isLoading,\n items,\n onCreateItem,\n onSearchChange,\n onValueChange,\n placeholder = 'Enter a value or select',\n searchValue,\n size,\n state,\n value,\n ...fieldProps\n } = props;\n\n const { contains } = useFilter({ sensitivity: 'base' });\n const { collection, filter } = useListCollection<BitkitSelectMenuItemProps>({\n initialItems: items,\n filter: (_itemText, filterText, item) => contains(item.label, filterText),\n isItemDisabled: (item) => !!item.disabled,\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 invalid={isInvalid}\n onInputValueChange={(e) => {\n filter(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 value={value ? [value] : undefined}\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>\n <Combobox.Positioner>\n <BitkitSelectMenu\n collection={collection}\n createItemLabel={createItemLabel}\n emptyHelperText={emptyHelperText}\n emptyLabel={emptyLabel}\n isLoading={isLoading}\n onCreateItem={onCreateItem}\n size={size}\n variant=\"combobox\"\n {...(hasSearch\n ? { hasSearch: true as const, onSearchChange, searchValue }\n : { hasSearch: false as const })}\n />\n </Combobox.Positioner>\n </Portal>\n </Combobox.Root>\n </BitkitField>\n );\n});\n\nBitkitCombobox.displayName = 'BitkitCombobox';\n\nexport default BitkitCombobox;\n"],"mappings":";;;;;;;;;;;;;AAgCA,IAAM,iBAAiB,YAAiD,OAA4B,QAAQ;CAC1G,MAAM,EACJ,eACA,iBACA,cACA,iBACA,YACA,WACA,WACA,OACA,cACA,gBACA,eACA,cAAc,2BACd,aACA,MACA,OACA,OACA,GAAG,eACD;CAEJ,MAAM,EAAE,aAAa,UAAU,EAAE,aAAa,QAAQ,CAAC;CACvD,MAAM,EAAE,YAAY,WAAW,kBAA6C;EAC1E,cAAc;EACd,SAAS,WAAW,YAAY,SAAS,SAAS,KAAK,OAAO,WAAW;EACzE,iBAAiB,SAAS,CAAC,CAAC,KAAK;EAClC,CAAC;CAEF,MAAM,aAAa,UAAU,aAAa,CAAC,CAAC,WAAW;CACvD,MAAM,YAAY,UAAU,WAAW,CAAC,CAAC,WAAW;CACpD,MAAM,WAAW,SAAS,OAAO,OAAO;CAExC,IAAI;AACJ,KAAI,UACF,cAAa,oBAAC,uBAAD;EAAuB,MAAM;EAAU,OAAM;EAAkB,CAAA;UACnE,WACT,cAAa,oBAAC,mBAAD,EAAmB,MAAM,UAAY,CAAA;AAGpD,QACE,oBAAC,aAAD;EAAkB;EAAY;EAAO,GAAI;YACvC,qBAAC,SAAS,MAAV;GACE,GAAI;GACQ;GACZ,cAAc,eAAe,CAAC,aAAa,GAAG,KAAA;GAC9C,UAAU,UAAU;GACpB,SAAS;GACT,qBAAqB,MAAM;AACzB,WAAO,EAAE,WAAW;;GAEtB,gBAAgB,YAAY,gBAAgB,QAAQ,MAAM,GAAG;GAC7D,UAAU,UAAU;GAGpB,kBAAkB,EAAE,iBAAiB,YAAY,EAAE,eAAe,EAAE,OAAO,WAAW,CAAC;GACjF;GACN,OAAO,QAAQ,CAAC,MAAM,GAAG,KAAA;aAf3B,CAiBE,qBAAC,SAAS,SAAV;IAAkB,WAAU;cAA5B,CACE,oBAAC,SAAS,OAAV,EAA6B,aAAe,CAAA,EAC5C,qBAAC,SAAS,gBAAV,EAAA,UAAA;KACE,oBAAC,SAAS,cAAV;MAAuB,SAAA;gBACrB,oBAAC,mBAAD,EAAmB,MAAK,MAAO,CAAA;MACT,CAAA;KACvB;KACD,oBAAC,SAAS,SAAV;MAAkB,SAAA;gBAChB,oBAAC,oBAAD,EAAsB,CAAA;MACL,CAAA;KACK,EAAA,CAAA,CACT;OACnB,oBAAC,QAAD,EAAA,UACE,oBAAC,SAAS,YAAV,EAAA,UACE,oBAAC,kBAAD;IACc;IACK;IACA;IACL;IACD;IACG;IACR;IACN,SAAQ;IACR,GAAK,YACD;KAAE,WAAW;KAAe;KAAgB;KAAa,GACzD,EAAE,WAAW,OAAgB;IACjC,CAAA,EACkB,CAAA,EACf,CAAA,CACK;;EACJ,CAAA;EAEhB;AAEF,eAAe,cAAc"}
@@ -0,0 +1,19 @@
1
+ import { SelectRootProps, SelectTriggerProps } from '@chakra-ui/react/select';
2
+ import { BitkitFieldProps } from '../BitkitField/BitkitField';
3
+ import { BitkitSelectMenuCreateItemProps, BitkitSelectMenuEmptyStateProps, BitkitSelectMenuItemProps, BitkitSelectMenuSearchProps } from '../BitkitSelectMenu/BitkitSelectMenu';
4
+ export type BitkitMultiselectTriggerProps = SelectTriggerProps;
5
+ export type BitkitMultiselectProps = Omit<BitkitFieldProps, 'children' | 'state'> & {
6
+ constrained?: boolean;
7
+ defaultValue?: Array<string>;
8
+ isLoading?: boolean;
9
+ items: Array<BitkitSelectMenuItemProps>;
10
+ onValueChange?: (newVal: Array<string>) => void;
11
+ placeholder?: string;
12
+ selectProps?: Omit<SelectRootProps, 'collection' | 'defaultValue' | 'multiple' | 'onValueChange' | 'value'>;
13
+ size?: 'md' | 'lg';
14
+ state?: 'disabled' | 'error' | 'readOnly' | 'warning';
15
+ triggerProps?: BitkitMultiselectTriggerProps;
16
+ value?: Array<string>;
17
+ } & BitkitSelectMenuCreateItemProps & BitkitSelectMenuSearchProps & BitkitSelectMenuEmptyStateProps;
18
+ declare const BitkitMultiselect: import('react').ForwardRefExoticComponent<BitkitMultiselectProps & import('react').RefAttributes<HTMLDivElement>>;
19
+ export default BitkitMultiselect;
@@ -0,0 +1,184 @@
1
+ import AssetSelectChevron from "../../utilities/AssetSelectChevron.js";
2
+ import IconErrorCircleFilled from "../../icons/IconErrorCircleFilled.js";
3
+ import IconWarningYellow from "../../icons/IconWarningYellow.js";
4
+ import BitkitCloseButton from "../BitkitCloseButton/BitkitCloseButton.js";
5
+ import BitkitSelectMenu from "../BitkitSelectMenu/BitkitSelectMenu.js";
6
+ import BitkitField from "../BitkitField/BitkitField.js";
7
+ import BitkitTag from "../BitkitTag/BitkitTag.js";
8
+ import { Box } from "@chakra-ui/react/box";
9
+ import { useSlotRecipe } from "@chakra-ui/react/styled-system";
10
+ import { Text } from "@chakra-ui/react/text";
11
+ import { forwardRef } from "react";
12
+ import { Fragment as Fragment$1, jsx, jsxs } from "react/jsx-runtime";
13
+ import { Portal } from "@chakra-ui/react/portal";
14
+ import { createListCollection } from "@chakra-ui/react/collection";
15
+ import { Select, useSelectContext } from "@chakra-ui/react/select";
16
+ //#region lib/components/BitkitMultiselect/BitkitMultiselect.tsx
17
+ var NON_INTERACTIVE_STATES = [
18
+ "disabled",
19
+ "readOnly",
20
+ "error",
21
+ "warning"
22
+ ];
23
+ /** Whether the clear-all button should be rendered (and the overlay should reserve extra room for it). */
24
+ var shouldShowClearButton = (constrained, selectionCount, state) => !constrained && selectionCount > 0 && !NON_INTERACTIVE_STATES.includes(state);
25
+ var MultiselectOverlay = ({ constrained, placeholder, size, state }) => {
26
+ const select = useSelectContext();
27
+ const styles = useSlotRecipe({ key: "multiselect" })({
28
+ constrained,
29
+ size
30
+ });
31
+ const selectedItems = select.selectedItems;
32
+ const selectedValues = select.value;
33
+ const isDisabled = state === "disabled";
34
+ const isReadOnly = state === "readOnly";
35
+ const tagState = isDisabled ? "disabled" : void 0;
36
+ const overlayPaddingEnd = shouldShowClearButton(constrained, selectedValues.length, state) ? "96" : "48";
37
+ const resolvedPlaceholder = placeholder ?? (isReadOnly ? "(not selected)" : "Select options");
38
+ const canRemove = !isDisabled && !isReadOnly;
39
+ const hasSelection = selectedValues.length > 0;
40
+ const renderTags = () => {
41
+ if (constrained) return /* @__PURE__ */ jsxs(Fragment$1, { children: [hasSelection && /* @__PURE__ */ jsx(TagSlot, { children: /* @__PURE__ */ jsx(BitkitTag, {
42
+ size: "sm",
43
+ colorPalette: "neutral",
44
+ labelText: String(selectedValues.length),
45
+ state: tagState,
46
+ onRemove: canRemove ? () => select.clearValue() : void 0
47
+ }) }), /* @__PURE__ */ jsx(Text, {
48
+ as: "span",
49
+ css: styles.placeholderText,
50
+ "data-placeholder": hasSelection ? void 0 : "",
51
+ children: resolvedPlaceholder
52
+ })] });
53
+ if (selectedItems.length === 0) return /* @__PURE__ */ jsx(Text, {
54
+ as: "span",
55
+ css: styles.placeholderText,
56
+ "data-placeholder": "",
57
+ children: resolvedPlaceholder
58
+ });
59
+ return selectedItems.map((item) => /* @__PURE__ */ jsx(TagSlot, { children: /* @__PURE__ */ jsx(BitkitTag, {
60
+ size: "sm",
61
+ colorPalette: "neutral",
62
+ labelText: item.label,
63
+ state: tagState,
64
+ onRemove: canRemove ? () => select.setValue(selectedValues.filter((v) => v !== item.value)) : void 0
65
+ }) }, item.value));
66
+ };
67
+ return /* @__PURE__ */ jsx(Box, {
68
+ css: styles.overlay,
69
+ pointerEvents: "none",
70
+ paddingInlineEnd: overlayPaddingEnd,
71
+ children: /* @__PURE__ */ jsx(Box, {
72
+ css: styles.tagsBlock,
73
+ children: renderTags()
74
+ })
75
+ });
76
+ };
77
+ var TagSlot = ({ children }) => /* @__PURE__ */ jsx(Box, {
78
+ "data-slot": "tag",
79
+ display: "inline-flex",
80
+ pointerEvents: "auto",
81
+ children
82
+ });
83
+ var ClearAllButton = ({ state }) => {
84
+ const select = useSelectContext();
85
+ if (!shouldShowClearButton(false, select.value.length, state)) return null;
86
+ return /* @__PURE__ */ jsx(BitkitCloseButton, {
87
+ size: "sm",
88
+ colorPalette: "neutral",
89
+ "aria-label": "Clear all",
90
+ onClick: () => select.clearValue()
91
+ });
92
+ };
93
+ var BitkitMultiselect = forwardRef((props, ref) => {
94
+ const { constrained = false, createItemLabel, defaultValue, emptyHelperText, emptyLabel, hasSearch, isLoading, items, onCreateItem, onSearchChange, onValueChange, placeholder, searchValue, selectProps, size = "lg", state, triggerProps, value, ...fieldProps } = props;
95
+ const collection = createListCollection({
96
+ items,
97
+ groupBy: (item) => item.group || "",
98
+ isItemDisabled: (item) => !!item.disabled
99
+ });
100
+ const styles = useSlotRecipe({ key: "multiselect" })({
101
+ constrained,
102
+ size
103
+ });
104
+ const iconSize = size === "lg" ? "24" : "16";
105
+ const isInvalid = state === "error" || !!fieldProps.errorText;
106
+ return /* @__PURE__ */ jsx(BitkitField, {
107
+ ref,
108
+ state,
109
+ ...fieldProps,
110
+ children: /* @__PURE__ */ jsxs(Select.Root, {
111
+ collection,
112
+ multiple: true,
113
+ ...selectProps,
114
+ defaultValue,
115
+ disabled: state === "disabled",
116
+ invalid: isInvalid,
117
+ onValueChange: (details) => onValueChange?.(details.value),
118
+ readOnly: state === "readOnly",
119
+ scrollToIndexFn: ({ getElement }) => getElement()?.scrollIntoView({ block: "nearest" }),
120
+ value,
121
+ children: [
122
+ /* @__PURE__ */ jsx(Select.HiddenSelect, {}),
123
+ /* @__PURE__ */ jsxs(Select.Control, {
124
+ css: styles.control,
125
+ className: "group",
126
+ children: [
127
+ /* @__PURE__ */ jsx(Select.Trigger, {
128
+ css: styles.trigger,
129
+ ...triggerProps
130
+ }),
131
+ /* @__PURE__ */ jsx(MultiselectOverlay, {
132
+ constrained,
133
+ placeholder,
134
+ size,
135
+ state
136
+ }),
137
+ /* @__PURE__ */ jsxs(Select.IndicatorGroup, {
138
+ css: styles.indicatorGroup,
139
+ children: [
140
+ !constrained && /* @__PURE__ */ jsx(ClearAllButton, { state }),
141
+ state === "error" && /* @__PURE__ */ jsx(Select.Indicator, {
142
+ css: styles.indicator,
143
+ children: /* @__PURE__ */ jsx(IconErrorCircleFilled, {
144
+ size: iconSize,
145
+ color: "icon/negative"
146
+ })
147
+ }),
148
+ state === "warning" && /* @__PURE__ */ jsx(Select.Indicator, {
149
+ css: styles.indicator,
150
+ children: /* @__PURE__ */ jsx(IconWarningYellow, { size: iconSize })
151
+ }),
152
+ /* @__PURE__ */ jsx(Select.Indicator, {
153
+ css: styles.indicator,
154
+ asChild: true,
155
+ children: /* @__PURE__ */ jsx(AssetSelectChevron, {})
156
+ })
157
+ ]
158
+ })
159
+ ]
160
+ }),
161
+ /* @__PURE__ */ jsx(Portal, { children: /* @__PURE__ */ jsx(Select.Positioner, { children: /* @__PURE__ */ jsx(BitkitSelectMenu, {
162
+ collection,
163
+ createItemLabel,
164
+ emptyHelperText,
165
+ emptyLabel,
166
+ isLoading,
167
+ multiple: true,
168
+ onCreateItem,
169
+ ...hasSearch ? {
170
+ hasSearch: true,
171
+ onSearchChange,
172
+ searchValue
173
+ } : { hasSearch: false },
174
+ size
175
+ }) }) })
176
+ ]
177
+ })
178
+ });
179
+ });
180
+ BitkitMultiselect.displayName = "BitkitMultiselect";
181
+ //#endregion
182
+ export { BitkitMultiselect as default };
183
+
184
+ //# sourceMappingURL=BitkitMultiselect.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"BitkitMultiselect.js","names":[],"sources":["../../../lib/components/BitkitMultiselect/BitkitMultiselect.tsx"],"sourcesContent":["import { Box } from '@chakra-ui/react/box';\nimport { createListCollection } from '@chakra-ui/react/collection';\nimport { Portal } from '@chakra-ui/react/portal';\nimport { Select, type SelectRootProps, type SelectTriggerProps, useSelectContext } from '@chakra-ui/react/select';\nimport { useSlotRecipe } from '@chakra-ui/react/styled-system';\nimport { Text } from '@chakra-ui/react/text';\nimport { forwardRef, type ReactNode } from 'react';\n\nimport { IconErrorCircleFilled, IconWarningYellow } from '../../icons';\nimport AssetSelectChevron from '../../utilities/AssetSelectChevron';\nimport BitkitCloseButton from '../BitkitCloseButton/BitkitCloseButton';\nimport BitkitField, { type BitkitFieldProps } from '../BitkitField/BitkitField';\nimport BitkitSelectMenu, {\n type BitkitSelectMenuCreateItemProps,\n type BitkitSelectMenuEmptyStateProps,\n type BitkitSelectMenuItemProps,\n type BitkitSelectMenuSearchProps,\n} from '../BitkitSelectMenu/BitkitSelectMenu';\nimport BitkitTag from '../BitkitTag/BitkitTag';\n\nexport type BitkitMultiselectTriggerProps = SelectTriggerProps;\n\nexport type BitkitMultiselectProps = Omit<BitkitFieldProps, 'children' | 'state'> & {\n constrained?: boolean;\n defaultValue?: Array<string>;\n isLoading?: boolean;\n items: Array<BitkitSelectMenuItemProps>;\n onValueChange?: (newVal: Array<string>) => void;\n placeholder?: string;\n selectProps?: Omit<SelectRootProps, 'collection' | 'defaultValue' | 'multiple' | 'onValueChange' | 'value'>;\n size?: 'md' | 'lg';\n state?: 'disabled' | 'error' | 'readOnly' | 'warning';\n triggerProps?: BitkitMultiselectTriggerProps;\n value?: Array<string>;\n} & BitkitSelectMenuCreateItemProps &\n BitkitSelectMenuSearchProps &\n BitkitSelectMenuEmptyStateProps;\n\ntype MultiselectState = BitkitMultiselectProps['state'];\n\nconst NON_INTERACTIVE_STATES: ReadonlyArray<MultiselectState> = ['disabled', 'readOnly', 'error', 'warning'];\n\n/** Whether the clear-all button should be rendered (and the overlay should reserve extra room for it). */\nconst shouldShowClearButton = (constrained: boolean, selectionCount: number, state: MultiselectState): boolean =>\n !constrained && selectionCount > 0 && !NON_INTERACTIVE_STATES.includes(state);\n\ntype MultiselectOverlayProps = {\n constrained: boolean;\n placeholder?: string;\n size: 'md' | 'lg';\n state?: MultiselectState;\n};\n\nconst MultiselectOverlay = ({ constrained, placeholder, size, state }: MultiselectOverlayProps) => {\n const select = useSelectContext();\n const recipe = useSlotRecipe({ key: 'multiselect' });\n const styles = recipe({ constrained, size });\n\n const selectedItems = select.selectedItems as Array<BitkitSelectMenuItemProps>;\n const selectedValues = select.value;\n const isDisabled = state === 'disabled';\n const isReadOnly = state === 'readOnly';\n const tagState = isDisabled ? 'disabled' : undefined;\n // Overlay reserves ~96px on the right when the clear-all is visible (to keep the chevron +\n // clear button out of the tag row), otherwise ~48px (chevron only). Using spacing tokens\n // because '80' (the minimum that fits both icons with gaps) isn't a valid token; '96' is\n // the next one up.\n const overlayPaddingEnd = shouldShowClearButton(constrained, selectedValues.length, state) ? '96' : '48';\n\n const resolvedPlaceholder = placeholder ?? (isReadOnly ? '(not selected)' : 'Select options');\n const canRemove = !isDisabled && !isReadOnly;\n\n const hasSelection = selectedValues.length > 0;\n\n const renderTags = () => {\n if (constrained) {\n return (\n <>\n {hasSelection && (\n <TagSlot>\n <BitkitTag\n size=\"sm\"\n colorPalette=\"neutral\"\n labelText={String(selectedValues.length)}\n state={tagState}\n onRemove={canRemove ? () => select.clearValue() : undefined}\n />\n </TagSlot>\n )}\n <Text as=\"span\" css={styles.placeholderText} data-placeholder={hasSelection ? undefined : ''}>\n {resolvedPlaceholder}\n </Text>\n </>\n );\n }\n\n if (selectedItems.length === 0) {\n return (\n <Text as=\"span\" css={styles.placeholderText} data-placeholder=\"\">\n {resolvedPlaceholder}\n </Text>\n );\n }\n\n return selectedItems.map((item) => (\n <TagSlot key={item.value}>\n <BitkitTag\n size=\"sm\"\n colorPalette=\"neutral\"\n labelText={item.label}\n state={tagState}\n onRemove={canRemove ? () => select.setValue(selectedValues.filter((v) => v !== item.value)) : undefined}\n />\n </TagSlot>\n ));\n };\n\n return (\n <Box css={styles.overlay} pointerEvents=\"none\" paddingInlineEnd={overlayPaddingEnd}>\n <Box css={styles.tagsBlock}>{renderTags()}</Box>\n </Box>\n );\n};\n\nconst TagSlot = ({ children }: { children: ReactNode }) => (\n <Box data-slot=\"tag\" display=\"inline-flex\" pointerEvents=\"auto\">\n {children}\n </Box>\n);\n\ntype ClearAllButtonProps = {\n state?: MultiselectState;\n};\n\nconst ClearAllButton = ({ state }: ClearAllButtonProps) => {\n const select = useSelectContext();\n\n // Constrained mode has its own inline clear-all on the counter tag; this is the non-constrained trigger-level clear.\n if (!shouldShowClearButton(false, select.value.length, state)) return null;\n\n return (\n <BitkitCloseButton size=\"sm\" colorPalette=\"neutral\" aria-label=\"Clear all\" onClick={() => select.clearValue()} />\n );\n};\n\nconst BitkitMultiselect = forwardRef<HTMLDivElement, BitkitMultiselectProps>((props, ref) => {\n const {\n constrained = false,\n createItemLabel,\n defaultValue,\n emptyHelperText,\n emptyLabel,\n hasSearch,\n isLoading,\n items,\n onCreateItem,\n onSearchChange,\n onValueChange,\n placeholder,\n searchValue,\n selectProps,\n size = 'lg',\n state,\n triggerProps,\n value,\n ...fieldProps\n } = props;\n\n const collection = createListCollection({\n items,\n groupBy: (item) => item.group || '',\n isItemDisabled: (item) => !!item.disabled,\n });\n\n const recipe = useSlotRecipe({ key: 'multiselect' });\n const styles = recipe({ constrained, size });\n\n const iconSize = size === 'lg' ? '24' : '16';\n const isInvalid = state === 'error' || !!fieldProps.errorText;\n\n return (\n <BitkitField ref={ref} state={state} {...fieldProps}>\n <Select.Root\n collection={collection}\n multiple\n {...selectProps}\n defaultValue={defaultValue}\n disabled={state === 'disabled'}\n invalid={isInvalid}\n onValueChange={(details) => onValueChange?.(details.value)}\n readOnly={state === 'readOnly'}\n // Zag's default scrollIntoView gates on `isScrollable(contentEl)`. Our content is\n // overflow:hidden + flex column (so the sticky-bottom create row stays visible while\n // the inner itemList Box scrolls). That gate fails, so keyboard highlight never\n // scrolls the items into view. Providing scrollToIndexFn bypasses the gate and lets\n // the browser's native scrollIntoView walk up to the real scroll container (itemList).\n scrollToIndexFn={({ getElement }) => getElement()?.scrollIntoView({ block: 'nearest' })}\n value={value}\n >\n <Select.HiddenSelect />\n <Select.Control css={styles.control} className=\"group\">\n <Select.Trigger css={styles.trigger} {...triggerProps} />\n <MultiselectOverlay constrained={constrained} placeholder={placeholder} size={size} state={state} />\n <Select.IndicatorGroup css={styles.indicatorGroup}>\n {!constrained && <ClearAllButton state={state} />}\n {state === 'error' && (\n <Select.Indicator css={styles.indicator}>\n <IconErrorCircleFilled size={iconSize} color=\"icon/negative\" />\n </Select.Indicator>\n )}\n {state === 'warning' && (\n <Select.Indicator css={styles.indicator}>\n <IconWarningYellow size={iconSize} />\n </Select.Indicator>\n )}\n <Select.Indicator css={styles.indicator} asChild>\n <AssetSelectChevron />\n </Select.Indicator>\n </Select.IndicatorGroup>\n </Select.Control>\n <Portal>\n <Select.Positioner>\n <BitkitSelectMenu\n collection={collection}\n createItemLabel={createItemLabel}\n emptyHelperText={emptyHelperText}\n emptyLabel={emptyLabel}\n isLoading={isLoading}\n multiple\n onCreateItem={onCreateItem}\n {...(hasSearch\n ? { hasSearch: true as const, onSearchChange, searchValue }\n : { hasSearch: false as const })}\n size={size}\n />\n </Select.Positioner>\n </Portal>\n </Select.Root>\n </BitkitField>\n );\n});\n\nBitkitMultiselect.displayName = 'BitkitMultiselect';\n\nexport default BitkitMultiselect;\n"],"mappings":";;;;;;;;;;;;;;;;AAwCA,IAAM,yBAA0D;CAAC;CAAY;CAAY;CAAS;CAAU;;AAG5G,IAAM,yBAAyB,aAAsB,gBAAwB,UAC3E,CAAC,eAAe,iBAAiB,KAAK,CAAC,uBAAuB,SAAS,MAAM;AAS/E,IAAM,sBAAsB,EAAE,aAAa,aAAa,MAAM,YAAqC;CACjG,MAAM,SAAS,kBAAkB;CAEjC,MAAM,SADS,cAAc,EAAE,KAAK,eAAe,CAAC,CAC9B;EAAE;EAAa;EAAM,CAAC;CAE5C,MAAM,gBAAgB,OAAO;CAC7B,MAAM,iBAAiB,OAAO;CAC9B,MAAM,aAAa,UAAU;CAC7B,MAAM,aAAa,UAAU;CAC7B,MAAM,WAAW,aAAa,aAAa,KAAA;CAK3C,MAAM,oBAAoB,sBAAsB,aAAa,eAAe,QAAQ,MAAM,GAAG,OAAO;CAEpG,MAAM,sBAAsB,gBAAgB,aAAa,mBAAmB;CAC5E,MAAM,YAAY,CAAC,cAAc,CAAC;CAElC,MAAM,eAAe,eAAe,SAAS;CAE7C,MAAM,mBAAmB;AACvB,MAAI,YACF,QACE,qBAAA,YAAA,EAAA,UAAA,CACG,gBACC,oBAAC,SAAD,EAAA,UACE,oBAAC,WAAD;GACE,MAAK;GACL,cAAa;GACb,WAAW,OAAO,eAAe,OAAO;GACxC,OAAO;GACP,UAAU,kBAAkB,OAAO,YAAY,GAAG,KAAA;GAClD,CAAA,EACM,CAAA,EAEZ,oBAAC,MAAD;GAAM,IAAG;GAAO,KAAK,OAAO;GAAiB,oBAAkB,eAAe,KAAA,IAAY;aACvF;GACI,CAAA,CACN,EAAA,CAAA;AAIP,MAAI,cAAc,WAAW,EAC3B,QACE,oBAAC,MAAD;GAAM,IAAG;GAAO,KAAK,OAAO;GAAiB,oBAAiB;aAC3D;GACI,CAAA;AAIX,SAAO,cAAc,KAAK,SACxB,oBAAC,SAAD,EAAA,UACE,oBAAC,WAAD;GACE,MAAK;GACL,cAAa;GACb,WAAW,KAAK;GAChB,OAAO;GACP,UAAU,kBAAkB,OAAO,SAAS,eAAe,QAAQ,MAAM,MAAM,KAAK,MAAM,CAAC,GAAG,KAAA;GAC9F,CAAA,EACM,EARI,KAAK,MAQT,CACV;;AAGJ,QACE,oBAAC,KAAD;EAAK,KAAK,OAAO;EAAS,eAAc;EAAO,kBAAkB;YAC/D,oBAAC,KAAD;GAAK,KAAK,OAAO;aAAY,YAAY;GAAO,CAAA;EAC5C,CAAA;;AAIV,IAAM,WAAW,EAAE,eACjB,oBAAC,KAAD;CAAK,aAAU;CAAM,SAAQ;CAAc,eAAc;CACtD;CACG,CAAA;AAOR,IAAM,kBAAkB,EAAE,YAAiC;CACzD,MAAM,SAAS,kBAAkB;AAGjC,KAAI,CAAC,sBAAsB,OAAO,OAAO,MAAM,QAAQ,MAAM,CAAE,QAAO;AAEtE,QACE,oBAAC,mBAAD;EAAmB,MAAK;EAAK,cAAa;EAAU,cAAW;EAAY,eAAe,OAAO,YAAY;EAAI,CAAA;;AAIrH,IAAM,oBAAoB,YAAoD,OAAO,QAAQ;CAC3F,MAAM,EACJ,cAAc,OACd,iBACA,cACA,iBACA,YACA,WACA,WACA,OACA,cACA,gBACA,eACA,aACA,aACA,aACA,OAAO,MACP,OACA,cACA,OACA,GAAG,eACD;CAEJ,MAAM,aAAa,qBAAqB;EACtC;EACA,UAAU,SAAS,KAAK,SAAS;EACjC,iBAAiB,SAAS,CAAC,CAAC,KAAK;EAClC,CAAC;CAGF,MAAM,SADS,cAAc,EAAE,KAAK,eAAe,CAAC,CAC9B;EAAE;EAAa;EAAM,CAAC;CAE5C,MAAM,WAAW,SAAS,OAAO,OAAO;CACxC,MAAM,YAAY,UAAU,WAAW,CAAC,CAAC,WAAW;AAEpD,QACE,oBAAC,aAAD;EAAkB;EAAY;EAAO,GAAI;YACvC,qBAAC,OAAO,MAAR;GACc;GACZ,UAAA;GACA,GAAI;GACU;GACd,UAAU,UAAU;GACpB,SAAS;GACT,gBAAgB,YAAY,gBAAgB,QAAQ,MAAM;GAC1D,UAAU,UAAU;GAMpB,kBAAkB,EAAE,iBAAiB,YAAY,EAAE,eAAe,EAAE,OAAO,WAAW,CAAC;GAChF;aAfT;IAiBE,oBAAC,OAAO,cAAR,EAAuB,CAAA;IACvB,qBAAC,OAAO,SAAR;KAAgB,KAAK,OAAO;KAAS,WAAU;eAA/C;MACE,oBAAC,OAAO,SAAR;OAAgB,KAAK,OAAO;OAAS,GAAI;OAAgB,CAAA;MACzD,oBAAC,oBAAD;OAAiC;OAA0B;OAAmB;OAAa;OAAS,CAAA;MACpG,qBAAC,OAAO,gBAAR;OAAuB,KAAK,OAAO;iBAAnC;QACG,CAAC,eAAe,oBAAC,gBAAD,EAAuB,OAAS,CAAA;QAChD,UAAU,WACT,oBAAC,OAAO,WAAR;SAAkB,KAAK,OAAO;mBAC5B,oBAAC,uBAAD;UAAuB,MAAM;UAAU,OAAM;UAAkB,CAAA;SAC9C,CAAA;QAEpB,UAAU,aACT,oBAAC,OAAO,WAAR;SAAkB,KAAK,OAAO;mBAC5B,oBAAC,mBAAD,EAAmB,MAAM,UAAY,CAAA;SACpB,CAAA;QAErB,oBAAC,OAAO,WAAR;SAAkB,KAAK,OAAO;SAAW,SAAA;mBACvC,oBAAC,oBAAD,EAAsB,CAAA;SACL,CAAA;QACG;;MACT;;IACjB,oBAAC,QAAD,EAAA,UACE,oBAAC,OAAO,YAAR,EAAA,UACE,oBAAC,kBAAD;KACc;KACK;KACA;KACL;KACD;KACX,UAAA;KACc;KACd,GAAK,YACD;MAAE,WAAW;MAAe;MAAgB;MAAa,GACzD,EAAE,WAAW,OAAgB;KAC3B;KACN,CAAA,EACgB,CAAA,EACb,CAAA;IACG;;EACF,CAAA;EAEhB;AAEF,kBAAkB,cAAc"}
@@ -1,9 +1,8 @@
1
1
  import { SelectRootProps, SelectTriggerProps } from '@chakra-ui/react/select';
2
2
  import { BitkitFieldProps } from '../BitkitField/BitkitField.tsx';
3
- import { BitkitSelectContentProps, BitkitSelectMenuCreateItemProps, BitkitSelectMenuItemProps, BitkitSelectMenuSearchProps } from '../BitkitSelectMenu/BitkitSelectMenu.tsx';
3
+ import { BitkitSelectMenuCreateItemProps, BitkitSelectMenuEmptyStateProps, BitkitSelectMenuItemProps, BitkitSelectMenuSearchProps } from '../BitkitSelectMenu/BitkitSelectMenu.tsx';
4
4
  export type BitkitSelectTriggerProps = SelectTriggerProps;
5
5
  export type BitkitSelectProps = Omit<BitkitFieldProps, 'children' | 'state'> & {
6
- contentProps?: BitkitSelectContentProps;
7
6
  defaultValue?: string;
8
7
  isLoading?: boolean;
9
8
  items: Array<BitkitSelectMenuItemProps>;
@@ -14,6 +13,6 @@ export type BitkitSelectProps = Omit<BitkitFieldProps, 'children' | 'state'> & {
14
13
  state?: 'disabled' | 'error' | 'readOnly' | 'warning';
15
14
  triggerProps?: BitkitSelectTriggerProps;
16
15
  value?: string;
17
- } & BitkitSelectMenuCreateItemProps & BitkitSelectMenuSearchProps;
16
+ } & BitkitSelectMenuCreateItemProps & BitkitSelectMenuSearchProps & BitkitSelectMenuEmptyStateProps;
18
17
  declare const BitkitSelect: import('react').ForwardRefExoticComponent<BitkitSelectProps & import('react').RefAttributes<HTMLDivElement>>;
19
18
  export default BitkitSelect;
@@ -26,11 +26,13 @@ var SelectValue = ({ placeholder, state, size }) => {
26
26
  }) : /* @__PURE__ */ jsx(Select.ValueText, { placeholder: placeholder ?? (state === "readOnly" ? "(not selected)" : "Select an option") });
27
27
  };
28
28
  var BitkitSelect = forwardRef((props, ref) => {
29
- const { contentProps, createItemHref, createItemLabel, createItemProps, defaultValue, hasSearch, isLoading, items, onCreateItem, onSearchChange, onValueChange, placeholder, selectProps, size = "md", state, triggerProps, value, ...fieldProps } = props;
29
+ const { createItemLabel, defaultValue, emptyHelperText, emptyLabel, hasSearch, isLoading, items, onCreateItem, onSearchChange, onValueChange, searchValue, placeholder, selectProps, size = "md", state, triggerProps, value, ...fieldProps } = props;
30
30
  const collection = createListCollection({
31
31
  items,
32
- groupBy: (item) => item.group || ""
32
+ groupBy: (item) => item.group || "",
33
+ isItemDisabled: (item) => !!item.disabled
33
34
  });
35
+ const isInvalid = state === "error" || !!fieldProps.errorText;
34
36
  return /* @__PURE__ */ jsx(BitkitField, {
35
37
  ref,
36
38
  state,
@@ -40,7 +42,11 @@ var BitkitSelect = forwardRef((props, ref) => {
40
42
  size,
41
43
  ...selectProps,
42
44
  defaultValue: defaultValue ? [defaultValue] : void 0,
45
+ disabled: state === "disabled",
46
+ invalid: isInvalid,
43
47
  onValueChange: (newVal) => onValueChange?.(newVal.value[0]),
48
+ readOnly: state === "readOnly",
49
+ scrollToIndexFn: ({ getElement }) => getElement()?.scrollIntoView({ block: "nearest" }),
44
50
  value: value ? [value] : void 0,
45
51
  children: [
46
52
  /* @__PURE__ */ jsx(Select.HiddenSelect, {}),
@@ -67,15 +73,15 @@ var BitkitSelect = forwardRef((props, ref) => {
67
73
  }),
68
74
  /* @__PURE__ */ jsx(Portal, { children: /* @__PURE__ */ jsx(Select.Positioner, { children: /* @__PURE__ */ jsx(BitkitSelectMenu, {
69
75
  collection,
70
- createItemHref,
71
76
  createItemLabel,
72
- createItemProps,
73
- contentProps,
77
+ emptyHelperText,
78
+ emptyLabel,
74
79
  isLoading,
75
80
  onCreateItem,
76
81
  ...hasSearch ? {
77
82
  hasSearch: true,
78
- onSearchChange
83
+ onSearchChange,
84
+ searchValue
79
85
  } : { hasSearch: false },
80
86
  size
81
87
  }) }) })
@@ -1 +1 @@
1
- {"version":3,"file":"BitkitSelect.js","names":[],"sources":["../../../lib/components/BitkitSelect/BitkitSelect.tsx"],"sourcesContent":["import { Box } from '@chakra-ui/react/box';\nimport { createListCollection } from '@chakra-ui/react/collection';\nimport { Portal } from '@chakra-ui/react/portal';\nimport { Select, type SelectRootProps, type SelectTriggerProps, useSelectContext } from '@chakra-ui/react/select';\nimport { forwardRef } from 'react';\n\nimport { IconErrorCircleFilled, IconWarningYellow } from '../../icons';\nimport AssetSelectChevron from '../../utilities/AssetSelectChevron.tsx';\nimport BitkitField, { type BitkitFieldProps } from '../BitkitField/BitkitField.tsx';\nimport BitkitSelectMenu, {\n type BitkitSelectContentProps,\n type BitkitSelectMenuCreateItemProps,\n type BitkitSelectMenuItemProps,\n type BitkitSelectMenuSearchProps,\n} from '../BitkitSelectMenu/BitkitSelectMenu.tsx';\n\nexport type BitkitSelectTriggerProps = SelectTriggerProps;\n\nexport type BitkitSelectProps = Omit<BitkitFieldProps, 'children' | 'state'> & {\n contentProps?: BitkitSelectContentProps;\n defaultValue?: string;\n isLoading?: boolean;\n items: Array<BitkitSelectMenuItemProps>;\n onValueChange?: (newVal: string) => void;\n placeholder?: string;\n selectProps?: Omit<SelectRootProps, 'collection' | 'defaultValue' | 'onValueChange' | 'value'>;\n size?: 'md' | 'lg';\n state?: 'disabled' | 'error' | 'readOnly' | 'warning';\n triggerProps?: BitkitSelectTriggerProps;\n value?: string;\n} & BitkitSelectMenuCreateItemProps &\n BitkitSelectMenuSearchProps;\n\ntype SelectValueProps = {\n placeholder?: string;\n size: BitkitSelectProps['size'];\n state?: BitkitSelectProps['state'];\n};\n\nconst SelectValue = ({ placeholder, state, size }: SelectValueProps) => {\n const select = useSelectContext();\n const items = select.selectedItems as Array<BitkitSelectMenuItemProps>;\n\n const Icon = items[0]?.icon;\n const label = items[0]?.label;\n\n const iconSize = size === 'md' ? '16' : '24';\n\n return items[0] ? (\n <Select.ValueText placeholder={placeholder || state === 'readOnly' ? '(not selected)' : 'Select an option'}>\n <Box display=\"flex\" alignItems=\"center\" gap=\"8\">\n {Icon && <Icon size={iconSize} />}\n {label}\n </Box>\n </Select.ValueText>\n ) : (\n <Select.ValueText placeholder={placeholder ?? (state === 'readOnly' ? '(not selected)' : 'Select an option')} />\n );\n};\n\nconst BitkitSelect = forwardRef<HTMLDivElement, BitkitSelectProps>((props: BitkitSelectProps, ref) => {\n const {\n contentProps,\n createItemHref,\n createItemLabel,\n createItemProps,\n defaultValue,\n hasSearch,\n isLoading,\n items,\n onCreateItem,\n onSearchChange,\n onValueChange,\n placeholder,\n selectProps,\n size = 'md',\n state,\n triggerProps,\n value,\n ...fieldProps\n } = props;\n\n const collection = createListCollection({\n items,\n groupBy: (item) => item.group || '',\n });\n\n return (\n <BitkitField ref={ref} state={state} {...fieldProps}>\n <Select.Root\n collection={collection}\n size={size}\n {...selectProps}\n defaultValue={defaultValue ? [defaultValue] : undefined}\n onValueChange={(newVal) => onValueChange?.(newVal.value[0])}\n value={value ? [value] : undefined}\n >\n <Select.HiddenSelect />\n <Select.Control className=\"group\">\n <Select.Trigger {...triggerProps}>\n <SelectValue placeholder={placeholder} size={size} state={state} />\n </Select.Trigger>\n <Select.IndicatorGroup>\n {state === 'error' && (\n <Select.Indicator>\n <IconErrorCircleFilled size={size === 'lg' ? '24' : '16'} color=\"icon/negative\" />\n </Select.Indicator>\n )}\n {state === 'warning' && (\n <Select.Indicator>\n <IconWarningYellow size={size === 'lg' ? '24' : '16'} />\n </Select.Indicator>\n )}\n <Select.Indicator asChild>\n <AssetSelectChevron />\n </Select.Indicator>\n </Select.IndicatorGroup>\n </Select.Control>\n <Portal>\n <Select.Positioner>\n <BitkitSelectMenu\n collection={collection}\n createItemHref={createItemHref}\n createItemLabel={createItemLabel}\n createItemProps={createItemProps}\n contentProps={contentProps}\n isLoading={isLoading}\n onCreateItem={onCreateItem}\n {...(hasSearch ? { hasSearch: true, onSearchChange } : { hasSearch: false as const })}\n size={size}\n />\n </Select.Positioner>\n </Portal>\n </Select.Root>\n </BitkitField>\n );\n});\n\nBitkitSelect.displayName = 'BitkitSelect';\n\nexport default BitkitSelect;\n"],"mappings":";;;;;;;;;;;;AAuCA,IAAM,eAAe,EAAE,aAAa,OAAO,WAA6B;CAEtE,MAAM,QADS,kBAAkB,CACZ;CAErB,MAAM,OAAO,MAAM,IAAI;CACvB,MAAM,QAAQ,MAAM,IAAI;CAExB,MAAM,WAAW,SAAS,OAAO,OAAO;AAExC,QAAO,MAAM,KACX,oBAAC,OAAO,WAAR;EAAkB,aAAa,eAAe,UAAU,aAAa,mBAAmB;YACtF,qBAAC,KAAD;GAAK,SAAQ;GAAO,YAAW;GAAS,KAAI;aAA5C,CACG,QAAQ,oBAAC,MAAD,EAAM,MAAM,UAAY,CAAA,EAChC,MACG;;EACW,CAAA,GAEnB,oBAAC,OAAO,WAAR,EAAkB,aAAa,gBAAgB,UAAU,aAAa,mBAAmB,qBAAuB,CAAA;;AAIpH,IAAM,eAAe,YAA+C,OAA0B,QAAQ;CACpG,MAAM,EACJ,cACA,gBACA,iBACA,iBACA,cACA,WACA,WACA,OACA,cACA,gBACA,eACA,aACA,aACA,OAAO,MACP,OACA,cACA,OACA,GAAG,eACD;CAEJ,MAAM,aAAa,qBAAqB;EACtC;EACA,UAAU,SAAS,KAAK,SAAS;EAClC,CAAC;AAEF,QACE,oBAAC,aAAD;EAAkB;EAAY;EAAO,GAAI;YACvC,qBAAC,OAAO,MAAR;GACc;GACN;GACN,GAAI;GACJ,cAAc,eAAe,CAAC,aAAa,GAAG,KAAA;GAC9C,gBAAgB,WAAW,gBAAgB,OAAO,MAAM,GAAG;GAC3D,OAAO,QAAQ,CAAC,MAAM,GAAG,KAAA;aAN3B;IAQE,oBAAC,OAAO,cAAR,EAAuB,CAAA;IACvB,qBAAC,OAAO,SAAR;KAAgB,WAAU;eAA1B,CACE,oBAAC,OAAO,SAAR;MAAgB,GAAI;gBAClB,oBAAC,aAAD;OAA0B;OAAmB;OAAa;OAAS,CAAA;MACpD,CAAA,EACjB,qBAAC,OAAO,gBAAR,EAAA,UAAA;MACG,UAAU,WACT,oBAAC,OAAO,WAAR,EAAA,UACE,oBAAC,uBAAD;OAAuB,MAAM,SAAS,OAAO,OAAO;OAAM,OAAM;OAAkB,CAAA,EACjE,CAAA;MAEpB,UAAU,aACT,oBAAC,OAAO,WAAR,EAAA,UACE,oBAAC,mBAAD,EAAmB,MAAM,SAAS,OAAO,OAAO,MAAQ,CAAA,EACvC,CAAA;MAErB,oBAAC,OAAO,WAAR;OAAkB,SAAA;iBAChB,oBAAC,oBAAD,EAAsB,CAAA;OACL,CAAA;MACG,EAAA,CAAA,CACT;;IACjB,oBAAC,QAAD,EAAA,UACE,oBAAC,OAAO,YAAR,EAAA,UACE,oBAAC,kBAAD;KACc;KACI;KACC;KACA;KACH;KACH;KACG;KACd,GAAK,YAAY;MAAE,WAAW;MAAM;MAAgB,GAAG,EAAE,WAAW,OAAgB;KAC9E;KACN,CAAA,EACgB,CAAA,EACb,CAAA;IACG;;EACF,CAAA;EAEhB;AAEF,aAAa,cAAc"}
1
+ {"version":3,"file":"BitkitSelect.js","names":[],"sources":["../../../lib/components/BitkitSelect/BitkitSelect.tsx"],"sourcesContent":["import { Box } from '@chakra-ui/react/box';\nimport { createListCollection } from '@chakra-ui/react/collection';\nimport { Portal } from '@chakra-ui/react/portal';\nimport { Select, type SelectRootProps, type SelectTriggerProps, useSelectContext } from '@chakra-ui/react/select';\nimport { forwardRef } from 'react';\n\nimport { IconErrorCircleFilled, IconWarningYellow } from '../../icons';\nimport AssetSelectChevron from '../../utilities/AssetSelectChevron.tsx';\nimport BitkitField, { type BitkitFieldProps } from '../BitkitField/BitkitField.tsx';\nimport BitkitSelectMenu, {\n type BitkitSelectMenuCreateItemProps,\n type BitkitSelectMenuEmptyStateProps,\n type BitkitSelectMenuItemProps,\n type BitkitSelectMenuSearchProps,\n} from '../BitkitSelectMenu/BitkitSelectMenu.tsx';\n\nexport type BitkitSelectTriggerProps = SelectTriggerProps;\n\nexport type BitkitSelectProps = Omit<BitkitFieldProps, 'children' | 'state'> & {\n defaultValue?: string;\n isLoading?: boolean;\n items: Array<BitkitSelectMenuItemProps>;\n onValueChange?: (newVal: string) => void;\n placeholder?: string;\n selectProps?: Omit<SelectRootProps, 'collection' | 'defaultValue' | 'onValueChange' | 'value'>;\n size?: 'md' | 'lg';\n state?: 'disabled' | 'error' | 'readOnly' | 'warning';\n triggerProps?: BitkitSelectTriggerProps;\n value?: string;\n} & BitkitSelectMenuCreateItemProps &\n BitkitSelectMenuSearchProps &\n BitkitSelectMenuEmptyStateProps;\n\ntype SelectValueProps = {\n placeholder?: string;\n size: BitkitSelectProps['size'];\n state?: BitkitSelectProps['state'];\n};\n\nconst SelectValue = ({ placeholder, state, size }: SelectValueProps) => {\n const select = useSelectContext();\n const items = select.selectedItems as Array<BitkitSelectMenuItemProps>;\n\n const Icon = items[0]?.icon;\n const label = items[0]?.label;\n\n const iconSize = size === 'md' ? '16' : '24';\n\n return items[0] ? (\n <Select.ValueText placeholder={placeholder || state === 'readOnly' ? '(not selected)' : 'Select an option'}>\n <Box display=\"flex\" alignItems=\"center\" gap=\"8\">\n {Icon && <Icon size={iconSize} />}\n {label}\n </Box>\n </Select.ValueText>\n ) : (\n <Select.ValueText placeholder={placeholder ?? (state === 'readOnly' ? '(not selected)' : 'Select an option')} />\n );\n};\n\nconst BitkitSelect = forwardRef<HTMLDivElement, BitkitSelectProps>((props: BitkitSelectProps, ref) => {\n const {\n createItemLabel,\n defaultValue,\n emptyHelperText,\n emptyLabel,\n hasSearch,\n isLoading,\n items,\n onCreateItem,\n onSearchChange,\n onValueChange,\n searchValue,\n placeholder,\n selectProps,\n size = 'md',\n state,\n triggerProps,\n value,\n ...fieldProps\n } = props;\n\n const collection = createListCollection({\n items,\n groupBy: (item) => item.group || '',\n isItemDisabled: (item) => !!item.disabled,\n });\n\n const isInvalid = state === 'error' || !!fieldProps.errorText;\n\n return (\n <BitkitField ref={ref} state={state} {...fieldProps}>\n <Select.Root\n collection={collection}\n size={size}\n {...selectProps}\n defaultValue={defaultValue ? [defaultValue] : undefined}\n disabled={state === 'disabled'}\n invalid={isInvalid}\n onValueChange={(newVal) => onValueChange?.(newVal.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 value={value ? [value] : undefined}\n >\n <Select.HiddenSelect />\n <Select.Control className=\"group\">\n <Select.Trigger {...triggerProps}>\n <SelectValue placeholder={placeholder} size={size} state={state} />\n </Select.Trigger>\n <Select.IndicatorGroup>\n {state === 'error' && (\n <Select.Indicator>\n <IconErrorCircleFilled size={size === 'lg' ? '24' : '16'} color=\"icon/negative\" />\n </Select.Indicator>\n )}\n {state === 'warning' && (\n <Select.Indicator>\n <IconWarningYellow size={size === 'lg' ? '24' : '16'} />\n </Select.Indicator>\n )}\n <Select.Indicator asChild>\n <AssetSelectChevron />\n </Select.Indicator>\n </Select.IndicatorGroup>\n </Select.Control>\n <Portal>\n <Select.Positioner>\n <BitkitSelectMenu\n collection={collection}\n createItemLabel={createItemLabel}\n emptyHelperText={emptyHelperText}\n emptyLabel={emptyLabel}\n isLoading={isLoading}\n onCreateItem={onCreateItem}\n {...(hasSearch\n ? { hasSearch: true as const, onSearchChange, searchValue }\n : { hasSearch: false as const })}\n size={size}\n />\n </Select.Positioner>\n </Portal>\n </Select.Root>\n </BitkitField>\n );\n});\n\nBitkitSelect.displayName = 'BitkitSelect';\n\nexport default BitkitSelect;\n"],"mappings":";;;;;;;;;;;;AAuCA,IAAM,eAAe,EAAE,aAAa,OAAO,WAA6B;CAEtE,MAAM,QADS,kBAAkB,CACZ;CAErB,MAAM,OAAO,MAAM,IAAI;CACvB,MAAM,QAAQ,MAAM,IAAI;CAExB,MAAM,WAAW,SAAS,OAAO,OAAO;AAExC,QAAO,MAAM,KACX,oBAAC,OAAO,WAAR;EAAkB,aAAa,eAAe,UAAU,aAAa,mBAAmB;YACtF,qBAAC,KAAD;GAAK,SAAQ;GAAO,YAAW;GAAS,KAAI;aAA5C,CACG,QAAQ,oBAAC,MAAD,EAAM,MAAM,UAAY,CAAA,EAChC,MACG;;EACW,CAAA,GAEnB,oBAAC,OAAO,WAAR,EAAkB,aAAa,gBAAgB,UAAU,aAAa,mBAAmB,qBAAuB,CAAA;;AAIpH,IAAM,eAAe,YAA+C,OAA0B,QAAQ;CACpG,MAAM,EACJ,iBACA,cACA,iBACA,YACA,WACA,WACA,OACA,cACA,gBACA,eACA,aACA,aACA,aACA,OAAO,MACP,OACA,cACA,OACA,GAAG,eACD;CAEJ,MAAM,aAAa,qBAAqB;EACtC;EACA,UAAU,SAAS,KAAK,SAAS;EACjC,iBAAiB,SAAS,CAAC,CAAC,KAAK;EAClC,CAAC;CAEF,MAAM,YAAY,UAAU,WAAW,CAAC,CAAC,WAAW;AAEpD,QACE,oBAAC,aAAD;EAAkB;EAAY;EAAO,GAAI;YACvC,qBAAC,OAAO,MAAR;GACc;GACN;GACN,GAAI;GACJ,cAAc,eAAe,CAAC,aAAa,GAAG,KAAA;GAC9C,UAAU,UAAU;GACpB,SAAS;GACT,gBAAgB,WAAW,gBAAgB,OAAO,MAAM,GAAG;GAC3D,UAAU,UAAU;GAGpB,kBAAkB,EAAE,iBAAiB,YAAY,EAAE,eAAe,EAAE,OAAO,WAAW,CAAC;GACvF,OAAO,QAAQ,CAAC,MAAM,GAAG,KAAA;aAZ3B;IAcE,oBAAC,OAAO,cAAR,EAAuB,CAAA;IACvB,qBAAC,OAAO,SAAR;KAAgB,WAAU;eAA1B,CACE,oBAAC,OAAO,SAAR;MAAgB,GAAI;gBAClB,oBAAC,aAAD;OAA0B;OAAmB;OAAa;OAAS,CAAA;MACpD,CAAA,EACjB,qBAAC,OAAO,gBAAR,EAAA,UAAA;MACG,UAAU,WACT,oBAAC,OAAO,WAAR,EAAA,UACE,oBAAC,uBAAD;OAAuB,MAAM,SAAS,OAAO,OAAO;OAAM,OAAM;OAAkB,CAAA,EACjE,CAAA;MAEpB,UAAU,aACT,oBAAC,OAAO,WAAR,EAAA,UACE,oBAAC,mBAAD,EAAmB,MAAM,SAAS,OAAO,OAAO,MAAQ,CAAA,EACvC,CAAA;MAErB,oBAAC,OAAO,WAAR;OAAkB,SAAA;iBAChB,oBAAC,oBAAD,EAAsB,CAAA;OACL,CAAA;MACG,EAAA,CAAA,CACT;;IACjB,oBAAC,QAAD,EAAA,UACE,oBAAC,OAAO,YAAR,EAAA,UACE,oBAAC,kBAAD;KACc;KACK;KACA;KACL;KACD;KACG;KACd,GAAK,YACD;MAAE,WAAW;MAAe;MAAgB;MAAa,GACzD,EAAE,WAAW,OAAgB;KAC3B;KACN,CAAA,EACgB,CAAA,EACb,CAAA;IACG;;EACF,CAAA;EAEhB;AAEF,aAAa,cAAc"}
@@ -1,35 +1,46 @@
1
1
  import { ListCollection } from '@chakra-ui/react/collection';
2
2
  import { SelectContentProps } from '@chakra-ui/react/select';
3
- import { AnchorHTMLAttributes } from 'react';
4
3
  import { BitkitIconComponent } from '../../icons';
5
4
  export type BitkitSelectMenuCreateItemProps = {
6
- createItemHref?: string;
7
5
  createItemLabel?: string;
8
- createItemProps?: AnchorHTMLAttributes<HTMLAnchorElement>;
9
6
  onCreateItem?: () => void;
10
7
  };
11
8
  export type BitkitSelectMenuSearchProps = {
12
9
  hasSearch?: boolean;
13
10
  } & ({
14
11
  hasSearch: true;
15
- onSearchChange?: (searchText: string) => void;
12
+ onSearchChange: (searchText: string) => void;
13
+ searchValue: string;
16
14
  } | {
17
15
  hasSearch?: false;
18
16
  onSearchChange?: never;
17
+ searchValue?: never;
19
18
  });
20
19
  export type BitkitSelectMenuItemProps = {
21
20
  value: string;
22
21
  label: string;
23
22
  group?: string;
24
23
  icon?: BitkitIconComponent;
24
+ avatar?: string;
25
+ helperText?: string;
26
+ disabled?: boolean;
27
+ loading?: boolean;
28
+ };
29
+ export type BitkitSelectMenuEmptyStateProps = {
30
+ emptyLabel?: string;
31
+ emptyHelperText?: string;
25
32
  };
26
33
  export type BitkitSelectMenuProps = {
27
34
  collection: ListCollection<BitkitSelectMenuItemProps>;
28
- contentProps?: BitkitSelectContentProps;
35
+ /** Forwarded to the underlying Select/Combobox.Content. Kept for internal callers
36
+ * (e.g. BitkitCalendar's in-grid selects that need to tweak max-height / width). The
37
+ * three public components (BitkitSelect, BitkitCombobox, BitkitMultiselect) intentionally
38
+ * do not expose this escape hatch. */
39
+ contentProps?: SelectContentProps;
29
40
  isLoading?: boolean;
41
+ multiple?: boolean;
30
42
  size?: 'md' | 'lg';
31
43
  variant?: 'select' | 'combobox';
32
- } & BitkitSelectMenuCreateItemProps & BitkitSelectMenuSearchProps;
33
- export type BitkitSelectContentProps = SelectContentProps;
44
+ } & BitkitSelectMenuCreateItemProps & BitkitSelectMenuSearchProps & BitkitSelectMenuEmptyStateProps;
34
45
  declare const BitkitSelectMenu: import('react').ForwardRefExoticComponent<BitkitSelectMenuProps & import('react').RefAttributes<HTMLDivElement>>;
35
46
  export default BitkitSelectMenu;