@opengovsg/oui 0.0.7 → 0.0.9

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 (122) hide show
  1. package/dist/cjs/badge/badge.cjs +42 -0
  2. package/dist/cjs/badge/index.cjs +8 -0
  3. package/dist/cjs/badge/use-badge.cjs +111 -0
  4. package/dist/cjs/calendar/calendar-base.cjs +347 -0
  5. package/dist/cjs/calendar/calendar-style-context.cjs +38 -0
  6. package/dist/cjs/calendar/calendar.cjs +16 -0
  7. package/dist/cjs/calendar/index.cjs +22 -0
  8. package/dist/cjs/calendar/types.cjs +3 -0
  9. package/dist/cjs/calendar/utils.cjs +62 -0
  10. package/dist/cjs/combo-box/combo-box-fuzzy.cjs +52 -30
  11. package/dist/cjs/combo-box/combo-box-item.cjs +70 -0
  12. package/dist/cjs/combo-box/combo-box-variant-context.cjs +13 -0
  13. package/dist/cjs/combo-box/combo-box.cjs +46 -100
  14. package/dist/cjs/combo-box/index.cjs +5 -1
  15. package/dist/cjs/index.cjs +30 -1
  16. package/dist/cjs/node_modules/.pnpm/lucide-react@0.475.0_react@19.0.0/node_modules/lucide-react/dist/esm/icons/{check.cjs → chevron-left.cjs} +3 -3
  17. package/dist/cjs/node_modules/.pnpm/lucide-react@0.475.0_react@19.0.0/node_modules/lucide-react/dist/esm/icons/{chevrons-up-down.cjs → chevron-right.cjs} +3 -6
  18. package/dist/cjs/select/index.cjs +5 -0
  19. package/dist/cjs/select/select-item.cjs +12 -24
  20. package/dist/cjs/select/select-variant-context.cjs +1 -0
  21. package/dist/cjs/select/select.cjs +14 -6
  22. package/dist/cjs/system/react-utils/index.cjs +2 -0
  23. package/dist/cjs/system/react-utils/refs.cjs +12 -0
  24. package/dist/cjs/system/utils.cjs +9 -6
  25. package/dist/cjs/tag-field/index.cjs +2 -0
  26. package/dist/cjs/tag-field/tag-field-item.cjs +28 -0
  27. package/dist/cjs/tag-field/tag-field-list.cjs +11 -21
  28. package/dist/cjs/tag-field/tag-field-tag-list.cjs +3 -2
  29. package/dist/cjs/tag-field/tag-field-trigger.cjs +1 -0
  30. package/dist/cjs/tag-field/tag-field.cjs +2 -1
  31. package/dist/esm/badge/badge.js +40 -0
  32. package/dist/esm/badge/index.js +2 -0
  33. package/dist/esm/badge/use-badge.js +109 -0
  34. package/dist/esm/calendar/calendar-base.js +343 -0
  35. package/dist/esm/calendar/calendar-style-context.js +34 -0
  36. package/dist/esm/calendar/calendar.js +14 -0
  37. package/dist/esm/calendar/index.js +5 -0
  38. package/dist/esm/calendar/types.js +1 -0
  39. package/dist/esm/calendar/utils.js +57 -0
  40. package/dist/esm/combo-box/combo-box-fuzzy.js +55 -33
  41. package/dist/esm/combo-box/combo-box-item.js +68 -0
  42. package/dist/esm/combo-box/combo-box-variant-context.js +10 -0
  43. package/dist/esm/combo-box/combo-box.js +48 -101
  44. package/dist/esm/combo-box/index.js +3 -1
  45. package/dist/esm/index.js +11 -1
  46. package/dist/esm/node_modules/.pnpm/lucide-react@0.475.0_react@19.0.0/node_modules/lucide-react/dist/esm/icons/{check.js → chevron-left.js} +3 -3
  47. package/dist/esm/node_modules/.pnpm/lucide-react@0.475.0_react@19.0.0/node_modules/lucide-react/dist/esm/icons/chevron-right.js +14 -0
  48. package/dist/esm/select/index.js +2 -0
  49. package/dist/esm/select/select-item.js +13 -25
  50. package/dist/esm/select/select-variant-context.js +1 -0
  51. package/dist/esm/select/select.js +15 -7
  52. package/dist/esm/system/react-utils/index.js +1 -0
  53. package/dist/esm/system/react-utils/refs.js +10 -0
  54. package/dist/esm/system/utils.js +9 -6
  55. package/dist/esm/tag-field/index.js +1 -0
  56. package/dist/esm/tag-field/tag-field-item.js +26 -0
  57. package/dist/esm/tag-field/tag-field-list.js +12 -21
  58. package/dist/esm/tag-field/tag-field-tag-list.js +3 -2
  59. package/dist/esm/tag-field/tag-field-trigger.js +1 -0
  60. package/dist/esm/tag-field/tag-field.js +3 -2
  61. package/dist/types/badge/badge.d.ts +3 -0
  62. package/dist/types/badge/badge.d.ts.map +1 -0
  63. package/dist/types/badge/index.d.ts +2 -0
  64. package/dist/types/badge/index.d.ts.map +1 -0
  65. package/dist/types/badge/use-badge.d.ts +166 -0
  66. package/dist/types/badge/use-badge.d.ts.map +1 -0
  67. package/dist/types/button/button.d.ts +5 -0
  68. package/dist/types/button/button.d.ts.map +1 -1
  69. package/dist/types/calendar/calendar-base.d.ts +14 -0
  70. package/dist/types/calendar/calendar-base.d.ts.map +1 -0
  71. package/dist/types/calendar/calendar-style-context.d.ts +1032 -0
  72. package/dist/types/calendar/calendar-style-context.d.ts.map +1 -0
  73. package/dist/types/calendar/calendar.d.ts +5 -0
  74. package/dist/types/calendar/calendar.d.ts.map +1 -0
  75. package/dist/types/calendar/index.d.ts +6 -0
  76. package/dist/types/calendar/index.d.ts.map +1 -0
  77. package/dist/types/calendar/types.d.ts +58 -0
  78. package/dist/types/calendar/types.d.ts.map +1 -0
  79. package/dist/types/calendar/utils.d.ts +13 -0
  80. package/dist/types/calendar/utils.d.ts.map +1 -0
  81. package/dist/types/combo-box/combo-box-fuzzy.d.ts +12 -4
  82. package/dist/types/combo-box/combo-box-fuzzy.d.ts.map +1 -1
  83. package/dist/types/combo-box/combo-box-item.d.ts +11 -0
  84. package/dist/types/combo-box/combo-box-item.d.ts.map +1 -0
  85. package/dist/types/combo-box/combo-box-variant-context.d.ts +4 -0
  86. package/dist/types/combo-box/combo-box-variant-context.d.ts.map +1 -0
  87. package/dist/types/combo-box/combo-box.d.ts +5 -21
  88. package/dist/types/combo-box/combo-box.d.ts.map +1 -1
  89. package/dist/types/combo-box/index.d.ts +2 -0
  90. package/dist/types/combo-box/index.d.ts.map +1 -1
  91. package/dist/types/index.d.mts +2 -0
  92. package/dist/types/index.d.ts +2 -0
  93. package/dist/types/index.d.ts.map +1 -1
  94. package/dist/types/select/index.d.ts +2 -0
  95. package/dist/types/select/index.d.ts.map +1 -1
  96. package/dist/types/select/select-item.d.ts.map +1 -1
  97. package/dist/types/select/select-variant-context.d.ts.map +1 -1
  98. package/dist/types/select/select.d.ts.map +1 -1
  99. package/dist/types/system/react-utils/index.d.ts +1 -0
  100. package/dist/types/system/react-utils/index.d.ts.map +1 -1
  101. package/dist/types/system/react-utils/refs.d.ts +4 -0
  102. package/dist/types/system/react-utils/refs.d.ts.map +1 -0
  103. package/dist/types/system/utils.d.ts.map +1 -1
  104. package/dist/types/tag-field/index.d.ts +1 -0
  105. package/dist/types/tag-field/index.d.ts.map +1 -1
  106. package/dist/types/tag-field/tag-field-item.d.ts +7 -0
  107. package/dist/types/tag-field/tag-field-item.d.ts.map +1 -0
  108. package/dist/types/tag-field/tag-field-list.d.ts +5 -9
  109. package/dist/types/tag-field/tag-field-list.d.ts.map +1 -1
  110. package/dist/types/tag-field/tag-field-root.d.ts +4 -4
  111. package/dist/types/tag-field/tag-field-root.d.ts.map +1 -1
  112. package/dist/types/tag-field/tag-field-state-context.d.ts +1 -2
  113. package/dist/types/tag-field/tag-field-state-context.d.ts.map +1 -1
  114. package/dist/types/tag-field/tag-field-tag-list.d.ts +2 -3
  115. package/dist/types/tag-field/tag-field-tag-list.d.ts.map +1 -1
  116. package/dist/types/tag-field/tag-field-trigger.d.ts.map +1 -1
  117. package/dist/types/tag-field/tag-field.d.ts +2 -2
  118. package/dist/types/tag-field/tag-field.d.ts.map +1 -1
  119. package/dist/types/tag-field/types.d.ts +6 -9
  120. package/dist/types/tag-field/types.d.ts.map +1 -1
  121. package/package.json +8 -6
  122. package/dist/esm/node_modules/.pnpm/lucide-react@0.475.0_react@19.0.0/node_modules/lucide-react/dist/esm/icons/chevrons-up-down.js +0 -17
