@impulse-ui-native/select 2.0.1 → 2.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (50) hide show
  1. package/LICENSE +21 -0
  2. package/dist/components/index.d.mts +6 -0
  3. package/dist/components/index.js +7 -0
  4. package/dist/components/index.js.map +1 -0
  5. package/dist/components/multi-select.d.mts +8 -0
  6. package/dist/components/multi-select.js +59 -0
  7. package/dist/components/multi-select.js.map +1 -0
  8. package/dist/components/option.d.mts +9 -0
  9. package/dist/components/option.js +35 -0
  10. package/dist/components/option.js.map +1 -0
  11. package/dist/components/select-control.d.mts +8 -0
  12. package/dist/components/select-control.js +58 -0
  13. package/dist/components/select-control.js.map +1 -0
  14. package/dist/components/select.d.mts +8 -0
  15. package/dist/components/select.flyout.d.mts +8 -0
  16. package/dist/components/select.flyout.js +46 -0
  17. package/dist/components/select.flyout.js.map +1 -0
  18. package/dist/components/select.js +46 -0
  19. package/dist/components/select.js.map +1 -0
  20. package/dist/constants/index.d.mts +3 -0
  21. package/dist/constants/index.js +5 -0
  22. package/dist/constants/index.js.map +1 -0
  23. package/dist/hooks/index.d.mts +2 -0
  24. package/dist/hooks/index.js +1 -0
  25. package/dist/hooks/index.js.map +1 -0
  26. package/dist/hooks/use-multi-select.hook.d.mts +13 -0
  27. package/dist/hooks/use-multi-select.hook.js +50 -0
  28. package/dist/hooks/use-multi-select.hook.js.map +1 -0
  29. package/dist/hooks/use-select.hook.d.mts +13 -0
  30. package/dist/hooks/use-select.hook.js +45 -0
  31. package/dist/hooks/use-select.hook.js.map +1 -0
  32. package/dist/index.d.mts +6 -49
  33. package/dist/index.js +2 -336
  34. package/dist/index.js.map +1 -1
  35. package/dist/types/common.types.d.mts +3 -0
  36. package/dist/types/common.types.js +1 -0
  37. package/dist/types/common.types.js.map +1 -0
  38. package/dist/types/index.d.mts +3 -0
  39. package/dist/types/index.js +2 -0
  40. package/dist/types/index.js.map +1 -0
  41. package/dist/types/select.types.d.mts +44 -0
  42. package/dist/types/select.types.js +1 -0
  43. package/dist/types/select.types.js.map +1 -0
  44. package/dist/utils/index.d.mts +4 -0
  45. package/dist/utils/index.js +5 -0
  46. package/dist/utils/index.js.map +1 -0
  47. package/dist/utils/option.utils.d.mts +8 -0
  48. package/dist/utils/option.utils.js +17 -0
  49. package/dist/utils/option.utils.js.map +1 -0
  50. package/package.json +14 -13
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 ImpulseUI Native contributors
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,6 @@
1
+ export { Select } from './select.mjs';
2
+ export { MultiSelect } from './multi-select.mjs';
3
+ import '../types/select.types.mjs';
4
+ import 'react';
5
+ import '@impulse-ui-native/flyout';
6
+ import '@impulse-ui-native/primitives';
@@ -0,0 +1,7 @@
1
+ import { Select } from "./select";
2
+ import { MultiSelect } from "./multi-select";
3
+ export {
4
+ MultiSelect,
5
+ Select
6
+ };
7
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/components/index.ts"],"sourcesContent":["export { Select } from \"./select\";\nexport { MultiSelect } from \"./multi-select\";\n"],"mappings":"AAAA,SAAS,cAAc;AACvB,SAAS,mBAAmB;","names":[]}
@@ -0,0 +1,8 @@
1
+ import { ReactElement } from 'react';
2
+ import { PrimitiveValue, MultiSelectProps } from '../types/select.types.mjs';
3
+ import '@impulse-ui-native/flyout';
4
+ import '@impulse-ui-native/primitives';
5
+
6
+ declare const MultiSelect: <Value extends PrimitiveValue>(props: MultiSelectProps<Value>) => ReactElement | null;
7
+
8
+ export { MultiSelect };
@@ -0,0 +1,59 @@
1
+ import { jsx, jsxs } from "react/jsx-runtime";
2
+ import { memo, useId } from "react";
3
+ import { useIsOpen } from "@impulse-ui-native/core";
4
+ import { Control, Tag, View } from "@impulse-ui-native/primitives";
5
+ import { useMultiSelect } from "../hooks/use-multi-select.hook";
6
+ import { SelectControl } from "./select-control";
7
+ import { SelectFlyout } from "./select.flyout";
8
+ function MultiSelectComponent(props) {
9
+ const { options, value, defaultValue, onChange, placeholder, ...rest } = props;
10
+ const { isOpen, open, close } = useIsOpen();
11
+ const id = useId();
12
+ const { selected, hasSelected, select, isSelected, getLabel } = useMultiSelect({
13
+ options,
14
+ value,
15
+ defaultValue,
16
+ onChange
17
+ });
18
+ return /* @__PURE__ */ jsxs(SelectControl, { ...rest, onPress: open, children: [
19
+ !hasSelected ? /* @__PURE__ */ jsx(Control.Placeholder, { children: placeholder }) : null,
20
+ hasSelected ? /* @__PURE__ */ jsx(
21
+ View,
22
+ {
23
+ flex: 1,
24
+ flexDirection: "row",
25
+ gap: 4,
26
+ marginHorizontal: 4,
27
+ overflow: "hidden",
28
+ children: selected ? selected.map((value2) => /* @__PURE__ */ jsx(
29
+ Tag,
30
+ {
31
+ variant: "filled",
32
+ size: props.size,
33
+ closable: true,
34
+ onClose: () => select(value2),
35
+ label: String(getLabel(value2))
36
+ },
37
+ value2
38
+ )) : null
39
+ }
40
+ ) : null,
41
+ /* @__PURE__ */ jsx(
42
+ SelectFlyout,
43
+ {
44
+ id,
45
+ title: "Options",
46
+ open: isOpen,
47
+ options,
48
+ isSelected,
49
+ onCloseFinished: close,
50
+ onSelect: select
51
+ }
52
+ )
53
+ ] });
54
+ }
55
+ const MultiSelect = memo(MultiSelectComponent);
56
+ export {
57
+ MultiSelect
58
+ };
59
+ //# sourceMappingURL=multi-select.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/components/multi-select.tsx"],"sourcesContent":["import { memo, ReactElement, useId } from \"react\";\n\nimport { useIsOpen } from \"@impulse-ui-native/core\";\nimport { Control, Tag, View } from \"@impulse-ui-native/primitives\";\n\nimport { useMultiSelect } from \"../hooks/use-multi-select.hook\";\nimport { MultiSelectProps, PrimitiveValue } from \"../types\";\nimport { SelectControl } from \"./select-control\";\nimport { SelectFlyout } from \"./select.flyout\";\n\nfunction MultiSelectComponent<Value extends PrimitiveValue>(\n props: MultiSelectProps<Value>,\n) {\n const { options, value, defaultValue, onChange, placeholder, ...rest } =\n props;\n const { isOpen, open, close } = useIsOpen();\n\n const id = useId();\n\n const { selected, hasSelected, select, isSelected, getLabel } =\n useMultiSelect({\n options,\n value,\n defaultValue,\n onChange,\n });\n\n return (\n <SelectControl {...rest} onPress={open}>\n {!hasSelected ? (\n <Control.Placeholder>{placeholder}</Control.Placeholder>\n ) : null}\n {hasSelected ? (\n <View\n flex={1}\n flexDirection=\"row\"\n gap={4}\n marginHorizontal={4}\n overflow=\"hidden\"\n >\n {selected\n ? selected.map((value) => (\n <Tag\n variant=\"filled\"\n size={props.size}\n key={value}\n closable\n onClose={() => select(value)}\n label={String(getLabel(value))}\n />\n ))\n : null}\n </View>\n ) : null}\n <SelectFlyout\n id={id}\n title=\"Options\"\n open={isOpen}\n options={options}\n isSelected={isSelected}\n onCloseFinished={close}\n onSelect={select}\n />\n </SelectControl>\n );\n}\n\nexport const MultiSelect = memo(MultiSelectComponent) as <\n Value extends PrimitiveValue,\n>(\n props: MultiSelectProps<Value>,\n) => ReactElement | null;\n"],"mappings":"AA4BI,SAEI,KAFJ;AA5BJ,SAAS,MAAoB,aAAa;AAE1C,SAAS,iBAAiB;AAC1B,SAAS,SAAS,KAAK,YAAY;AAEnC,SAAS,sBAAsB;AAE/B,SAAS,qBAAqB;AAC9B,SAAS,oBAAoB;AAE7B,SAAS,qBACP,OACA;AACA,QAAM,EAAE,SAAS,OAAO,cAAc,UAAU,aAAa,GAAG,KAAK,IACnE;AACF,QAAM,EAAE,QAAQ,MAAM,MAAM,IAAI,UAAU;AAE1C,QAAM,KAAK,MAAM;AAEjB,QAAM,EAAE,UAAU,aAAa,QAAQ,YAAY,SAAS,IAC1D,eAAe;AAAA,IACb;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF,CAAC;AAEH,SACE,qBAAC,iBAAe,GAAG,MAAM,SAAS,MAC/B;AAAA,KAAC,cACA,oBAAC,QAAQ,aAAR,EAAqB,uBAAY,IAChC;AAAA,IACH,cACC;AAAA,MAAC;AAAA;AAAA,QACC,MAAM;AAAA,QACN,eAAc;AAAA,QACd,KAAK;AAAA,QACL,kBAAkB;AAAA,QAClB,UAAS;AAAA,QAER,qBACG,SAAS,IAAI,CAACA,WACZ;AAAA,UAAC;AAAA;AAAA,YACC,SAAQ;AAAA,YACR,MAAM,MAAM;AAAA,YAEZ,UAAQ;AAAA,YACR,SAAS,MAAM,OAAOA,MAAK;AAAA,YAC3B,OAAO,OAAO,SAASA,MAAK,CAAC;AAAA;AAAA,UAHxBA;AAAA,QAIP,CACD,IACD;AAAA;AAAA,IACN,IACE;AAAA,IACJ;AAAA,MAAC;AAAA;AAAA,QACC;AAAA,QACA,OAAM;AAAA,QACN,MAAM;AAAA,QACN;AAAA,QACA;AAAA,QACA,iBAAiB;AAAA,QACjB,UAAU;AAAA;AAAA,IACZ;AAAA,KACF;AAEJ;AAEO,MAAM,cAAc,KAAK,oBAAoB;","names":["value"]}
@@ -0,0 +1,9 @@
1
+ import * as react from 'react';
2
+ import * as react_jsx_runtime from 'react/jsx-runtime';
3
+ import { OptionProps } from '../types/select.types.mjs';
4
+ import '@impulse-ui-native/flyout';
5
+ import '@impulse-ui-native/primitives';
6
+
7
+ declare const Option: react.MemoExoticComponent<(props: OptionProps) => react_jsx_runtime.JSX.Element>;
8
+
9
+ export { Option };
@@ -0,0 +1,35 @@
1
+ import { jsx, jsxs } from "react/jsx-runtime";
2
+ import { memo } from "react";
3
+ import { Icon } from "@impulse-ui-native/icon/components/icon";
4
+ import { CheckIcon } from "@impulse-ui-native/icon/icons/check";
5
+ import { Pressable, Typography, View } from "@impulse-ui-native/primitives";
6
+ import { useComponentsTokens } from "@impulse-ui-native/theme";
7
+ const Option = memo(function Option2(props) {
8
+ const { label, selected, ...rest } = props;
9
+ const tokens = useComponentsTokens();
10
+ const optionTokens = tokens.select.option;
11
+ return /* @__PURE__ */ jsx(Pressable, { ...rest, children: /* @__PURE__ */ jsxs(
12
+ View,
13
+ {
14
+ padding: optionTokens.padding,
15
+ flexDirection: "row",
16
+ alignItems: "center",
17
+ justifyContent: "space-between",
18
+ children: [
19
+ /* @__PURE__ */ jsx(Typography.Body, { children: label }),
20
+ /* @__PURE__ */ jsx(
21
+ Icon,
22
+ {
23
+ icon: CheckIcon,
24
+ color: optionTokens.selectedIconColor,
25
+ opacity: selected ? optionTokens.selectedIconVisibleOpacity : optionTokens.selectedIconHiddenOpacity
26
+ }
27
+ )
28
+ ]
29
+ }
30
+ ) });
31
+ });
32
+ export {
33
+ Option
34
+ };
35
+ //# sourceMappingURL=option.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/components/option.tsx"],"sourcesContent":["import { memo } from \"react\";\n\nimport { Icon } from \"@impulse-ui-native/icon/components/icon\";\nimport { CheckIcon } from \"@impulse-ui-native/icon/icons/check\";\nimport { Pressable, Typography, View } from \"@impulse-ui-native/primitives\";\nimport { useComponentsTokens } from \"@impulse-ui-native/theme\";\n\nimport { OptionProps } from \"../types\";\n\nexport const Option = memo(function Option(props: OptionProps) {\n const { label, selected, ...rest } = props;\n\n const tokens = useComponentsTokens();\n const optionTokens = tokens.select.option;\n\n return (\n <Pressable {...rest}>\n <View\n padding={optionTokens.padding}\n flexDirection=\"row\"\n alignItems=\"center\"\n justifyContent=\"space-between\"\n >\n <Typography.Body>{label}</Typography.Body>\n\n <Icon\n icon={CheckIcon}\n color={optionTokens.selectedIconColor}\n opacity={\n selected\n ? optionTokens.selectedIconVisibleOpacity\n : optionTokens.selectedIconHiddenOpacity\n }\n />\n </View>\n </Pressable>\n );\n});\n"],"mappings":"AAiBM,SAME,KANF;AAjBN,SAAS,YAAY;AAErB,SAAS,YAAY;AACrB,SAAS,iBAAiB;AAC1B,SAAS,WAAW,YAAY,YAAY;AAC5C,SAAS,2BAA2B;AAI7B,MAAM,SAAS,KAAK,SAASA,QAAO,OAAoB;AAC7D,QAAM,EAAE,OAAO,UAAU,GAAG,KAAK,IAAI;AAErC,QAAM,SAAS,oBAAoB;AACnC,QAAM,eAAe,OAAO,OAAO;AAEnC,SACE,oBAAC,aAAW,GAAG,MACb;AAAA,IAAC;AAAA;AAAA,MACC,SAAS,aAAa;AAAA,MACtB,eAAc;AAAA,MACd,YAAW;AAAA,MACX,gBAAe;AAAA,MAEf;AAAA,4BAAC,WAAW,MAAX,EAAiB,iBAAM;AAAA,QAExB;AAAA,UAAC;AAAA;AAAA,YACC,MAAM;AAAA,YACN,OAAO,aAAa;AAAA,YACpB,SACE,WACI,aAAa,6BACb,aAAa;AAAA;AAAA,QAErB;AAAA;AAAA;AAAA,EACF,GACF;AAEJ,CAAC;","names":["Option"]}
@@ -0,0 +1,8 @@
1
+ import { PropsWithChildren, ReactElement } from 'react';
2
+ import { PrimitiveValue, SelectControlProps } from '../types/select.types.mjs';
3
+ import '@impulse-ui-native/flyout';
4
+ import '@impulse-ui-native/primitives';
5
+
6
+ declare const SelectControl: <Value extends PrimitiveValue>(props: PropsWithChildren<SelectControlProps<Value>>) => ReactElement | null;
7
+
8
+ export { SelectControl };
@@ -0,0 +1,58 @@
1
+ import { jsx, jsxs } from "react/jsx-runtime";
2
+ import { memo } from "react";
3
+ import { Control, Pressable } from "@impulse-ui-native/primitives";
4
+ function SelectControlComponent(props) {
5
+ const {
6
+ size = "medium",
7
+ variant = "outlined",
8
+ label,
9
+ error,
10
+ disabled,
11
+ loading,
12
+ PrefixIcon,
13
+ Prefix,
14
+ onPressPrefix,
15
+ SuffixIcon,
16
+ Suffix,
17
+ onPressSuffix,
18
+ onPress,
19
+ children
20
+ } = props;
21
+ return /* @__PURE__ */ jsx(
22
+ Control.Provider,
23
+ {
24
+ size,
25
+ variant,
26
+ error,
27
+ disabled,
28
+ children: /* @__PURE__ */ jsxs(Control.Root, { children: [
29
+ /* @__PURE__ */ jsx(Control.Label, { children: label }),
30
+ /* @__PURE__ */ jsx(Pressable, { onPress, children: /* @__PURE__ */ jsxs(Control.Container, { children: [
31
+ /* @__PURE__ */ jsx(
32
+ Control.Addon,
33
+ {
34
+ icon: PrefixIcon,
35
+ Content: Prefix,
36
+ onPress: onPressPrefix
37
+ }
38
+ ),
39
+ children,
40
+ /* @__PURE__ */ jsx(
41
+ Control.Addon,
42
+ {
43
+ icon: SuffixIcon,
44
+ Content: loading ? Control.Loader : Suffix,
45
+ onPress: onPressSuffix
46
+ }
47
+ )
48
+ ] }) }),
49
+ /* @__PURE__ */ jsx(Control.Error, {})
50
+ ] })
51
+ }
52
+ );
53
+ }
54
+ const SelectControl = memo(SelectControlComponent);
55
+ export {
56
+ SelectControl
57
+ };
58
+ //# sourceMappingURL=select-control.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/components/select-control.tsx"],"sourcesContent":["import { memo, PropsWithChildren, ReactElement } from \"react\";\n\nimport { Control, Pressable } from \"@impulse-ui-native/primitives\";\n\nimport { PrimitiveValue, SelectControlProps } from \"../types\";\n\nfunction SelectControlComponent<Value extends PrimitiveValue>(\n props: PropsWithChildren<SelectControlProps<Value>>,\n) {\n const {\n size = \"medium\",\n variant = \"outlined\",\n label,\n error,\n disabled,\n loading,\n PrefixIcon,\n Prefix,\n onPressPrefix,\n SuffixIcon,\n Suffix,\n onPressSuffix,\n onPress,\n children,\n } = props;\n\n return (\n <Control.Provider\n size={size}\n variant={variant}\n error={error}\n disabled={disabled}\n >\n <Control.Root>\n <Control.Label>{label}</Control.Label>\n <Pressable onPress={onPress}>\n <Control.Container>\n <Control.Addon\n icon={PrefixIcon}\n Content={Prefix}\n onPress={onPressPrefix}\n />\n {children}\n <Control.Addon\n icon={SuffixIcon}\n Content={loading ? Control.Loader : Suffix}\n onPress={onPressSuffix}\n />\n </Control.Container>\n </Pressable>\n <Control.Error />\n </Control.Root>\n </Control.Provider>\n );\n}\n\nexport const SelectControl = memo(SelectControlComponent) as <\n Value extends PrimitiveValue,\n>(\n props: PropsWithChildren<SelectControlProps<Value>>,\n) => ReactElement | null;\n"],"mappings":"AAkCQ,cAEE,YAFF;AAlCR,SAAS,YAA6C;AAEtD,SAAS,SAAS,iBAAiB;AAInC,SAAS,uBACP,OACA;AACA,QAAM;AAAA,IACJ,OAAO;AAAA,IACP,UAAU;AAAA,IACV;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF,IAAI;AAEJ,SACE;AAAA,IAAC,QAAQ;AAAA,IAAR;AAAA,MACC;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MAEA,+BAAC,QAAQ,MAAR,EACC;AAAA,4BAAC,QAAQ,OAAR,EAAe,iBAAM;AAAA,QACtB,oBAAC,aAAU,SACT,+BAAC,QAAQ,WAAR,EACC;AAAA;AAAA,YAAC,QAAQ;AAAA,YAAR;AAAA,cACC,MAAM;AAAA,cACN,SAAS;AAAA,cACT,SAAS;AAAA;AAAA,UACX;AAAA,UACC;AAAA,UACD;AAAA,YAAC,QAAQ;AAAA,YAAR;AAAA,cACC,MAAM;AAAA,cACN,SAAS,UAAU,QAAQ,SAAS;AAAA,cACpC,SAAS;AAAA;AAAA,UACX;AAAA,WACF,GACF;AAAA,QACA,oBAAC,QAAQ,OAAR,EAAc;AAAA,SACjB;AAAA;AAAA,EACF;AAEJ;AAEO,MAAM,gBAAgB,KAAK,sBAAsB;","names":[]}
@@ -0,0 +1,8 @@
1
+ import { ReactElement } from 'react';
2
+ import { PrimitiveValue, SelectProps } from '../types/select.types.mjs';
3
+ import '@impulse-ui-native/flyout';
4
+ import '@impulse-ui-native/primitives';
5
+
6
+ declare const Select: <Value extends PrimitiveValue>(props: SelectProps<Value>) => ReactElement | null;
7
+
8
+ export { Select };
@@ -0,0 +1,8 @@
1
+ import { ReactElement } from 'react';
2
+ import { PrimitiveValue, SelectFlyoutProps } from '../types/select.types.mjs';
3
+ import '@impulse-ui-native/flyout';
4
+ import '@impulse-ui-native/primitives';
5
+
6
+ declare const SelectFlyout: <Value extends PrimitiveValue>(props: SelectFlyoutProps<Value>) => ReactElement | null;
7
+
8
+ export { SelectFlyout };
@@ -0,0 +1,46 @@
1
+ import { jsx } from "react/jsx-runtime";
2
+ import { memo, useCallback } from "react";
3
+ import { FlatList } from "react-native";
4
+ import { Flyout } from "@impulse-ui-native/flyout";
5
+ import { Portal } from "@impulse-ui-native/portal";
6
+ import { View } from "@impulse-ui-native/primitives";
7
+ import { getOptionId } from "../utils";
8
+ import { Option } from "./option";
9
+ const SelectFlyoutComponent = function SelectFlyoutContent(props) {
10
+ const { options, isSelected, onSelect, ...rest } = props;
11
+ const renderItem = useCallback(
12
+ ({ item }) => {
13
+ return /* @__PURE__ */ jsx(
14
+ Option,
15
+ {
16
+ label: item.label,
17
+ onPress: () => onSelect(item.value),
18
+ disabled: item.disabled,
19
+ selected: isSelected(item.value)
20
+ }
21
+ );
22
+ },
23
+ [isSelected, onSelect]
24
+ );
25
+ return /* @__PURE__ */ jsx(Portal, { children: /* @__PURE__ */ jsx(Flyout, { ...rest, children: /* @__PURE__ */ jsx(View, { height: 300, children: /* @__PURE__ */ jsx(
26
+ FlatList,
27
+ {
28
+ data: options,
29
+ renderItem,
30
+ keyExtractor: getOptionId,
31
+ showsHorizontalScrollIndicator: false,
32
+ showsVerticalScrollIndicator: false,
33
+ keyboardShouldPersistTaps: "handled",
34
+ removeClippedSubviews: true,
35
+ windowSize: 5,
36
+ initialNumToRender: 12,
37
+ maxToRenderPerBatch: 12,
38
+ updateCellsBatchingPeriod: 32
39
+ }
40
+ ) }) }) });
41
+ };
42
+ const SelectFlyout = memo(SelectFlyoutComponent);
43
+ export {
44
+ SelectFlyout
45
+ };
46
+ //# sourceMappingURL=select.flyout.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/components/select.flyout.tsx"],"sourcesContent":["import { memo, ReactElement, useCallback } from \"react\";\nimport { FlatList, ListRenderItemInfo } from \"react-native\";\n\nimport { Flyout } from \"@impulse-ui-native/flyout\";\nimport { Portal } from \"@impulse-ui-native/portal\";\nimport { View } from \"@impulse-ui-native/primitives\";\n\nimport { PrimitiveValue, SelectFlyoutProps, SelectOption } from \"../types\";\nimport { getOptionId } from \"../utils\";\nimport { Option } from \"./option\";\n\nconst SelectFlyoutComponent = function SelectFlyoutContent<\n Value extends PrimitiveValue,\n>(props: SelectFlyoutProps<Value>) {\n const { options, isSelected, onSelect, ...rest } = props;\n\n const renderItem = useCallback(\n ({ item }: ListRenderItemInfo<SelectOption<Value>>) => {\n return (\n <Option\n label={item.label}\n onPress={() => onSelect(item.value)}\n disabled={item.disabled}\n selected={isSelected(item.value)}\n />\n );\n },\n [isSelected, onSelect],\n );\n\n return (\n <Portal>\n <Flyout {...rest}>\n <View height={300}>\n <FlatList\n data={options}\n renderItem={renderItem}\n keyExtractor={getOptionId}\n showsHorizontalScrollIndicator={false}\n showsVerticalScrollIndicator={false}\n keyboardShouldPersistTaps=\"handled\"\n removeClippedSubviews\n windowSize={5}\n initialNumToRender={12}\n maxToRenderPerBatch={12}\n updateCellsBatchingPeriod={32}\n />\n </View>\n </Flyout>\n </Portal>\n );\n};\n\nexport const SelectFlyout = memo(SelectFlyoutComponent) as <\n Value extends PrimitiveValue,\n>(\n props: SelectFlyoutProps<Value>,\n) => ReactElement | null;\n"],"mappings":"AAmBQ;AAnBR,SAAS,MAAoB,mBAAmB;AAChD,SAAS,gBAAoC;AAE7C,SAAS,cAAc;AACvB,SAAS,cAAc;AACvB,SAAS,YAAY;AAGrB,SAAS,mBAAmB;AAC5B,SAAS,cAAc;AAEvB,MAAM,wBAAwB,SAAS,oBAErC,OAAiC;AACjC,QAAM,EAAE,SAAS,YAAY,UAAU,GAAG,KAAK,IAAI;AAEnD,QAAM,aAAa;AAAA,IACjB,CAAC,EAAE,KAAK,MAA+C;AACrD,aACE;AAAA,QAAC;AAAA;AAAA,UACC,OAAO,KAAK;AAAA,UACZ,SAAS,MAAM,SAAS,KAAK,KAAK;AAAA,UAClC,UAAU,KAAK;AAAA,UACf,UAAU,WAAW,KAAK,KAAK;AAAA;AAAA,MACjC;AAAA,IAEJ;AAAA,IACA,CAAC,YAAY,QAAQ;AAAA,EACvB;AAEA,SACE,oBAAC,UACC,8BAAC,UAAQ,GAAG,MACV,8BAAC,QAAK,QAAQ,KACZ;AAAA,IAAC;AAAA;AAAA,MACC,MAAM;AAAA,MACN;AAAA,MACA,cAAc;AAAA,MACd,gCAAgC;AAAA,MAChC,8BAA8B;AAAA,MAC9B,2BAA0B;AAAA,MAC1B,uBAAqB;AAAA,MACrB,YAAY;AAAA,MACZ,oBAAoB;AAAA,MACpB,qBAAqB;AAAA,MACrB,2BAA2B;AAAA;AAAA,EAC7B,GACF,GACF,GACF;AAEJ;AAEO,MAAM,eAAe,KAAK,qBAAqB;","names":[]}
@@ -0,0 +1,46 @@
1
+ import { jsx, jsxs } from "react/jsx-runtime";
2
+ import { memo, useCallback, useId } from "react";
3
+ import { useIsOpen } from "@impulse-ui-native/core";
4
+ import { Control } from "@impulse-ui-native/primitives";
5
+ import { useSelect } from "../hooks/use-select.hook";
6
+ import { SelectControl } from "./select-control";
7
+ import { SelectFlyout } from "./select.flyout";
8
+ function SelectComponent(props) {
9
+ const { options, value, defaultValue, onChange, placeholder, ...rest } = props;
10
+ const { isOpen, open, close } = useIsOpen();
11
+ const id = useId();
12
+ const { selected, hasSelected, select, isSelected, getLabel } = useSelect({
13
+ options,
14
+ value,
15
+ defaultValue,
16
+ onChange
17
+ });
18
+ const handleOnSelect = useCallback(
19
+ (value2) => {
20
+ select(value2);
21
+ close();
22
+ },
23
+ [select, close]
24
+ );
25
+ return /* @__PURE__ */ jsxs(SelectControl, { ...rest, onPress: open, children: [
26
+ !hasSelected ? /* @__PURE__ */ jsx(Control.Placeholder, { children: placeholder }) : null,
27
+ selected !== null && selected !== void 0 ? /* @__PURE__ */ jsx(Control.Value, { children: getLabel(selected) }) : null,
28
+ /* @__PURE__ */ jsx(
29
+ SelectFlyout,
30
+ {
31
+ id,
32
+ title: "Options",
33
+ open: isOpen,
34
+ options,
35
+ isSelected,
36
+ onCloseFinished: close,
37
+ onSelect: handleOnSelect
38
+ }
39
+ )
40
+ ] });
41
+ }
42
+ const Select = memo(SelectComponent);
43
+ export {
44
+ Select
45
+ };
46
+ //# sourceMappingURL=select.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/components/select.tsx"],"sourcesContent":["import { memo, ReactElement, useCallback, useId } from \"react\";\n\nimport { useIsOpen } from \"@impulse-ui-native/core\";\nimport { Control } from \"@impulse-ui-native/primitives\";\n\nimport { useSelect } from \"../hooks/use-select.hook\";\nimport { PrimitiveValue, SelectProps } from \"../types\";\nimport { SelectControl } from \"./select-control\";\nimport { SelectFlyout } from \"./select.flyout\";\n\nfunction SelectComponent<Value extends PrimitiveValue>(\n props: SelectProps<Value>,\n) {\n const { options, value, defaultValue, onChange, placeholder, ...rest } =\n props;\n const { isOpen, open, close } = useIsOpen();\n\n const id = useId();\n\n const { selected, hasSelected, select, isSelected, getLabel } = useSelect({\n options,\n value,\n defaultValue,\n onChange,\n });\n\n const handleOnSelect = useCallback(\n (value: Value) => {\n select(value);\n close();\n },\n [select, close],\n );\n\n return (\n <SelectControl {...rest} onPress={open}>\n {!hasSelected ? (\n <Control.Placeholder>{placeholder}</Control.Placeholder>\n ) : null}\n {selected !== null && selected !== undefined ? (\n <Control.Value>{getLabel(selected)}</Control.Value>\n ) : null}\n <SelectFlyout\n id={id}\n title=\"Options\"\n open={isOpen}\n options={options}\n isSelected={isSelected}\n onCloseFinished={close}\n onSelect={handleOnSelect}\n />\n </SelectControl>\n );\n}\n\nexport const Select = memo(SelectComponent) as <Value extends PrimitiveValue>(\n props: SelectProps<Value>,\n) => ReactElement | null;\n"],"mappings":"AAmCI,SAEI,KAFJ;AAnCJ,SAAS,MAAoB,aAAa,aAAa;AAEvD,SAAS,iBAAiB;AAC1B,SAAS,eAAe;AAExB,SAAS,iBAAiB;AAE1B,SAAS,qBAAqB;AAC9B,SAAS,oBAAoB;AAE7B,SAAS,gBACP,OACA;AACA,QAAM,EAAE,SAAS,OAAO,cAAc,UAAU,aAAa,GAAG,KAAK,IACnE;AACF,QAAM,EAAE,QAAQ,MAAM,MAAM,IAAI,UAAU;AAE1C,QAAM,KAAK,MAAM;AAEjB,QAAM,EAAE,UAAU,aAAa,QAAQ,YAAY,SAAS,IAAI,UAAU;AAAA,IACxE;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF,CAAC;AAED,QAAM,iBAAiB;AAAA,IACrB,CAACA,WAAiB;AAChB,aAAOA,MAAK;AACZ,YAAM;AAAA,IACR;AAAA,IACA,CAAC,QAAQ,KAAK;AAAA,EAChB;AAEA,SACE,qBAAC,iBAAe,GAAG,MAAM,SAAS,MAC/B;AAAA,KAAC,cACA,oBAAC,QAAQ,aAAR,EAAqB,uBAAY,IAChC;AAAA,IACH,aAAa,QAAQ,aAAa,SACjC,oBAAC,QAAQ,OAAR,EAAe,mBAAS,QAAQ,GAAE,IACjC;AAAA,IACJ;AAAA,MAAC;AAAA;AAAA,QACC;AAAA,QACA,OAAM;AAAA,QACN,MAAM;AAAA,QACN;AAAA,QACA;AAAA,QACA,iBAAiB;AAAA,QACjB,UAAU;AAAA;AAAA,IACZ;AAAA,KACF;AAEJ;AAEO,MAAM,SAAS,KAAK,eAAe;","names":["value"]}
@@ -0,0 +1,3 @@
1
+ declare const temp = "";
2
+
3
+ export { temp };
@@ -0,0 +1,5 @@
1
+ const temp = "";
2
+ export {
3
+ temp
4
+ };
5
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/constants/index.ts"],"sourcesContent":["export const temp = \"\";\n"],"mappings":"AAAO,MAAM,OAAO;","names":[]}
@@ -0,0 +1,2 @@
1
+
2
+ export { }
@@ -0,0 +1 @@
1
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":[],"sourcesContent":[],"mappings":"","names":[]}
@@ -0,0 +1,13 @@
1
+ import { PrimitiveValue, UseSelectProps } from '../types/select.types.mjs';
2
+ import '@impulse-ui-native/flyout';
3
+ import '@impulse-ui-native/primitives';
4
+
5
+ declare function useMultiSelect<Value extends PrimitiveValue>(props: UseSelectProps<Value[]>): {
6
+ selected: Value[] | undefined;
7
+ hasSelected: boolean | undefined;
8
+ select: (value: Value) => void;
9
+ isSelected: (value: Value) => boolean;
10
+ getLabel: (value: Value) => string | undefined;
11
+ };
12
+
13
+ export { useMultiSelect };
@@ -0,0 +1,50 @@
1
+ import { useCallback, useMemo } from "react";
2
+ import { useControllableState } from "@impulse-ui-native/core";
3
+ import { buildLabelMap } from "../utils/option.utils";
4
+ function useMultiSelect(props) {
5
+ const { value, defaultValue, onChange } = props;
6
+ const [selected, setSelected] = useControllableState({
7
+ prop: value,
8
+ defaultProp: defaultValue,
9
+ onChange
10
+ });
11
+ const selectedValuesSet = useMemo(() => new Set(selected), [selected]);
12
+ const labelsMap = useMemo(
13
+ () => buildLabelMap(props.options),
14
+ [props.options]
15
+ );
16
+ const getLabel = useCallback(
17
+ (value2) => labelsMap[String(value2)],
18
+ [labelsMap]
19
+ );
20
+ const select = useCallback(
21
+ (value2) => {
22
+ setSelected((prev) => {
23
+ if (!prev) {
24
+ return [value2];
25
+ }
26
+ const exists = prev.includes(value2);
27
+ if (exists) {
28
+ return prev.filter((prevValue) => prevValue !== value2);
29
+ }
30
+ return [...prev, value2];
31
+ });
32
+ },
33
+ [setSelected]
34
+ );
35
+ const isSelected = useCallback(
36
+ (value2) => selectedValuesSet.has(value2),
37
+ [selectedValuesSet]
38
+ );
39
+ return {
40
+ selected,
41
+ hasSelected: selected && selected.length > 0,
42
+ select,
43
+ isSelected,
44
+ getLabel
45
+ };
46
+ }
47
+ export {
48
+ useMultiSelect
49
+ };
50
+ //# sourceMappingURL=use-multi-select.hook.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/hooks/use-multi-select.hook.ts"],"sourcesContent":["import { useCallback, useMemo } from \"react\";\n\nimport { useControllableState } from \"@impulse-ui-native/core\";\n\nimport { PrimitiveValue, UseSelectProps } from \"../types\";\nimport { buildLabelMap } from \"../utils/option.utils\";\n\nexport function useMultiSelect<Value extends PrimitiveValue>(\n props: UseSelectProps<Value[]>,\n) {\n const { value, defaultValue, onChange } = props;\n\n const [selected, setSelected] = useControllableState({\n prop: value,\n defaultProp: defaultValue,\n onChange,\n });\n\n const selectedValuesSet = useMemo(() => new Set(selected), [selected]);\n\n const labelsMap = useMemo(\n () => buildLabelMap(props.options),\n [props.options],\n );\n\n const getLabel = useCallback(\n (value: Value) => labelsMap[String(value)],\n [labelsMap],\n );\n\n const select = useCallback(\n (value: Value) => {\n setSelected((prev) => {\n if (!prev) {\n return [value];\n }\n\n const exists = prev.includes(value);\n\n if (exists) {\n return prev.filter((prevValue) => prevValue !== value);\n }\n\n return [...prev, value];\n });\n },\n [setSelected],\n );\n\n const isSelected = useCallback(\n (value: Value) => selectedValuesSet.has(value),\n [selectedValuesSet],\n );\n\n return {\n selected,\n hasSelected: selected && selected.length > 0,\n select,\n isSelected,\n getLabel,\n };\n}\n"],"mappings":"AAAA,SAAS,aAAa,eAAe;AAErC,SAAS,4BAA4B;AAGrC,SAAS,qBAAqB;AAEvB,SAAS,eACd,OACA;AACA,QAAM,EAAE,OAAO,cAAc,SAAS,IAAI;AAE1C,QAAM,CAAC,UAAU,WAAW,IAAI,qBAAqB;AAAA,IACnD,MAAM;AAAA,IACN,aAAa;AAAA,IACb;AAAA,EACF,CAAC;AAED,QAAM,oBAAoB,QAAQ,MAAM,IAAI,IAAI,QAAQ,GAAG,CAAC,QAAQ,CAAC;AAErE,QAAM,YAAY;AAAA,IAChB,MAAM,cAAc,MAAM,OAAO;AAAA,IACjC,CAAC,MAAM,OAAO;AAAA,EAChB;AAEA,QAAM,WAAW;AAAA,IACf,CAACA,WAAiB,UAAU,OAAOA,MAAK,CAAC;AAAA,IACzC,CAAC,SAAS;AAAA,EACZ;AAEA,QAAM,SAAS;AAAA,IACb,CAACA,WAAiB;AAChB,kBAAY,CAAC,SAAS;AACpB,YAAI,CAAC,MAAM;AACT,iBAAO,CAACA,MAAK;AAAA,QACf;AAEA,cAAM,SAAS,KAAK,SAASA,MAAK;AAElC,YAAI,QAAQ;AACV,iBAAO,KAAK,OAAO,CAAC,cAAc,cAAcA,MAAK;AAAA,QACvD;AAEA,eAAO,CAAC,GAAG,MAAMA,MAAK;AAAA,MACxB,CAAC;AAAA,IACH;AAAA,IACA,CAAC,WAAW;AAAA,EACd;AAEA,QAAM,aAAa;AAAA,IACjB,CAACA,WAAiB,kBAAkB,IAAIA,MAAK;AAAA,IAC7C,CAAC,iBAAiB;AAAA,EACpB;AAEA,SAAO;AAAA,IACL;AAAA,IACA,aAAa,YAAY,SAAS,SAAS;AAAA,IAC3C;AAAA,IACA;AAAA,IACA;AAAA,EACF;AACF;","names":["value"]}
@@ -0,0 +1,13 @@
1
+ import { PrimitiveValue, UseSelectProps } from '../types/select.types.mjs';
2
+ import '@impulse-ui-native/flyout';
3
+ import '@impulse-ui-native/primitives';
4
+
5
+ declare function useSelect<Value extends PrimitiveValue>(props: UseSelectProps<Value>): {
6
+ selected: Value | undefined;
7
+ hasSelected: boolean;
8
+ select: (value: Value) => void;
9
+ getLabel: (value: Value) => string | undefined;
10
+ isSelected: (value: Value) => boolean;
11
+ };
12
+
13
+ export { useSelect };
@@ -0,0 +1,45 @@
1
+ import { useCallback, useMemo } from "react";
2
+ import { useControllableState } from "@impulse-ui-native/core";
3
+ import { buildLabelMap } from "../utils/option.utils";
4
+ function useSelect(props) {
5
+ const { value, defaultValue, onChange } = props;
6
+ const [selected, setSelected] = useControllableState({
7
+ prop: value,
8
+ defaultProp: defaultValue,
9
+ onChange
10
+ });
11
+ const labelsMap = useMemo(
12
+ () => buildLabelMap(props.options),
13
+ [props.options]
14
+ );
15
+ const getLabel = useCallback(
16
+ (value2) => labelsMap[String(value2)],
17
+ [labelsMap]
18
+ );
19
+ const select = useCallback(
20
+ (value2) => {
21
+ setSelected((prev) => {
22
+ if (prev === value2) {
23
+ return null;
24
+ }
25
+ return value2;
26
+ });
27
+ },
28
+ [setSelected]
29
+ );
30
+ const isSelected = useCallback(
31
+ (value2) => value2 === selected,
32
+ [selected]
33
+ );
34
+ return {
35
+ selected,
36
+ hasSelected: selected !== null && selected !== void 0,
37
+ select,
38
+ getLabel,
39
+ isSelected
40
+ };
41
+ }
42
+ export {
43
+ useSelect
44
+ };
45
+ //# sourceMappingURL=use-select.hook.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/hooks/use-select.hook.ts"],"sourcesContent":["import { useCallback, useMemo } from \"react\";\n\nimport { useControllableState } from \"@impulse-ui-native/core\";\n\nimport { PrimitiveValue, UseSelectProps } from \"../types\";\nimport { buildLabelMap } from \"../utils/option.utils\";\n\nexport function useSelect<Value extends PrimitiveValue>(\n props: UseSelectProps<Value>,\n) {\n const { value, defaultValue, onChange } = props;\n\n const [selected, setSelected] = useControllableState({\n prop: value,\n defaultProp: defaultValue,\n onChange,\n });\n\n const labelsMap = useMemo(\n () => buildLabelMap(props.options),\n [props.options],\n );\n\n const getLabel = useCallback(\n (value: Value) => labelsMap[String(value)],\n [labelsMap],\n );\n\n const select = useCallback(\n (value: Value) => {\n setSelected((prev) => {\n if (prev === value) {\n return null as Value;\n }\n\n return value;\n });\n },\n [setSelected],\n );\n\n const isSelected = useCallback(\n (value: Value) => value === selected,\n [selected],\n );\n\n return {\n selected,\n hasSelected: selected !== null && selected !== undefined,\n select,\n getLabel,\n isSelected,\n };\n}\n"],"mappings":"AAAA,SAAS,aAAa,eAAe;AAErC,SAAS,4BAA4B;AAGrC,SAAS,qBAAqB;AAEvB,SAAS,UACd,OACA;AACA,QAAM,EAAE,OAAO,cAAc,SAAS,IAAI;AAE1C,QAAM,CAAC,UAAU,WAAW,IAAI,qBAAqB;AAAA,IACnD,MAAM;AAAA,IACN,aAAa;AAAA,IACb;AAAA,EACF,CAAC;AAED,QAAM,YAAY;AAAA,IAChB,MAAM,cAAc,MAAM,OAAO;AAAA,IACjC,CAAC,MAAM,OAAO;AAAA,EAChB;AAEA,QAAM,WAAW;AAAA,IACf,CAACA,WAAiB,UAAU,OAAOA,MAAK,CAAC;AAAA,IACzC,CAAC,SAAS;AAAA,EACZ;AAEA,QAAM,SAAS;AAAA,IACb,CAACA,WAAiB;AAChB,kBAAY,CAAC,SAAS;AACpB,YAAI,SAASA,QAAO;AAClB,iBAAO;AAAA,QACT;AAEA,eAAOA;AAAA,MACT,CAAC;AAAA,IACH;AAAA,IACA,CAAC,WAAW;AAAA,EACd;AAEA,QAAM,aAAa;AAAA,IACjB,CAACA,WAAiBA,WAAU;AAAA,IAC5B,CAAC,QAAQ;AAAA,EACX;AAEA,SAAO;AAAA,IACL;AAAA,IACA,aAAa,aAAa,QAAQ,aAAa;AAAA,IAC/C;AAAA,IACA;AAAA,IACA;AAAA,EACF;AACF;","names":["value"]}
package/dist/index.d.mts CHANGED
@@ -1,49 +1,6 @@
1
- import { ReactElement } from 'react';
2
- import { FlyoutProps } from '@impulse-ui-native/flyout';
3
- import { ControlComponentProps, ControlComponentCommonProps, PressableCoreProps } from '@impulse-ui-native/primitives';
4
-
5
- type PrimitiveValue = string | number | null | undefined;
6
- type SelectFn<Value extends PrimitiveValue> = (option: SelectOption<Value>) => void;
7
- type SelectOption<Value> = {
8
- label: string;
9
- value: Value;
10
- disabled?: boolean;
11
- };
12
- interface CommonSelectProps<Value> extends Partial<ControlComponentProps>, ControlComponentCommonProps {
13
- loading?: boolean;
14
- onChange?: (value: Value | undefined) => void;
15
- }
16
- interface SelectControlProps<Value> extends CommonSelectProps<Value> {
17
- onPress: PressableCoreProps["onPress"];
18
- }
19
- interface SelectProps<Value extends PrimitiveValue> extends CommonSelectProps<Value> {
20
- options: SelectOption<Value>[];
21
- value?: Value;
22
- defaultValue?: Value;
23
- }
24
- interface MultiSelectProps<Value extends PrimitiveValue> extends Partial<ControlComponentProps>, CommonSelectProps<Value[]> {
25
- options: SelectOption<Value>[];
26
- value?: Value[];
27
- defaultValue?: Value[];
28
- }
29
- interface SelectFlyoutProps<Value extends PrimitiveValue> extends FlyoutProps {
30
- options: SelectOption<Value>[];
31
- isSelected: (value: Value) => boolean;
32
- onSelect: (value: Value) => void;
33
- }
34
- interface OptionProps extends PressableCoreProps {
35
- label: string;
36
- selected: boolean;
37
- }
38
- interface UseSelectProps<Value> {
39
- options: SelectOption<PrimitiveValue>[];
40
- value?: Value;
41
- defaultValue?: Value;
42
- onChange?: (value: Value | undefined) => void;
43
- }
44
-
45
- declare const Select: <Value extends PrimitiveValue>(props: SelectProps<Value>) => ReactElement | null;
46
-
47
- declare const MultiSelect: <Value extends PrimitiveValue>(props: MultiSelectProps<Value>) => ReactElement | null;
48
-
49
- export { type CommonSelectProps, MultiSelect, type MultiSelectProps, type OptionProps, type PrimitiveValue, Select, type SelectControlProps, type SelectFlyoutProps, type SelectFn, type SelectOption, type SelectProps, type UseSelectProps };
1
+ export { Select } from './components/select.mjs';
2
+ export { MultiSelect } from './components/multi-select.mjs';
3
+ export { CommonSelectProps, MultiSelectProps, OptionProps, PrimitiveValue, SelectControlProps, SelectFlyoutProps, SelectFn, SelectOption, SelectProps, UseSelectProps } from './types/select.types.mjs';
4
+ import 'react';
5
+ import '@impulse-ui-native/flyout';
6
+ import '@impulse-ui-native/primitives';
package/dist/index.js CHANGED
@@ -1,337 +1,3 @@
1
- // src/components/select.tsx
2
- import { memo as memo4, useCallback as useCallback3, useId } from "react";
3
- import { useIsOpen } from "@impulse-ui-native/core";
4
- import { Control as Control2 } from "@impulse-ui-native/primitives";
5
-
6
- // src/hooks/use-select.hook.ts
7
- import { useCallback, useMemo } from "react";
8
- import { useControllableState } from "@impulse-ui-native/core";
9
-
10
- // src/utils/option.utils.ts
11
- function buildLabelMap(options) {
12
- return options.reduce((acc, current) => {
13
- if (current.value !== null && current.value !== void 0) {
14
- acc[String(current.value)] = current.label;
15
- return acc;
16
- }
17
- return acc;
18
- }, {});
19
- }
20
-
21
- // src/hooks/use-select.hook.ts
22
- function useSelect(props) {
23
- const { value, defaultValue, onChange } = props;
24
- const [selected, setSelected] = useControllableState({
25
- prop: value,
26
- defaultProp: defaultValue,
27
- onChange
28
- });
29
- const labelsMap = useMemo(
30
- () => buildLabelMap(props.options),
31
- [props.options]
32
- );
33
- const getLabel = useCallback(
34
- (value2) => labelsMap[String(value2)],
35
- [labelsMap]
36
- );
37
- const select = useCallback(
38
- (value2) => {
39
- setSelected((prev) => {
40
- if (prev === value2) {
41
- return null;
42
- }
43
- return value2;
44
- });
45
- },
46
- [setSelected]
47
- );
48
- const isSelected = useCallback(
49
- (value2) => value2 === selected,
50
- [selected]
51
- );
52
- return {
53
- selected,
54
- hasSelected: selected !== null && selected !== void 0,
55
- select,
56
- getLabel,
57
- isSelected
58
- };
59
- }
60
-
61
- // src/components/select-control.tsx
62
- import { memo } from "react";
63
- import { Control, Pressable } from "@impulse-ui-native/primitives";
64
- import { jsx, jsxs } from "react/jsx-runtime";
65
- function SelectControlComponent(props) {
66
- const {
67
- size = "medium",
68
- variant = "outlined",
69
- label,
70
- error,
71
- disabled,
72
- loading,
73
- PrefixIcon,
74
- Prefix,
75
- onPressPrefix,
76
- SuffixIcon,
77
- Suffix,
78
- onPressSuffix,
79
- onPress,
80
- children
81
- } = props;
82
- return /* @__PURE__ */ jsx(
83
- Control.Provider,
84
- {
85
- size,
86
- variant,
87
- error,
88
- disabled,
89
- children: /* @__PURE__ */ jsxs(Control.Root, { children: [
90
- /* @__PURE__ */ jsx(Control.Label, { children: label }),
91
- /* @__PURE__ */ jsx(Pressable, { onPress, children: /* @__PURE__ */ jsxs(Control.Container, { children: [
92
- /* @__PURE__ */ jsx(
93
- Control.Addon,
94
- {
95
- icon: PrefixIcon,
96
- Content: Prefix,
97
- onPress: onPressPrefix
98
- }
99
- ),
100
- children,
101
- /* @__PURE__ */ jsx(
102
- Control.Addon,
103
- {
104
- icon: SuffixIcon,
105
- Content: loading ? Control.Loader : Suffix,
106
- onPress: onPressSuffix
107
- }
108
- )
109
- ] }) }),
110
- /* @__PURE__ */ jsx(Control.Error, {})
111
- ] })
112
- }
113
- );
114
- }
115
- var SelectControl = memo(SelectControlComponent);
116
-
117
- // src/components/select.flyout.tsx
118
- import { memo as memo3, useCallback as useCallback2 } from "react";
119
- import { FlatList } from "react-native";
120
- import { Flyout } from "@impulse-ui-native/flyout";
121
- import { Portal } from "@impulse-ui-native/portal";
122
- import { View as View2 } from "@impulse-ui-native/primitives";
123
-
124
- // src/components/option.tsx
125
- import { memo as memo2 } from "react";
126
- import { CheckIcon, Icon } from "@impulse-ui-native/icon";
127
- import { Pressable as Pressable2, Typography, View } from "@impulse-ui-native/primitives";
128
- import { useComponentsTokens } from "@impulse-ui-native/theme";
129
- import { jsx as jsx2, jsxs as jsxs2 } from "react/jsx-runtime";
130
- var Option = memo2(function Option2(props) {
131
- const { label, selected, ...rest } = props;
132
- const tokens = useComponentsTokens();
133
- const optionTokens = tokens.select.option;
134
- return /* @__PURE__ */ jsx2(Pressable2, { ...rest, children: /* @__PURE__ */ jsxs2(
135
- View,
136
- {
137
- padding: optionTokens.padding,
138
- flexDirection: "row",
139
- alignItems: "center",
140
- justifyContent: "space-between",
141
- children: [
142
- /* @__PURE__ */ jsx2(Typography.Body, { children: label }),
143
- /* @__PURE__ */ jsx2(
144
- Icon,
145
- {
146
- icon: CheckIcon,
147
- color: optionTokens.selectedIconColor,
148
- opacity: selected ? optionTokens.selectedIconVisibleOpacity : optionTokens.selectedIconHiddenOpacity
149
- }
150
- )
151
- ]
152
- }
153
- ) });
154
- });
155
-
156
- // src/components/select.flyout.tsx
157
- import { jsx as jsx3 } from "react/jsx-runtime";
158
- var SelectFlyoutComponent = function SelectFlyoutContent(props) {
159
- const { options, isSelected, onSelect, ...rest } = props;
160
- const renderItem = useCallback2(
161
- ({ item }) => {
162
- return /* @__PURE__ */ jsx3(
163
- Option,
164
- {
165
- label: item.label,
166
- onPress: () => onSelect(item.value),
167
- disabled: item.disabled,
168
- selected: isSelected(item.value)
169
- }
170
- );
171
- },
172
- [isSelected, onSelect]
173
- );
174
- return /* @__PURE__ */ jsx3(Portal, { children: /* @__PURE__ */ jsx3(Flyout, { ...rest, children: /* @__PURE__ */ jsx3(View2, { height: 300, children: /* @__PURE__ */ jsx3(
175
- FlatList,
176
- {
177
- data: options,
178
- renderItem,
179
- keyExtractor: getOptionId2,
180
- showsHorizontalScrollIndicator: false,
181
- showsVerticalScrollIndicator: false,
182
- keyboardShouldPersistTaps: "handled",
183
- removeClippedSubviews: true,
184
- windowSize: 5,
185
- initialNumToRender: 12,
186
- maxToRenderPerBatch: 12,
187
- updateCellsBatchingPeriod: 32
188
- }
189
- ) }) }) });
190
- };
191
- var SelectFlyout = memo3(SelectFlyoutComponent);
192
-
193
- // src/components/select.tsx
194
- import { jsx as jsx4, jsxs as jsxs3 } from "react/jsx-runtime";
195
- function SelectComponent(props) {
196
- const { options, value, defaultValue, onChange, placeholder, ...rest } = props;
197
- const { isOpen, open, close } = useIsOpen();
198
- const id = useId();
199
- const { selected, hasSelected, select, isSelected, getLabel } = useSelect({
200
- options,
201
- value,
202
- defaultValue,
203
- onChange
204
- });
205
- const handleOnSelect = useCallback3(
206
- (value2) => {
207
- select(value2);
208
- close();
209
- },
210
- [select, close]
211
- );
212
- return /* @__PURE__ */ jsxs3(SelectControl, { ...rest, onPress: open, children: [
213
- !hasSelected ? /* @__PURE__ */ jsx4(Control2.Placeholder, { children: placeholder }) : null,
214
- selected !== null && selected !== void 0 ? /* @__PURE__ */ jsx4(Control2.Value, { children: getLabel(selected) }) : null,
215
- /* @__PURE__ */ jsx4(
216
- SelectFlyout,
217
- {
218
- id,
219
- title: "Options",
220
- open: isOpen,
221
- options,
222
- isSelected,
223
- onCloseFinished: close,
224
- onSelect: handleOnSelect
225
- }
226
- )
227
- ] });
228
- }
229
- var Select = memo4(SelectComponent);
230
-
231
- // src/components/multi-select.tsx
232
- import { memo as memo5, useId as useId2 } from "react";
233
- import { useIsOpen as useIsOpen2 } from "@impulse-ui-native/core";
234
- import { Control as Control3, Tag, View as View3 } from "@impulse-ui-native/primitives";
235
-
236
- // src/hooks/use-multi-select.hook.ts
237
- import { useCallback as useCallback4, useMemo as useMemo2 } from "react";
238
- import { useControllableState as useControllableState2 } from "@impulse-ui-native/core";
239
- function useMultiSelect(props) {
240
- const { value, defaultValue, onChange } = props;
241
- const [selected, setSelected] = useControllableState2({
242
- prop: value,
243
- defaultProp: defaultValue,
244
- onChange
245
- });
246
- const selectedValuesSet = useMemo2(() => new Set(selected), [selected]);
247
- const labelsMap = useMemo2(
248
- () => buildLabelMap(props.options),
249
- [props.options]
250
- );
251
- const getLabel = useCallback4(
252
- (value2) => labelsMap[String(value2)],
253
- [labelsMap]
254
- );
255
- const select = useCallback4(
256
- (value2) => {
257
- setSelected((prev) => {
258
- if (!prev) {
259
- return [value2];
260
- }
261
- const exists = prev.includes(value2);
262
- if (exists) {
263
- return prev.filter((prevValue) => prevValue !== value2);
264
- }
265
- return [...prev, value2];
266
- });
267
- },
268
- [setSelected]
269
- );
270
- const isSelected = useCallback4(
271
- (value2) => selectedValuesSet.has(value2),
272
- [selectedValuesSet]
273
- );
274
- return {
275
- selected,
276
- hasSelected: selected && selected.length > 0,
277
- select,
278
- isSelected,
279
- getLabel
280
- };
281
- }
282
-
283
- // src/components/multi-select.tsx
284
- import { jsx as jsx5, jsxs as jsxs4 } from "react/jsx-runtime";
285
- function MultiSelectComponent(props) {
286
- const { options, value, defaultValue, onChange, placeholder, ...rest } = props;
287
- const { isOpen, open, close } = useIsOpen2();
288
- const id = useId2();
289
- const { selected, hasSelected, select, isSelected, getLabel } = useMultiSelect({
290
- options,
291
- value,
292
- defaultValue,
293
- onChange
294
- });
295
- return /* @__PURE__ */ jsxs4(SelectControl, { ...rest, onPress: open, children: [
296
- !hasSelected ? /* @__PURE__ */ jsx5(Control3.Placeholder, { children: placeholder }) : null,
297
- hasSelected ? /* @__PURE__ */ jsx5(
298
- View3,
299
- {
300
- flex: 1,
301
- flexDirection: "row",
302
- gap: 4,
303
- marginHorizontal: 4,
304
- overflow: "hidden",
305
- children: selected ? selected.map((value2) => /* @__PURE__ */ jsx5(
306
- Tag,
307
- {
308
- variant: "filled",
309
- size: props.size,
310
- closable: true,
311
- onClose: () => select(value2),
312
- label: String(getLabel(value2))
313
- },
314
- value2
315
- )) : null
316
- }
317
- ) : null,
318
- /* @__PURE__ */ jsx5(
319
- SelectFlyout,
320
- {
321
- id,
322
- title: "Options",
323
- open: isOpen,
324
- options,
325
- isSelected,
326
- onCloseFinished: close,
327
- onSelect: select
328
- }
329
- )
330
- ] });
331
- }
332
- var MultiSelect = memo5(MultiSelectComponent);
333
- export {
334
- MultiSelect,
335
- Select
336
- };
1
+ export * from "./components";
2
+ export * from "./types";
337
3
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/components/select.tsx","../src/hooks/use-select.hook.ts","../src/utils/option.utils.ts","../src/components/select-control.tsx","../src/components/select.flyout.tsx","../src/components/option.tsx","../src/components/multi-select.tsx","../src/hooks/use-multi-select.hook.ts"],"sourcesContent":["import { memo, ReactElement, useCallback, useId } from \"react\";\r\n\r\nimport { useIsOpen } from \"@impulse-ui-native/core\";\r\nimport { Control } from \"@impulse-ui-native/primitives\";\r\n\r\nimport { useSelect } from \"../hooks/use-select.hook\";\r\nimport { PrimitiveValue, SelectProps } from \"../types\";\r\nimport { SelectControl } from \"./select-control\";\r\nimport { SelectFlyout } from \"./select.flyout\";\r\n\r\nfunction SelectComponent<Value extends PrimitiveValue>(\r\n props: SelectProps<Value>,\r\n) {\r\n const { options, value, defaultValue, onChange, placeholder, ...rest } =\r\n props;\r\n const { isOpen, open, close } = useIsOpen();\r\n\r\n const id = useId();\r\n\r\n const { selected, hasSelected, select, isSelected, getLabel } = useSelect({\r\n options,\r\n value,\r\n defaultValue,\r\n onChange,\r\n });\r\n\r\n const handleOnSelect = useCallback(\r\n (value: Value) => {\r\n select(value);\r\n close();\r\n },\r\n [select, close],\r\n );\r\n\r\n return (\r\n <SelectControl {...rest} onPress={open}>\r\n {!hasSelected ? (\r\n <Control.Placeholder>{placeholder}</Control.Placeholder>\r\n ) : null}\r\n {selected !== null && selected !== undefined ? (\r\n <Control.Value>{getLabel(selected)}</Control.Value>\r\n ) : null}\r\n <SelectFlyout\r\n id={id}\r\n title=\"Options\"\r\n open={isOpen}\r\n options={options}\r\n isSelected={isSelected}\r\n onCloseFinished={close}\r\n onSelect={handleOnSelect}\r\n />\r\n </SelectControl>\r\n );\r\n}\r\n\r\nexport const Select = memo(SelectComponent) as <Value extends PrimitiveValue>(\r\n props: SelectProps<Value>,\r\n) => ReactElement | null;\r\n","import { useCallback, useMemo } from \"react\";\r\n\r\nimport { useControllableState } from \"@impulse-ui-native/core\";\r\n\r\nimport { PrimitiveValue, UseSelectProps } from \"../types\";\r\nimport { buildLabelMap } from \"../utils/option.utils\";\r\n\r\nexport function useSelect<Value extends PrimitiveValue>(\r\n props: UseSelectProps<Value>,\r\n) {\r\n const { value, defaultValue, onChange } = props;\r\n\r\n const [selected, setSelected] = useControllableState({\r\n prop: value,\r\n defaultProp: defaultValue,\r\n onChange,\r\n });\r\n\r\n const labelsMap = useMemo(\r\n () => buildLabelMap(props.options),\r\n [props.options],\r\n );\r\n\r\n const getLabel = useCallback(\r\n (value: Value) => labelsMap[String(value)],\r\n [labelsMap],\r\n );\r\n\r\n const select = useCallback(\r\n (value: Value) => {\r\n setSelected((prev) => {\r\n if (prev === value) {\r\n return null as Value;\r\n }\r\n\r\n return value;\r\n });\r\n },\r\n [setSelected],\r\n );\r\n\r\n const isSelected = useCallback(\r\n (value: Value) => value === selected,\r\n [selected],\r\n );\r\n\r\n return {\r\n selected,\r\n hasSelected: selected !== null && selected !== undefined,\r\n select,\r\n getLabel,\r\n isSelected,\r\n };\r\n}\r\n","import { PrimitiveValue, SelectOption } from \"../../dist/index.mjs\";\r\n\r\nexport function buildLabelMap<Value extends PrimitiveValue>(\r\n options: SelectOption<Value>[],\r\n) {\r\n return options.reduce<Record<string, string>>((acc, current) => {\r\n if (current.value !== null && current.value !== undefined) {\r\n acc[String(current.value)] = current.label;\r\n\r\n return acc;\r\n }\r\n\r\n return acc;\r\n }, {});\r\n}\r\n","import { memo, PropsWithChildren, ReactElement } from \"react\";\r\n\r\nimport { Control, Pressable } from \"@impulse-ui-native/primitives\";\r\n\r\nimport { PrimitiveValue, SelectControlProps } from \"../types\";\r\n\r\nfunction SelectControlComponent<Value extends PrimitiveValue>(\r\n props: PropsWithChildren<SelectControlProps<Value>>,\r\n) {\r\n const {\r\n size = \"medium\",\r\n variant = \"outlined\",\r\n label,\r\n error,\r\n disabled,\r\n loading,\r\n PrefixIcon,\r\n Prefix,\r\n onPressPrefix,\r\n SuffixIcon,\r\n Suffix,\r\n onPressSuffix,\r\n onPress,\r\n children,\r\n } = props;\r\n\r\n return (\r\n <Control.Provider\r\n size={size}\r\n variant={variant}\r\n error={error}\r\n disabled={disabled}\r\n >\r\n <Control.Root>\r\n <Control.Label>{label}</Control.Label>\r\n <Pressable onPress={onPress}>\r\n <Control.Container>\r\n <Control.Addon\r\n icon={PrefixIcon}\r\n Content={Prefix}\r\n onPress={onPressPrefix}\r\n />\r\n {children}\r\n <Control.Addon\r\n icon={SuffixIcon}\r\n Content={loading ? Control.Loader : Suffix}\r\n onPress={onPressSuffix}\r\n />\r\n </Control.Container>\r\n </Pressable>\r\n <Control.Error />\r\n </Control.Root>\r\n </Control.Provider>\r\n );\r\n}\r\n\r\nexport const SelectControl = memo(SelectControlComponent) as <\r\n Value extends PrimitiveValue,\r\n>(\r\n props: PropsWithChildren<SelectControlProps<Value>>,\r\n) => ReactElement | null;\r\n","import { memo, ReactElement, useCallback } from \"react\";\r\nimport { FlatList, ListRenderItemInfo } from \"react-native\";\r\n\r\nimport { Flyout } from \"@impulse-ui-native/flyout\";\r\nimport { Portal } from \"@impulse-ui-native/portal\";\r\nimport { View } from \"@impulse-ui-native/primitives\";\r\n\r\nimport { PrimitiveValue, SelectFlyoutProps, SelectOption } from \"../types\";\r\nimport { getOptionId } from \"../utils\";\r\nimport { Option } from \"./option\";\r\n\r\nconst SelectFlyoutComponent = function SelectFlyoutContent<\r\n Value extends PrimitiveValue,\r\n>(props: SelectFlyoutProps<Value>) {\r\n const { options, isSelected, onSelect, ...rest } = props;\r\n\r\n const renderItem = useCallback(\r\n ({ item }: ListRenderItemInfo<SelectOption<Value>>) => {\r\n return (\r\n <Option\r\n label={item.label}\r\n onPress={() => onSelect(item.value)}\r\n disabled={item.disabled}\r\n selected={isSelected(item.value)}\r\n />\r\n );\r\n },\r\n [isSelected, onSelect],\r\n );\r\n\r\n return (\r\n <Portal>\r\n <Flyout {...rest}>\r\n <View height={300}>\r\n <FlatList\r\n data={options}\r\n renderItem={renderItem}\r\n keyExtractor={getOptionId}\r\n showsHorizontalScrollIndicator={false}\r\n showsVerticalScrollIndicator={false}\r\n keyboardShouldPersistTaps=\"handled\"\r\n removeClippedSubviews\r\n windowSize={5}\r\n initialNumToRender={12}\r\n maxToRenderPerBatch={12}\r\n updateCellsBatchingPeriod={32}\r\n />\r\n </View>\r\n </Flyout>\r\n </Portal>\r\n );\r\n};\r\n\r\nexport const SelectFlyout = memo(SelectFlyoutComponent) as <\r\n Value extends PrimitiveValue,\r\n>(\r\n props: SelectFlyoutProps<Value>,\r\n) => ReactElement | null;\r\n","import { memo } from \"react\";\r\n\r\nimport { CheckIcon, Icon } from \"@impulse-ui-native/icon\";\r\nimport { Pressable, Typography, View } from \"@impulse-ui-native/primitives\";\r\nimport { useComponentsTokens } from \"@impulse-ui-native/theme\";\r\n\r\nimport { OptionProps } from \"../types\";\r\n\r\nexport const Option = memo(function Option(props: OptionProps) {\r\n const { label, selected, ...rest } = props;\r\n\r\n const tokens = useComponentsTokens();\r\n const optionTokens = tokens.select.option;\r\n\r\n return (\r\n <Pressable {...rest}>\r\n <View\r\n padding={optionTokens.padding}\r\n flexDirection=\"row\"\r\n alignItems=\"center\"\r\n justifyContent=\"space-between\"\r\n >\r\n <Typography.Body>{label}</Typography.Body>\r\n\r\n <Icon\r\n icon={CheckIcon}\r\n color={optionTokens.selectedIconColor}\r\n opacity={\r\n selected\r\n ? optionTokens.selectedIconVisibleOpacity\r\n : optionTokens.selectedIconHiddenOpacity\r\n }\r\n />\r\n </View>\r\n </Pressable>\r\n );\r\n});\r\n","import { memo, ReactElement, useId } from \"react\";\r\n\r\nimport { useIsOpen } from \"@impulse-ui-native/core\";\r\nimport { Control, Tag, View } from \"@impulse-ui-native/primitives\";\r\n\r\nimport { useMultiSelect } from \"../hooks/use-multi-select.hook\";\r\nimport { MultiSelectProps, PrimitiveValue } from \"../types\";\r\nimport { SelectControl } from \"./select-control\";\r\nimport { SelectFlyout } from \"./select.flyout\";\r\n\r\nfunction MultiSelectComponent<Value extends PrimitiveValue>(\r\n props: MultiSelectProps<Value>,\r\n) {\r\n const { options, value, defaultValue, onChange, placeholder, ...rest } =\r\n props;\r\n const { isOpen, open, close } = useIsOpen();\r\n\r\n const id = useId();\r\n\r\n const { selected, hasSelected, select, isSelected, getLabel } =\r\n useMultiSelect({\r\n options,\r\n value,\r\n defaultValue,\r\n onChange,\r\n });\r\n\r\n return (\r\n <SelectControl {...rest} onPress={open}>\r\n {!hasSelected ? (\r\n <Control.Placeholder>{placeholder}</Control.Placeholder>\r\n ) : null}\r\n {hasSelected ? (\r\n <View\r\n flex={1}\r\n flexDirection=\"row\"\r\n gap={4}\r\n marginHorizontal={4}\r\n overflow=\"hidden\"\r\n >\r\n {selected\r\n ? selected.map((value) => (\r\n <Tag\r\n variant=\"filled\"\r\n size={props.size}\r\n key={value}\r\n closable\r\n onClose={() => select(value)}\r\n label={String(getLabel(value))}\r\n />\r\n ))\r\n : null}\r\n </View>\r\n ) : null}\r\n <SelectFlyout\r\n id={id}\r\n title=\"Options\"\r\n open={isOpen}\r\n options={options}\r\n isSelected={isSelected}\r\n onCloseFinished={close}\r\n onSelect={select}\r\n />\r\n </SelectControl>\r\n );\r\n}\r\n\r\nexport const MultiSelect = memo(MultiSelectComponent) as <\r\n Value extends PrimitiveValue,\r\n>(\r\n props: MultiSelectProps<Value>,\r\n) => ReactElement | null;\r\n","import { useCallback, useMemo } from \"react\";\r\n\r\nimport { useControllableState } from \"@impulse-ui-native/core\";\r\n\r\nimport { PrimitiveValue, UseSelectProps } from \"../types\";\r\nimport { buildLabelMap } from \"../utils/option.utils\";\r\n\r\nexport function useMultiSelect<Value extends PrimitiveValue>(\r\n props: UseSelectProps<Value[]>,\r\n) {\r\n const { value, defaultValue, onChange } = props;\r\n\r\n const [selected, setSelected] = useControllableState({\r\n prop: value,\r\n defaultProp: defaultValue,\r\n onChange,\r\n });\r\n\r\n const selectedValuesSet = useMemo(() => new Set(selected), [selected]);\r\n\r\n const labelsMap = useMemo(\r\n () => buildLabelMap(props.options),\r\n [props.options],\r\n );\r\n\r\n const getLabel = useCallback(\r\n (value: Value) => labelsMap[String(value)],\r\n [labelsMap],\r\n );\r\n\r\n const select = useCallback(\r\n (value: Value) => {\r\n setSelected((prev) => {\r\n if (!prev) {\r\n return [value];\r\n }\r\n\r\n const exists = prev.includes(value);\r\n\r\n if (exists) {\r\n return prev.filter((prevValue) => prevValue !== value);\r\n }\r\n\r\n return [...prev, value];\r\n });\r\n },\r\n [setSelected],\r\n );\r\n\r\n const isSelected = useCallback(\r\n (value: Value) => selectedValuesSet.has(value),\r\n [selectedValuesSet],\r\n );\r\n\r\n return {\r\n selected,\r\n hasSelected: selected && selected.length > 0,\r\n select,\r\n isSelected,\r\n getLabel,\r\n };\r\n}\r\n"],"mappings":"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","names":["memo","useCallback","Control","value","memo","useCallback","View","memo","Pressable","jsx","jsxs","Option","jsx","useCallback","View","getOptionId","memo","jsx","jsxs","useCallback","value","Control","memo","memo","useId","useIsOpen","Control","View","useCallback","useMemo","useControllableState","useControllableState","useMemo","useCallback","value","jsx","jsxs","useIsOpen","useId","Control","View","value","memo"]}
1
+ {"version":3,"sources":["../src/index.ts"],"sourcesContent":["export * from \"./components\";\nexport * from \"./types\";\n"],"mappings":"AAAA,cAAc;AACd,cAAc;","names":[]}
@@ -0,0 +1,3 @@
1
+ type PrimitiveValue = string | number;
2
+
3
+ export type { PrimitiveValue };
@@ -0,0 +1 @@
1
+ //# sourceMappingURL=common.types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":[],"sourcesContent":[],"mappings":"","names":[]}
@@ -0,0 +1,3 @@
1
+ export { CommonSelectProps, MultiSelectProps, OptionProps, PrimitiveValue, SelectControlProps, SelectFlyoutProps, SelectFn, SelectOption, SelectProps, UseSelectProps } from './select.types.mjs';
2
+ import '@impulse-ui-native/flyout';
3
+ import '@impulse-ui-native/primitives';
@@ -0,0 +1,2 @@
1
+ export * from "./select.types";
2
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/types/index.ts"],"sourcesContent":["export * from \"./select.types\";\n"],"mappings":"AAAA,cAAc;","names":[]}
@@ -0,0 +1,44 @@
1
+ import { FlyoutProps } from '@impulse-ui-native/flyout';
2
+ import { ControlComponentProps, ControlComponentCommonProps, PressableCoreProps } from '@impulse-ui-native/primitives';
3
+
4
+ type PrimitiveValue = string | number | null | undefined;
5
+ type SelectFn<Value extends PrimitiveValue> = (option: SelectOption<Value>) => void;
6
+ type SelectOption<Value> = {
7
+ label: string;
8
+ value: Value;
9
+ disabled?: boolean;
10
+ };
11
+ interface CommonSelectProps<Value> extends Partial<ControlComponentProps>, ControlComponentCommonProps {
12
+ loading?: boolean;
13
+ onChange?: (value: Value | undefined) => void;
14
+ }
15
+ interface SelectControlProps<Value> extends CommonSelectProps<Value> {
16
+ onPress: PressableCoreProps["onPress"];
17
+ }
18
+ interface SelectProps<Value extends PrimitiveValue> extends CommonSelectProps<Value> {
19
+ options: SelectOption<Value>[];
20
+ value?: Value;
21
+ defaultValue?: Value;
22
+ }
23
+ interface MultiSelectProps<Value extends PrimitiveValue> extends Partial<ControlComponentProps>, CommonSelectProps<Value[]> {
24
+ options: SelectOption<Value>[];
25
+ value?: Value[];
26
+ defaultValue?: Value[];
27
+ }
28
+ interface SelectFlyoutProps<Value extends PrimitiveValue> extends FlyoutProps {
29
+ options: SelectOption<Value>[];
30
+ isSelected: (value: Value) => boolean;
31
+ onSelect: (value: Value) => void;
32
+ }
33
+ interface OptionProps extends PressableCoreProps {
34
+ label: string;
35
+ selected: boolean;
36
+ }
37
+ interface UseSelectProps<Value> {
38
+ options: SelectOption<PrimitiveValue>[];
39
+ value?: Value;
40
+ defaultValue?: Value;
41
+ onChange?: (value: Value | undefined) => void;
42
+ }
43
+
44
+ export type { CommonSelectProps, MultiSelectProps, OptionProps, PrimitiveValue, SelectControlProps, SelectFlyoutProps, SelectFn, SelectOption, SelectProps, UseSelectProps };
@@ -0,0 +1 @@
1
+ //# sourceMappingURL=select.types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":[],"sourcesContent":[],"mappings":"","names":[]}
@@ -0,0 +1,4 @@
1
+ export { getOptionId } from './option.utils.mjs';
2
+ import '../types/select.types.mjs';
3
+ import '@impulse-ui-native/flyout';
4
+ import '@impulse-ui-native/primitives';
@@ -0,0 +1,5 @@
1
+ import { getOptionId } from "./option.utils";
2
+ export {
3
+ getOptionId
4
+ };
5
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/utils/index.ts"],"sourcesContent":["export { getOptionId } from \"./option.utils\";\n"],"mappings":"AAAA,SAAS,mBAAmB;","names":[]}
@@ -0,0 +1,8 @@
1
+ import { PrimitiveValue, SelectOption } from '../types/select.types.mjs';
2
+ import '@impulse-ui-native/flyout';
3
+ import '@impulse-ui-native/primitives';
4
+
5
+ declare function buildLabelMap<Value extends PrimitiveValue>(options: SelectOption<Value>[]): Record<string, string>;
6
+ declare function getOptionId<Value extends PrimitiveValue>(option: SelectOption<Value>, index: number): string;
7
+
8
+ export { buildLabelMap, getOptionId };
@@ -0,0 +1,17 @@
1
+ function buildLabelMap(options) {
2
+ return options.reduce((acc, current) => {
3
+ if (current.value !== null && current.value !== void 0) {
4
+ acc[String(current.value)] = current.label;
5
+ return acc;
6
+ }
7
+ return acc;
8
+ }, {});
9
+ }
10
+ function getOptionId(option, index) {
11
+ return option.value === null || option.value === void 0 ? `${option.label}-${index}` : String(option.value);
12
+ }
13
+ export {
14
+ buildLabelMap,
15
+ getOptionId
16
+ };
17
+ //# sourceMappingURL=option.utils.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/utils/option.utils.ts"],"sourcesContent":["import { PrimitiveValue, SelectOption } from \"../types\";\n\nexport function buildLabelMap<Value extends PrimitiveValue>(\n options: SelectOption<Value>[],\n) {\n return options.reduce<Record<string, string>>((acc, current) => {\n if (current.value !== null && current.value !== undefined) {\n acc[String(current.value)] = current.label;\n\n return acc;\n }\n\n return acc;\n }, {});\n}\n\nexport function getOptionId<Value extends PrimitiveValue>(\n option: SelectOption<Value>,\n index: number,\n): string {\n return option.value === null || option.value === undefined\n ? `${option.label}-${index}`\n : String(option.value);\n}\n"],"mappings":"AAEO,SAAS,cACd,SACA;AACA,SAAO,QAAQ,OAA+B,CAAC,KAAK,YAAY;AAC9D,QAAI,QAAQ,UAAU,QAAQ,QAAQ,UAAU,QAAW;AACzD,UAAI,OAAO,QAAQ,KAAK,CAAC,IAAI,QAAQ;AAErC,aAAO;AAAA,IACT;AAEA,WAAO;AAAA,EACT,GAAG,CAAC,CAAC;AACP;AAEO,SAAS,YACd,QACA,OACQ;AACR,SAAO,OAAO,UAAU,QAAQ,OAAO,UAAU,SAC7C,GAAG,OAAO,KAAK,IAAI,KAAK,KACxB,OAAO,OAAO,KAAK;AACzB;","names":[]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@impulse-ui-native/select",
3
- "version": "2.0.1",
3
+ "version": "2.1.1",
4
4
  "source": "src/index.ts",
