@opengovsg/oui 0.0.39 → 0.0.41

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 (90) hide show
  1. package/dist/cjs/badge/i18n.cjs +19 -0
  2. package/dist/cjs/badge/use-badge.cjs +4 -17
  3. package/dist/cjs/banner/banner.cjs +3 -16
  4. package/dist/cjs/banner/i18n.cjs +19 -0
  5. package/dist/cjs/calendar/calendar-bottom-content.cjs +4 -3
  6. package/dist/cjs/calendar/calendar-month-day-selector.cjs +5 -4
  7. package/dist/cjs/calendar/hooks/index.cjs +0 -3
  8. package/dist/cjs/calendar/i18n.cjs +27 -0
  9. package/dist/cjs/combo-box/combo-box.cjs +5 -22
  10. package/dist/cjs/combo-box/i18n.cjs +23 -0
  11. package/dist/cjs/date-field/date-field.cjs +18 -10
  12. package/dist/cjs/date-picker/date-picker.cjs +1 -0
  13. package/dist/cjs/date-range-picker/date-range-picker.cjs +2 -0
  14. package/dist/cjs/index.cjs +4 -0
  15. package/dist/cjs/modal/i18n.cjs +4 -4
  16. package/dist/cjs/modal/modal-content.cjs +2 -2
  17. package/dist/cjs/navbar/navbar-menu/i18n.cjs +8 -8
  18. package/dist/cjs/navbar/navbar-menu/toggle.cjs +2 -2
  19. package/dist/cjs/node_modules/.pnpm/lucide-react@0.475.0_react@19.2.3/node_modules/lucide-react/dist/esm/icons/search.cjs +22 -0
  20. package/dist/cjs/search-field/i18n.cjs +19 -0
  21. package/dist/cjs/search-field/index.cjs +8 -0
  22. package/dist/cjs/search-field/search-field.cjs +91 -0
  23. package/dist/cjs/time-field/index.cjs +8 -0
  24. package/dist/cjs/time-field/time-field.cjs +61 -0
  25. package/dist/esm/badge/i18n.js +17 -0
  26. package/dist/esm/badge/use-badge.js +5 -18
  27. package/dist/esm/banner/banner.js +4 -17
  28. package/dist/esm/banner/i18n.js +17 -0
  29. package/dist/esm/calendar/calendar-bottom-content.js +4 -3
  30. package/dist/esm/calendar/calendar-month-day-selector.js +5 -4
  31. package/dist/esm/calendar/hooks/index.js +0 -1
  32. package/dist/esm/calendar/i18n.js +25 -0
  33. package/dist/esm/combo-box/combo-box.js +6 -23
  34. package/dist/esm/combo-box/i18n.js +21 -0
  35. package/dist/esm/date-field/date-field.js +19 -11
  36. package/dist/esm/date-picker/date-picker.js +1 -0
  37. package/dist/esm/date-range-picker/date-range-picker.js +2 -0
  38. package/dist/esm/index.js +2 -0
  39. package/dist/esm/modal/i18n.js +4 -4
  40. package/dist/esm/modal/modal-content.js +3 -3
  41. package/dist/esm/navbar/navbar-menu/i18n.js +8 -8
  42. package/dist/esm/navbar/navbar-menu/toggle.js +3 -3
  43. package/dist/esm/node_modules/.pnpm/lucide-react@0.475.0_react@19.2.3/node_modules/lucide-react/dist/esm/icons/search.js +17 -0
  44. package/dist/esm/search-field/i18n.js +17 -0
  45. package/dist/esm/search-field/index.js +2 -0
  46. package/dist/esm/search-field/search-field.js +89 -0
  47. package/dist/esm/time-field/index.js +2 -0
  48. package/dist/esm/time-field/time-field.js +59 -0
  49. package/dist/types/badge/i18n.d.ts +15 -0
  50. package/dist/types/badge/i18n.d.ts.map +1 -0
  51. package/dist/types/badge/use-badge.d.ts.map +1 -1
  52. package/dist/types/banner/banner.d.ts.map +1 -1
  53. package/dist/types/banner/i18n.d.ts +15 -0
  54. package/dist/types/banner/i18n.d.ts.map +1 -0
  55. package/dist/types/calendar/calendar-bottom-content.d.ts.map +1 -1
  56. package/dist/types/calendar/calendar-month-day-selector.d.ts.map +1 -1
  57. package/dist/types/calendar/hooks/index.d.ts +0 -1
  58. package/dist/types/calendar/hooks/index.d.ts.map +1 -1
  59. package/dist/types/calendar/i18n.d.ts +23 -0
  60. package/dist/types/calendar/i18n.d.ts.map +1 -0
  61. package/dist/types/combo-box/combo-box.d.ts.map +1 -1
  62. package/dist/types/combo-box/i18n.d.ts +19 -0
  63. package/dist/types/combo-box/i18n.d.ts.map +1 -0
  64. package/dist/types/date-field/date-field.d.ts +4 -6
  65. package/dist/types/date-field/date-field.d.ts.map +1 -1
  66. package/dist/types/date-picker/date-picker.d.ts.map +1 -1
  67. package/dist/types/date-range-picker/date-range-picker.d.ts.map +1 -1
  68. package/dist/types/index.d.mts +2 -0
  69. package/dist/types/index.d.ts +2 -0
  70. package/dist/types/index.d.ts.map +1 -1
  71. package/dist/types/modal/i18n.d.ts +14 -2
  72. package/dist/types/modal/i18n.d.ts.map +1 -1
  73. package/dist/types/navbar/navbar-menu/i18n.d.ts +18 -2
  74. package/dist/types/navbar/navbar-menu/i18n.d.ts.map +1 -1
  75. package/dist/types/navbar/navbar-menu/toggle.d.ts.map +1 -1
  76. package/dist/types/search-field/i18n.d.ts +15 -0
  77. package/dist/types/search-field/i18n.d.ts.map +1 -0
  78. package/dist/types/search-field/index.d.ts +2 -0
  79. package/dist/types/search-field/index.d.ts.map +1 -0
  80. package/dist/types/search-field/search-field.d.ts +15 -0
  81. package/dist/types/search-field/search-field.d.ts.map +1 -0
  82. package/dist/types/time-field/index.d.ts +2 -0
  83. package/dist/types/time-field/index.d.ts.map +1 -0
  84. package/dist/types/time-field/time-field.d.ts +12 -0
  85. package/dist/types/time-field/time-field.d.ts.map +1 -0
  86. package/package.json +3 -3
  87. package/dist/cjs/calendar/hooks/use-calendar-i18n.cjs +0 -33
  88. package/dist/esm/calendar/hooks/use-calendar-i18n.js +0 -30
  89. package/dist/types/calendar/hooks/use-calendar-i18n.d.ts +0 -4
  90. package/dist/types/calendar/hooks/use-calendar-i18n.d.ts.map +0 -1