@@ -0,0 +1,343 @@
1
+ "use strict";
2
+ "use client";
3
+ import { jsxs, jsx } from 'react/jsx-runtime';
4
+ import { useMemo, useContext } from 'react';
5
+ import { today, getLocalTimeZone, CalendarDate } from '@internationalized/date';
6
+ import { useMessageFormatter, useDateFormatter } from 'react-aria';
7
+ import { Calendar, composeRenderProps, CalendarGrid, CalendarGridBody, CalendarCell, useLocale, CalendarStateContext, Group, Heading, CalendarGridHeader as CalendarGridHeader$1, CalendarHeaderCell } from 'react-aria-components';
8
+ import { cn } from '@opengovsg/oui-theme';
9
+ import { Button } from '../button/button.js';
10
+ import { useCalendarStyleContext } from './calendar-style-context.js';
11
+ import { useLocalizedMonthYear, useGenerateLocalizedMonths, useGenerateLocalizedYears } from './utils.js';
12
+ import ChevronRight from '../node_modules/.pnpm/lucide-react@0.475.0_react@19.0.0/node_modules/lucide-react/dist/esm/icons/chevron-right.js';
13
+ import ChevronLeft from '../node_modules/.pnpm/lucide-react@0.475.0_react@19.0.0/node_modules/lucide-react/dist/esm/icons/chevron-left.js';
14
+ import { Select } from '../select/select.js';
15
+ import { SelectItem } from '../select/select-item.js';
16
+
17
+ const useCalendarSelectors = (state) => {
18
+ const yearRange = useMemo(() => {
19
+ const start = state.minValue.year ?? 1900;
20
+ const end = state.maxValue.year ?? 2100;
21
+ return { start, end };
22
+ }, [state.maxValue, state.minValue]);
23
+ const dateFormatter = useDateFormatter(state);
24
+ const datePartOrder = useMemo(() => {
25
+ const parts = dateFormatter.formatToParts(
26
+ state.visibleRange.start.toDate(state.timeZone)
27
+ );
28
+ const filteredParts = parts.filter(
29
+ (part) => ["year", "month"].includes(part.type)
30
+ );
31
+ const filteredPartNames = filteredParts.map((part) => part.type);
32
+ return filteredPartNames;
33
+ }, [dateFormatter, state.timeZone, state.visibleRange.start]);
34
+ const months = useGenerateLocalizedMonths(state.timeZone);
35
+ const years = useGenerateLocalizedYears(
36
+ yearRange.start,
37
+ yearRange.end,
38
+ state.timeZone
39
+ );
40
+ return useMemo(() => {
41
+ return {
42
+ months,
43
+ years,
44
+ datePartOrder
45
+ };
46
+ }, [datePartOrder, months, years]);
47
+ };
48
+ const i18nStrings = {
49
+ "en-SG": {
50
+ selectMonth: "Select month",
51
+ selectYear: "Select year",
52
+ today: "Today"
53
+ },
54
+ "zh-SG": {
55
+ selectMonth: "\u9009\u62E9\u6708\u4EFD",
56
+ selectYear: "\u9009\u62E9\u5E74\u4EFD",
57
+ today: "\u4ECA\u5929"
58
+ },
59
+ "ms-SG": {
60
+ selectMonth: "Pilih bulan",
61
+ selectYear: "Pilih tahun",
62
+ today: "Hari ini"
63
+ },
64
+ "ta-SG": {
65
+ selectMonth: "\u0BAE\u0BBE\u0BA4\u0BA4\u0BCD\u0BA4\u0BC8 \u0BA4\u0BC7\u0BB0\u0BCD\u0BA8\u0BCD\u0BA4\u0BC6\u0B9F\u0BC1\u0B95\u0BCD\u0B95\u0BB5\u0BC1\u0BAE\u0BCD",
66
+ selectYear: "\u0B86\u0BA3\u0BCD\u0B9F\u0BC8 \u0BA4\u0BC7\u0BB0\u0BCD\u0BA8\u0BCD\u0BA4\u0BC6\u0B9F\u0BC1\u0B95\u0BCD\u0B95\u0BB5\u0BC1\u0BAE\u0BCD",
67
+ today: "\u0B87\u0BA9\u0BCD\u0BB1\u0BC1"
68
+ }
69
+ };
70
+ const CalendarBottomContent = ({
71
+ bottomContent,
72
+ showTodayButton
73
+ }) => {
74
+ const state = useContext(CalendarStateContext);
75
+ const { slots, classNames, size } = useCalendarStyleContext();
76
+ const formatMessage = useMessageFormatter(i18nStrings);
77
+ if (bottomContent) {
78
+ return bottomContent;
79
+ }
80
+ if (!showTodayButton) {
81
+ return null;
82
+ }
83
+ return /* @__PURE__ */ jsx(
84
+ "div",
85
+ {
86
+ className: slots.bottomContentWrapper({
87
+ className: classNames?.bottomContentWrapper
88
+ }),
89
+ children: /* @__PURE__ */ jsx(
90
+ Button,
91
+ {
92
+ isDisabled: state.isDisabled,
93
+ variant: "clear",
94
+ color: "sub",
95
+ size,
96
+ slot: null,
97
+ className: slots.todayButton({ className: classNames?.todayButton }),
98
+ onPress: () => {
99
+ state.setFocusedDate(today(getLocalTimeZone()));
100
+ },
101
+ children: formatMessage("today")
102
+ }
103
+ )
104
+ }
105
+ );
106
+ };
107
+ function CalendarBase({
108
+ weekdayStyle = "narrow",
109
+ calendarRef,
110
+ minValue = new CalendarDate(1900, 0, 1),
111
+ maxValue = new CalendarDate(2100, 12, 31),
112
+ bottomContent,
113
+ showTodayButton = true,
114
+ ...props
115
+ }) {
116
+ const { slots, className, classNames } = useCalendarStyleContext();
117
+ const numberOfVisibleMonths = props.visibleDuration?.months ?? 1;
118
+ const dateToHighlight = useMemo(() => {
119
+ return props.defaultFocusedValue ?? today(getLocalTimeZone());
120
+ }, [props.defaultFocusedValue]);
121
+ return /* @__PURE__ */ jsxs(
122
+ Calendar,
123
+ {
124
+ pageBehavior: "single",
125
+ ...props,
126
+ ref: calendarRef,
127
+ minValue,
128
+ maxValue,
129
+ className: composeRenderProps(
130
+ className,
131
+ (className2, renderProps) => slots.base({
132
+ className: cn(classNames?.base, className2),
133
+ ...renderProps
134
+ })
135
+ ),
136
+ children: [
137
+ /* @__PURE__ */ jsx(
138
+ "div",
139
+ {
140
+ className: slots.gridWrapper({
141
+ className: classNames?.gridWrapper
142
+ }),
143
+ children: Array.from({ length: numberOfVisibleMonths }).map((_, index) => /* @__PURE__ */ jsxs(
144
+ "div",
145
+ {
146
+ className: slots.calendar({ className: classNames?.calendar }),
147
+ children: [
148
+ /* @__PURE__ */ jsx(CalendarHeader, { offsetMonths: index }),
149
+ /* @__PURE__ */ jsxs(
150
+ CalendarGrid,
151
+ {
152
+ className: slots.grid({ className: classNames?.grid }),
153
+ weekdayStyle,
154
+ offset: { months: index },
155
+ children: [
156
+ /* @__PURE__ */ jsx(CalendarGridHeader, {}),
157
+ /* @__PURE__ */ jsx(
158
+ CalendarGridBody,
159
+ {
160
+ className: slots.gridBody({ className: classNames?.gridBody }),
161
+ children: (date) => /* @__PURE__ */ jsx(
162
+ CalendarCell,
163
+ {
164
+ className: composeRenderProps(
165
+ classNames?.cell,
166
+ (className2, renderProps) => slots.cell({
167
+ className: className2,
168
+ isMultipleMonths: numberOfVisibleMonths >= 2,
169
+ isDateHighlighted: date.compare(dateToHighlight) === 0,
170
+ ...renderProps
171
+ })
172
+ ),
173
+ date
174
+ }
175
+ )
176
+ }
177
+ )
178
+ ]
179
+ }
180
+ )
181
+ ]
182
+ },
183
+ index
184
+ ))
185
+ }
186
+ ),
187
+ /* @__PURE__ */ jsx(
188
+ CalendarBottomContent,
189
+ {
190
+ bottomContent,
191
+ showTodayButton
192
+ }
193
+ )
194
+ ]
195
+ }
196
+ );
197
+ }
198
+ const CalendarMonthDaySelector = () => {
199
+ const { slots, size, classNames } = useCalendarStyleContext();
200
+ const state = useContext(CalendarStateContext);
201
+ const { months, years, datePartOrder } = useCalendarSelectors(state);
202
+ const formatMessage = useMessageFormatter(i18nStrings);
203
+ return /* @__PURE__ */ jsx(Group, { className: slots.selectors({ className: classNames?.selectors }), children: datePartOrder.map((part) => {
204
+ if (part === "month") {
205
+ return /* @__PURE__ */ jsx(
206
+ Select,
207
+ {
208
+ isDisabled: state.isDisabled,
209
+ size,
210
+ items: months,
211
+ variant: "clear",
212
+ classNames: {
213
+ trigger: slots.monthSelector({
214
+ className: classNames?.monthSelector
215
+ }),
216
+ list: slots.monthList({ className: classNames?.monthList }),
217
+ selectedText: slots.selectorText({
218
+ className: classNames?.selectorText
219
+ }),
220
+ popover: "min-w-[12ch]"
221
+ },
222
+ selectedKey: state.visibleRange.start.month,
223
+ "aria-label": formatMessage("selectMonth"),
224
+ onSelectionChange: (month) => {
225
+ state.setFocusedDate(
226
+ new CalendarDate(state.focusedDate.year, Number(month), 1)
227
+ );
228
+ },
229
+ children: (month) => /* @__PURE__ */ jsx(SelectItem, { children: month.textValue })
230
+ },
231
+ part
232
+ );
233
+ }
234
+ return /* @__PURE__ */ jsx(
235
+ Select,
236
+ {
237
+ isDisabled: state.isDisabled,
238
+ size,
239
+ variant: "clear",
240
+ items: years,
241
+ classNames: {
242
+ trigger: slots.yearSelector({
243
+ className: classNames?.yearSelector
244
+ }),
245
+ list: slots.yearList({ className: classNames?.yearList }),
246
+ selectedText: slots.selectorText({
247
+ className: classNames?.selectorText
248
+ })
249
+ },
250
+ selectedKey: state.visibleRange.start.year,
251
+ "aria-label": formatMessage("selectYear"),
252
+ onSelectionChange: (year) => {
253
+ state.setFocusedDate(
254
+ new CalendarDate(
255
+ Number(year),
256
+ state.focusedDate.month,
257
+ state.focusedDate.day
258
+ )
259
+ );
260
+ },
261
+ children: (year) => /* @__PURE__ */ jsx(SelectItem, { children: year.textValue })
262
+ },
263
+ part
264
+ );
265
+ }) });
266
+ };
267
+ function CalendarHeader({ offsetMonths = 0 }) {
268
+ const { direction } = useLocale();
269
+ const { slots, classNames, size } = useCalendarStyleContext();
270
+ const state = useContext(CalendarStateContext);
271
+ const monthYearTitle = useLocalizedMonthYear(
272
+ state.visibleRange.start.add({ months: offsetMonths }),
273
+ state.timeZone
274
+ );
275
+ if (offsetMonths === 0) {
276
+ return /* @__PURE__ */ jsxs("div", { className: slots.header({ className: classNames?.header }), children: [
277
+ /* @__PURE__ */ jsx(CalendarMonthDaySelector, {}),
278
+ /* @__PURE__ */ jsxs(
279
+ Group,
280
+ {
281
+ className: slots.buttonGroup({ className: classNames?.buttonGroup }),
282
+ children: [
283
+ /* @__PURE__ */ jsx(
284
+ Button,
285
+ {
286
+ size,
287
+ isIconOnly: true,
288
+ variant: "clear",
289
+ color: "sub",
290
+ slot: "previous",
291
+ className: slots.prevButton({ className: classNames?.prevButton }),
292
+ children: direction === "rtl" ? /* @__PURE__ */ jsx(ChevronRight, { "aria-hidden": true }) : /* @__PURE__ */ jsx(ChevronLeft, { "aria-hidden": true })
293
+ }
294
+ ),
295
+ /* @__PURE__ */ jsx(
296
+ Button,
297
+ {
298
+ size,
299
+ variant: "clear",
300
+ color: "sub",
301
+ isIconOnly: true,
302
+ slot: "next",
303
+ className: slots.nextButton({
304
+ className: classNames?.nextButton
305
+ }),
306
+ children: direction === "rtl" ? /* @__PURE__ */ jsx(ChevronLeft, { "aria-hidden": true }) : /* @__PURE__ */ jsx(ChevronRight, { "aria-hidden": true })
307
+ }
308
+ )
309
+ ]
310
+ }
311
+ )
312
+ ] });
313
+ }
314
+ return /* @__PURE__ */ jsx(
315
+ Heading,
316
+ {
317
+ className: slots.header({ className: classNames?.header }),
318
+ "aria-hidden": true,
319
+ level: 2,
320
+ children: monthYearTitle
321
+ }
322
+ );
323
+ }
324
+ function CalendarGridHeader() {
325
+ const { slots, classNames } = useCalendarStyleContext();
326
+ return /* @__PURE__ */ jsx(
327
+ CalendarGridHeader$1,
328
+ {
329
+ className: slots.gridHeader({ className: classNames?.gridHeader }),
330
+ children: (day) => /* @__PURE__ */ jsx(
331
+ CalendarHeaderCell,
332
+ {
333
+ className: slots.gridHeaderCell({
334
+ className: classNames?.gridHeaderCell
335
+ }),
336
+ children: day
337
+ }
338
+ )
339
+ }
340
+ );
341
+ }
342
+
343
+ export { CalendarBase, CalendarGridHeader, CalendarHeader };
@@ -0,0 +1,34 @@
1
+ "use strict";
2
+ "use client";
3
+ import { useDeepCompareMemo } from 'use-deep-compare';
4
+ import { calendarStyles } from '@opengovsg/oui-theme';
5
+ import { mapPropsVariants } from '../system/utils.js';
6
+ import { createContext } from '../system/react-utils/context.js';
7
+
8
+ function useProvideCalendarStyles(originalProps) {
9
+ const [props, variantProps] = mapPropsVariants(
10
+ originalProps,
11
+ calendarStyles.variantKeys
12
+ );
13
+ const { errorMessage, className, classNames, ...restProps } = props;
14
+ const slots = useDeepCompareMemo(
15
+ () => calendarStyles(variantProps),
16
+ [variantProps]
17
+ );
18
+ return {
19
+ context: {
20
+ slots,
21
+ classNames,
22
+ className,
23
+ size: variantProps.size ?? calendarStyles.defaultVariants.size,
24
+ errorMessage
25
+ },
26
+ calendarProps: { ...restProps, onChange: restProps.onChange }
27
+ };
28
+ }
29
+ const [CalendarStyleContext, useCalendarStyleContext] = createContext({
30
+ name: "CalendarStyleContext",
31
+ strict: true
32
+ });
33
+
34
+ export { CalendarStyleContext, useCalendarStyleContext, useProvideCalendarStyles };
@@ -0,0 +1,14 @@
1
+ "use strict";
2
+ "use client";
3
+ import { jsx } from 'react/jsx-runtime';
4
+ import { Provider } from 'react-aria-components';
5
+ import { forwardRef } from '../system/utils.js';
6
+ import { CalendarBase } from './calendar-base.js';
7
+ import { useProvideCalendarStyles, CalendarStyleContext } from './calendar-style-context.js';
8
+
9
+ const Calendar = forwardRef(function Calendar2(props, ref) {
10
+ const { calendarProps, context } = useProvideCalendarStyles(props);
11
+ return /* @__PURE__ */ jsx(Provider, { values: [[CalendarStyleContext, context]], children: /* @__PURE__ */ jsx(CalendarBase, { calendarRef: ref, ...calendarProps }) });
12
+ });
13
+
14
+ export { Calendar };
@@ -0,0 +1,5 @@
1
+ "use strict";
2
+ export { Calendar } from './calendar.js';
3
+ export { CalendarStyleContext, useCalendarStyleContext, useProvideCalendarStyles } from './calendar-style-context.js';
4
+ export { getEraFormat, useGenerateLocalizedMonths, useGenerateLocalizedYears, useLocalizedMonthYear } from './utils.js';
5
+ export { CalendarDate } from '@internationalized/date';
@@ -0,0 +1 @@
1
+ "use strict";
@@ -0,0 +1,57 @@
1
+ "use strict";
2
+ import { useMemo } from 'react';
3
+ import { CalendarDate } from '@internationalized/date';
4
+ import { useDateFormatter } from '@react-aria/i18n';
5
+
6
+ function getEraFormat(date) {
7
+ return date?.calendar.identifier === "gregory" && date.era === "BC" ? "short" : void 0;
8
+ }
9
+ function useLocalizedMonthYear(date, timeZone) {
10
+ const era = getEraFormat(date);
11
+ const monthFormatter = useDateFormatter({
12
+ month: "long",
13
+ year: "numeric",
14
+ era,
15
+ calendar: date.calendar.identifier,
16
+ timeZone
17
+ });
18
+ return monthFormatter.format(date.toDate(timeZone));
19
+ }
20
+ function useGenerateLocalizedMonths(timeZone, formatterOptions) {
21
+ const formatter = useDateFormatter({
22
+ month: "long",
23
+ timeZone,
24
+ ...formatterOptions
25
+ });
26
+ return useMemo(() => {
27
+ return Array.from({ length: 12 }, (_, i) => {
28
+ const id = i + 1;
29
+ return {
30
+ id,
31
+ textValue: formatter.format(
32
+ new CalendarDate(2020, id, 1).toDate(timeZone)
33
+ )
34
+ };
35
+ });
36
+ }, [formatter, timeZone]);
37
+ }
38
+ function useGenerateLocalizedYears(yearStart, yearEnd, timeZone, formatterOptions) {
39
+ const formatter = useDateFormatter({
40
+ year: "numeric",
41
+ timeZone,
42
+ ...formatterOptions
43
+ });
44
+ return useMemo(() => {
45
+ return Array.from({ length: yearEnd - yearStart + 1 }, (_, i) => {
46
+ const year = yearStart + i;
47
+ return {
48
+ id: year,
49
+ textValue: formatter.format(
50
+ new CalendarDate(year, 1, 1).toDate(timeZone)
51
+ )
52
+ };
53
+ });
54
+ }, [formatter, yearStart, yearEnd, timeZone]);
55
+ }
56
+
57
+ export { getEraFormat, useGenerateLocalizedMonths, useGenerateLocalizedYears, useLocalizedMonthYear };
@@ -1,10 +1,13 @@
1
1
  "use strict";
