@bitrise/bitkit-v2 0.3.240 → 0.3.242
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/AGENTS.md +1 -1
- package/dist/components/BitkitCombobox/BitkitCombobox.d.ts +2 -0
- package/dist/components/BitkitCombobox/BitkitCombobox.js +18 -13
- package/dist/components/BitkitCombobox/BitkitCombobox.js.map +1 -1
- package/dist/components/BitkitDialog/BitkitDialogContent.js +34 -29
- package/dist/components/BitkitDialog/BitkitDialogContent.js.map +1 -1
- package/dist/components/BitkitMultiselect/BitkitMultiselect.d.ts +2 -0
- package/dist/components/BitkitMultiselect/BitkitMultiselect.js +17 -12
- package/dist/components/BitkitMultiselect/BitkitMultiselect.js.map +1 -1
- package/dist/components/BitkitSelect/BitkitSelect.d.ts +2 -0
- package/dist/components/BitkitSelect/BitkitSelect.js +17 -12
- package/dist/components/BitkitSelect/BitkitSelect.js.map +1 -1
- package/dist/utilities/BitkitPortalContext.d.ts +7 -0
- package/dist/utilities/BitkitPortalContext.js +7 -0
- package/dist/utilities/BitkitPortalContext.js.map +1 -0
- package/package.json +1 -1
package/AGENTS.md
CHANGED
|
@@ -117,7 +117,7 @@ Bitkit components use consistent prop names across the library:
|
|
|
117
117
|
|
|
118
118
|
- **Only use tokens that exist** — never guess token names. Verify via the Storybook MCP `Docs/Colors - *`, `Docs/Shadows`, `Docs/Text Styles`, etc. pages.
|
|
119
119
|
- **Slash-separated token paths** — `background/primary`, not `background.primary`.
|
|
120
|
-
- **Always semantic colors** — use semantic tokens (`
|
|
120
|
+
- **Always semantic colors** — use semantic tokens (`background/primary`, `text/body`, `border/minimal`, `icon/secondary`). Never palette colors (`purple.50`), system colors (`sys.fg.base`), raw codes (`#fff`), or color names (`white`, `grey`).
|
|
121
121
|
- **Always use `textStyle`** — never set `fontFamily` or `fontSize` on `<Text>`. Use `textStyle="body/md/regular"`, `textStyle="code/md"`, etc.
|
|
122
122
|
- **Sizes as strings** — `width="32"`, not `width={32}`. Tokens are strings.
|
|
123
123
|
- **Use existing size tokens** — closest existing token (1, 2, 4, 6, 8, 12, 16, 20, 24, 32, 40, 48, 64, 96, 128) representing pixel values (1=1px, 32=32px). Avoid arbitrary px (`width="100px"`).
|
|
@@ -6,6 +6,7 @@ export type BitkitComboboxProps = Omit<BitkitFieldProps, 'children' | 'state'> &
|
|
|
6
6
|
children?: BitkitSelectMenuActionChild;
|
|
7
7
|
comboboxProps?: Omit<ComboboxRootProps, 'collection' | 'defaultValue' | 'onValueChange' | 'value'>;
|
|
8
8
|
defaultValue?: string;
|
|
9
|
+
disablePortal?: boolean;
|
|
9
10
|
isLoading?: boolean;
|
|
10
11
|
items: Array<BitkitSelectMenuItemProps>;
|
|
11
12
|
onValueChange?: (newVal: string | undefined) => void;
|
|
@@ -18,6 +19,7 @@ declare const _default: import('react').ForwardRefExoticComponent<Omit<BitkitFie
|
|
|
18
19
|
children?: BitkitSelectMenuActionChild;
|
|
19
20
|
comboboxProps?: Omit<ComboboxRootProps, "collection" | "defaultValue" | "onValueChange" | "value">;
|
|
20
21
|
defaultValue?: string;
|
|
22
|
+
disablePortal?: boolean;
|
|
21
23
|
isLoading?: boolean;
|
|
22
24
|
items: Array<BitkitSelectMenuItemProps>;
|
|
23
25
|
onValueChange?: (newVal: string | undefined) => void;
|
|
@@ -5,8 +5,9 @@ import BitkitCloseButton from "../BitkitCloseButton/BitkitCloseButton.js";
|
|
|
5
5
|
import { withSubComponents } from "../../utilities/withSubComponents.js";
|
|
6
6
|
import BitkitSelectMenuAction from "../BitkitSelectMenu/BitkitSelectMenuAction.js";
|
|
7
7
|
import BitkitSelectMenu from "../BitkitSelectMenu/BitkitSelectMenu.js";
|
|
8
|
+
import BitkitPortalContext from "../../utilities/BitkitPortalContext.js";
|
|
8
9
|
import BitkitField from "../BitkitField/BitkitField.js";
|
|
9
|
-
import { forwardRef } from "react";
|
|
10
|
+
import { forwardRef, useContext } from "react";
|
|
10
11
|
import { jsx, jsxs } from "react/jsx-runtime";
|
|
11
12
|
import { Portal } from "@chakra-ui/react/portal";
|
|
12
13
|
import { useListCollection } from "@chakra-ui/react/hooks";
|
|
@@ -14,7 +15,8 @@ import { Combobox } from "@chakra-ui/react/combobox";
|
|
|
14
15
|
import { useFilter } from "@chakra-ui/react/locale";
|
|
15
16
|
//#region lib/components/BitkitCombobox/BitkitCombobox.tsx
|
|
16
17
|
var BitkitCombobox = forwardRef((props, ref) => {
|
|
17
|
-
const { children, comboboxProps, defaultValue, emptyHelperText, emptyLabel, isLoading, items, onSearchChange, onValueChange, placeholder = "Enter a value or select", searchValue, size, state, value, ...fieldProps } = props;
|
|
18
|
+
const { children, comboboxProps, defaultValue, disablePortal, emptyHelperText, emptyLabel, isLoading, items, onSearchChange, onValueChange, placeholder = "Enter a value or select", searchValue, size, state, value, ...fieldProps } = props;
|
|
19
|
+
const { disablePortal: disablePortalFromContext } = useContext(BitkitPortalContext);
|
|
18
20
|
const { contains } = useFilter({ sensitivity: "base" });
|
|
19
21
|
const { collection, filter } = useListCollection({
|
|
20
22
|
initialItems: items,
|
|
@@ -62,17 +64,20 @@ var BitkitCombobox = forwardRef((props, ref) => {
|
|
|
62
64
|
children: /* @__PURE__ */ jsx(AssetSelectChevron, {})
|
|
63
65
|
})
|
|
64
66
|
] })]
|
|
65
|
-
}), /* @__PURE__ */ jsx(Portal, {
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
67
|
+
}), /* @__PURE__ */ jsx(Portal, {
|
|
68
|
+
disabled: disablePortal || disablePortalFromContext,
|
|
69
|
+
children: /* @__PURE__ */ jsx(Combobox.Positioner, { children: /* @__PURE__ */ jsx(BitkitSelectMenu, {
|
|
70
|
+
collection,
|
|
71
|
+
emptyHelperText,
|
|
72
|
+
emptyLabel,
|
|
73
|
+
isLoading,
|
|
74
|
+
onSearchChange,
|
|
75
|
+
searchValue,
|
|
76
|
+
size,
|
|
77
|
+
variant: "combobox",
|
|
78
|
+
children
|
|
79
|
+
}) })
|
|
80
|
+
})]
|
|
76
81
|
})
|
|
77
82
|
});
|
|
78
83
|
});
|
|
@@ -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 { forwardRef } from 'react';\n\nimport IconErrorCircleFilled from '../../icons/IconErrorCircleFilled';\nimport IconWarningYellow from '../../icons/IconWarningYellow';\nimport AssetSelectChevron from '../../utilities/AssetSelectChevron';\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 BitkitSelectMenuSearchProps,\n} from '../BitkitSelectMenu/BitkitSelectMenu';\nimport BitkitSelectMenuAction, { type BitkitSelectMenuActionChild } from '../BitkitSelectMenu/BitkitSelectMenuAction';\n\nexport type BitkitComboboxProps = Omit<BitkitFieldProps, 'children' | 'state'> & {\n children?: BitkitSelectMenuActionChild;\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} & BitkitSelectMenuSearchProps &\n BitkitSelectMenuEmptyStateProps;\n\nconst BitkitCombobox = forwardRef<HTMLDivElement, BitkitComboboxProps>((props: BitkitComboboxProps, ref) => {\n const {\n children,\n comboboxProps,\n defaultValue,\n emptyHelperText,\n emptyLabel,\n isLoading,\n items,\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 hasStatusIcon={!!statusIcon}\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 emptyHelperText={emptyHelperText}\n emptyLabel={emptyLabel}\n isLoading={isLoading}\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":"
|
|
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, useContext } 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 BitkitSelectMenuSearchProps,\n} from '../BitkitSelectMenu/BitkitSelectMenu';\nimport BitkitSelectMenuAction, { type BitkitSelectMenuActionChild } from '../BitkitSelectMenu/BitkitSelectMenuAction';\n\nexport type BitkitComboboxProps = Omit<BitkitFieldProps, 'children' | '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 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 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 { disablePortal: disablePortalFromContext } = useContext(BitkitPortalContext);\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 hasStatusIcon={!!statusIcon}\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 disabled={disablePortal || disablePortalFromContext}>\n <Combobox.Positioner>\n <BitkitSelectMenu\n collection={collection}\n emptyHelperText={emptyHelperText}\n emptyLabel={emptyLabel}\n isLoading={isLoading}\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":";;;;;;;;;;;;;;;;AAmCA,IAAM,iBAAiB,YAAiD,OAA4B,QAAQ;CAC1G,MAAM,EACJ,UACA,eACA,cACA,eACA,iBACA,YACA,WACA,OACA,gBACA,eACA,cAAc,2BACd,aACA,MACA,OACA,OACA,GAAG,eACD;CAEJ,MAAM,EAAE,eAAe,6BAA6B,WAAW,mBAAmB;CAElF,MAAM,EAAE,aAAa,UAAU,EAAE,aAAa,OAAO,CAAC;CACtD,MAAM,EAAE,YAAY,WAAW,kBAA6C;EAC1E,cAAc;EACd,SAAS,WAAW,YAAY,SAAS,SAAS,KAAK,OAAO,UAAU;EACxE,iBAAiB,SAAS,CAAC,CAAC,KAAK;CACnC,CAAC;CAED,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;YACvC,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,OAAO,EAAE,UAAU;GACrB;GACA,gBAAgB,YAAY,gBAAgB,QAAQ,MAAM,EAAE;GAC5D,UAAU,UAAU;GAGpB,kBAAkB,EAAE,iBAAiB,WAAW,GAAG,eAAe,EAAE,OAAO,UAAU,CAAC;GAChF;GACN,OAAO,QAAQ,CAAC,KAAK,IAAI,KAAA;aAhB3B,CAkBE,qBAAC,SAAS,SAAV;IAAkB,WAAU;cAA5B,CACE,oBAAC,SAAS,OAAV,EAA6B,YAAc,CAAA,GAC3C,qBAAC,SAAS,gBAAV,EAAA,UAAA;KACE,oBAAC,SAAS,cAAV;MAAuB,SAAA;gBACrB,oBAAC,mBAAD,EAAmB,MAAK,KAAM,CAAA;KACT,CAAA;KACtB;KACD,oBAAC,SAAS,SAAV;MAAkB,SAAA;gBAChB,oBAAC,oBAAD,CAAqB,CAAA;KACL,CAAA;IACK,EAAA,CAAA,CACT;OAClB,oBAAC,QAAD;IAAQ,UAAU,iBAAiB;cACjC,oBAAC,SAAS,YAAV,EAAA,UACE,oBAAC,kBAAD;KACc;KACK;KACL;KACD;KACK;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,4 +1,5 @@
|
|
|
1
1
|
import BitkitCloseButton from "../BitkitCloseButton/BitkitCloseButton.js";
|
|
2
|
+
import BitkitPortalContext from "../../utilities/BitkitPortalContext.js";
|
|
2
3
|
import { BitkitDialogStepProvider } from "./BitkitDialogStepContext.js";
|
|
3
4
|
import { DialogBodyContext } from "./BitkitDialogBody.js";
|
|
4
5
|
import { Box } from "@chakra-ui/react/box";
|
|
@@ -6,39 +7,43 @@ import { chakra } from "@chakra-ui/react/styled-system";
|
|
|
6
7
|
import { jsx, jsxs } from "react/jsx-runtime";
|
|
7
8
|
import { Dialog, useDialogStyles } from "@chakra-ui/react/dialog";
|
|
8
9
|
//#region lib/components/BitkitDialog/BitkitDialogContent.tsx
|
|
10
|
+
var PORTAL_DISABLED = { disablePortal: true };
|
|
9
11
|
var DialogContentInner = ({ children, closable = true, headerLabel, scrollBehavior: scrollBehaviorProp = "outside", showScrollGradient = true, step = 0, stepHeader, title, variant }) => {
|
|
10
12
|
const scrollBehavior = variant === "overflowContent" ? "inside" : scrollBehaviorProp;
|
|
11
13
|
const styles = useDialogStyles();
|
|
12
|
-
return /* @__PURE__ */ jsx(
|
|
13
|
-
value:
|
|
14
|
-
children: /* @__PURE__ */
|
|
15
|
-
value: {
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
children: headerLabel
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
14
|
+
return /* @__PURE__ */ jsx(BitkitPortalContext.Provider, {
|
|
15
|
+
value: PORTAL_DISABLED,
|
|
16
|
+
children: /* @__PURE__ */ jsx(BitkitDialogStepProvider, {
|
|
17
|
+
value: { step },
|
|
18
|
+
children: /* @__PURE__ */ jsxs(DialogBodyContext.Provider, {
|
|
19
|
+
value: {
|
|
20
|
+
scrollBehavior,
|
|
21
|
+
showScrollGradient
|
|
22
|
+
},
|
|
23
|
+
children: [/* @__PURE__ */ jsxs(Dialog.Header, { children: [
|
|
24
|
+
/* @__PURE__ */ jsxs(Box, {
|
|
25
|
+
display: "flex",
|
|
26
|
+
flexDirection: "column",
|
|
27
|
+
gap: "4",
|
|
28
|
+
children: [headerLabel && /* @__PURE__ */ jsx(chakra.p, {
|
|
29
|
+
css: styles.label,
|
|
30
|
+
children: headerLabel
|
|
31
|
+
}), /* @__PURE__ */ jsx(Dialog.Title, { children: title })]
|
|
32
|
+
}),
|
|
33
|
+
!!stepHeader && /* @__PURE__ */ jsx(Box, {
|
|
34
|
+
css: styles.stepHeader,
|
|
35
|
+
children: stepHeader
|
|
36
|
+
}),
|
|
37
|
+
/* @__PURE__ */ jsx(Dialog.CloseTrigger, {
|
|
38
|
+
asChild: true,
|
|
39
|
+
children: /* @__PURE__ */ jsx(BitkitCloseButton, {
|
|
40
|
+
disabled: !closable,
|
|
41
|
+
size: variant === "overflowContent" ? "xs" : "md",
|
|
42
|
+
type: "button"
|
|
43
|
+
})
|
|
39
44
|
})
|
|
40
|
-
})
|
|
41
|
-
|
|
45
|
+
] }), children]
|
|
46
|
+
})
|
|
42
47
|
})
|
|
43
48
|
});
|
|
44
49
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"BitkitDialogContent.js","names":[],"sources":["../../../lib/components/BitkitDialog/BitkitDialogContent.tsx"],"sourcesContent":["import { Box } from '@chakra-ui/react/box';\nimport { Dialog, useDialogStyles } from '@chakra-ui/react/dialog';\nimport { chakra } from '@chakra-ui/react/styled-system';\nimport { type ReactNode } from 'react';\n\nimport BitkitCloseButton from '../BitkitCloseButton/BitkitCloseButton';\nimport { DialogBodyContext } from './BitkitDialogBody';\nimport { BitkitDialogStepProvider } from './BitkitDialogStepContext';\n\ninterface DialogContentInnerProps {\n children?: ReactNode;\n closable?: boolean;\n headerLabel?: string;\n scrollBehavior?: 'inside' | 'outside';\n showScrollGradient?: boolean;\n step?: number;\n stepHeader?: ReactNode;\n title: ReactNode;\n variant?: 'overflowContent';\n}\n\nexport const DialogContentInner = ({\n children,\n closable = true,\n headerLabel,\n scrollBehavior: scrollBehaviorProp = 'outside',\n showScrollGradient = true,\n step = 0,\n stepHeader,\n title,\n variant,\n}: DialogContentInnerProps) => {\n const scrollBehavior = variant === 'overflowContent' ? 'inside' : scrollBehaviorProp;\n const styles = useDialogStyles();\n\n return (\n <BitkitDialogStepProvider value={{ step }}>\n
|
|
1
|
+
{"version":3,"file":"BitkitDialogContent.js","names":[],"sources":["../../../lib/components/BitkitDialog/BitkitDialogContent.tsx"],"sourcesContent":["import { Box } from '@chakra-ui/react/box';\nimport { Dialog, useDialogStyles } from '@chakra-ui/react/dialog';\nimport { chakra } from '@chakra-ui/react/styled-system';\nimport { type ReactNode } from 'react';\n\nimport BitkitPortalContext from '../../utilities/BitkitPortalContext';\nimport BitkitCloseButton from '../BitkitCloseButton/BitkitCloseButton';\n\nconst PORTAL_DISABLED = { disablePortal: true };\nimport { DialogBodyContext } from './BitkitDialogBody';\nimport { BitkitDialogStepProvider } from './BitkitDialogStepContext';\n\ninterface DialogContentInnerProps {\n children?: ReactNode;\n closable?: boolean;\n headerLabel?: string;\n scrollBehavior?: 'inside' | 'outside';\n showScrollGradient?: boolean;\n step?: number;\n stepHeader?: ReactNode;\n title: ReactNode;\n variant?: 'overflowContent';\n}\n\nexport const DialogContentInner = ({\n children,\n closable = true,\n headerLabel,\n scrollBehavior: scrollBehaviorProp = 'outside',\n showScrollGradient = true,\n step = 0,\n stepHeader,\n title,\n variant,\n}: DialogContentInnerProps) => {\n const scrollBehavior = variant === 'overflowContent' ? 'inside' : scrollBehaviorProp;\n const styles = useDialogStyles();\n\n return (\n <BitkitPortalContext.Provider value={PORTAL_DISABLED}>\n <BitkitDialogStepProvider value={{ step }}>\n <DialogBodyContext.Provider value={{ scrollBehavior, showScrollGradient }}>\n <Dialog.Header>\n <Box display=\"flex\" flexDirection=\"column\" gap=\"4\">\n {headerLabel && <chakra.p css={styles.label}>{headerLabel}</chakra.p>}\n <Dialog.Title>{title}</Dialog.Title>\n </Box>\n {!!stepHeader && <Box css={styles.stepHeader}>{stepHeader}</Box>}\n <Dialog.CloseTrigger asChild>\n <BitkitCloseButton\n disabled={!closable}\n size={variant === 'overflowContent' ? 'xs' : 'md'}\n type=\"button\"\n />\n </Dialog.CloseTrigger>\n </Dialog.Header>\n {children}\n </DialogBodyContext.Provider>\n </BitkitDialogStepProvider>\n </BitkitPortalContext.Provider>\n );\n};\n\nexport interface BitkitDialogContentProps {\n children?: ReactNode;\n closable?: boolean;\n headerLabel?: string;\n maxHeight?: string;\n scrollBehavior?: 'inside' | 'outside';\n showScrollGradient?: boolean;\n step?: number;\n stepHeader?: ReactNode;\n title: ReactNode;\n variant?: 'overflowContent';\n}\n\nconst BitkitDialogContent = ({ maxHeight, ...inner }: BitkitDialogContentProps) => (\n <Dialog.Content maxHeight={maxHeight}>\n <DialogContentInner {...inner} />\n </Dialog.Content>\n);\n\nexport default BitkitDialogContent;\n"],"mappings":";;;;;;;;;AAQA,IAAM,kBAAkB,EAAE,eAAe,KAAK;AAgB9C,IAAa,sBAAsB,EACjC,UACA,WAAW,MACX,aACA,gBAAgB,qBAAqB,WACrC,qBAAqB,MACrB,OAAO,GACP,YACA,OACA,cAC6B;CAC7B,MAAM,iBAAiB,YAAY,oBAAoB,WAAW;CAClE,MAAM,SAAS,gBAAgB;CAE/B,OACE,oBAAC,oBAAoB,UAArB;EAA8B,OAAO;YACnC,oBAAC,0BAAD;GAA0B,OAAO,EAAE,KAAK;aACtC,qBAAC,kBAAkB,UAAnB;IAA4B,OAAO;KAAE;KAAgB;IAAmB;cAAxE,CACE,qBAAC,OAAO,QAAR,EAAA,UAAA;KACE,qBAAC,KAAD;MAAK,SAAQ;MAAO,eAAc;MAAS,KAAI;gBAA/C,CACG,eAAe,oBAAC,OAAO,GAAR;OAAU,KAAK,OAAO;iBAAQ;MAAsB,CAAA,GACpE,oBAAC,OAAO,OAAR,EAAA,UAAe,MAAoB,CAAA,CAChC;;KACJ,CAAC,CAAC,cAAc,oBAAC,KAAD;MAAK,KAAK,OAAO;gBAAa;KAAgB,CAAA;KAC/D,oBAAC,OAAO,cAAR;MAAqB,SAAA;gBACnB,oBAAC,mBAAD;OACE,UAAU,CAAC;OACX,MAAM,YAAY,oBAAoB,OAAO;OAC7C,MAAK;MACN,CAAA;KACkB,CAAA;IACR,EAAA,CAAA,GACd,QACyB;;EACJ,CAAA;CACE,CAAA;AAElC;AAeA,IAAM,uBAAuB,EAAE,WAAW,GAAG,YAC3C,oBAAC,OAAO,SAAR;CAA2B;WACzB,oBAAC,oBAAD,EAAoB,GAAI,MAAQ,CAAA;AAClB,CAAA"}
|
|
@@ -12,6 +12,7 @@ export type BitkitMultiselectProps = Omit<BitkitFieldProps, 'children' | 'state'
|
|
|
12
12
|
items: Array<BitkitMultiselectMenuItemProps>;
|
|
13
13
|
onValueChange?: (newVal: Array<string>) => void;
|
|
14
14
|
placeholder?: string;
|
|
15
|
+
disablePortal?: boolean;
|
|
15
16
|
selectProps?: Omit<SelectRootProps, 'collection' | 'defaultValue' | 'multiple' | 'onValueChange' | 'value'>;
|
|
16
17
|
size?: 'md' | 'lg';
|
|
17
18
|
state?: 'disabled' | 'error' | 'readOnly' | 'warning';
|
|
@@ -26,6 +27,7 @@ declare const _default: import('react').ForwardRefExoticComponent<Omit<BitkitFie
|
|
|
26
27
|
items: Array<BitkitMultiselectMenuItemProps>;
|
|
27
28
|
onValueChange?: (newVal: Array<string>) => void;
|
|
28
29
|
placeholder?: string;
|
|
30
|
+
disablePortal?: boolean;
|
|
29
31
|
selectProps?: Omit<SelectRootProps, "collection" | "defaultValue" | "multiple" | "onValueChange" | "value">;
|
|
30
32
|
size?: "md" | "lg";
|
|
31
33
|
state?: "disabled" | "error" | "readOnly" | "warning";
|
|
@@ -4,13 +4,14 @@ import IconWarningYellow from "../../icons/IconWarningYellow.js";
|
|
|
4
4
|
import BitkitCloseButton from "../BitkitCloseButton/BitkitCloseButton.js";
|
|
5
5
|
import { withSubComponents } from "../../utilities/withSubComponents.js";
|
|
6
6
|
import BitkitSelectMenuAction from "../BitkitSelectMenu/BitkitSelectMenuAction.js";
|
|
7
|
+
import BitkitPortalContext from "../../utilities/BitkitPortalContext.js";
|
|
7
8
|
import BitkitField from "../BitkitField/BitkitField.js";
|
|
8
9
|
import BitkitMultiselectMenu from "../BitkitMultiselectMenu/BitkitMultiselectMenu.js";
|
|
9
10
|
import BitkitTag from "../BitkitTag/BitkitTag.js";
|
|
10
11
|
import { Box } from "@chakra-ui/react/box";
|
|
11
12
|
import { useSlotRecipe } from "@chakra-ui/react/styled-system";
|
|
12
13
|
import { Text } from "@chakra-ui/react/text";
|
|
13
|
-
import { forwardRef } from "react";
|
|
14
|
+
import { forwardRef, useContext } from "react";
|
|
14
15
|
import { Fragment as Fragment$1, jsx, jsxs } from "react/jsx-runtime";
|
|
15
16
|
import { Portal } from "@chakra-ui/react/portal";
|
|
16
17
|
import { createListCollection } from "@chakra-ui/react/collection";
|
|
@@ -93,7 +94,7 @@ var ClearAllButton = ({ state }) => {
|
|
|
93
94
|
});
|
|
94
95
|
};
|
|
95
96
|
var BitkitMultiselect = forwardRef((props, ref) => {
|
|
96
|
-
const { children, constrained = false, defaultValue, emptyHelperText, emptyLabel, isLoading, items, onSearchChange, onValueChange, placeholder, searchValue, selectProps, size = "lg", state, triggerProps, value, ...fieldProps } = props;
|
|
97
|
+
const { children, constrained = false, defaultValue, emptyHelperText, emptyLabel, isLoading, items, onSearchChange, onValueChange, placeholder, disablePortal, searchValue, selectProps, size = "lg", state, triggerProps, value, ...fieldProps } = props;
|
|
97
98
|
const collection = createListCollection({
|
|
98
99
|
items,
|
|
99
100
|
groupBy: (item) => item.group || "",
|
|
@@ -103,6 +104,7 @@ var BitkitMultiselect = forwardRef((props, ref) => {
|
|
|
103
104
|
constrained,
|
|
104
105
|
size
|
|
105
106
|
});
|
|
107
|
+
const { disablePortal: disablePortalFromContext } = useContext(BitkitPortalContext);
|
|
106
108
|
const iconSize = size === "lg" ? "24" : "16";
|
|
107
109
|
const isInvalid = state === "error" || !!fieldProps.errorText;
|
|
108
110
|
return /* @__PURE__ */ jsx(BitkitField, {
|
|
@@ -160,16 +162,19 @@ var BitkitMultiselect = forwardRef((props, ref) => {
|
|
|
160
162
|
})
|
|
161
163
|
]
|
|
162
164
|
}),
|
|
163
|
-
/* @__PURE__ */ jsx(Portal, {
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
165
|
+
/* @__PURE__ */ jsx(Portal, {
|
|
166
|
+
disabled: disablePortal || disablePortalFromContext,
|
|
167
|
+
children: /* @__PURE__ */ jsx(Select.Positioner, { children: /* @__PURE__ */ jsx(BitkitMultiselectMenu, {
|
|
168
|
+
collection,
|
|
169
|
+
emptyHelperText,
|
|
170
|
+
emptyLabel,
|
|
171
|
+
isLoading,
|
|
172
|
+
onSearchChange,
|
|
173
|
+
searchValue,
|
|
174
|
+
size,
|
|
175
|
+
children
|
|
176
|
+
}) })
|
|
177
|
+
})
|
|
173
178
|
]
|
|
174
179
|
})
|
|
175
180
|
});
|
|
@@ -1 +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 { withSubComponents } from '../../utilities/withSubComponents';\nimport BitkitCloseButton from '../BitkitCloseButton/BitkitCloseButton';\nimport BitkitField, { type BitkitFieldProps } from '../BitkitField/BitkitField';\nimport BitkitMultiselectMenu, {\n type BitkitMultiselectMenuItemProps,\n} from '../BitkitMultiselectMenu/BitkitMultiselectMenu';\nimport {\n type BitkitSelectMenuEmptyStateProps,\n type BitkitSelectMenuSearchProps,\n} from '../BitkitSelectMenu/BitkitSelectMenu';\nimport BitkitSelectMenuAction, { type BitkitSelectMenuActionChild } from '../BitkitSelectMenu/BitkitSelectMenuAction';\nimport BitkitTag from '../BitkitTag/BitkitTag';\n\nexport type BitkitMultiselectTriggerProps = SelectTriggerProps;\n\nexport type BitkitMultiselectProps = Omit<BitkitFieldProps, 'children' | 'state'> & {\n children?: BitkitSelectMenuActionChild;\n constrained?: boolean;\n defaultValue?: Array<string>;\n isLoading?: boolean;\n items: Array<BitkitMultiselectMenuItemProps>;\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} & 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<BitkitMultiselectMenuItemProps>;\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 children,\n constrained = false,\n defaultValue,\n emptyHelperText,\n emptyLabel,\n isLoading,\n items,\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 <BitkitMultiselectMenu\n collection={collection}\n emptyHelperText={emptyHelperText}\n emptyLabel={emptyLabel}\n isLoading={isLoading}\n onSearchChange={onSearchChange}\n searchValue={searchValue}\n size={size}\n >\n {children}\n </BitkitMultiselectMenu>\n </Select.Positioner>\n </Portal>\n </Select.Root>\n </BitkitField>\n );\n});\n\nBitkitMultiselect.displayName = 'BitkitMultiselect';\n\nexport default withSubComponents(BitkitMultiselect, { Action: BitkitSelectMenuAction });\n"],"mappings":"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"}
|
|
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, useContext } from 'react';\n\nimport { IconErrorCircleFilled, IconWarningYellow } from '../../icons';\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 BitkitMultiselectMenu, {\n type BitkitMultiselectMenuItemProps,\n} from '../BitkitMultiselectMenu/BitkitMultiselectMenu';\nimport {\n type BitkitSelectMenuEmptyStateProps,\n type BitkitSelectMenuSearchProps,\n} from '../BitkitSelectMenu/BitkitSelectMenu';\nimport BitkitSelectMenuAction, { type BitkitSelectMenuActionChild } from '../BitkitSelectMenu/BitkitSelectMenuAction';\nimport BitkitTag from '../BitkitTag/BitkitTag';\n\nexport type BitkitMultiselectTriggerProps = SelectTriggerProps;\n\nexport type BitkitMultiselectProps = Omit<BitkitFieldProps, 'children' | 'state'> & {\n children?: BitkitSelectMenuActionChild;\n constrained?: boolean;\n defaultValue?: Array<string>;\n isLoading?: boolean;\n items: Array<BitkitMultiselectMenuItemProps>;\n onValueChange?: (newVal: Array<string>) => void;\n placeholder?: string;\n disablePortal?: boolean;\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} & 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<BitkitMultiselectMenuItemProps>;\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 children,\n constrained = false,\n defaultValue,\n emptyHelperText,\n emptyLabel,\n isLoading,\n items,\n onSearchChange,\n onValueChange,\n placeholder,\n disablePortal,\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 { disablePortal: disablePortalFromContext } = useContext(BitkitPortalContext);\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 disabled={disablePortal || disablePortalFromContext}>\n <Select.Positioner>\n <BitkitMultiselectMenu\n collection={collection}\n emptyHelperText={emptyHelperText}\n emptyLabel={emptyLabel}\n isLoading={isLoading}\n onSearchChange={onSearchChange}\n searchValue={searchValue}\n size={size}\n >\n {children}\n </BitkitMultiselectMenu>\n </Select.Positioner>\n </Portal>\n </Select.Root>\n </BitkitField>\n );\n});\n\nBitkitMultiselect.displayName = 'BitkitMultiselect';\n\nexport default withSubComponents(BitkitMultiselect, { Action: BitkitSelectMenuAction });\n"],"mappings":"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"}
|
|
@@ -10,6 +10,7 @@ export type BitkitSelectProps = Omit<BitkitFieldProps, 'children' | 'state'> & {
|
|
|
10
10
|
items: Array<BitkitSelectMenuItemProps>;
|
|
11
11
|
onValueChange?: (newVal: string) => void;
|
|
12
12
|
placeholder?: string;
|
|
13
|
+
disablePortal?: boolean;
|
|
13
14
|
selectProps?: Omit<SelectRootProps, 'collection' | 'defaultValue' | 'onValueChange' | 'value'>;
|
|
14
15
|
size?: 'md' | 'lg';
|
|
15
16
|
state?: 'disabled' | 'error' | 'readOnly' | 'warning';
|
|
@@ -23,6 +24,7 @@ declare const _default: import('react').ForwardRefExoticComponent<Omit<BitkitFie
|
|
|
23
24
|
items: Array<BitkitSelectMenuItemProps>;
|
|
24
25
|
onValueChange?: (newVal: string) => void;
|
|
25
26
|
placeholder?: string;
|
|
27
|
+
disablePortal?: boolean;
|
|
26
28
|
selectProps?: Omit<SelectRootProps, "collection" | "defaultValue" | "onValueChange" | "value">;
|
|
27
29
|
size?: "md" | "lg";
|
|
28
30
|
state?: "disabled" | "error" | "readOnly" | "warning";
|
|
@@ -4,9 +4,10 @@ import IconWarningYellow from "../../icons/IconWarningYellow.js";
|
|
|
4
4
|
import { withSubComponents } from "../../utilities/withSubComponents.js";
|
|
5
5
|
import BitkitSelectMenuAction from "../BitkitSelectMenu/BitkitSelectMenuAction.js";
|
|
6
6
|
import BitkitSelectMenu from "../BitkitSelectMenu/BitkitSelectMenu.js";
|
|
7
|
+
import BitkitPortalContext from "../../utilities/BitkitPortalContext.js";
|
|
7
8
|
import BitkitField from "../BitkitField/BitkitField.js";
|
|
8
9
|
import { Text } from "@chakra-ui/react/text";
|
|
9
|
-
import { forwardRef } from "react";
|
|
10
|
+
import { forwardRef, useContext } from "react";
|
|
10
11
|
import { jsx, jsxs } from "react/jsx-runtime";
|
|
11
12
|
import { Portal } from "@chakra-ui/react/portal";
|
|
12
13
|
import { createListCollection } from "@chakra-ui/react/collection";
|
|
@@ -33,12 +34,13 @@ var SelectValue = ({ placeholder, state, size }) => {
|
|
|
33
34
|
}) : /* @__PURE__ */ jsx(Select.ValueText, { placeholder: placeholder ?? (state === "readOnly" ? "(not selected)" : "Select an option") });
|
|
34
35
|
};
|
|
35
36
|
var BitkitSelect = forwardRef((props, ref) => {
|
|
36
|
-
const { children, defaultValue, emptyHelperText, emptyLabel, isLoading, items, onSearchChange, onValueChange,
|
|
37
|
+
const { children, defaultValue, emptyHelperText, emptyLabel, isLoading, items, onSearchChange, onValueChange, placeholder, disablePortal, searchValue, selectProps, size, state, triggerProps, value, ...fieldProps } = props;
|
|
37
38
|
const collection = createListCollection({
|
|
38
39
|
items,
|
|
39
40
|
groupBy: (item) => item.group || "",
|
|
40
41
|
isItemDisabled: (item) => !!item.disabled
|
|
41
42
|
});
|
|
43
|
+
const { disablePortal: disablePortalFromContext } = useContext(BitkitPortalContext);
|
|
42
44
|
const isInvalid = state === "error" || !!fieldProps.errorText;
|
|
43
45
|
return /* @__PURE__ */ jsx(BitkitField, {
|
|
44
46
|
ref,
|
|
@@ -79,16 +81,19 @@ var BitkitSelect = forwardRef((props, ref) => {
|
|
|
79
81
|
})
|
|
80
82
|
] })]
|
|
81
83
|
}),
|
|
82
|
-
/* @__PURE__ */ jsx(Portal, {
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
84
|
+
/* @__PURE__ */ jsx(Portal, {
|
|
85
|
+
disabled: disablePortal || disablePortalFromContext,
|
|
86
|
+
children: /* @__PURE__ */ jsx(Select.Positioner, { children: /* @__PURE__ */ jsx(BitkitSelectMenu, {
|
|
87
|
+
collection,
|
|
88
|
+
emptyHelperText,
|
|
89
|
+
emptyLabel,
|
|
90
|
+
isLoading,
|
|
91
|
+
onSearchChange,
|
|
92
|
+
searchValue,
|
|
93
|
+
size,
|
|
94
|
+
children
|
|
95
|
+
}) })
|
|
96
|
+
})
|
|
92
97
|
]
|
|
93
98
|
})
|
|
94
99
|
});
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"BitkitSelect.js","names":[],"sources":["../../../lib/components/BitkitSelect/BitkitSelect.tsx"],"sourcesContent":["import { 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 { Text } from '@chakra-ui/react/text';\nimport { forwardRef } from 'react';\n\nimport { IconErrorCircleFilled, IconWarningYellow } from '../../icons';\nimport AssetSelectChevron from '../../utilities/AssetSelectChevron.tsx';\nimport { withSubComponents } from '../../utilities/withSubComponents.ts';\nimport BitkitField, { type BitkitFieldProps } from '../BitkitField/BitkitField.tsx';\nimport BitkitSelectMenu, {\n type BitkitSelectMenuEmptyStateProps,\n type BitkitSelectMenuItemProps,\n type BitkitSelectMenuSearchProps,\n} from '../BitkitSelectMenu/BitkitSelectMenu.tsx';\nimport BitkitSelectMenuAction, {\n type BitkitSelectMenuActionChild,\n} from '../BitkitSelectMenu/BitkitSelectMenuAction.tsx';\n\nexport type BitkitSelectTriggerProps = SelectTriggerProps;\n\nexport type BitkitSelectProps = Omit<BitkitFieldProps, 'children' | 'state'> & {\n children?: BitkitSelectMenuActionChild;\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} & 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 {Icon && <Icon size={iconSize} flexShrink={0} />}\n <Text as=\"span\" overflow=\"hidden\" textOverflow=\"ellipsis\" whiteSpace=\"nowrap\" minWidth={0}>\n {label}\n </Text>\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 children,\n defaultValue,\n emptyHelperText,\n emptyLabel,\n isLoading,\n items,\n onSearchChange,\n onValueChange,\n
|
|
1
|
+
{"version":3,"file":"BitkitSelect.js","names":[],"sources":["../../../lib/components/BitkitSelect/BitkitSelect.tsx"],"sourcesContent":["import { 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 { Text } from '@chakra-ui/react/text';\nimport { forwardRef, useContext } from 'react';\n\nimport { IconErrorCircleFilled, IconWarningYellow } from '../../icons';\nimport AssetSelectChevron from '../../utilities/AssetSelectChevron.tsx';\nimport BitkitPortalContext from '../../utilities/BitkitPortalContext';\nimport { withSubComponents } from '../../utilities/withSubComponents.ts';\nimport BitkitField, { type BitkitFieldProps } from '../BitkitField/BitkitField.tsx';\nimport BitkitSelectMenu, {\n type BitkitSelectMenuEmptyStateProps,\n type BitkitSelectMenuItemProps,\n type BitkitSelectMenuSearchProps,\n} from '../BitkitSelectMenu/BitkitSelectMenu.tsx';\nimport BitkitSelectMenuAction, {\n type BitkitSelectMenuActionChild,\n} from '../BitkitSelectMenu/BitkitSelectMenuAction.tsx';\n\nexport type BitkitSelectTriggerProps = SelectTriggerProps;\n\nexport type BitkitSelectProps = Omit<BitkitFieldProps, 'children' | 'state'> & {\n children?: BitkitSelectMenuActionChild;\n defaultValue?: string;\n isLoading?: boolean;\n items: Array<BitkitSelectMenuItemProps>;\n onValueChange?: (newVal: string) => void;\n placeholder?: string;\n disablePortal?: boolean;\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} & 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 {Icon && <Icon size={iconSize} flexShrink={0} />}\n <Text as=\"span\" overflow=\"hidden\" textOverflow=\"ellipsis\" whiteSpace=\"nowrap\" minWidth={0}>\n {label}\n </Text>\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 children,\n defaultValue,\n emptyHelperText,\n emptyLabel,\n isLoading,\n items,\n onSearchChange,\n onValueChange,\n placeholder,\n disablePortal,\n searchValue,\n selectProps,\n size,\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 { disablePortal: disablePortalFromContext } = useContext(BitkitPortalContext);\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 hasStatusIcon={state === 'error' || state === 'warning'}\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 disabled={disablePortal || disablePortalFromContext}>\n <Select.Positioner>\n <BitkitSelectMenu\n collection={collection}\n emptyHelperText={emptyHelperText}\n emptyLabel={emptyLabel}\n isLoading={isLoading}\n onSearchChange={onSearchChange}\n searchValue={searchValue}\n size={size}\n >\n {children}\n </BitkitSelectMenu>\n </Select.Positioner>\n </Portal>\n </Select.Root>\n </BitkitField>\n );\n});\n\nBitkitSelect.displayName = 'BitkitSelect';\n\nexport default withSubComponents(BitkitSelect, { Action: BitkitSelectMenuAction });\n"],"mappings":";;;;;;;;;;;;;;;AA4CA,IAAM,eAAe,EAAE,aAAa,OAAO,WAA6B;CAEtE,MAAM,QADS,iBACD,EAAO;CAErB,MAAM,OAAO,MAAM,IAAI;CACvB,MAAM,QAAQ,MAAM,IAAI;CAExB,MAAM,WAAW,SAAS,OAAO,OAAO;CAExC,OAAO,MAAM,KACX,qBAAC,OAAO,WAAR;EAAkB,aAAa,gBAAgB,UAAU,aAAa,mBAAmB;YAAzF,CACG,QAAQ,oBAAC,MAAD;GAAM,MAAM;GAAU,YAAY;EAAI,CAAA,GAC/C,oBAAC,MAAD;GAAM,IAAG;GAAO,UAAS;GAAS,cAAa;GAAW,YAAW;GAAS,UAAU;aACrF;EACG,CAAA,CACU;MAElB,oBAAC,OAAO,WAAR,EAAkB,aAAa,gBAAgB,UAAU,aAAa,mBAAmB,oBAAsB,CAAA;AAEnH;AAEA,IAAM,eAAe,YAA+C,OAA0B,QAAQ;CACpG,MAAM,EACJ,UACA,cACA,iBACA,YACA,WACA,OACA,gBACA,eACA,aACA,eACA,aACA,aACA,MACA,OACA,cACA,OACA,GAAG,eACD;CAEJ,MAAM,aAAa,qBAAqB;EACtC;EACA,UAAU,SAAS,KAAK,SAAS;EACjC,iBAAiB,SAAS,CAAC,CAAC,KAAK;CACnC,CAAC;CAED,MAAM,EAAE,eAAe,6BAA6B,WAAW,mBAAmB;CAClF,MAAM,YAAY,UAAU,WAAW,CAAC,CAAC,WAAW;CAEpD,OACE,oBAAC,aAAD;EAAkB;EAAY;EAAO,GAAI;YACvC,qBAAC,OAAO,MAAR;GACc;GACN;GACN,GAAI;GACJ,cAAc,eAAe,CAAC,YAAY,IAAI,KAAA;GAC9C,UAAU,UAAU;GACpB,eAAe,UAAU,WAAW,UAAU;GAC9C,SAAS;GACT,gBAAgB,WAAW,gBAAgB,OAAO,MAAM,EAAE;GAC1D,UAAU,UAAU;GAGpB,kBAAkB,EAAE,iBAAiB,WAAW,GAAG,eAAe,EAAE,OAAO,UAAU,CAAC;GACtF,OAAO,QAAQ,CAAC,KAAK,IAAI,KAAA;aAb3B;IAeE,oBAAC,OAAO,cAAR,CAAsB,CAAA;IACtB,qBAAC,OAAO,SAAR;KAAgB,WAAU;eAA1B,CACE,oBAAC,OAAO,SAAR;MAAgB,GAAI;gBAClB,oBAAC,aAAD;OAA0B;OAAmB;OAAa;MAAQ,CAAA;KACpD,CAAA,GAChB,qBAAC,OAAO,gBAAR,EAAA,UAAA;MACG,UAAU,WACT,oBAAC,OAAO,WAAR,EAAA,UACE,oBAAC,uBAAD;OAAuB,MAAM,SAAS,OAAO,OAAO;OAAM,OAAM;MAAiB,CAAA,EACjE,CAAA;MAEnB,UAAU,aACT,oBAAC,OAAO,WAAR,EAAA,UACE,oBAAC,mBAAD,EAAmB,MAAM,SAAS,OAAO,OAAO,KAAO,CAAA,EACvC,CAAA;MAEpB,oBAAC,OAAO,WAAR;OAAkB,SAAA;iBAChB,oBAAC,oBAAD,CAAqB,CAAA;MACL,CAAA;KACG,EAAA,CAAA,CACT;;IAChB,oBAAC,QAAD;KAAQ,UAAU,iBAAiB;eACjC,oBAAC,OAAO,YAAR,EAAA,UACE,oBAAC,kBAAD;MACc;MACK;MACL;MACD;MACK;MACH;MACP;MAEL;KACe,CAAA,EACD,CAAA;IACb,CAAA;GACG;;CACF,CAAA;AAEjB,CAAC;AAED,aAAa,cAAc;AAE3B,IAAA,uBAAe,kBAAkB,cAAc,EAAE,QAAQ,uBAAuB,CAAC"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { createContext } from "react";
|
|
2
|
+
//#region lib/utilities/BitkitPortalContext.ts
|
|
3
|
+
var BitkitPortalContext = createContext({ disablePortal: false });
|
|
4
|
+
//#endregion
|
|
5
|
+
export { BitkitPortalContext as default };
|
|
6
|
+
|
|
7
|
+
//# sourceMappingURL=BitkitPortalContext.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"BitkitPortalContext.js","names":[],"sources":["../../lib/utilities/BitkitPortalContext.ts"],"sourcesContent":["import { createContext, useContext } from 'react';\n\nconst BitkitPortalContext = createContext({ disablePortal: false });\n\nexport const usePortalContext = () => useContext(BitkitPortalContext);\n\nexport default BitkitPortalContext;\n"],"mappings":";;AAEA,IAAM,sBAAsB,cAAc,EAAE,eAAe,MAAM,CAAC"}
|