@@ -0,0 +1,91 @@
1
+ "use strict";
2
+ 'use strict';
3
+
4
+ var jsxRuntime = require('react/jsx-runtime');
5
+ var reactAria = require('react-aria');
6
+ var reactAriaComponents = require('react-aria-components');
7
+ var ouiTheme = require('@opengovsg/oui-theme');
8
+ var button = require('../button/button.cjs');
9
+ var field = require('../field/field.cjs');
10
+ var input = require('../input/input.cjs');
11
+ var utils = require('../system/utils.cjs');
12
+ var i18n = require('./i18n.cjs');
13
+ var search = require('../node_modules/.pnpm/lucide-react@0.475.0_react@19.2.3/node_modules/lucide-react/dist/esm/icons/search.cjs');
14
+ var x = require('../node_modules/.pnpm/lucide-react@0.475.0_react@19.2.3/node_modules/lucide-react/dist/esm/icons/x.cjs');
15
+
16
+ function SearchField(originalProps) {
17
+ const [
18
+ {
19
+ label,
20
+ description,
21
+ errorMessage,
22
+ searchIcon,
23
+ inputProps,
24
+ classNames,
25
+ ...props
26
+ },
27
+ variantProps
28
+ ] = utils.mapPropsVariants(originalProps, ouiTheme.searchFieldStyles.variantKeys);
29
+ const stringFormatter = reactAria.useLocalizedStringFormatter(i18n.i18nStrings);
30
+ const styles = ouiTheme.searchFieldStyles(variantProps);
31
+ return /* @__PURE__ */ jsxRuntime.jsxs(
32
+ reactAriaComponents.SearchField,
33
+ {
34
+ "aria-label": stringFormatter.format("Search"),
35
+ ...props,
36
+ className: ouiTheme.composeRenderProps(
37
+ props.className,
38
+ (className, renderProps) => styles.base({
39
+ className,
40
+ ...renderProps
41
+ })
42
+ ),
43
+ children: [
44
+ label && /* @__PURE__ */ jsxRuntime.jsx(
45
+ field.Label,
46
+ {
47
+ size: variantProps.size,
48
+ className: styles.label({ className: classNames?.label }),
49
+ children: label
50
+ }
51
+ ),
52
+ /* @__PURE__ */ jsxRuntime.jsxs(field.FieldGroup, { className: styles.group({ className: classNames?.group }), children: [
53
+ searchIcon !== null && (searchIcon === void 0 ? /* @__PURE__ */ jsxRuntime.jsx(
54
+ search.default,
55
+ {
56
+ "aria-hidden": true,
57
+ className: styles.searchIcon({
58
+ className: classNames?.searchIcon
59
+ })
60
+ }
61
+ ) : searchIcon),
62
+ /* @__PURE__ */ jsxRuntime.jsx(
63
+ input.Input,
64
+ {
65
+ size: variantProps.size,
66
+ variant: "unstyled",
67
+ className: styles.input({ className: classNames?.input }),
68
+ ...inputProps
69
+ }
70
+ ),
71
+ /* @__PURE__ */ jsxRuntime.jsx(
72
+ button.Button,
73
+ {
74
+ isIconOnly: true,
75
+ isAttached: true,
76
+ variant: "clear",
77
+ color: "sub",
78
+ size: variantProps.size,
79
+ className: styles.clearButton({ className: classNames?.clearButton }),
80
+ children: /* @__PURE__ */ jsxRuntime.jsx(x.default, { "aria-hidden": true })
81
+ }
82
+ )
83
+ ] }),
84
+ description && /* @__PURE__ */ jsxRuntime.jsx(field.Description, { size: variantProps.size, children: description }),
85
+ /* @__PURE__ */ jsxRuntime.jsx(field.FieldError, { size: variantProps.size, children: errorMessage })
86
+ ]
87
+ }
88
+ );
89
+ }
90
+
91
+ exports.SearchField = SearchField;
@@ -0,0 +1,8 @@
1
+ "use strict";
2
+ 'use strict';
3
+
4
+ var timeField = require('./time-field.cjs');
5
+
6
+
7
+
8
+ exports.TimeField = timeField.TimeField;
@@ -0,0 +1,61 @@
1
+ "use strict";
2
+ 'use strict';
3
+
4
+ var jsxRuntime = require('react/jsx-runtime');
5
+ var $670gB$react = require('react');
6
+ var reactAriaComponents = require('react-aria-components');
7
+ var ouiTheme = require('@opengovsg/oui-theme');
8
+ var dateField = require('../date-field/date-field.cjs');
9
+ var field = require('../field/field.cjs');
10
+ var utils = require('../system/utils.cjs');
11
+
12
+ function TimeField(originalProps) {
13
+ const [
14
+ {
15
+ label,
16
+ description,
17
+ className,
18
+ classNames,
19
+ errorMessage,
20
+ inputProps,
21
+ ...props
22
+ },
23
+ variantProps
24
+ ] = $670gB$react.useMemo(
25
+ () => utils.mapPropsVariants(originalProps, ouiTheme.dateInputStyles.variantKeys),
26
+ [originalProps]
27
+ );
28
+ return /* @__PURE__ */ jsxRuntime.jsxs(
29
+ reactAriaComponents.TimeField,
30
+ {
31
+ ...props,
32
+ isDisabled: variantProps.isDisabled,
33
+ className: ouiTheme.composeTailwindRenderProps(
34
+ className ?? classNames?.base,
35
+ "flex w-full flex-col gap-2"
36
+ ),
37
+ children: [
38
+ label && /* @__PURE__ */ jsxRuntime.jsx(field.Label, { size: variantProps.size, className: classNames?.label, children: label }),
39
+ /* @__PURE__ */ jsxRuntime.jsx(
40
+ dateField.DateInput,
41
+ {
42
+ ...variantProps,
43
+ ...inputProps,
44
+ className: classNames?.input ?? inputProps?.className
45
+ }
46
+ ),
47
+ description && /* @__PURE__ */ jsxRuntime.jsx(
48
+ field.Description,
49
+ {
50
+ size: variantProps.size,
51
+ className: classNames?.description,
52
+ children: description
53
+ }
54
+ ),
55
+ /* @__PURE__ */ jsxRuntime.jsx(field.FieldError, { size: variantProps.size, className: classNames?.error, children: errorMessage })
56
+ ]
57
+ }
58
+ );
59
+ }
60
+
61
+ exports.TimeField = TimeField;
@@ -0,0 +1,17 @@
1
+ "use strict";
2
+ const i18nStrings = {
3
+ "en-SG": {
4
+ "Close badge": "Close badge"
5
+ },
6
+ "zh-SG": {
7
+ "Close badge": "\u5173\u95ED\u5FBD\u7AE0"
8
+ },
9
+ "ms-SG": {
10
+ "Close badge": "Tutup lencana"
11
+ },
12
+ "ta-SG": {
13
+ "Close badge": "\u0BAA\u0BC7\u0B9F\u0BCD\u0B9C\u0BC8 \u0BAE\u0BC2\u0B9F\u0BC1"
14
+ }
15
+ };
16
+
17
+ export { i18nStrings };
@@ -1,26 +1,13 @@
1
1
  "use strict";
