@yahoo/uds-mobile 2.22.0 → 2.23.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 (88) hide show
  1. package/dist/bin/automated-config/dist/generated/generatedConfigs.mjs +3127 -452
  2. package/dist/bin/uds-mobile.mjs +7 -7
  3. package/dist/components/Select/Select.cjs +194 -0
  4. package/dist/components/Select/Select.d.cts +47 -0
  5. package/dist/components/Select/Select.d.cts.map +1 -0
  6. package/dist/components/Select/Select.d.ts +47 -0
  7. package/dist/components/Select/Select.d.ts.map +1 -0
  8. package/dist/components/Select/Select.js +194 -0
  9. package/dist/components/Select/Select.js.map +1 -0
  10. package/dist/components/Select/SelectContent.cjs +148 -0
  11. package/dist/components/Select/SelectContent.d.cts +31 -0
  12. package/dist/components/Select/SelectContent.d.cts.map +1 -0
  13. package/dist/components/Select/SelectContent.d.ts +31 -0
  14. package/dist/components/Select/SelectContent.d.ts.map +1 -0
  15. package/dist/components/Select/SelectContent.js +147 -0
  16. package/dist/components/Select/SelectContent.js.map +1 -0
  17. package/dist/components/Select/SelectItem.cjs +138 -0
  18. package/dist/components/Select/SelectItem.d.cts +24 -0
  19. package/dist/components/Select/SelectItem.d.cts.map +1 -0
  20. package/dist/components/Select/SelectItem.d.ts +24 -0
  21. package/dist/components/Select/SelectItem.d.ts.map +1 -0
  22. package/dist/components/Select/SelectItem.js +137 -0
  23. package/dist/components/Select/SelectItem.js.map +1 -0
  24. package/dist/components/Select/SelectTrigger.cjs +140 -0
  25. package/dist/components/Select/SelectTrigger.d.cts +13 -0
  26. package/dist/components/Select/SelectTrigger.d.cts.map +1 -0
  27. package/dist/components/Select/SelectTrigger.d.ts +13 -0
  28. package/dist/components/Select/SelectTrigger.d.ts.map +1 -0
  29. package/dist/components/Select/SelectTrigger.js +139 -0
  30. package/dist/components/Select/SelectTrigger.js.map +1 -0
  31. package/dist/components/Select/index.cjs +8 -0
  32. package/dist/components/Select/index.d.cts +5 -0
  33. package/dist/components/Select/index.d.ts +5 -0
  34. package/dist/components/Select/index.js +5 -0
  35. package/dist/components/Select/selectContext.cjs +22 -0
  36. package/dist/components/Select/selectContext.d.cts +12 -0
  37. package/dist/components/Select/selectContext.d.cts.map +1 -0
  38. package/dist/components/Select/selectContext.d.ts +12 -0
  39. package/dist/components/Select/selectContext.d.ts.map +1 -0
  40. package/dist/components/Select/selectContext.js +19 -0
  41. package/dist/components/Select/selectContext.js.map +1 -0
  42. package/dist/components/Select/selectItemTheme.cjs +39 -0
  43. package/dist/components/Select/selectItemTheme.d.cts +19 -0
  44. package/dist/components/Select/selectItemTheme.d.cts.map +1 -0
  45. package/dist/components/Select/selectItemTheme.d.ts +19 -0
  46. package/dist/components/Select/selectItemTheme.d.ts.map +1 -0
  47. package/dist/components/Select/selectItemTheme.js +39 -0
  48. package/dist/components/Select/selectItemTheme.js.map +1 -0
  49. package/dist/components/Select/types.cjs +1 -0
  50. package/dist/components/Select/types.d.cts +43 -0
  51. package/dist/components/Select/types.d.cts.map +1 -0
  52. package/dist/components/Select/types.d.ts +43 -0
  53. package/dist/components/Select/types.d.ts.map +1 -0
  54. package/dist/components/Select/types.js +1 -0
  55. package/dist/components/Text.cjs +15 -3
  56. package/dist/components/Text.d.cts +2 -2
  57. package/dist/components/Text.d.cts.map +1 -1
  58. package/dist/components/Text.d.ts +2 -2
  59. package/dist/components/Text.d.ts.map +1 -1
  60. package/dist/components/Text.js +15 -3
  61. package/dist/components/Text.js.map +1 -1
  62. package/dist/components/internal/Overlay/index.cjs +2 -0
  63. package/dist/components/internal/Overlay/index.d.cts +2 -1
  64. package/dist/components/internal/Overlay/index.d.ts +2 -1
  65. package/dist/components/internal/Overlay/index.js +2 -1
  66. package/dist/components/internal/Overlay/measureTrigger.cjs +35 -0
  67. package/dist/components/internal/Overlay/measureTrigger.d.cts +9 -0
  68. package/dist/components/internal/Overlay/measureTrigger.d.cts.map +1 -0
  69. package/dist/components/internal/Overlay/measureTrigger.d.ts +9 -0
  70. package/dist/components/internal/Overlay/measureTrigger.d.ts.map +1 -0
  71. package/dist/components/internal/Overlay/measureTrigger.js +36 -0
  72. package/dist/components/internal/Overlay/measureTrigger.js.map +1 -0
  73. package/dist/jest/mocks/styles.cjs +47 -1
  74. package/dist/jest/mocks/styles.d.cts +5 -2
  75. package/dist/jest/mocks/styles.d.cts.map +1 -1
  76. package/dist/jest/mocks/styles.d.ts +5 -2
  77. package/dist/jest/mocks/styles.d.ts.map +1 -1
  78. package/dist/jest/mocks/styles.js +45 -2
  79. package/dist/jest/mocks/styles.js.map +1 -1
  80. package/dist/types/dist/index.d.cts +28 -1
  81. package/dist/types/dist/index.d.cts.map +1 -1
  82. package/dist/types/dist/index.d.ts +28 -1
  83. package/dist/types/dist/index.d.ts.map +1 -1
  84. package/generated/styles.cjs +125 -0
  85. package/generated/styles.d.ts +39 -0
  86. package/generated/styles.mjs +125 -0
  87. package/generated/unistyles.d.ts +108 -8
  88. package/package.json +11 -1