5
5
  "module": "dist/index.js",
6
6
  "types": "dist/index.d.mts",
@@ -17,25 +17,26 @@
17
17
  "README.md",
18
18
  "LICENSE"
19
19
  ],
20
+ "sideEffects": false,
20
21
  "dependencies": {
21
- "@impulse-ui-native/theme": "2.0.1",
22
- "@impulse-ui-native/input": "2.0.1",
23
- "@impulse-ui-native/icon": "2.0.1",
24
- "@impulse-ui-native/layers": "2.0.1",
25
- "@impulse-ui-native/core": "2.0.1",
26
- "@impulse-ui-native/types": "2.0.1",
27
- "@impulse-ui-native/primitives": "2.0.1",
28
- "@impulse-ui-native/flyout": "2.0.1",
29
- "@impulse-ui-native/portal": "2.0.1"
22
+ "@impulse-ui-native/input": "2.1.1",
23
+ "@impulse-ui-native/primitives": "2.1.1",
24
+ "@impulse-ui-native/theme": "2.1.1",
25
+ "@impulse-ui-native/icon": "2.1.1",
26
+ "@impulse-ui-native/core": "2.1.1",
27
+ "@impulse-ui-native/flyout": "2.1.1",
28
+ "@impulse-ui-native/layers": "2.1.1",
29
+ "@impulse-ui-native/portal": "2.1.1",
30
+ "@impulse-ui-native/types": "2.1.1"
30
31
  },
31
32
  "devDependencies": {
32
33
  "@shopify/flash-list": "2.0.2",
33
34
  "@types/react": "~19.2.14",
34
35
  "eslint": "^9.38.0",
35
36
  "prettier": "^3.6.2",
36
- "react": "19.2.0",
37
- "react-native": "0.83.6",
38
- "typescript": "~5.9.2",
37
+ "react": "19.2.3",
38
+ "react-native": "0.86.2",
39
+ "typescript": "~6.0.3",
39
40
  "@impulse-ui-native/eslint-config": "1.0.0",
40
41
  "@impulse-ui-native/prettier-config": "1.0.0",
41
42
  "@impulse-ui-native/tsconfig": "1.0.0"