2
2
  import { useMemo, useCallback, cloneElement, isValidElement } from 'react';
3
3
  import { mergeProps } from '@react-aria/utils';
4
- import { useMessageFormatter, useFocusRing, usePress } from 'react-aria';
4
+ import { useLocalizedStringFormatter, useFocusRing, usePress } from 'react-aria';
5
5
  import { useDeepCompareMemo } from 'use-deep-compare';
6
6
  import { badgeStyles, cn, badgeCloseButtonStyles } from '@opengovsg/oui-theme';
7
7
  import { mapPropsVariants } from '../system/utils.js';
8
+ import { i18nStrings } from './i18n.js';
8
9
  import { useDomRef } from '../system/react-utils/refs.js';
9
10
 
10
- const i18nStrings = {
11
- "en-SG": {
12
- close: "Close badge"
13
- },
14
- "zh-SG": {
15
- close: "\u5173\u95ED\u5FBD\u7AE0"
16
- },
17
- "ms-SG": {
18
- close: "Tutup lencana"
19
- },
20
- "ta-SG": {
21
- close: "\u0BAA\u0BC7\u0B9F\u0BCD\u0B9C\u0BC8 \u0BAE\u0BC2\u0B9F\u0BC1"
22
- }
23
- };
24
11
  function useBadge(originalProps) {
25
12
  const [_props, variantProps] = mapPropsVariants(
26
13
  originalProps,
@@ -40,7 +27,7 @@ function useBadge(originalProps) {
40
27
  const domRef = useDomRef(ref);
41
28
  const Component = useMemo(() => as || "div", [as]);
42
29
  const baseClassName = cn(classNames?.base, className);
43
- const formatMessage = useMessageFormatter(i18nStrings);
30
+ const stringFormatter = useLocalizedStringFormatter(i18nStrings);
44
31
  const isCloseable = variantProps.isCloseable || !!onClose;
45
32
  const {
46
33
  focusProps: closeFocusProps,
@@ -81,16 +68,16 @@ function useBadge(originalProps) {
81
68
  className: classNames?.closeButton,
82
69
  isFocusVisible: isCloseButtonFocusVisible
83
70
  }),
84
- "aria-label": formatMessage("close"),
71
+ "aria-label": stringFormatter.format("Close badge"),
85
72
  ...mergeProps(closePressProps, closeFocusProps)
86
73
  };
87
74
  }, [
88
75
  classNames?.closeButton,
89
76
  closeFocusProps,
90
77
  closePressProps,
91
- formatMessage,
92
78
  isCloseButtonFocusVisible,
93
79
  slots,
80
+ stringFormatter,
94
81
  variantProps?.size
95
82
  ]);