@@ -97,13 +97,6 @@ async function loadConfigFromFile(configPath) {
97
97
  const moduleUrl = pathToFileURL(absolutePath).href;
98
98
  log(`Loading config from: ${configPath}`, "dim");
99
99
  const configModule = await import(moduleUrl);
100
- for (const key in configModule) if (key.endsWith("Config") || key === "default") {
101
- const config = configModule[key];
102
- if (config && typeof config === "object") {
103
- logStep("Found", `config export: ${key}`);
104
- return config;
105
- }
106
- }
107
100
  for (const name of [
108
101
  "config",
109
102
  "tokens",
@@ -113,6 +106,13 @@ async function loadConfigFromFile(configPath) {
113
106
  logStep("Found", `config export: ${name}`);
114
107
  return configModule[name];
115
108
  }
109
+ for (const key in configModule) if (key.endsWith("Config") || key === "default") {
110
+ const config = configModule[key];
111
+ if (config && typeof config === "object") {
112
+ logStep("Found", `config export: ${key}`);
113
+ return config;
114
+ }
115
+ }
116
116
  throw new Error(`No config export found in ${configPath}. Expected an export ending with "Config" or a default export.`);
117
117
  }
118
118
  async function runSync(opts = {}) {
@@ -0,0 +1,194 @@
1
+ /*! © 2026 Yahoo, Inc. UDS Mobile v0.0.0-development */
2
+ Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
3
+ require("../../_virtual/_rolldown/runtime.cjs");
4
+ const require_components_HStack = require("../HStack.cjs");
5
+ const require_components_Text = require("../Text.cjs");
6
+ const require_components_InputHelpText = require("../InputHelpText.cjs");
7
+ const require_components_VStack = require("../VStack.cjs");
8
+ const require_components_internal_Overlay_useControllableState = require("../internal/Overlay/useControllableState.cjs");
9
+ const require_components_Select_selectContext = require("./selectContext.cjs");
10
+ const require_components_Select_SelectTrigger = require("./SelectTrigger.cjs");
11
+ let react = require("react");
12
+ let react_jsx_runtime = require("react/jsx-runtime");
13
+ let generated_styles = require("../../../generated/styles");
14
+ let lodash_es = require("lodash-es");
15
+ //#region src/components/Select/Select.tsx
16
+ /**
17
+ * **⚙️ A composable Select component**
18
+ *
19
+ * @description
20
+ * Select lets users pick one value from a list. Compose with `SelectContent` and
21
+ * `SelectItem`, similar to `Tabs` with `TabList` and `Tab`.
22
+ *
23
+ * @category Form
24
+ * @platform mobile
25
+ *
26
+ * @example
27
+ * ```tsx
28
+ * import { Select, SelectContent, SelectItem } from '@yahoo/uds-mobile/Select';
29
+ *
30
+ * <Select label="Country" placeholder="Select a country" defaultValue="us">
31
+ * <SelectContent>
32
+ * <SelectItem value="us">United States</SelectItem>
33
+ * <SelectItem value="ca">Canada</SelectItem>
34
+ * </SelectContent>
35
+ * </Select>
36
+ * ```
37
+ */
38
+ const Select = (0, react.memo)(function Select({ label, helpText, helperTextIcon, placeholder, size = "md", disabled, required, hasError, readOnly, width = "100%", reduceMotion = false, startIcon, endIcon, value: valueProp, defaultValue = "", onChange, children, testID }) {
39
+ const uid = `uds-select-${(0, react.useId)()}`;
40
+ const triggerRef = (0, react.useRef)(null);
41
+ const [triggerRect, setTriggerRect] = (0, react.useState)(null);
42
+ const [highlightedValue, setHighlightedValue] = (0, react.useState)(null);
43
+ const itemsRef = (0, react.useRef)(/* @__PURE__ */ new Map());
44
+ const [, setItemsVersion] = (0, react.useState)(0);
45
+ const [value, setValue] = require_components_internal_Overlay_useControllableState.useControllableState({
46
+ value: valueProp,
47
+ defaultValue,
48
+ onChange
49
+ });
50
+ const [open, setOpen] = require_components_internal_Overlay_useControllableState.useControllableState({
51
+ defaultValue: false,
52
+ onChange: (nextOpen) => {
53
+ if (!nextOpen) setHighlightedValue(null);
54
+ }
55
+ });
56
+ const registerItem = (0, react.useCallback)((itemValue, itemLabel) => {
57
+ if (itemsRef.current.get(itemValue) === itemLabel) return;
58
+ itemsRef.current.set(itemValue, itemLabel);
59
+ setItemsVersion((version) => version + 1);
60
+ }, []);
61
+ const unregisterItem = (0, react.useCallback)((itemValue) => {
62
+ if (!itemsRef.current.has(itemValue)) return;
63
+ itemsRef.current.delete(itemValue);
64
+ setItemsVersion((version) => version + 1);
65
+ }, []);
66
+ const getItemLabel = (0, react.useCallback)((itemValue) => itemsRef.current.get(itemValue), []);
67
+ const fieldContext = (0, react.useMemo)(() => ({
68
+ size,
69
+ disabled,
70
+ readOnly,
71
+ required,
72
+ hasError,
73
+ width,
74
+ reduceMotion,
75
+ placeholder,
76
+ uid
77
+ }), [
78
+ disabled,
79
+ hasError,
80
+ placeholder,
81
+ readOnly,
82
+ reduceMotion,
83
+ required,
84
+ size,
85
+ uid,
86
+ width
87
+ ]);
88
+ const contextValue = (0, react.useMemo)(() => ({
89
+ value,
90
+ setValue,
91
+ open,
92
+ setOpen,
93
+ triggerRef,
94
+ triggerRect,
95
+ setTriggerRect,
96
+ registerItem,
97
+ unregisterItem,
98
+ getItemLabel,
99
+ highlightedValue,
100
+ setHighlightedValue,
101
+ field: fieldContext,
102
+ reduceMotion
103
+ }), [
104
+ fieldContext,
105
+ getItemLabel,
106
+ highlightedValue,
107
+ open,
108
+ reduceMotion,
109
+ registerItem,
110
+ setOpen,
111
+ setValue,
112
+ triggerRect,
113
+ unregisterItem,
114
+ value
115
+ ]);
116
+ const valueState = value.length > 0 ? "filled" : "empty";
117
+ generated_styles.inputStyles.useVariants({
118
+ size,
119
+ value: valueState,
120
+ pressed: open,
121
+ readonly: readOnly,
122
+ invalid: hasError
123
+ });
124
+ const rootStyle = (0, react.useMemo)(() => [{
125
+ width,
126
+ opacity: disabled ? .5 : 1
127
+ }], [disabled, width]);
128
+ const labelContent = (0, react.useMemo)(() => {
129
+ if (!label) return null;
130
+ const content = (0, lodash_es.isFunction)(label) ? label() : label;
131
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(require_components_HStack.HStack, {
132
+ columnGap: "1",
133
+ alignItems: "flex-end",
134
+ spacingBottom: "2",
135
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_components_Text.Text, {
136
+ style: generated_styles.inputStyles.label,
137
+ children: content
138
+ }), required && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_components_Text.Text, {
139
+ style: generated_styles.inputStyles.labelRequired,
140
+ children: "*"
141
+ })]
142
+ });
143
+ }, [
144
+ label,
145
+ required,
146
+ generated_styles.inputStyles.label,
147
+ generated_styles.inputStyles.labelRequired
148
+ ]);
149
+ const helpTextContent = (0, react.useMemo)(() => {
150
+ if (!helpText) return null;
151
+ const content = (0, lodash_es.isFunction)(helpText) ? helpText() : helpText;
152
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_components_InputHelpText.InputHelpText, {
153
+ startIcon: helperTextIcon,
154
+ size,
155
+ isFilled: valueState === "filled",
156
+ disabled,
157
+ readOnly,
158
+ hasError,
159
+ pressed: open,
160
+ children: content
161
+ });
162
+ }, [
163
+ disabled,
164
+ hasError,
165
+ helpText,
166
+ helperTextIcon,
167
+ open,
168
+ readOnly,
169
+ size,
170
+ valueState
171
+ ]);
172
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_components_Select_selectContext.SelectContext.Provider, {
173
+ value: contextValue,
174
+ children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_components_Select_selectContext.SelectFieldContext.Provider, {
175
+ value: fieldContext,
176
+ children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(require_components_VStack.VStack, {
177
+ testID,
178
+ style: rootStyle,
179
+ children: [
180
+ labelContent,
181
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_components_Select_SelectTrigger.SelectTrigger, {
182
+ startIcon,
183
+ endIcon
184
+ }),
185
+ helpTextContent,
186
+ children
187
+ ]
188
+ })
189
+ })
190
+ });
191
+ });
192
+ Select.displayName = "Select";
193
+ //#endregion
194
+ exports.Select = Select;
@@ -0,0 +1,47 @@
1
+
2
+ import { UniversalSelectProps } from "../../types/dist/index.cjs";
3
+ import { IconSlotType } from "../IconSlot.cjs";
4
+ import * as _$react from "react";
5
+ import { ReactNode } from "react";
6
+
7
+ //#region src/components/Select/Select.d.ts
8
+ interface SelectProps extends Omit<UniversalSelectProps<IconSlotType>, 'width'> {
9
+ /** Placeholder text shown when no value is selected. */
10
+ placeholder?: string;
11
+ /** Selected value for controlled usage. */
12
+ value?: string;
13
+ /** Initial value for uncontrolled usage. @default '' */
14
+ defaultValue?: string;
15
+ /** Called when the selected value changes. */
16
+ onChange?: (value: string) => void;
17
+ /** Container width. @default '100%' */
18
+ width?: number | `${number}%` | '100%';
19
+ children?: ReactNode;
20
+ testID?: string;
21
+ }
22
+ /**
23
+ * **⚙️ A composable Select component**
24
+ *
25
+ * @description
26
+ * Select lets users pick one value from a list. Compose with `SelectContent` and
27
+ * `SelectItem`, similar to `Tabs` with `TabList` and `Tab`.
28
+ *
29
+ * @category Form
30
+ * @platform mobile
31
+ *
32
+ * @example
33
+ * ```tsx
34
+ * import { Select, SelectContent, SelectItem } from '@yahoo/uds-mobile/Select';
35
+ *
36
+ * <Select label="Country" placeholder="Select a country" defaultValue="us">
37
+ * <SelectContent>
38
+ * <SelectItem value="us">United States</SelectItem>
39
+ * <SelectItem value="ca">Canada</SelectItem>
40
+ * </SelectContent>
41
+ * </Select>
42
+ * ```
43
+ */
44
+ declare const Select: _$react.NamedExoticComponent<SelectProps>;
45
+ //#endregion
46
+ export { Select, type SelectProps };
47
+ //# sourceMappingURL=Select.d.cts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Select.d.cts","names":[],"sources":["../../../src/components/Select/Select.tsx"],"mappings":";;;;;;;UAiBU,WAAA,SAAoB,IAAA,CAAK,oBAAA,CAAqB,YAAA;;EAEtD,WAAA;EAFQ;EAIR,KAAA;;EAEA,YAAA;EANiC;EAQjC,QAAA,IAAY,KAAA;EARgB;EAU5B,KAAA;EACA,QAAA,GAAW,SAAA;EACX,MAAA;AAAA;;;;;;;;;;;;;AAAM;;;;;;;;;;cAyBF,MAAA,EAAM,OAAA,CAAA,oBAAA,CAAA,WAAA"}
@@ -0,0 +1,47 @@
1
+
2
+ import { UniversalSelectProps } from "../../types/dist/index.js";
3
+ import { IconSlotType } from "../IconSlot.js";
4
+ import * as _$react from "react";
5
+ import { ReactNode } from "react";
6
+
7
+ //#region src/components/Select/Select.d.ts
8
+ interface SelectProps extends Omit<UniversalSelectProps<IconSlotType>, 'width'> {
9
+ /** Placeholder text shown when no value is selected. */
10
+ placeholder?: string;
11
+ /** Selected value for controlled usage. */
12
+ value?: string;
13
+ /** Initial value for uncontrolled usage. @default '' */
14
+ defaultValue?: string;
15
+ /** Called when the selected value changes. */
16
+ onChange?: (value: string) => void;
17
+ /** Container width. @default '100%' */
18
+ width?: number | `${number}%` | '100%';
19
+ children?: ReactNode;
20
+ testID?: string;
21
+ }
22
+ /**
23
+ * **⚙️ A composable Select component**
24
+ *
25
+ * @description
26
+ * Select lets users pick one value from a list. Compose with `SelectContent` and
27
+ * `SelectItem`, similar to `Tabs` with `TabList` and `Tab`.
28
+ *
29
+ * @category Form
30
+ * @platform mobile
31
+ *
32
+ * @example
33
+ * ```tsx
34
+ * import { Select, SelectContent, SelectItem } from '@yahoo/uds-mobile/Select';
35
+ *
36
+ * <Select label="Country" placeholder="Select a country" defaultValue="us">
37
+ * <SelectContent>
38
+ * <SelectItem value="us">United States</SelectItem>
39
+ * <SelectItem value="ca">Canada</SelectItem>
40
+ * </SelectContent>
41
+ * </Select>
42
+ * ```
43
+ */
44
+ declare const Select: _$react.NamedExoticComponent<SelectProps>;
45
+ //#endregion
46
+ export { Select, type SelectProps };
47
+ //# sourceMappingURL=Select.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Select.d.ts","names":[],"sources":["../../../src/components/Select/Select.tsx"],"mappings":";;;;;;;UAiBU,WAAA,SAAoB,IAAA,CAAK,oBAAA,CAAqB,YAAA;;EAEtD,WAAA;EAFQ;EAIR,KAAA;;EAEA,YAAA;EANiC;EAQjC,QAAA,IAAY,KAAA;EARgB;EAU5B,KAAA;EACA,QAAA,GAAW,SAAA;EACX,MAAA;AAAA;;;;;;;;;;;;;AAAM;;;;;;;;;;cAyBF,MAAA,EAAM,OAAA,CAAA,oBAAA,CAAA,WAAA"}
@@ -0,0 +1,194 @@
1
+ /*! © 2026 Yahoo, Inc. UDS Mobile v0.0.0-development */
2
+ import { HStack } from "../HStack.js";
3
+ import { Text } from "../Text.js";
4
+ import { InputHelpText } from "../InputHelpText.js";
5
+ import { VStack } from "../VStack.js";
6
+ import { useControllableState } from "../internal/Overlay/useControllableState.js";
7
+ import { SelectContext, SelectFieldContext } from "./selectContext.js";
8
+ import { SelectTrigger } from "./SelectTrigger.js";
9
+ import { memo, useCallback, useId, useMemo, useRef, useState } from "react";
10
+ import { jsx, jsxs } from "react/jsx-runtime";
11
+ import { inputStyles } from "../../../generated/styles";
12
+ import { isFunction } from "lodash-es";
13
+ //#region src/components/Select/Select.tsx
14
+ /**
15
+ * **⚙️ A composable Select component**
16
+ *
17
+ * @description
18
+ * Select lets users pick one value from a list. Compose with `SelectContent` and
19
+ * `SelectItem`, similar to `Tabs` with `TabList` and `Tab`.
20
+ *
21
+ * @category Form
22
+ * @platform mobile
23
+ *
24
+ * @example
25
+ * ```tsx
26
+ * import { Select, SelectContent, SelectItem } from '@yahoo/uds-mobile/Select';
27
+ *
28
+ * <Select label="Country" placeholder="Select a country" defaultValue="us">
29
+ * <SelectContent>
30
+ * <SelectItem value="us">United States</SelectItem>
31
+ * <SelectItem value="ca">Canada</SelectItem>
32
+ * </SelectContent>
33
+ * </Select>
34
+ * ```
35
+ */
36
+ const Select = memo(function Select({ label, helpText, helperTextIcon, placeholder, size = "md", disabled, required, hasError, readOnly, width = "100%", reduceMotion = false, startIcon, endIcon, value: valueProp, defaultValue = "", onChange, children, testID }) {
37
+ const uid = `uds-select-${useId()}`;
38
+ const triggerRef = useRef(null);
39
+ const [triggerRect, setTriggerRect] = useState(null);
40
+ const [highlightedValue, setHighlightedValue] = useState(null);
41
+ const itemsRef = useRef(/* @__PURE__ */ new Map());
42
+ const [, setItemsVersion] = useState(0);
43
+ const [value, setValue] = useControllableState({
44
+ value: valueProp,
45
+ defaultValue,
46
+ onChange
47
+ });
48
+ const [open, setOpen] = useControllableState({
49
+ defaultValue: false,
50
+ onChange: (nextOpen) => {
51
+ if (!nextOpen) setHighlightedValue(null);
52
+ }
53
+ });
54
+ const registerItem = useCallback((itemValue, itemLabel) => {
55
+ if (itemsRef.current.get(itemValue) === itemLabel) return;
56
+ itemsRef.current.set(itemValue, itemLabel);
57
+ setItemsVersion((version) => version + 1);
58
+ }, []);
59
+ const unregisterItem = useCallback((itemValue) => {
60
+ if (!itemsRef.current.has(itemValue)) return;
61
+ itemsRef.current.delete(itemValue);
62
+ setItemsVersion((version) => version + 1);
63
+ }, []);
64
+ const getItemLabel = useCallback((itemValue) => itemsRef.current.get(itemValue), []);
65
+ const fieldContext = useMemo(() => ({
66
+ size,
67
+ disabled,
68
+ readOnly,
69
+ required,
70
+ hasError,
71
+ width,
72
+ reduceMotion,
73
+ placeholder,
74
+ uid
75
+ }), [
76
+ disabled,
77
+ hasError,
78
+ placeholder,
79
+ readOnly,
80
+ reduceMotion,
81
+ required,
82
+ size,
83
+ uid,
84
+ width
85
+ ]);
86
+ const contextValue = useMemo(() => ({
87
+ value,
88
+ setValue,
89
+ open,
90
+ setOpen,
91
+ triggerRef,
92
+ triggerRect,
93
+ setTriggerRect,
94
+ registerItem,
95
+ unregisterItem,
96
+ getItemLabel,
97
+ highlightedValue,
98
+ setHighlightedValue,
99
+ field: fieldContext,
100
+ reduceMotion
101
+ }), [
102
+ fieldContext,
103
+ getItemLabel,
104
+ highlightedValue,
105
+ open,
106
+ reduceMotion,
107
+ registerItem,
108
+ setOpen,
109
+ setValue,
110
+ triggerRect,
111
+ unregisterItem,
112
+ value
113
+ ]);
114
+ const valueState = value.length > 0 ? "filled" : "empty";
115
+ inputStyles.useVariants({
116
+ size,
117
+ value: valueState,
118
+ pressed: open,
119
+ readonly: readOnly,
120
+ invalid: hasError
121
+ });
122
+ const rootStyle = useMemo(() => [{
123
+ width,
124
+ opacity: disabled ? .5 : 1
125
+ }], [disabled, width]);
126
+ const labelContent = useMemo(() => {
127
+ if (!label) return null;
128
+ const content = isFunction(label) ? label() : label;
129
+ return /* @__PURE__ */ jsxs(HStack, {
130
+ columnGap: "1",
131
+ alignItems: "flex-end",
132
+ spacingBottom: "2",
133
+ children: [/* @__PURE__ */ jsx(Text, {
134
+ style: inputStyles.label,
135
+ children: content
136
+ }), required && /* @__PURE__ */ jsx(Text, {
137
+ style: inputStyles.labelRequired,
138
+ children: "*"
139
+ })]
140
+ });
141
+ }, [
142
+ label,
143
+ required,
144
+ inputStyles.label,
145
+ inputStyles.labelRequired
146
+ ]);
147
+ const helpTextContent = useMemo(() => {
148
+ if (!helpText) return null;
149
+ const content = isFunction(helpText) ? helpText() : helpText;
150
+ return /* @__PURE__ */ jsx(InputHelpText, {
151
+ startIcon: helperTextIcon,
152
+ size,
153
+ isFilled: valueState === "filled",
154
+ disabled,
155
+ readOnly,
156
+ hasError,
157
+ pressed: open,
158
+ children: content
159
+ });
160
+ }, [
161
+ disabled,
162
+ hasError,
163
+ helpText,
164
+ helperTextIcon,
165
+ open,
166
+ readOnly,
167
+ size,
168
+ valueState
169
+ ]);
170
+ return /* @__PURE__ */ jsx(SelectContext.Provider, {
171
+ value: contextValue,
172
+ children: /* @__PURE__ */ jsx(SelectFieldContext.Provider, {
173
+ value: fieldContext,
174
+ children: /* @__PURE__ */ jsxs(VStack, {
175
+ testID,
176
+ style: rootStyle,
177
+ children: [
178
+ labelContent,
179
+ /* @__PURE__ */ jsx(SelectTrigger, {
180
+ startIcon,
181
+ endIcon
182
+ }),
183
+ helpTextContent,
184
+ children
185
+ ]
186
+ })
187
+ })
188
+ });
189
+ });
190
+ Select.displayName = "Select";
191
+ //#endregion
192
+ export { Select };
193
+
194
+ //# sourceMappingURL=Select.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Select.js","names":[],"sources":["../../../src/components/Select/Select.tsx"],"sourcesContent":["import type { UniversalSelectProps } from '@yahoo/uds-types';\nimport { isFunction } from 'lodash-es';\nimport type { ReactNode } from 'react';\nimport { memo, useCallback, useId, useMemo, useRef, useState } from 'react';\nimport type { View } from 'react-native';\n\nimport { inputStyles } from '../../../generated/styles';\nimport { HStack } from '../HStack';\nimport type { IconSlotType } from '../IconSlot';\nimport { InputHelpText } from '../InputHelpText';\nimport { useControllableState } from '../internal/Overlay';\nimport { Text } from '../Text';\nimport { VStack } from '../VStack';\nimport { SelectContext, SelectFieldContext } from './selectContext';\nimport { SelectTrigger } from './SelectTrigger';\nimport type { SelectContextValue, SelectFieldContextValue } from './types';\n\ninterface SelectProps extends Omit<UniversalSelectProps<IconSlotType>, 'width'> {\n /** Placeholder text shown when no value is selected. */\n placeholder?: string;\n /** Selected value for controlled usage. */\n value?: string;\n /** Initial value for uncontrolled usage. @default '' */\n defaultValue?: string;\n /** Called when the selected value changes. */\n onChange?: (value: string) => void;\n /** Container width. @default '100%' */\n width?: number | `${number}%` | '100%';\n children?: ReactNode;\n testID?: string;\n}\n\n/**\n * **⚙️ A composable Select component**\n *\n * @description\n * Select lets users pick one value from a list. Compose with `SelectContent` and\n * `SelectItem`, similar to `Tabs` with `TabList` and `Tab`.\n *\n * @category Form\n * @platform mobile\n *\n * @example\n * ```tsx\n * import { Select, SelectContent, SelectItem } from '@yahoo/uds-mobile/Select';\n *\n * <Select label=\"Country\" placeholder=\"Select a country\" defaultValue=\"us\">\n * <SelectContent>\n * <SelectItem value=\"us\">United States</SelectItem>\n * <SelectItem value=\"ca\">Canada</SelectItem>\n * </SelectContent>\n * </Select>\n * ```\n */\nconst Select = memo(function Select({\n label,\n helpText,\n helperTextIcon,\n placeholder,\n size = 'md',\n disabled,\n required,\n hasError,\n readOnly,\n width = '100%',\n reduceMotion = false,\n startIcon,\n endIcon,\n value: valueProp,\n defaultValue = '',\n onChange,\n children,\n testID,\n}: SelectProps) {\n const generatedId = useId();\n const uid = `uds-select-${generatedId}`;\n const triggerRef = useRef<View | null>(null);\n const [triggerRect, setTriggerRect] = useState<SelectContextValue['triggerRect']>(null);\n const [highlightedValue, setHighlightedValue] = useState<string | null>(null);\n const itemsRef = useRef(new Map<string, string>());\n const [, setItemsVersion] = useState(0);\n\n const [value, setValue] = useControllableState({\n value: valueProp,\n defaultValue,\n onChange,\n });\n\n const [open, setOpen] = useControllableState({\n defaultValue: false,\n onChange: (nextOpen) => {\n if (!nextOpen) {\n setHighlightedValue(null);\n }\n },\n });\n\n const registerItem = useCallback((itemValue: string, itemLabel: string) => {\n if (itemsRef.current.get(itemValue) === itemLabel) {\n return;\n }\n\n itemsRef.current.set(itemValue, itemLabel);\n setItemsVersion((version) => version + 1);\n }, []);\n\n const unregisterItem = useCallback((itemValue: string) => {\n if (!itemsRef.current.has(itemValue)) {\n return;\n }\n\n itemsRef.current.delete(itemValue);\n setItemsVersion((version) => version + 1);\n }, []);\n\n const getItemLabel = useCallback((itemValue: string) => itemsRef.current.get(itemValue), []);\n\n const fieldContext = useMemo<SelectFieldContextValue>(\n () => ({\n size,\n disabled,\n readOnly,\n required,\n hasError,\n width,\n reduceMotion,\n placeholder,\n uid,\n }),\n [disabled, hasError, placeholder, readOnly, reduceMotion, required, size, uid, width],\n );\n\n const contextValue = useMemo<SelectContextValue>(\n () => ({\n value,\n setValue,\n open,\n setOpen,\n triggerRef,\n triggerRect,\n setTriggerRect,\n registerItem,\n unregisterItem,\n getItemLabel,\n highlightedValue,\n setHighlightedValue,\n field: fieldContext,\n reduceMotion,\n }),\n [\n fieldContext,\n getItemLabel,\n highlightedValue,\n open,\n reduceMotion,\n registerItem,\n setOpen,\n setValue,\n triggerRect,\n unregisterItem,\n value,\n ],\n );\n\n const hasValue = value.length > 0;\n const valueState = hasValue ? 'filled' : 'empty';\n\n inputStyles.useVariants({\n size,\n value: valueState,\n pressed: open,\n readonly: readOnly,\n invalid: hasError,\n });\n\n const rootStyle = useMemo(() => [{ width, opacity: disabled ? 0.5 : 1 }], [disabled, width]);\n\n const labelContent = useMemo(() => {\n if (!label) {\n return null;\n }\n\n const content = isFunction(label) ? label() : label;\n return (\n <HStack columnGap=\"1\" alignItems=\"flex-end\" spacingBottom=\"2\">\n <Text style={inputStyles.label}>{content}</Text>\n {required && <Text style={inputStyles.labelRequired}>*</Text>}\n </HStack>\n );\n }, [label, required, inputStyles.label, inputStyles.labelRequired]);\n\n const helpTextContent = useMemo(() => {\n if (!helpText) {\n return null;\n }\n\n const content = isFunction(helpText) ? helpText() : helpText;\n return (\n <InputHelpText\n startIcon={helperTextIcon}\n size={size}\n isFilled={valueState === 'filled'}\n disabled={disabled}\n readOnly={readOnly}\n hasError={hasError}\n pressed={open}\n >\n {content}\n </InputHelpText>\n );\n }, [disabled, hasError, helpText, helperTextIcon, open, readOnly, size, valueState]);\n\n return (\n <SelectContext.Provider value={contextValue}>\n <SelectFieldContext.Provider value={fieldContext}>\n <VStack testID={testID} style={rootStyle}>\n {labelContent}\n\n <SelectTrigger startIcon={startIcon} endIcon={endIcon} />\n\n {helpTextContent}\n\n {children}\n </VStack>\n </SelectFieldContext.Provider>\n </SelectContext.Provider>\n );\n});\n\nSelect.displayName = 'Select';\n\nexport { Select, type SelectProps };\n"],"mappings":"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"}
@@ -0,0 +1,148 @@
1
+ /*! © 2026 Yahoo, Inc. UDS Mobile v0.0.0-development */
2
+ Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
3
+ const require_runtime = require("../../_virtual/_rolldown/runtime.cjs");
4
+ const require_components_VStack = require("../VStack.cjs");
5
+ const require_components_internal_Overlay_useAnchoredPosition = require("../internal/Overlay/useAnchoredPosition.cjs");
6
+ const require_components_Popover_PopoverPortalLayer = require("../Popover/PopoverPortalLayer.cjs");
7
+ const require_components_Select_selectContext = require("./selectContext.cjs");
8
+ let react = require("react");
9
+ let react_native = require("react-native");
10
+ let react_jsx_runtime = require("react/jsx-runtime");
11
+ let generated_styles = require("../../../generated/styles");
12
+ let react_native_reanimated = require("react-native-reanimated");
13
+ react_native_reanimated = require_runtime.__toESM(react_native_reanimated);
14
+ //#region src/components/Select/SelectContent.tsx
15
+ const DEFAULT_OFFSET = 4;
16
+ const DEFAULT_MAX_HEIGHT = 240;
17
+ const ANIMATION_DURATION = 200;
18
+ const OFFSCREEN_REGISTRY_STYLE = react_native.StyleSheet.create({ registry: {
19
+ position: "absolute",
20
+ top: 0,
21
+ left: 0,
22
+ width: 1,
23
+ height: 1,
24
+ opacity: 0,
25
+ overflow: "hidden",
26
+ zIndex: -1
27
+ } });
28
+ /**
29
+ * **▾ Select content panel**
30
+ *
31
+ * Floating listbox container for {@link SelectItem} options.
32
+ */
33
+ const SelectContent = (0, react.memo)(function SelectContent({ children, size: _size = "default", variant: _variant = "default", keepOpenOnInteractOutside = false, maxHeight = DEFAULT_MAX_HEIGHT, gutter = DEFAULT_OFFSET, sameWidth = true, style, testID }) {
34
+ const { open, setOpen, triggerRect, reduceMotion } = require_components_Select_selectContext.useSelectContext();
35
+ const [contentSize, setContentSize] = (0, react.useState)({
36
+ width: 0,
37
+ height: 0
38
+ });
39
+ const [shouldRender, setShouldRender] = (0, react.useState)(open);
40
+ const dismiss = (0, react.useCallback)(() => {
41
+ if (keepOpenOnInteractOutside) return;
42
+ setOpen(false);
43
+ }, [keepOpenOnInteractOutside, setOpen]);
44
+ const { contentStyle, anchorReady, maxWidth: positionedMaxWidth } = require_components_internal_Overlay_useAnchoredPosition.useAnchoredPosition({
45
+ triggerRect,
46
+ contentSize,
47
+ placement: "bottom",
48
+ offset: gutter,
49
+ sameWidth,
50
+ width: sameWidth ? "trigger" : "content",
51
+ avoidCollisions: true,
52
+ collisionPadding: 12
53
+ });
54
+ const isPositionedOpen = open && anchorReady && contentSize.height > 0;
55
+ const progress = (0, react_native_reanimated.useDerivedValue)(() => (0, react_native_reanimated.withTiming)(isPositionedOpen ? 1 : 0, {
56
+ duration: reduceMotion ? 0 : ANIMATION_DURATION,
57
+ easing: react_native_reanimated.Easing.out(react_native_reanimated.Easing.ease)
58
+ }), [isPositionedOpen, reduceMotion]);
59
+ const animatedStyle = (0, react_native_reanimated.useAnimatedStyle)(() => ({
60
+ opacity: progress.value,
61
+ transform: [{ scale: .97 + progress.value * .03 }, { translateY: (1 - progress.value) * 8 }]
62
+ }));
63
+ const handleLayout = (0, react.useCallback)((event) => {
64
+ const { width, height } = event.nativeEvent.layout;
65
+ setContentSize({
66
+ width,
67
+ height
68
+ });
69
+ }, []);
70
+ (0, react.useEffect)(() => {
71
+ if (open) {
72
+ setShouldRender(true);
73
+ return;
74
+ }
75
+ if (reduceMotion) {
76
+ setShouldRender(false);
77
+ setContentSize({
78
+ width: 0,
79
+ height: 0
80
+ });
81
+ return;
82
+ }
83
+ const timeout = setTimeout(() => {
84
+ setShouldRender(false);
85
+ setContentSize({
86
+ width: 0,
87
+ height: 0
88
+ });
89
+ }, ANIMATION_DURATION);
90
+ return () => clearTimeout(timeout);
91
+ }, [open, reduceMotion]);
92
+ generated_styles.selectContentStyles.useVariants({});
93
+ const panelStyle = (0, react.useMemo)(() => react_native.StyleSheet.flatten([
94
+ generated_styles.selectContentStyles.root,
95
+ {
96
+ maxHeight,
97
+ maxWidth: positionedMaxWidth > 0 ? positionedMaxWidth : void 0,
98
+ overflow: "hidden",
99
+ zIndex: 1
100
+ },
101
+ style
102
+ ]), [
103
+ maxHeight,
104
+ positionedMaxWidth,
105
+ generated_styles.selectContentStyles.root,
106
+ style
107
+ ]);
108
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [!open ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)(react_native.View, {
109
+ accessibilityElementsHidden: true,
110
+ importantForAccessibility: "no-hide-descendants",
111
+ pointerEvents: "none",
112
+ style: OFFSCREEN_REGISTRY_STYLE.registry,
113
+ children
114
+ }) : null, open && shouldRender ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_components_Popover_PopoverPortalLayer.PopoverPortalLayer, {
115
+ open,
116
+ dismissible: !keepOpenOnInteractOutside,
117
+ onDismiss: dismiss,
118
+ children: () => /* @__PURE__ */ (0, react_jsx_runtime.jsx)(react_native_reanimated.default.View, {
119
+ testID,
120
+ style: [
121
+ contentStyle,
122
+ animatedStyle,
123
+ {
124
+ overflow: "visible",
125
+ zIndex: 1e3
126
+ }
127
+ ],
128
+ onLayout: handleLayout,
129
+ accessibilityRole: "menu",
130
+ children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(react_native.View, {
131
+ style: panelStyle,
132
+ children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(react_native.ScrollView, {
133
+ keyboardShouldPersistTaps: "handled",
134
+ nestedScrollEnabled: true,
135
+ style: { maxHeight },
136
+ children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_components_VStack.VStack, {
137
+ alignItems: "stretch",
138
+ justifyContent: "flex-start",
139
+ children
140
+ })
141
+ })
142
+ })
143
+ })
144
+ }) : null] });
145
+ });
146
+ SelectContent.displayName = "SelectContent";
147
+ //#endregion
148
+ exports.SelectContent = SelectContent;