2
2
  "use client";
3
- import { jsx } from 'react/jsx-runtime';
3
+ import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
4
4
  import { useDeferredValue, useMemo, useState, useCallback } from 'react';
5
5
  import fuzzysort from 'fuzzysort';
6
- import { comboBoxFuzzyHighlightedTextStyles } from '@opengovsg/oui-theme';
7
- import { ComboBox, ComboBoxItem } from './combo-box.js';
6
+ import { Text } from 'react-aria-components';
7
+ import { comboBoxStyles, comboBoxItemStyles, comboBoxFuzzyHighlightedTextStyles } from '@opengovsg/oui-theme';
8
+ import { mapPropsVariants } from '../system/utils.js';
9
+ import { ComboBox } from './combo-box.js';
10
+ import { ComboBoxItem } from './combo-box-item.js';
8
11
 
9
12
  function HighlightedText({
10
13
  result,
@@ -27,18 +30,24 @@ function HighlightedText({
27
30
  i
28
31
  ));
29
32
  }
30
- function ComboBoxFuzzy({
31
- items,
32
- itemClassNames,
33
- onSelectionChange: onSelectionChangeProp,
34
- onInputChange: onInputChangeProp,
35
- ...props
36
- }) {
37
- const deferredInputValue = useDeferredValue(props.inputValue);
33
+ function ComboBoxFuzzy(originalProps) {
34
+ const [_props, variantProps] = mapPropsVariants(
35
+ originalProps,
36
+ comboBoxStyles.variantKeys
37
+ );
38
+ const {
39
+ items,
40
+ itemClassNames,
41
+ onSelectionChange: onSelectionChangeProp,
42
+ onInputChange: onInputChangeProp,
43
+ inputValue,
44
+ ...props
45
+ } = _props;
46
+ const deferredInputValue = useDeferredValue(inputValue);
38
47
  const preparedItems = useMemo(() => {
39
48
  return items?.map((item) => ({
40
49
  ...item,
41
- prepared: fuzzysort.prepare(item.name)
50
+ prepared: fuzzysort.prepare(item.textValue)
42
51
  })) ?? [];
43
52
  }, [items]);
44
53
  const [filteredResults, setFilteredResults] = useState({ items, result: {} });
@@ -61,7 +70,7 @@ function ComboBoxFuzzy({
61
70
  }).reduce(
62
71
  (acc, result) => {
63
72
  acc.items.push(result.obj);
64
- acc.result[result.obj.name] = result;
73
+ acc.result[result.obj.textValue] = result;
65
74
  return acc;
66
75
  },
67
76
  { items: [], result: {} }
@@ -70,34 +79,47 @@ function ComboBoxFuzzy({
70
79
  },
71
80
  [onInputChangeProp, preparedItems]
72
81
  );
82
+ const comboboxItemStyles = comboBoxItemStyles(variantProps);
73
83
  return /* @__PURE__ */ jsx(
74
84
  ComboBox,
75
85
  {
76
86
  ...props,
87
+ inputValue,
77
88
  items: filteredResults.items,
78
89
  dependencies: [deferredInputValue],
79
90
  onSelectionChange,
80
91
  onInputChange,
81
- children: (item) => /* @__PURE__ */ jsx(
82
- ComboBoxItem,
83
- {
84
- classNames: itemClassNames,
85
- label: ({ isSelected, isFocused }) => /* @__PURE__ */ jsx(
86
- HighlightedText,
87
- {
88
- className: itemClassNames?.highlight,
89
- result: filteredResults.result?.[item.name],
90
- originalText: item.name,
91
- isSelected,
92
- isFocused
93
- }
94
- ),
95
- description: item.description,
96
- textValue: item.name,
97
- id: item.value
98
- },
99
- item.name
100
- )
92
+ children: (item) => /* @__PURE__ */ jsx(ComboBoxItem, { textValue: item.textValue, id: item.id, children: ({ isSelected, isFocused }) => /* @__PURE__ */ jsxs(Fragment, { children: [
93
+ /* @__PURE__ */ jsx(
94
+ Text,
95
+ {
96
+ className: comboboxItemStyles.label({
97
+ className: itemClassNames?.label
98
+ }),
99
+ slot: "label",
100
+ children: /* @__PURE__ */ jsx(
101
+ HighlightedText,
102
+ {
103
+ className: itemClassNames?.highlight,
104
+ result: filteredResults.result?.[item.textValue],
105
+ originalText: item.textValue,
106
+ isSelected,
107
+ isFocused
108
+ }
109
+ )
110
+ }
111
+ ),
112
+ item.description && /* @__PURE__ */ jsx(
113
+ Text,
114
+ {
115
+ className: comboboxItemStyles.description({
116
+ className: itemClassNames?.description
117
+ }),
118
+ slot: "description",
119
+ children: item.description
120
+ }
121
+ )
122
+ ] }) }, item.id)
101
123
  }
102
124
  );
103
125
  }
@@ -0,0 +1,68 @@
1
+ "use strict";
2
+ "use client";
3
+ import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
4
+ import { useMemo } from 'react';
5
+ import { useContextProps, ListBoxItem, composeRenderProps, Text } from 'react-aria-components';
6
+ import { comboBoxItemStyles } from '@opengovsg/oui-theme';
7
+ import { forwardRef, mapPropsVariants } from '../system/utils.js';
8
+ import { ComboBoxVariantContext } from './combo-box-variant-context.js';
9
+
10
+ const ComboBoxItem = forwardRef(function ComboBoxItem2(originalProps, ref) {
11
+ [originalProps, ref] = useContextProps(
12
+ originalProps,
13
+ ref,
14
+ ComboBoxVariantContext
15
+ );
16
+ const [
17
+ { className, description, children, classNames, ...props },
18
+ variantProps
19
+ ] = mapPropsVariants(originalProps, comboBoxItemStyles.variantKeys);
20
+ const styles = comboBoxItemStyles(variantProps);
21
+ const defaultTextValue = useMemo(() => {
22
+ if (props.textValue) {
23
+ return props.textValue;
24
+ }
25
+ if (typeof children === "string") {
26
+ return children;
27
+ }
28
+ return void 0;
29
+ }, [children, props.textValue]);
30
+ return /* @__PURE__ */ jsx(
31
+ ListBoxItem,
32
+ {
33
+ textValue: defaultTextValue,
34
+ ...props,
35
+ className: composeRenderProps(
36
+ className ?? classNames?.container,
37
+ (className2, renderProps) => styles.container({ ...renderProps, className: className2 })
38
+ ),
39
+ children: (renderProps) => {
40
+ if (typeof children === "function") {
41
+ return children(renderProps);
42
+ }
43
+ return /* @__PURE__ */ jsxs(Fragment, { children: [
44
+ /* @__PURE__ */ jsx(
45
+ Text,
46
+ {
47
+ className: styles.label({ className: classNames?.label }),
48
+ slot: "label",
49
+ children
50
+ }
51
+ ),
52
+ description && /* @__PURE__ */ jsx(
53
+ Text,
54
+ {
55
+ className: styles.description({
56
+ className: classNames?.description
57
+ }),
58
+ slot: "description",
59
+ children: description
60
+ }
61
+ )
62
+ ] });
63
+ }
64
+ }
65
+ );
66
+ });
67
+
68
+ export { ComboBoxItem };
@@ -0,0 +1,10 @@
1
+ "use strict";
2
+ "use client";
3
+ import { createContext } from '../system/react-utils/context.js';
4
+
5
+ const [ComboBoxVariantContext, useComboBoxVariantContext] = createContext({
6
+ name: "ComboBoxVariantContext",
7
+ strict: true
8
+ });
9
+
10
+ export { ComboBoxVariantContext, useComboBoxVariantContext };