@opengovsg/oui 0.0.45 → 0.0.46

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 (84) hide show
  1. package/dist/cjs/banner/banner.cjs +1 -1
  2. package/dist/cjs/checkbox/checkbox.cjs +1 -1
  3. package/dist/cjs/combo-box/combo-box.cjs +1 -1
  4. package/dist/cjs/date-field/date-field.cjs +1 -1
  5. package/dist/cjs/date-picker/date-picker.cjs +5 -4
  6. package/dist/cjs/date-range-picker/date-range-picker.cjs +3 -3
  7. package/dist/cjs/field/field.cjs +15 -12
  8. package/dist/cjs/file-dropzone/file-dropzone.cjs +2 -2
  9. package/dist/cjs/file-dropzone/file-info.cjs +1 -1
  10. package/dist/cjs/index.cjs +98 -72
  11. package/dist/cjs/modal/modal-content.cjs +1 -1
  12. package/dist/cjs/number-field/number-field.cjs +2 -2
  13. package/dist/cjs/phone-number-field/constants.cjs +500 -0
  14. package/dist/cjs/phone-number-field/context.cjs +11 -0
  15. package/dist/cjs/phone-number-field/i18n.cjs +1043 -0
  16. package/dist/cjs/phone-number-field/index.cjs +32 -0
  17. package/dist/cjs/phone-number-field/phone-number-field.cjs +299 -0
  18. package/dist/cjs/phone-number-field/types.cjs +3 -0
  19. package/dist/cjs/range-calendar/range-calendar.cjs +1 -1
  20. package/dist/cjs/search-field/search-field.cjs +2 -2
  21. package/dist/cjs/select/i18n.cjs +23 -0
  22. package/dist/cjs/select/select.cjs +47 -47
  23. package/dist/cjs/sidebar/sidebar-list.cjs +1 -1
  24. package/dist/cjs/system/l10n.cjs +18 -0
  25. package/dist/cjs/system/react-utils/sizing.cjs +21 -0
  26. package/dist/cjs/tag-field/tag-field.cjs +1 -1
  27. package/dist/cjs/text-area-field/text-area-field.cjs +1 -1
  28. package/dist/cjs/text-field/text-field.cjs +1 -1
  29. package/dist/cjs/time-field/time-field.cjs +2 -2
  30. package/dist/esm/banner/banner.js +1 -1
  31. package/dist/esm/checkbox/checkbox.js +1 -1
  32. package/dist/esm/combo-box/combo-box.js +1 -1
  33. package/dist/esm/date-field/date-field.js +1 -1
  34. package/dist/esm/date-picker/date-picker.js +5 -4
  35. package/dist/esm/date-range-picker/date-range-picker.js +3 -3
  36. package/dist/esm/field/field.js +18 -15
  37. package/dist/esm/file-dropzone/file-dropzone.js +2 -2
  38. package/dist/esm/file-dropzone/file-info.js +1 -1
  39. package/dist/esm/index.js +27 -25
  40. package/dist/esm/modal/modal-content.js +1 -1
  41. package/dist/esm/number-field/number-field.js +2 -2
  42. package/dist/esm/phone-number-field/constants.js +497 -0
  43. package/dist/esm/phone-number-field/context.js +8 -0
  44. package/dist/esm/phone-number-field/i18n.js +1041 -0
  45. package/dist/esm/phone-number-field/index.js +3 -0
  46. package/dist/esm/phone-number-field/phone-number-field.js +294 -0
  47. package/dist/esm/phone-number-field/types.js +1 -0
  48. package/dist/esm/range-calendar/range-calendar.js +1 -1
  49. package/dist/esm/search-field/search-field.js +2 -2
  50. package/dist/esm/select/i18n.js +21 -0
  51. package/dist/esm/select/select.js +47 -47
  52. package/dist/esm/sidebar/sidebar-list.js +1 -1
  53. package/dist/esm/system/l10n.js +16 -0
  54. package/dist/esm/system/react-utils/sizing.js +19 -0
  55. package/dist/esm/tag-field/tag-field.js +1 -1
  56. package/dist/esm/text-area-field/text-area-field.js +1 -1
  57. package/dist/esm/text-field/text-field.js +1 -1
  58. package/dist/esm/time-field/time-field.js +2 -2
  59. package/dist/types/field/field.d.ts +1 -1
  60. package/dist/types/field/field.d.ts.map +1 -1
  61. package/dist/types/index.d.mts +1 -0
  62. package/dist/types/index.d.ts +1 -0
  63. package/dist/types/index.d.ts.map +1 -1
  64. package/dist/types/phone-number-field/constants.d.ts +495 -0
  65. package/dist/types/phone-number-field/constants.d.ts.map +1 -0
  66. package/dist/types/phone-number-field/context.d.ts +15 -0
  67. package/dist/types/phone-number-field/context.d.ts.map +1 -0
  68. package/dist/types/phone-number-field/i18n.d.ts +1039 -0
  69. package/dist/types/phone-number-field/i18n.d.ts.map +1 -0
  70. package/dist/types/phone-number-field/index.d.ts +9 -0
  71. package/dist/types/phone-number-field/index.d.ts.map +1 -0
  72. package/dist/types/phone-number-field/phone-number-field.d.ts +42 -0
  73. package/dist/types/phone-number-field/phone-number-field.d.ts.map +1 -0
  74. package/dist/types/phone-number-field/types.d.ts +21 -0
  75. package/dist/types/phone-number-field/types.d.ts.map +1 -0
  76. package/dist/types/select/i18n.d.ts +19 -0
  77. package/dist/types/select/i18n.d.ts.map +1 -0
  78. package/dist/types/select/select.d.ts +11 -1
  79. package/dist/types/select/select.d.ts.map +1 -1
  80. package/dist/types/system/l10n.d.ts +10 -0
  81. package/dist/types/system/l10n.d.ts.map +1 -0
  82. package/dist/types/system/react-utils/sizing.d.ts +8 -0
  83. package/dist/types/system/react-utils/sizing.d.ts.map +1 -0
  84. package/package.json +6 -4
