@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.
- package/dist/cjs/banner/banner.cjs +1 -1
- package/dist/cjs/checkbox/checkbox.cjs +1 -1
- package/dist/cjs/combo-box/combo-box.cjs +1 -1
- package/dist/cjs/date-field/date-field.cjs +1 -1
- package/dist/cjs/date-picker/date-picker.cjs +5 -4
- package/dist/cjs/date-range-picker/date-range-picker.cjs +3 -3
- package/dist/cjs/field/field.cjs +15 -12
- package/dist/cjs/file-dropzone/file-dropzone.cjs +2 -2
- package/dist/cjs/file-dropzone/file-info.cjs +1 -1
- package/dist/cjs/index.cjs +98 -72
- package/dist/cjs/modal/modal-content.cjs +1 -1
- package/dist/cjs/number-field/number-field.cjs +2 -2
- package/dist/cjs/phone-number-field/constants.cjs +500 -0
- package/dist/cjs/phone-number-field/context.cjs +11 -0
- package/dist/cjs/phone-number-field/i18n.cjs +1043 -0
- package/dist/cjs/phone-number-field/index.cjs +32 -0
- package/dist/cjs/phone-number-field/phone-number-field.cjs +299 -0
- package/dist/cjs/phone-number-field/types.cjs +3 -0
- package/dist/cjs/range-calendar/range-calendar.cjs +1 -1
- package/dist/cjs/search-field/search-field.cjs +2 -2
- package/dist/cjs/select/i18n.cjs +23 -0
- package/dist/cjs/select/select.cjs +47 -47
- package/dist/cjs/sidebar/sidebar-list.cjs +1 -1
- package/dist/cjs/system/l10n.cjs +18 -0
- package/dist/cjs/system/react-utils/sizing.cjs +21 -0
- package/dist/cjs/tag-field/tag-field.cjs +1 -1
- package/dist/cjs/text-area-field/text-area-field.cjs +1 -1
- package/dist/cjs/text-field/text-field.cjs +1 -1
- package/dist/cjs/time-field/time-field.cjs +2 -2
- package/dist/esm/banner/banner.js +1 -1
- package/dist/esm/checkbox/checkbox.js +1 -1
- package/dist/esm/combo-box/combo-box.js +1 -1
- package/dist/esm/date-field/date-field.js +1 -1
- package/dist/esm/date-picker/date-picker.js +5 -4
- package/dist/esm/date-range-picker/date-range-picker.js +3 -3
- package/dist/esm/field/field.js +18 -15
- package/dist/esm/file-dropzone/file-dropzone.js +2 -2
- package/dist/esm/file-dropzone/file-info.js +1 -1
- package/dist/esm/index.js +27 -25
- package/dist/esm/modal/modal-content.js +1 -1
- package/dist/esm/number-field/number-field.js +2 -2
- package/dist/esm/phone-number-field/constants.js +497 -0
- package/dist/esm/phone-number-field/context.js +8 -0
- package/dist/esm/phone-number-field/i18n.js +1041 -0
- package/dist/esm/phone-number-field/index.js +3 -0
- package/dist/esm/phone-number-field/phone-number-field.js +294 -0
- package/dist/esm/phone-number-field/types.js +1 -0
- package/dist/esm/range-calendar/range-calendar.js +1 -1
- package/dist/esm/search-field/search-field.js +2 -2
- package/dist/esm/select/i18n.js +21 -0
- package/dist/esm/select/select.js +47 -47
- package/dist/esm/sidebar/sidebar-list.js +1 -1
- package/dist/esm/system/l10n.js +16 -0
- package/dist/esm/system/react-utils/sizing.js +19 -0
- package/dist/esm/tag-field/tag-field.js +1 -1
- package/dist/esm/text-area-field/text-area-field.js +1 -1
- package/dist/esm/text-field/text-field.js +1 -1
- package/dist/esm/time-field/time-field.js +2 -2
- package/dist/types/field/field.d.ts +1 -1
- package/dist/types/field/field.d.ts.map +1 -1
- package/dist/types/index.d.mts +1 -0
- package/dist/types/index.d.ts +1 -0
- package/dist/types/index.d.ts.map +1 -1
- package/dist/types/phone-number-field/constants.d.ts +495 -0
- package/dist/types/phone-number-field/constants.d.ts.map +1 -0
- package/dist/types/phone-number-field/context.d.ts +15 -0
- package/dist/types/phone-number-field/context.d.ts.map +1 -0
- package/dist/types/phone-number-field/i18n.d.ts +1039 -0
- package/dist/types/phone-number-field/i18n.d.ts.map +1 -0
- package/dist/types/phone-number-field/index.d.ts +9 -0
- package/dist/types/phone-number-field/index.d.ts.map +1 -0
- package/dist/types/phone-number-field/phone-number-field.d.ts +42 -0
- package/dist/types/phone-number-field/phone-number-field.d.ts.map +1 -0
- package/dist/types/phone-number-field/types.d.ts +21 -0
- package/dist/types/phone-number-field/types.d.ts.map +1 -0
- package/dist/types/select/i18n.d.ts +19 -0
- package/dist/types/select/i18n.d.ts.map +1 -0
- package/dist/types/select/select.d.ts +11 -1
- package/dist/types/select/select.d.ts.map +1 -1
- package/dist/types/system/l10n.d.ts +10 -0
- package/dist/types/system/l10n.d.ts.map +1 -0
- package/dist/types/system/react-utils/sizing.d.ts +8 -0
- package/dist/types/system/react-utils/sizing.d.ts.map +1 -0
- package/package.json +6 -4
|
@@ -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
|
|
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(
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
{
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
}
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
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
|
|
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,
|
|
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"}
|
package/dist/types/index.d.mts
CHANGED
package/dist/types/index.d.ts
CHANGED
|
@@ -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"}
|