96
83
  return {
@@ -2,28 +2,15 @@
2
2
  "use client";
3
3
  import { jsx, jsxs } from 'react/jsx-runtime';
4
4
  import { useMemo, useRef } from 'react';
5
- import { useMessageFormatter, useDisclosure } from 'react-aria';
5
+ import { useLocalizedStringFormatter, useDisclosure } from 'react-aria';
6
6
  import { useDisclosureState } from 'react-stately';
7
7
  import { bannerStyles } from '@opengovsg/oui-theme';
8
8
  import { Button } from '../button/button.js';
9
+ import { i18nStrings } from './i18n.js';
9
10
  import CircleAlert from '../node_modules/.pnpm/lucide-react@0.475.0_react@19.2.3/node_modules/lucide-react/dist/esm/icons/circle-alert.js';
10
11
  import Info from '../node_modules/.pnpm/lucide-react@0.475.0_react@19.2.3/node_modules/lucide-react/dist/esm/icons/info.js';
11
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';
12
13
 
13
- const i18nStrings = {
14
- "en-SG": {
15
- dismiss: "Close banner"
16
- },
17
- "zh-SG": {
18
- dismiss: "\u5173\u95ED\u6A2A\u5E45"
19
- },
20
- "ms-SG": {
21
- dismiss: "Tutup sepanduk"
22
- },
23
- "ta-SG": {
24
- dismiss: "\u0B89\u0B9F\u0BC8\u0B95\u0BB3\u0BC8 \u0BAE\u0BC2\u0B9F\u0BC1\u0B99\u0BCD\u0B95\u0BB3\u0BCD"
25
- }
26
- };
27
14
  const Banner = ({
28
15
  variant = "info",
29
16
  size,
@@ -35,7 +22,7 @@ const Banner = ({
35
22
  defaultExpanded = true,
36
23
  ...disclosureProps
37
24
  }) => {
38
- const formatMessage = useMessageFormatter(i18nStrings);
25
+ const stringFormatter = useLocalizedStringFormatter(i18nStrings);
39
26
  const styles = bannerStyles({ variant, size });
40
27
  const startContent = useMemo(() => {
41
28
  if (startContentProp) {
@@ -105,7 +92,7 @@ const Banner = ({
105
92
  variant: "clear",
106
93
  color: "neutral",
107
94
  isIconOnly: true,
108
- "aria-label": formatMessage("dismiss"),
95
+ "aria-label": stringFormatter.format("Close banner"),
109
96
  className: styles.dismissButton({
110
97
  className: classNames?.dismissButton
111
98
  }),
@@ -0,0 +1,17 @@
1
+ "use strict";
2
+ const i18nStrings = {
3
+ "en-SG": {
4
+ "Close banner": "Close banner"
5
+ },
6
+ "zh-SG": {
7
+ "Close banner": "\u5173\u95ED\u6A2A\u5E45"
8
+ },
9
+ "ms-SG": {
10
+ "Close banner": "Tutup sepanduk"
11
+ },
12
+ "ta-SG": {
13
+ "Close banner": "\u0B89\u0B9F\u0BC8\u0B95\u0BB3\u0BC8 \u0BAE\u0BC2\u0B9F\u0BC1\u0B99\u0BCD\u0B95\u0BB3\u0BCD"
14
+ }
15
+ };
16
+
17
+ export { i18nStrings };
@@ -3,10 +3,11 @@
3
3
  import { jsx } from 'react/jsx-runtime';
4
4
  import { useContext, useCallback } from 'react';
5
5
  import { today, getLocalTimeZone } from '@internationalized/date';
6
+ import { useLocalizedStringFormatter } from 'react-aria';
6
7
  import { Button } from '../button/button.js';
7
8
  import { AgnosticCalendarStateContext } from './agnostic-calendar-state-context.js';
8
9
  import { useCalendarStyleContext } from './calendar-style-context.js';
9
- import { useCalendarI18n } from './hooks/use-calendar-i18n.js';
10
+ import { i18nStrings } from './i18n.js';
10
11
 
11
12
  const CalendarBottomContent = ({
12
13
  bottomContent,
@@ -15,7 +16,7 @@ const CalendarBottomContent = ({
15
16
  }) => {
16
17
  const state = useContext(AgnosticCalendarStateContext);
17
18
  const { slots, classNames, size } = useCalendarStyleContext();
18
- const formatMessage = useCalendarI18n();
19
+ const stringFormatter = useLocalizedStringFormatter(i18nStrings);
19
20
  const handleTodayClick = useCallback(() => {
20
21
  const todayDate = today(getLocalTimeZone());
21
22
  state.setFocusedDate(todayDate);
@@ -45,7 +46,7 @@ const CalendarBottomContent = ({
45
46
  slot: null,
46
47
  className: slots.todayButton({ className: classNames?.todayButton }),
47
48
  onPress: handleTodayClick,
48
- children: formatMessage("today")
49
+ children: stringFormatter.format("Today")
49
50
  }
50
51
  )
51
52
  }
@@ -3,19 +3,20 @@
3
3
  import { jsx } from 'react/jsx-runtime';
4
4
  import { useContext } from 'react';
5
5
  import { CalendarDate } from '@internationalized/date';
6
+ import { useLocalizedStringFormatter } from 'react-aria';
6
7
  import { Group } from 'react-aria-components';
7
8
  import { Select } from '../select/select.js';
8
9
  import { SelectItem } from '../select/select-item.js';
9
10
  import { AgnosticCalendarStateContext } from './agnostic-calendar-state-context.js';
10
11
  import { useCalendarStyleContext } from './calendar-style-context.js';
12
+ import { i18nStrings } from './i18n.js';
11
13
  import { useCalendarSelectors } from './hooks/use-calendar-selectors.js';
12
- import { useCalendarI18n } from './hooks/use-calendar-i18n.js';
13
14
 
14
15
  const CalendarMonthDaySelector = () => {
15
16
  const { slots, size, classNames } = useCalendarStyleContext();
16
17
  const state = useContext(AgnosticCalendarStateContext);
17
18
  const { months, years, datePartOrder } = useCalendarSelectors(state);
18
- const formatMessage = useCalendarI18n();
19
+ const stringFormatter = useLocalizedStringFormatter(i18nStrings);
19
20
  return /* @__PURE__ */ jsx(Group, { className: slots.selectors({ className: classNames?.selectors }), children: datePartOrder.map((part) => {
20
21
  if (part === "month") {
21
22
  return /* @__PURE__ */ jsx(
@@ -36,7 +37,7 @@ const CalendarMonthDaySelector = () => {
36
37
  popover: "min-w-[12ch]"
37
38
  },
38
39
  selectedKey: state.visibleRange.start.month,
39
- "aria-label": formatMessage("selectMonth"),
40
+ "aria-label": stringFormatter.format("Select month"),
40
41
  onSelectionChange: (month) => {
41
42
  state.setFocusedDate(
42
43
  new CalendarDate(state.focusedDate.year, Number(month), 1)
@@ -65,7 +66,7 @@ const CalendarMonthDaySelector = () => {
65
66
  popover: "min-w-[8ch]"
66
67
  },
67
68
  selectedKey: state.visibleRange.start.year,
68
- "aria-label": formatMessage("selectYear"),
69
+ "aria-label": stringFormatter.format("Select year"),
69
70
  onSelectionChange: (year) => {
70
71
  state.setFocusedDate(
71
72
  new CalendarDate(
@@ -1,3 +1,2 @@
1
1
  "use strict";
2
- export { i18nStrings, useCalendarI18n } from './use-calendar-i18n.js';
3
2
  export { useCalendarSelectors } from './use-calendar-selectors.js';
@@ -0,0 +1,25 @@
1
+ "use strict";
2
+ const i18nStrings = {
3
+ "en-SG": {
4
+ "Select month": "Select month",
5
+ "Select year": "Select year",
6
+ Today: "Today"
7
+ },
8
+ "zh-SG": {
9
+ "Select month": "\u9009\u62E9\u6708\u4EFD",
10
+ "Select year": "\u9009\u62E9\u5E74\u4EFD",
11
+ Today: "\u4ECA\u5929"
12
+ },
13
+ "ms-SG": {
14
+ "Select month": "Pilih bulan",
15
+ "Select year": "Pilih tahun",
16
+ Today: "Hari ini"
17
+ },
18
+ "ta-SG": {
19
+ "Select month": "\u0BAE\u0BBE\u0BA4\u0BA4\u0BCD\u0BA4\u0BC8 \u0BA4\u0BC7\u0BB0\u0BCD\u0BA8\u0BCD\u0BA4\u0BC6\u0B9F\u0BC1\u0B95\u0BCD\u0B95\u0BB5\u0BC1\u0BAE\u0BCD",
20
+ "Select year": "\u0B86\u0BA3\u0BCD\u0B9F\u0BC8 \u0BA4\u0BC7\u0BB0\u0BCD\u0BA8\u0BCD\u0BA4\u0BC6\u0B9F\u0BC1\u0B95\u0BCD\u0B95\u0BB5\u0BC1\u0BAE\u0BCD",
21
+ Today: "\u0B87\u0BA9\u0BCD\u0BB1\u0BC1"
22
+ }
23
+ };
24
+
25
+ export { i18nStrings };
@@ -2,13 +2,14 @@
2
2
  "use client";
3
3
  import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
4
4
  import { useMemo, useCallback } from 'react';
5
- import { useMessageFormatter } from 'react-aria';
5
+ import { useLocalizedStringFormatter } from 'react-aria';
6
6
  import { ListLayout, Provider, ComboBox as ComboBox$1, Input, Button, Virtualizer, ListBox } from 'react-aria-components';
7
7
  import { listBoxItemStyles, cn, comboBoxStyles, composeTailwindRenderProps, composeRenderProps, comboBoxClearButtonStyles } from '@opengovsg/oui-theme';
8
8
  import { Label, FieldGroup, Description, FieldError } from '../field/field.js';
9
9
  import { Popover } from '../popover/popover.js';
10
10
  import { mapPropsVariants } from '../system/utils.js';
11
11
  import { ComboBoxVariantContext } from './combo-box-variant-context.js';
12
+ import { i18nStrings } from './i18n.js';
12
13
  import ChevronUp from '../node_modules/.pnpm/lucide-react@0.475.0_react@19.2.3/node_modules/lucide-react/dist/esm/icons/chevron-up.js';
13
14
  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';
14
15
  import X from '../node_modules/.pnpm/lucide-react@0.475.0_react@19.2.3/node_modules/lucide-react/dist/esm/icons/x.js';
@@ -23,42 +24,24 @@ const calculateEstimatedRowHeight = (size) => {
23
24
  return 48;
24
25
  }
25
26
  };
26
- const i18nStrings = {
27
- "en-SG": {
28
- clear: "Clear",
29
- empty: "No matching results"
30
- },
31
- "zh-SG": {
32
- clear: "\u6E05\u9664",
33
- empty: "\u6CA1\u6709\u5339\u914D\u7684\u7ED3\u679C"
34
- },
35
- "ms-SG": {
36
- clear: "Jelas",
37
- empty: "Tiada hasil yang sepadan"
38
- },
39
- "ta-SG": {
40
- clear: "\u0BA4\u0BC6\u0BB3\u0BBF\u0BB5\u0BC1",
41
- empty: "\u0BAA\u0BCA\u0BB0\u0BC1\u0BA8\u0BCD\u0BA4\u0BC1\u0BAE\u0BCD \u0BAE\u0BC1\u0B9F\u0BBF\u0BB5\u0BC1\u0B95\u0BB3\u0BCD \u0B87\u0BB2\u0BCD\u0BB2\u0BC8"
42
- }
43
- };
44
27
  function ComboBoxEmptyState({
45
28
  size,
46
29
  className
47
30
  }) {
48
31
  const styles = listBoxItemStyles({ size });
49
- const formatMessage = useMessageFormatter(i18nStrings);
32
+ const stringFormatter = useLocalizedStringFormatter(i18nStrings);
50
33
  return /* @__PURE__ */ jsx(
51
34
  "span",
52
35
  {
53
36
  className: styles.container({
54
37
  className: cn("cursor-default italic", className)
55
38
  }),
56
- children: formatMessage("empty")
39
+ children: stringFormatter.format("No matching results")
57
40
  }
58
41
  );
59
42
  }
60
43
  function ComboBox(originalProps) {
61
- const formatMessage = useMessageFormatter(i18nStrings);
44
+ const stringFormatter = useLocalizedStringFormatter(i18nStrings);
62
45
  const [_props, variantProps] = mapPropsVariants(
63
46
  originalProps,
64
47
  comboBoxStyles.variantKeys
@@ -171,7 +154,7 @@ function ComboBox(originalProps) {
171
154
  slot: null,
172
155
  onPress: onClear,
173
156
  isDisabled: isComboBoxDisabled,
174
- "aria-label": formatMessage("clear"),
157
+ "aria-label": stringFormatter.format("Clear"),
175
158
  className: composeRenderProps(
176
159
  classNames?.clearButton,
177
160
  (className, renderProps) => comboBoxClearButtonStyles({
@@ -0,0 +1,21 @@
1
+ "use strict";
2
+ const i18nStrings = {
3
+ "en-SG": {
4
+ Clear: "Clear",
5
+ "No matching results": "No matching results"
6
+ },
7
+ "zh-SG": {
8
+ Clear: "\u6E05\u9664",
9
+ "No matching results": "\u6CA1\u6709\u5339\u914D\u7684\u7ED3\u679C"
10
+ },
11
+ "ms-SG": {
12
+ Clear: "Jelas",
13
+ "No matching results": "Tiada hasil yang sepadan"
14
+ },
15
+ "ta-SG": {
16
+ Clear: "\u0BA4\u0BC6\u0BB3\u0BBF\u0BB5\u0BC1",
17
+ "No matching results": "\u0BAA\u0BCA\u0BB0\u0BC1\u0BA8\u0BCD\u0BA4\u0BC1\u0BAE\u0BCD \u0BAE\u0BC1\u0B9F\u0BBF\u0BB5\u0BC1\u0B95\u0BB3\u0BCD \u0B87\u0BB2\u0BCD\u0BB2\u0BC8"
18
+ }
19
+ };
20
+
21
+ export { i18nStrings };
@@ -3,7 +3,7 @@
3
3
  import { jsxs, jsx } from 'react/jsx-runtime';
4
4
  import { useMemo } from 'react';
5
5
  import { DateField as DateField$1, DateInput as DateInput$1, DateSegment } from 'react-aria-components';
6
- import { dateFieldStyles, composeTailwindRenderProps, dateInputStyles, composeRenderProps } from '@opengovsg/oui-theme';
6
+ import { dateInputStyles, composeTailwindRenderProps, composeRenderProps, dateSegmentStyles } from '@opengovsg/oui-theme';
7
7
  import { Label, Description, FieldError } from '../field/field.js';
8
8
  import { mapPropsVariants } from '../system/utils.js';
9
9
 
@@ -20,13 +20,9 @@ function DateField(originalProps) {
20
20
  },
21
21
  variantProps
22
22
  ] = useMemo(
23
- () => mapPropsVariants(originalProps, dateFieldStyles.variantKeys),
23
+ () => mapPropsVariants(originalProps, dateInputStyles.variantKeys),
24
24
  [originalProps]
25
25
  );
26
- const styles = dateFieldStyles({
27
- className: classNames?.input,
28
- ...variantProps
29
- });
30
26
  return /* @__PURE__ */ jsxs(
31
27
  DateField$1,
32
28
  {
@@ -38,7 +34,14 @@ function DateField(originalProps) {
38
34
  ),
39
35
  children: [
40
36
  label && /* @__PURE__ */ jsx(Label, { size: variantProps.size, className: classNames?.label, children: label }),
41
- /* @__PURE__ */ jsx(DateInput, { size: variantProps.size, className: styles, ...inputProps }),
37
+ /* @__PURE__ */ jsx(
38
+ DateInput,
39
+ {
40
+ ...variantProps,
41
+ ...inputProps,
42
+ className: classNames?.input ?? inputProps?.className
43
+ }
44
+ ),
42
45
  description && /* @__PURE__ */ jsx(
43
46
  Description,
44
47
  {
@@ -57,13 +60,18 @@ function DateInput(originalProps) {
57
60
  () => mapPropsVariants(originalProps, dateInputStyles.variantKeys),
58
61
  [originalProps]
59
62
  );
60
- const styles = dateInputStyles(variantProps);
61
63
  return /* @__PURE__ */ jsx(
62
64
  DateInput$1,
63
65
  {
64
- className: composeTailwindRenderProps(
66
+ className: composeRenderProps(
65
67
  className ?? classNames?.base,
66
- styles.base()
68
+ (className2, renderProps) => {
69
+ return dateInputStyles({
70
+ ...variantProps,
71
+ ...renderProps,
72
+ className: className2
73
+ });
74
+ }
67
75
  ),
68
76
  ...props,
69
77
  children: (segment) => /* @__PURE__ */ jsx(
@@ -72,7 +80,7 @@ function DateInput(originalProps) {
72
80
  segment,
73
81
  className: composeRenderProps(
74
82
  classNames?.segment,
75
- (className2, renderProps) => styles.segment({
83
+ (className2, renderProps) => dateSegmentStyles({
76
84
  isEditable: segment.isEditable,
77
85
  ...renderProps,
78
86
  className: className2
@@ -47,6 +47,7 @@ function DatePicker(originalProps) {
47
47
  /* @__PURE__ */ jsx(
48
48
  DateInput,
49
49
  {
50
+ variant: "unstyled",
50
51
  size: variantProps.size,
51
52
  className: styles.input({ className: classNames?.input })
52
53
  }
@@ -63,6 +63,7 @@ function DateRangePicker(originalProps) {
63
63
  /* @__PURE__ */ jsx(
64
64
  DateInput,
65
65
  {
66
+ variant: "unstyled",
66
67
  slot: "start",
67
68
  size: variantProps.size,
68
69
  className: styles.startInput({ className: classNames?.startInput })
@@ -81,6 +82,7 @@ function DateRangePicker(originalProps) {
81
82
  /* @__PURE__ */ jsx(
82
83
  DateInput,
83
84
  {
85
+ variant: "unstyled",
84
86
  slot: "end",
85
87
  size: variantProps.size,
86
88
  className: styles.endInput({ className: classNames?.endInput })
package/dist/esm/index.js CHANGED
@@ -65,6 +65,8 @@ export { useNavbar } from './navbar/use-navbar.js';
65
65
  export { NavbarProvider, useNavbarContext } from './navbar/navbar-context.js';
66
66
  export { Avatar } from './avatar/index.js';
67
67
  export { Accordion, AccordionContent, AccordionHeader, AccordionItem, AccordionStyleContext, useAccordionStyleContext } from './accordion/accordion.js';
68
+ export { TimeField } from './time-field/time-field.js';
69
+ export { SearchField } from './search-field/search-field.js';
68
70
  export { toast } from 'sonner';
69
71
  export { AvatarContext, useAvatarContext } from './avatar/avatar-context.js';
70
72
  export { AvatarGroup } from './avatar/avatar-group.js';
@@ -1,16 +1,16 @@
1
1
  "use strict";
2
2
  const i18nStrings = {
3
3
  "en-SG": {
4
- dismiss: "Dismiss"
4
+ Dismiss: "Dismiss"
5
5
  },
6
6
  "zh-SG": {
7
- dismiss: "\u53D6\u6D88"
7
+ Dismiss: "\u53D6\u6D88"
8
8
  },
9
9
  "ms-SG": {
10
- dismiss: "Tutup"
10
+ Dismiss: "Tutup"
11
11
  },
12
12
  "ta-SG": {
13
- dismiss: "\u0BAE\u0BC2\u0B9F\u0BC1"
13
+ Dismiss: "\u0BAE\u0BC2\u0B9F\u0BC1"
14
14
  }
15
15
  };
16
16
 
@@ -2,7 +2,7 @@
2
2
  "use client";
3
3
  import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
4
4
  import { useContext, isValidElement } from 'react';
5
- import { useMessageFormatter } from 'react-aria';
5
+ import { useLocalizedStringFormatter } from 'react-aria';
6
6
  import { Dialog } from 'react-aria-components';
7
7
  import { cn } from '@opengovsg/oui-theme';
8
8
  import { Button } from '../button/button.js';
@@ -17,7 +17,7 @@ function ModalContent({
17
17
  ...props
18
18
  }) {
19
19
  const { slots, classNames, buttonSize } = useContext(ModalVariantContext);
20
- const formatMessage = useMessageFormatter(i18nStrings);
20
+ const stringFormatter = useLocalizedStringFormatter(i18nStrings);
21
21
  const closeButtonContent = isValidElement(closeButtonContentProp) ? closeButtonContentProp : /* @__PURE__ */ jsx(X, {});
22
22
  return /* @__PURE__ */ jsx(
23
23
  Dialog,
@@ -32,7 +32,7 @@ function ModalContent({
32
32
  {
33
33
  slot: "close",
34
34
  isIconOnly: true,
35
- "aria-label": formatMessage("dismiss"),
35
+ "aria-label": stringFormatter.format("Dismiss"),
36
36
  size: buttonSize,
37
37
  variant: "clear",
38
38
  color: "neutral",