@@ -0,0 +1,3 @@
1
+ "use strict";
2
+ export { CountrySelect, FlagComponent, PhoneInput, PhoneNumberField } from './phone-number-field.js';
3
+ export { formatPhoneNumber, formatPhoneNumberIntl, isPossiblePhoneNumber, isValidPhoneNumber, parsePhoneNumber } from 'react-phone-number-input';
@@ -0,0 +1,294 @@
1
+ "use strict";
2
+ "use client";
3
+ import { jsxs, jsx } from 'react/jsx-runtime';
4
+ import { useMemo, useState, useRef, useCallback } from 'react';
5
+ import { TextField, Provider } from 'react-aria-components';
6
+ import BasePhoneInput, { getCountryCallingCode } from 'react-phone-number-input';
7
+ import flags from 'react-phone-number-input/flags';
8
+ import NonInternationalBasePhoneInput from 'react-phone-number-input/input';
9
+ import { phoneNumberFieldStyles, cn } from '@opengovsg/oui-theme';
10
+ import { Label, FieldGroup, Description, FieldError } from '../field/field.js';
11
+ import { useControllableState } from '../hooks/use-controllable-state.js';
12
+ import { Input } from '../input/input.js';
13
+ import { Select } from '../select/select.js';
14
+ import { SelectItem } from '../select/select-item.js';
15
+ import { useLocalizedStringFormatter } from '../system/l10n.js';
16
+ import { mapPropsVariants } from '../system/utils.js';
17
+ import { MOBILE_EXAMPLES } from './constants.js';
18
+ import { PhoneInputContext, usePhoneInputContext } from './context.js';
19
+ import { i18nStrings } from './i18n.js';
20
+
21
+ const PhoneInput = ({
22
+ onClear,
23
+ onKeyDown,
24
+ ...props
25
+ }) => {
26
+ const {
27
+ placeholderMode,
28
+ examples,
29
+ selectedCountry,
30
+ styles,
31
+ size,
32
+ classNames,
33
+ stringFormatter
34
+ } = usePhoneInputContext();
35
+ const inputPlaceholder = useMemo(() => {
36
+ const defaultPlaceholder = stringFormatter.format("Enter a phone number");
37
+ if (placeholderMode === "off") {
38
+ return props.placeholder ?? defaultPlaceholder;
39
+ }
40
+ const exampleNumber = selectedCountry && examples[selectedCountry];
41
+ if (placeholderMode === "aggressive") {
42
+ return exampleNumber ?? props.placeholder ?? defaultPlaceholder;
43
+ }
44
+ return props.placeholder ?? exampleNumber ?? defaultPlaceholder;
45
+ }, [
46
+ props.placeholder,
47
+ stringFormatter,
48
+ placeholderMode,
49
+ examples,
50
+ selectedCountry
51
+ ]);
52
+ const handleKeyDown = useCallback(
53
+ (event) => {
54
+ if (event.metaKey && event.key === "Backspace") {
55
+ event.preventDefault();
56
+ onClear?.();
57
+ } else {
58
+ onKeyDown?.(event);
59
+ }
60
+ },
61
+ [onClear, onKeyDown]
62
+ );
63
+ return /* @__PURE__ */ jsx(
64
+ Input,
65
+ {
66
+ variant: "unstyled",
67
+ placeholder: inputPlaceholder,
68
+ type: "tel",
69
+ autoComplete: "tel",
70
+ size,
71
+ ...props,
72
+ onKeyDown: handleKeyDown,
73
+ className: styles.input({
74
+ className: cn(classNames?.input, props.className)
75
+ })
76
+ }
77
+ );
78
+ };
79
+ const PhoneNumberField = (originalProps) => {
80
+ const [
81
+ {
82
+ placeholderMode = "polite",
83
+ examples = MOBILE_EXAMPLES,
84
+ label,
85
+ description,
86
+ errorMessage,
87
+ classNames,
88
+ isInvalid,
89
+ ...props
90
+ },
91
+ { variant = "international", ...variantProps }
92
+ ] = mapPropsVariants(originalProps, phoneNumberFieldStyles.variantKeys);
93
+ const stringFormatter = useLocalizedStringFormatter(i18nStrings);
94
+ const defaultCountry = useMemo(
95
+ () => props.defaultCountry ?? "SG",
96
+ [props.defaultCountry]
97
+ );
98
+ const [selectedCountry, setSelectedCountry] = useState(
99
+ defaultCountry
100
+ );
101
+ const [value, setValue] = useControllableState({
102
+ defaultValue: props.defaultValue,
103
+ value: props.value,
104
+ onChange: props.onChange
105
+ });
106
+ const triggerRef = useRef(null);
107
+ const { size = "md", isDisabled } = variantProps;
108
+ const styles = phoneNumberFieldStyles({
109
+ ...variantProps,
110
+ variant,
111
+ isDisabled,
112
+ size
113
+ });
114
+ return /* @__PURE__ */ jsxs(
115
+ TextField,
116
+ {
117
+ isDisabled,
118
+ className: styles.base({
119
+ className: classNames?.base
120
+ }),
121
+ isInvalid,
122
+ children: [
123
+ label && /* @__PURE__ */ jsx(Label, { size, className: classNames?.label, children: label }),
124
+ /* @__PURE__ */ jsx(
125
+ Provider,
126
+ {
127
+ values: [
128
+ [
129
+ PhoneInputContext,
130
+ {
131
+ triggerRef,
132
+ placeholderMode,
133
+ examples,
134
+ selectedCountry,
135
+ classNames,
136
+ styles,
137
+ variant,
138
+ ...variantProps,
139
+ size,
140
+ stringFormatter
141
+ }
142
+ ]
143
+ ],
144
+ children: /* @__PURE__ */ jsx(
145
+ FieldGroup,
146
+ {
147
+ isInvalid,
148
+ isDisabled,
149
+ "data-variant": variant,
150
+ ref: triggerRef,
151
+ className: styles.group({
152
+ className: classNames?.group
153
+ }),
154
+ children: variant === "international" ? /* @__PURE__ */ jsx(
155
+ BasePhoneInput,
156
+ {
157
+ disabled: isDisabled,
158
+ className: styles.wrapper({
159
+ className: classNames?.wrapper
160
+ }),
161
+ international: false,
162
+ addInternationalOption: false,
163
+ defaultCountry: selectedCountry,
164
+ countryOptionsOrder: [defaultCountry],
165
+ onCountryChange: setSelectedCountry,
166
+ countrySelectComponent: CountrySelect,
167
+ inputComponent: PhoneInput,
168
+ onClear: () => setValue(void 0),
169
+ ...props,
170
+ value,
171
+ onChange: (v) => setValue(v)
172
+ }
173
+ ) : /* @__PURE__ */ jsxs("div", { className: styles.wrapper({ className: classNames?.wrapper }), children: [
174
+ /* @__PURE__ */ jsx(
175
+ NonInternationalBasePhoneInput,
176
+ {
177
+ country: defaultCountry,
178
+ onClear: () => setValue(void 0),
179
+ ...props,
180
+ inputComponent: PhoneInput,
181
+ value,
182
+ onChange: setValue
183
+ }
184
+ ),
185
+ /* @__PURE__ */ jsx(
186
+ FlagComponent,
187
+ {
188
+ className: styles.flag({ className: classNames?.flag }),
189
+ country: defaultCountry,
190
+ countryName: stringFormatter.format(defaultCountry)
191
+ }
192
+ )
193
+ ] })
194
+ }
195
+ )
196
+ }
197
+ ),
198
+ description && /* @__PURE__ */ jsx(Description, { size, className: classNames?.description, children: description }),
199
+ /* @__PURE__ */ jsx(FieldError, { size, className: classNames?.error, children: errorMessage })
200
+ ]
201
+ }
202
+ );
203
+ };
204
+ function CountrySelect(props) {
205
+ const { options, value, onChange, onBlur, onFocus } = props;
206
+ const { triggerRef, classNames, styles, size, isDisabled, stringFormatter } = usePhoneInputContext();
207
+ return /* @__PURE__ */ jsx(
208
+ Select,
209
+ {
210
+ size,
211
+ popoverProps: {
212
+ // Position popover relative to the wrapping div instead of the Button
213
+ triggerRef
214
+ },
215
+ classNames: {
216
+ base: styles.select({ className: classNames?.select }),
217
+ trigger: styles.selectTrigger({
218
+ className: classNames?.selectTrigger
219
+ }),
220
+ icon: styles.selectIcon({ className: classNames?.selectIcon }),
221
+ // Apply same styles as trigger for consistent sizing
222
+ list: styles.selectList({ className: classNames?.selectList }),
223
+ popover: styles.selectPopover({ className: classNames?.selectPopover })
224
+ },
225
+ enableSearch: true,
226
+ variant: "unstyled",
227
+ isDisabled,
228
+ value,
229
+ onChange: (v) => onChange(v),
230
+ items: options,
231
+ renderSelectValue: () => /* @__PURE__ */ jsx(
232
+ FlagComponent,
233
+ {
234
+ className: styles.flag({ className: classNames?.flag }),
235
+ country: value,
236
+ countryName: value && stringFormatter.format(value)
237
+ }
238
+ ),
239
+ onBlur,
240
+ onFocus,
241
+ children: (country) => {
242
+ const l10nLabel = country.value ? stringFormatter.format(country.value) : "";
243
+ return /* @__PURE__ */ jsxs(
244
+ SelectItem,
245
+ {
246
+ classNames: {
247
+ text: styles.selectItem({ className: classNames?.selectItem })
248
+ },
249
+ textValue: `${l10nLabel} ${country.label}`,
250
+ id: country.value,
251
+ children: [
252
+ /* @__PURE__ */ jsx(
253
+ FlagComponent,
254
+ {
255
+ className: styles.flag({ className: classNames?.flag }),
256
+ country: country.value,
257
+ countryName: l10nLabel
258
+ }
259
+ ),
260
+ /* @__PURE__ */ jsx(
261
+ "span",
262
+ {
263
+ className: styles.selectItemLabel({
264
+ className: classNames?.selectItemLabel
265
+ }),
266
+ children: l10nLabel
267
+ }
268
+ ),
269
+ country.value && /* @__PURE__ */ jsx(
270
+ "span",
271
+ {
272
+ className: styles.selectItemCountryCode({
273
+ className: classNames?.selectItemCountryCode
274
+ }),
275
+ children: `+${getCountryCallingCode(country.value)}`
276
+ }
277
+ )
278
+ ]
279
+ }
280
+ );
281
+ }
282
+ }
283
+ );
284
+ }
285
+ const FlagComponent = ({
286
+ country,
287
+ countryName,
288
+ className
289
+ }) => {
290
+ const Flag = country && flags[country];
291
+ return /* @__PURE__ */ jsx("span", { className, children: Flag && /* @__PURE__ */ jsx(Flag, { title: countryName }) });
292
+ };
293
+
294
+ export { CountrySelect, FlagComponent, PhoneInput, PhoneNumberField };
@@ -0,0 +1 @@
1
+ "use strict";
@@ -6,12 +6,12 @@ import { CalendarDate, today, getLocalTimeZone, getDayOfWeek } from '@internatio
6
6
  import { RangeCalendar as RangeCalendar$1, Provider, CalendarGrid, CalendarGridBody, Text, RangeCalendarStateContext, useLocale, CalendarCell } from 'react-aria-components';
7
7
  import { useDeepCompareMemo } from 'use-deep-compare';
8
8
  import { calendarStyles, composeRenderProps, cn, dataAttr } from '@opengovsg/oui-theme';
9
+ import { CalendarStyleContext, useCalendarStyleContext } from '../calendar/calendar-style-context.js';
9
10
  import { AgnosticCalendarStateContext } from '../calendar/agnostic-calendar-state-context.js';
10
11
  import { CalendarBottomContent } from '../calendar/calendar-bottom-content.js';
11
12
  import { CalendarGridHeader } from '../calendar/calendar-grid-header.js';
12
13
  import { CalendarHeader } from '../calendar/calendar-header.js';
13
14
  import { forwardRefGeneric, mapPropsVariants } from '../system/utils.js';
14
- import { CalendarStyleContext, useCalendarStyleContext } from '../calendar/calendar-style-context.js';
15
15
 
16
16
  const RangeCalendar = forwardRefGeneric(function RangeCalendar2(originalProps, ref) {
17
17
  const [props, variantProps] = mapPropsVariants(
@@ -3,13 +3,13 @@ import { jsxs, jsx } from 'react/jsx-runtime';
3
3
  import { useLocalizedStringFormatter } from 'react-aria';
4
4
  import { SearchField as SearchField$1 } from 'react-aria-components';
5
5
  import { searchFieldStyles, composeRenderProps } from '@opengovsg/oui-theme';
6
+ import { Button } from '../button/button.js';
7
+ import { Label, FieldGroup, Description, FieldError } from '../field/field.js';
6
8
  import { Input } from '../input/input.js';
7
9
  import { mapPropsVariants } from '../system/utils.js';
8
10
  import { i18nStrings } from './i18n.js';
9
11
  import Search from '../node_modules/.pnpm/lucide-react@0.475.0_react@19.2.3/node_modules/lucide-react/dist/esm/icons/search.js';
10
12
  import X from '../node_modules/.pnpm/lucide-react@0.475.0_react@19.2.3/node_modules/lucide-react/dist/esm/icons/x.js';
11
- import { Label, FieldGroup, Description, FieldError } from '../field/field.js';
12
- import { Button } from '../button/button.js';
13
13
 
14
14
  function SearchField(originalProps) {
15
15
  const [
@@ -0,0 +1,21 @@
1
+ "use strict";
2
+ const i18nStrings = {
3
+ "en-SG": {
4
+ "Search...": "Search...",
5
+ "Search options": "Search options"
6
+ },
7
+ "zh-SG": {
8
+ "Search...": "\u641C\u7D22...",
9
+ "Search options": "\u641C\u7D22\u9009\u9879"
10
+ },
11
+ "ms-SG": {
12
+ "Search...": "Cari...",
13
+ "Search options": "Cari pilihan"
14
+ },
15
+ "ta-SG": {
16
+ "Search...": "\u0BA4\u0BC7\u0B9F\u0BC1...",
17
+ "Search options": "\u0BA4\u0BC7\u0B9F\u0BB2\u0BCD \u0BB5\u0BBF\u0BB0\u0BC1\u0BAA\u0BCD\u0BAA\u0B99\u0BCD\u0B95\u0BB3\u0BCD"
18
+ }
19
+ };
20
+
21
+ export { i18nStrings };
@@ -5,31 +5,15 @@ import { useMemo, isValidElement, cloneElement } from 'react';
5
5
  import { useLocalizedStringFormatter } from 'react-aria';
6
6
  import { useFilter, Virtualizer, ListLayout, ListBox, Provider, Select as Select$1, SelectValue, Autocomplete, SearchField, Input } from 'react-aria-components';
7
7
  import { selectStyles, cn, composeRenderProps } from '@opengovsg/oui-theme';
8
+ import { Button } from '../button/button.js';
9
+ import { Label, Description, FieldError } from '../field/field.js';
8
10
  import { Popover } from '../popover/popover.js';
11
+ import { useElementWidth } from '../system/react-utils/sizing.js';
9
12
  import { mapPropsVariants } from '../system/utils.js';
13
+ import { i18nStrings } from './i18n.js';
10
14
  import { SelectVariantContext } from './select-variant-context.js';
11
- import { Label, Description, FieldError } from '../field/field.js';
12
15
  import ChevronDown from '../node_modules/.pnpm/lucide-react@0.475.0_react@19.2.3/node_modules/lucide-react/dist/esm/icons/chevron-down.js';
13
- import { Button } from '../button/button.js';
14
16
 
15
- const i18nStrings = {
16
- "en-SG": {
17
- searchPlaceholder: "Search...",
18
- searchAriaLabel: "Search options"
19
- },
20
- "zh-SG": {
21
- searchPlaceholder: "\u641C\u7D22...",
22
- searchAriaLabel: "\u641C\u7D22\u9009\u9879"
23
- },
24
- "ms-SG": {
25
- searchPlaceholder: "Cari...",
26
- searchAriaLabel: "Cari pilihan"
27
- },
28
- "ta-SG": {
29
- searchPlaceholder: "\u0BA4\u0BC7\u0B9F\u0BC1...",
30
- searchAriaLabel: "\u0BA4\u0BC7\u0B9F\u0BB2\u0BCD \u0BB5\u0BBF\u0BB0\u0BC1\u0BAA\u0BCD\u0BAA\u0B99\u0BCD\u0B95\u0BB3\u0BCD"
31
- }
32
- };
33
17
  const calculateEstimatedRowHeight = (size) => {
34
18
  switch (size) {
35
19
  case "xs":
@@ -47,7 +31,7 @@ function Select({
47
31
  errorMessage,
48
32
  ...originalProps
49
33
  }) {
50
- const formatter = useLocalizedStringFormatter(i18nStrings);
34
+ const stringFormatter = useLocalizedStringFormatter(i18nStrings);
51
35
  const [_props, variantProps] = mapPropsVariants(
52
36
  originalProps,
53
37
  selectStyles.variantKeys
@@ -59,9 +43,12 @@ function Select({
59
43
  enableSearch = false,
60
44
  searchPlaceholder,
61
45
  searchIcon,
46
+ renderSelectValue,
47
+ popoverProps,
62
48
  ...props
63
49
  } = _props;
64
50
  const styles = selectStyles(variantProps);
51
+ const triggerWidth = useElementWidth(popoverProps?.triggerRef);
65
52
  const { contains } = useFilter({ sensitivity: "base" });
66
53
  const layoutOptions = useMemo(() => {
67
54
  return {
@@ -128,7 +115,8 @@ function Select({
128
115
  {
129
116
  className: styles.selectedText({
130
117
  className: classNames?.selectedText
131
- })
118
+ }),
119
+ children: renderSelectValue
132
120
  }
133
121
  ),
134
122
  /* @__PURE__ */ jsx(
@@ -151,31 +139,43 @@ function Select({
151
139
  }
152
140
  ),
153
141
  /* @__PURE__ */ jsx(FieldError, { size: variantProps.size, className: classNames?.error, children: errorMessage }),
154
- /* @__PURE__ */ jsx(Popover, { className: styles.popover({ className: classNames?.popover }), children: enableSearch ? /* @__PURE__ */ jsxs(Autocomplete, { filter: contains, children: [
155
- /* @__PURE__ */ jsxs(
156
- SearchField,
157
- {
158
- autoFocus: true,
159
- "aria-label": formatter.format("searchAriaLabel"),
160
- className: styles.searchField({
161
- className: classNames?.searchField
162
- }),
163
- children: [
164
- renderedSearchIcon,
165
- /* @__PURE__ */ jsx(
166
- Input,
167
- {
168
- placeholder: searchPlaceholder ?? formatter.format("searchPlaceholder"),
169
- className: styles.searchInput({
170
- className: classNames?.searchInput
171
- })
172
- }
173
- )
174
- ]
175
- }
176
- ),
177
- listContent
178
- ] }) : listContent })
142
+ /* @__PURE__ */ jsx(
143
+ Popover,
144
+ {
145
+ className: styles.popover({ className: classNames?.popover }),
146
+ ...triggerWidth !== null ? {
147
+ style: {
148
+ "--trigger-width": triggerWidth
149
+ }
150
+ } : {},
151
+ ...popoverProps,
152
+ children: enableSearch ? /* @__PURE__ */ jsxs(Autocomplete, { filter: contains, children: [
153
+ /* @__PURE__ */ jsxs(
154
+ SearchField,
155
+ {
156
+ autoFocus: true,
157
+ "aria-label": stringFormatter.format("Search options"),
158
+ className: styles.searchField({
159
+ className: classNames?.searchField
160
+ }),
161
+ children: [
162
+ renderedSearchIcon,
163
+ /* @__PURE__ */ jsx(
164
+ Input,
165
+ {
166
+ placeholder: searchPlaceholder ?? stringFormatter.format("Search..."),
167
+ className: styles.searchInput({
168
+ className: classNames?.searchInput
169
+ })
170
+ }
171
+ )
172
+ ]
173
+ }
174
+ ),
175
+ listContent
176
+ ] }) : listContent
177
+ }
178
+ )
179
179
  ]
180
180
  }
181
181
  ) });
@@ -6,11 +6,11 @@ import { useLocalizedStringFormatter } from 'react-aria';
6
6
  import { Disclosure, DisclosurePanel, Provider, Link, Button as Button$1 } from 'react-aria-components';
7
7
  import { useDisclosureState } from 'react-stately';
8
8
  import { dataAttr } from '@opengovsg/oui-theme';
9
+ import { Button } from '../button/button.js';
9
10
  import { forwardRef } from '../system/utils.js';
10
11
  import { useSidebarStyleContext, useSidebarCollapseContext, SidebarNestContext, useSidebarNestContext } from './context.js';
11
12
  import { i18nStrings } from './i18n.js';
12
13
  import ChevronDown from '../node_modules/.pnpm/lucide-react@0.475.0_react@19.2.3/node_modules/lucide-react/dist/esm/icons/chevron-down.js';
13
- import { Button } from '../button/button.js';
14
14
 
15
15
  const SidebarListSection = ({
16
16
  onlyCaretToggle,
@@ -0,0 +1,16 @@
1
+ "use strict";
2
+ import { useMemo } from 'react';
3
+ import { LocalizedStringFormatter } from '@internationalized/string';
4
+ import { useLocalizedStringDictionary } from '@react-aria/i18n';
5
+ import { useLocale } from 'react-aria-components';
6
+
7
+ function useLocalizedStringFormatter(strings, packageName) {
8
+ const { locale } = useLocale();
9
+ const dictionary = useLocalizedStringDictionary(strings, packageName);
10
+ return useMemo(
11
+ () => new LocalizedStringFormatter(locale, dictionary),
12
+ [locale, dictionary]
13
+ );
14
+ }
15
+
16
+ export { useLocalizedStringFormatter };
@@ -0,0 +1,19 @@
1
+ "use strict";
2
+ import { useState, useCallback } from 'react';
3
+ import { useResizeObserver } from '@react-aria/utils';
4
+
5
+ function useElementWidth(ref) {
6
+ const [elementWidth, setElementWidth] = useState(null);
7
+ const onResize = useCallback(() => {
8
+ if (ref && ref.current && ref.current instanceof HTMLElement) {
9
+ setElementWidth(`${ref.current.offsetWidth}px`);
10
+ }
11
+ }, [ref]);
12
+ useResizeObserver({
13
+ ref,
14
+ onResize
15
+ });
16
+ return elementWidth;
17
+ }
18
+
19
+ export { useElementWidth };
@@ -4,6 +4,7 @@ import { jsxs, jsx } from 'react/jsx-runtime';
4
4
  import { createElement } from 'react';
5
5
  import { composeRenderProps } from 'react-aria-components';
6
6
  import { tagFieldStyles } from '@opengovsg/oui-theme';
7
+ import { Label, FieldGroup, Description, FieldError } from '../field/field.js';
7
8
  import { Input } from '../input/input.js';
8
9
  import { Popover } from '../popover/popover.js';
9
10
  import { TagFieldItem } from './tag-field-item.js';
@@ -12,7 +13,6 @@ import { TagFieldRoot } from './tag-field-root.js';
12
13
  import { TagFieldTagList } from './tag-field-tag-list.js';
13
14
  import { TagFieldTrigger } from './tag-field-trigger.js';
14
15
  import ChevronDown from '../node_modules/.pnpm/lucide-react@0.475.0_react@19.2.3/node_modules/lucide-react/dist/esm/icons/chevron-down.js';
15
- import { Label, FieldGroup, Description, FieldError } from '../field/field.js';
16
16
 
17
17
  function TagField({
18
18
  classNames,
@@ -3,8 +3,8 @@
3
3
  import { jsxs, jsx } from 'react/jsx-runtime';
4
4
  import { TextField } from 'react-aria-components';
5
5
  import { composeTailwindRenderProps } from '@opengovsg/oui-theme';
6
- import { TextArea } from '../text-area/text-area.js';
7
6
  import { Label, Description, FieldError } from '../field/field.js';
7
+ import { TextArea } from '../text-area/text-area.js';
8
8
 
9
9
  function TextAreaField({
10
10
  label,
@@ -3,8 +3,8 @@
3
3
  import { jsxs, jsx } from 'react/jsx-runtime';
4
4
  import { TextField as TextField$1 } from 'react-aria-components';
5
5
  import { composeTailwindRenderProps } from '@opengovsg/oui-theme';
6
- import { Input } from '../input/input.js';
7
6
  import { Label, Description, FieldError } from '../field/field.js';
7
+ import { Input } from '../input/input.js';
8
8
 
9
9
  function TextField({
10
10
  label,
@@ -3,9 +3,9 @@ import { jsxs, jsx } from 'react/jsx-runtime';
3
3
  import { useMemo } from 'react';
4
4
  import { TimeField as TimeField$1 } from 'react-aria-components';
5
5
  import { dateInputStyles, composeTailwindRenderProps } from '@opengovsg/oui-theme';
6
- import { mapPropsVariants } from '../system/utils.js';
7
- import { Label, Description, FieldError } from '../field/field.js';
8
6
  import { DateInput } from '../date-field/date-field.js';
7
+ import { Label, Description, FieldError } from '../field/field.js';
8
+ import { mapPropsVariants } from '../system/utils.js';
9
9
 
10
10
  function TimeField(originalProps) {
11
11
  const [
@@ -13,5 +13,5 @@ export declare function FieldErrorIcon({ size, className, }: Pick<FieldErrorProp
13
13
  className?: string;
14
14
  }): import("react/jsx-runtime").JSX.Element;
15
15
  export declare function FieldError({ children, className, size, classNames, ...props }: FieldErrorProps): import("react/jsx-runtime").JSX.Element;
16
- export declare function FieldGroup(props: GroupProps): import("react/jsx-runtime").JSX.Element;
16
+ export declare const FieldGroup: import("react").ForwardRefExoticComponent<GroupProps & import("react").RefAttributes<HTMLDivElement>>;
17
17
  //# sourceMappingURL=field.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"field.d.ts","sourceRoot":"","sources":["../../../src/field/field.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,EACV,eAAe,IAAI,mBAAmB,EACtC,UAAU,IAAI,cAAc,EAC5B,UAAU,EACV,SAAS,EACV,MAAM,uBAAuB,CAAA;AAU9B,OAAO,KAAK,EACV,uBAAuB,EACvB,eAAe,EACf,sBAAsB,EACtB,iBAAiB,EACjB,cAAc,EACf,MAAM,sBAAsB,CAAA;AAS7B,MAAM,WAAW,UAAW,SAAQ,cAAc,EAAE,iBAAiB;CAAG;AAExE,wBAAgB,KAAK,CAAC,EAAE,IAAI,EAAE,SAAS,EAAE,GAAG,KAAK,EAAE,EAAE,UAAU,2CAE9D;AAED,MAAM,WAAW,gBAAiB,SAAQ,SAAS,EAAE,uBAAuB;CAAG;AAE/E,wBAAgB,WAAW,CAAC,EAAE,IAAI,EAAE,SAAS,EAAE,GAAG,KAAK,EAAE,EAAE,gBAAgB,2CAQ1E;AAED,MAAM,WAAW,eACf,SAAQ,mBAAmB,EACzB,sBAAsB;IACxB,UAAU,CAAC,EAAE,cAAc,CAAC,eAAe,CAAC,CAAA;CAC7C;AAED,wBAAgB,cAAc,CAAC,EAC7B,IAAI,EACJ,SAAS,GACV,EAAE,IAAI,CAAC,eAAe,EAAE,MAAM,CAAC,GAAG;IAAE,SAAS,CAAC,EAAE,MAAM,CAAA;CAAE,2CAIxD;AAED,wBAAgB,UAAU,CAAC,EACzB,QAAQ,EACR,SAAS,EACT,IAAI,EACJ,UAAU,EACV,GAAG,KAAK,EACT,EAAE,eAAe,2CA0BjB;AAED,wBAAgB,UAAU,CAAC,KAAK,EAAE,UAAU,2CAS3C"}
1
+ {"version":3,"file":"field.d.ts","sourceRoot":"","sources":["../../../src/field/field.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,EACV,eAAe,IAAI,mBAAmB,EACtC,UAAU,IAAI,cAAc,EAC5B,UAAU,EACV,SAAS,EACV,MAAM,uBAAuB,CAAA;AAU9B,OAAO,KAAK,EACV,uBAAuB,EACvB,eAAe,EACf,sBAAsB,EACtB,iBAAiB,EACjB,cAAc,EACf,MAAM,sBAAsB,CAAA;AAS7B,MAAM,WAAW,UAAW,SAAQ,cAAc,EAAE,iBAAiB;CAAG;AAExE,wBAAgB,KAAK,CAAC,EAAE,IAAI,EAAE,SAAS,EAAE,GAAG,KAAK,EAAE,EAAE,UAAU,2CAE9D;AAED,MAAM,WAAW,gBAAiB,SAAQ,SAAS,EAAE,uBAAuB;CAAG;AAE/E,wBAAgB,WAAW,CAAC,EAAE,IAAI,EAAE,SAAS,EAAE,GAAG,KAAK,EAAE,EAAE,gBAAgB,2CAQ1E;AAED,MAAM,WAAW,eACf,SAAQ,mBAAmB,EACzB,sBAAsB;IACxB,UAAU,CAAC,EAAE,cAAc,CAAC,eAAe,CAAC,CAAA;CAC7C;AAED,wBAAgB,cAAc,CAAC,EAC7B,IAAI,EACJ,SAAS,GACV,EAAE,IAAI,CAAC,eAAe,EAAE,MAAM,CAAC,GAAG;IAAE,SAAS,CAAC,EAAE,MAAM,CAAA;CAAE,2CAIxD;AAED,wBAAgB,UAAU,CAAC,EACzB,QAAQ,EACR,SAAS,EACT,IAAI,EACJ,UAAU,EACV,GAAG,KAAK,EACT,EAAE,eAAe,2CA0BjB;AAED,eAAO,MAAM,UAAU,uGActB,CAAA"}
@@ -38,4 +38,5 @@ export * from "./link";
38
38
  export * from "./breadcrumbs";
39
39
  export * from "./sidebar";
40
40
  export * from "./tooltip";
41
+ export * from "./phone-number-field";
41
42
  //# sourceMappingURL=index.d.ts.map
@@ -38,4 +38,5 @@ export * from "./link";
38
38
  export * from "./breadcrumbs";
39
39
  export * from "./sidebar";
40
40
  export * from "./tooltip";
41
+ export * from "./phone-number-field";
41
42
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,SAAS,CAAA;AACvB,cAAc,UAAU,CAAA;AACxB,cAAc,eAAe,CAAA;AAC7B,cAAc,UAAU,CAAA;AACxB,cAAc,WAAW,CAAA;AACzB,cAAc,UAAU,CAAA;AACxB,cAAc,iBAAiB,CAAA;AAC/B,cAAc,SAAS,CAAA;AACvB,cAAc,cAAc,CAAA;AAC5B,cAAc,SAAS,CAAA;AACvB,cAAc,aAAa,CAAA;AAC3B,cAAc,mBAAmB,CAAA;AACjC,cAAc,aAAa,CAAA;AAC3B,cAAc,UAAU,CAAA;AACxB,cAAc,aAAa,CAAA;AAC3B,cAAc,UAAU,CAAA;AACxB,cAAc,SAAS,CAAA;AACvB,cAAc,YAAY,CAAA;AAC1B,cAAc,kBAAkB,CAAA;AAChC,cAAc,QAAQ,CAAA;AACtB,cAAc,WAAW,CAAA;AACzB,cAAc,QAAQ,CAAA;AACtB,cAAc,cAAc,CAAA;AAC5B,cAAc,eAAe,CAAA;AAC7B,cAAc,qBAAqB,CAAA;AACnC,cAAc,YAAY,CAAA;AAC1B,cAAc,cAAc,CAAA;AAC5B,cAAc,iBAAiB,CAAA;AAC/B,cAAc,gBAAgB,CAAA;AAC9B,cAAc,SAAS,CAAA;AACvB,cAAc,SAAS,CAAA;AACvB,cAAc,UAAU,CAAA;AACxB,cAAc,UAAU,CAAA;AACxB,cAAc,aAAa,CAAA;AAC3B,cAAc,cAAc,CAAA;AAC5B,cAAc,gBAAgB,CAAA;AAC9B,cAAc,QAAQ,CAAA;AACtB,cAAc,eAAe,CAAA;AAC7B,cAAc,WAAW,CAAA;AACzB,cAAc,WAAW,CAAA"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,SAAS,CAAA;AACvB,cAAc,UAAU,CAAA;AACxB,cAAc,eAAe,CAAA;AAC7B,cAAc,UAAU,CAAA;AACxB,cAAc,WAAW,CAAA;AACzB,cAAc,UAAU,CAAA;AACxB,cAAc,iBAAiB,CAAA;AAC/B,cAAc,SAAS,CAAA;AACvB,cAAc,cAAc,CAAA;AAC5B,cAAc,SAAS,CAAA;AACvB,cAAc,aAAa,CAAA;AAC3B,cAAc,mBAAmB,CAAA;AACjC,cAAc,aAAa,CAAA;AAC3B,cAAc,UAAU,CAAA;AACxB,cAAc,aAAa,CAAA;AAC3B,cAAc,UAAU,CAAA;AACxB,cAAc,SAAS,CAAA;AACvB,cAAc,YAAY,CAAA;AAC1B,cAAc,kBAAkB,CAAA;AAChC,cAAc,QAAQ,CAAA;AACtB,cAAc,WAAW,CAAA;AACzB,cAAc,QAAQ,CAAA;AACtB,cAAc,cAAc,CAAA;AAC5B,cAAc,eAAe,CAAA;AAC7B,cAAc,qBAAqB,CAAA;AACnC,cAAc,YAAY,CAAA;AAC1B,cAAc,cAAc,CAAA;AAC5B,cAAc,iBAAiB,CAAA;AAC/B,cAAc,gBAAgB,CAAA;AAC9B,cAAc,SAAS,CAAA;AACvB,cAAc,SAAS,CAAA;AACvB,cAAc,UAAU,CAAA;AACxB,cAAc,UAAU,CAAA;AACxB,cAAc,aAAa,CAAA;AAC3B,cAAc,cAAc,CAAA;AAC5B,cAAc,gBAAgB,CAAA;AAC9B,cAAc,QAAQ,CAAA;AACtB,cAAc,eAAe,CAAA;AAC7B,cAAc,WAAW,CAAA;AACzB,cAAc,WAAW,CAAA;AACzB,cAAc,sBAAsB,CAAA"}