@opengovsg/oui 0.0.0-snapshot-20250311073924

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 (215) hide show
  1. package/LICENSE.md +13 -0
  2. package/dist/cjs/banner/banner.cjs +118 -0
  3. package/dist/cjs/banner/index.cjs +8 -0
  4. package/dist/cjs/button/button.cjs +86 -0
  5. package/dist/cjs/button/index.cjs +8 -0
  6. package/dist/cjs/combo-box/combo-box-fuzzy.cjs +107 -0
  7. package/dist/cjs/combo-box/combo-box.cjs +277 -0
  8. package/dist/cjs/combo-box/index.cjs +12 -0
  9. package/dist/cjs/field/field.cjs +63 -0
  10. package/dist/cjs/field/index.cjs +11 -0
  11. package/dist/cjs/govt-banner/govt-banner.cjs +259 -0
  12. package/dist/cjs/govt-banner/index.cjs +8 -0
  13. package/dist/cjs/hooks/index.cjs +8 -0
  14. package/dist/cjs/hooks/use-callback-ref.cjs +17 -0
  15. package/dist/cjs/hooks/use-controllable-state.cjs +37 -0
  16. package/dist/cjs/index.cjs +47 -0
  17. package/dist/cjs/input/index.cjs +8 -0
  18. package/dist/cjs/input/input.cjs +28 -0
  19. package/dist/cjs/node_modules/.pnpm/lucide-react@0.475.0_react@19.0.0/node_modules/lucide-react/dist/esm/Icon.cjs +48 -0
  20. package/dist/cjs/node_modules/.pnpm/lucide-react@0.475.0_react@19.0.0/node_modules/lucide-react/dist/esm/createLucideIcon.cjs +30 -0
  21. package/dist/cjs/node_modules/.pnpm/lucide-react@0.475.0_react@19.0.0/node_modules/lucide-react/dist/esm/defaultAttributes.cjs +24 -0
  22. package/dist/cjs/node_modules/.pnpm/lucide-react@0.475.0_react@19.0.0/node_modules/lucide-react/dist/esm/icons/chevron-down.cjs +19 -0
  23. package/dist/cjs/node_modules/.pnpm/lucide-react@0.475.0_react@19.0.0/node_modules/lucide-react/dist/esm/icons/chevron-up.cjs +19 -0
  24. package/dist/cjs/node_modules/.pnpm/lucide-react@0.475.0_react@19.0.0/node_modules/lucide-react/dist/esm/icons/circle-alert.cjs +23 -0
  25. package/dist/cjs/node_modules/.pnpm/lucide-react@0.475.0_react@19.0.0/node_modules/lucide-react/dist/esm/icons/external-link.cjs +23 -0
  26. package/dist/cjs/node_modules/.pnpm/lucide-react@0.475.0_react@19.0.0/node_modules/lucide-react/dist/esm/icons/info.cjs +23 -0
  27. package/dist/cjs/node_modules/.pnpm/lucide-react@0.475.0_react@19.0.0/node_modules/lucide-react/dist/esm/icons/landmark.cjs +26 -0
  28. package/dist/cjs/node_modules/.pnpm/lucide-react@0.475.0_react@19.0.0/node_modules/lucide-react/dist/esm/icons/lock.cjs +22 -0
  29. package/dist/cjs/node_modules/.pnpm/lucide-react@0.475.0_react@19.0.0/node_modules/lucide-react/dist/esm/icons/x.cjs +22 -0
  30. package/dist/cjs/node_modules/.pnpm/lucide-react@0.475.0_react@19.0.0/node_modules/lucide-react/dist/esm/shared/src/utils.cjs +16 -0
  31. package/dist/cjs/ripple/index.cjs +10 -0
  32. package/dist/cjs/ripple/ripple.cjs +70 -0
  33. package/dist/cjs/ripple/use-ripple.cjs +29 -0
  34. package/dist/cjs/skip-nav-link/index.cjs +8 -0
  35. package/dist/cjs/skip-nav-link/skip-nav-link.cjs +18 -0
  36. package/dist/cjs/spinner/index.cjs +10 -0
  37. package/dist/cjs/spinner/spinner.cjs +17 -0
  38. package/dist/cjs/spinner/use-spinner.cjs +38 -0
  39. package/dist/cjs/system/react-utils/context.cjs +31 -0
  40. package/dist/cjs/system/react-utils/index.cjs +8 -0
  41. package/dist/cjs/system/types.cjs +3 -0
  42. package/dist/cjs/system/utils.cjs +101 -0
  43. package/dist/cjs/tag-field/index.cjs +8 -0
  44. package/dist/cjs/tag-field/tag-field-list.cjs +73 -0
  45. package/dist/cjs/tag-field/tag-field-root.cjs +184 -0
  46. package/dist/cjs/tag-field/tag-field-state-context.cjs +11 -0
  47. package/dist/cjs/tag-field/tag-field-tag-list.cjs +70 -0
  48. package/dist/cjs/tag-field/tag-field-trigger.cjs +27 -0
  49. package/dist/cjs/tag-field/tag-field.cjs +106 -0
  50. package/dist/cjs/tag-field/types.cjs +3 -0
  51. package/dist/cjs/tag-field/use-tag-field-state.cjs +103 -0
  52. package/dist/cjs/tag-field/use-tag-field.cjs +188 -0
  53. package/dist/cjs/text-area/index.cjs +8 -0
  54. package/dist/cjs/text-area/text-area.cjs +28 -0
  55. package/dist/cjs/text-area-field/index.cjs +8 -0
  56. package/dist/cjs/text-area-field/text-area-field.cjs +48 -0
  57. package/dist/cjs/text-field/index.cjs +8 -0
  58. package/dist/cjs/text-field/text-field.cjs +48 -0
  59. package/dist/cjs/toggle/index.cjs +8 -0
  60. package/dist/cjs/toggle/toggle.cjs +48 -0
  61. package/dist/esm/banner/banner.js +116 -0
  62. package/dist/esm/banner/index.js +2 -0
  63. package/dist/esm/button/button.js +84 -0
  64. package/dist/esm/button/index.js +2 -0
  65. package/dist/esm/combo-box/combo-box-fuzzy.js +105 -0
  66. package/dist/esm/combo-box/combo-box.js +273 -0
  67. package/dist/esm/combo-box/index.js +3 -0
  68. package/dist/esm/field/field.js +58 -0
  69. package/dist/esm/field/index.js +2 -0
  70. package/dist/esm/govt-banner/govt-banner.js +257 -0
  71. package/dist/esm/govt-banner/index.js +2 -0
  72. package/dist/esm/hooks/index.js +2 -0
  73. package/dist/esm/hooks/use-callback-ref.js +15 -0
  74. package/dist/esm/hooks/use-controllable-state.js +35 -0
  75. package/dist/esm/index.js +19 -0
  76. package/dist/esm/input/index.js +2 -0
  77. package/dist/esm/input/input.js +26 -0
  78. package/dist/esm/node_modules/.pnpm/lucide-react@0.475.0_react@19.0.0/node_modules/lucide-react/dist/esm/Icon.js +44 -0
  79. package/dist/esm/node_modules/.pnpm/lucide-react@0.475.0_react@19.0.0/node_modules/lucide-react/dist/esm/createLucideIcon.js +26 -0
  80. package/dist/esm/node_modules/.pnpm/lucide-react@0.475.0_react@19.0.0/node_modules/lucide-react/dist/esm/defaultAttributes.js +20 -0
  81. package/dist/esm/node_modules/.pnpm/lucide-react@0.475.0_react@19.0.0/node_modules/lucide-react/dist/esm/icons/chevron-down.js +14 -0
  82. package/dist/esm/node_modules/.pnpm/lucide-react@0.475.0_react@19.0.0/node_modules/lucide-react/dist/esm/icons/chevron-up.js +14 -0
  83. package/dist/esm/node_modules/.pnpm/lucide-react@0.475.0_react@19.0.0/node_modules/lucide-react/dist/esm/icons/circle-alert.js +18 -0
  84. package/dist/esm/node_modules/.pnpm/lucide-react@0.475.0_react@19.0.0/node_modules/lucide-react/dist/esm/icons/external-link.js +18 -0
  85. package/dist/esm/node_modules/.pnpm/lucide-react@0.475.0_react@19.0.0/node_modules/lucide-react/dist/esm/icons/info.js +18 -0
  86. package/dist/esm/node_modules/.pnpm/lucide-react@0.475.0_react@19.0.0/node_modules/lucide-react/dist/esm/icons/landmark.js +21 -0
  87. package/dist/esm/node_modules/.pnpm/lucide-react@0.475.0_react@19.0.0/node_modules/lucide-react/dist/esm/icons/lock.js +17 -0
  88. package/dist/esm/node_modules/.pnpm/lucide-react@0.475.0_react@19.0.0/node_modules/lucide-react/dist/esm/icons/x.js +17 -0
  89. package/dist/esm/node_modules/.pnpm/lucide-react@0.475.0_react@19.0.0/node_modules/lucide-react/dist/esm/shared/src/utils.js +13 -0
  90. package/dist/esm/ripple/index.js +3 -0
  91. package/dist/esm/ripple/ripple.js +49 -0
  92. package/dist/esm/ripple/use-ripple.js +27 -0
  93. package/dist/esm/skip-nav-link/index.js +2 -0
  94. package/dist/esm/skip-nav-link/skip-nav-link.js +16 -0
  95. package/dist/esm/spinner/index.js +3 -0
  96. package/dist/esm/spinner/spinner.js +15 -0
  97. package/dist/esm/spinner/use-spinner.js +36 -0
  98. package/dist/esm/system/react-utils/context.js +29 -0
  99. package/dist/esm/system/react-utils/index.js +2 -0
  100. package/dist/esm/system/types.js +1 -0
  101. package/dist/esm/system/utils.js +94 -0
  102. package/dist/esm/tag-field/index.js +2 -0
  103. package/dist/esm/tag-field/tag-field-list.js +69 -0
  104. package/dist/esm/tag-field/tag-field-root.js +182 -0
  105. package/dist/esm/tag-field/tag-field-state-context.js +9 -0
  106. package/dist/esm/tag-field/tag-field-tag-list.js +68 -0
  107. package/dist/esm/tag-field/tag-field-trigger.js +24 -0
  108. package/dist/esm/tag-field/tag-field.js +104 -0
  109. package/dist/esm/tag-field/types.js +1 -0
  110. package/dist/esm/tag-field/use-tag-field-state.js +101 -0
  111. package/dist/esm/tag-field/use-tag-field.js +186 -0
  112. package/dist/esm/text-area/index.js +2 -0
  113. package/dist/esm/text-area/text-area.js +26 -0
  114. package/dist/esm/text-area-field/index.js +2 -0
  115. package/dist/esm/text-area-field/text-area-field.js +46 -0
  116. package/dist/esm/text-field/index.js +2 -0
  117. package/dist/esm/text-field/text-field.js +46 -0
  118. package/dist/esm/toggle/index.js +2 -0
  119. package/dist/esm/toggle/toggle.js +46 -0
  120. package/dist/types/banner/banner.d.ts +19 -0
  121. package/dist/types/banner/banner.d.ts.map +1 -0
  122. package/dist/types/banner/index.d.ts +2 -0
  123. package/dist/types/banner/index.d.ts.map +1 -0
  124. package/dist/types/button/button.d.ts +48 -0
  125. package/dist/types/button/button.d.ts.map +1 -0
  126. package/dist/types/button/index.d.ts +2 -0
  127. package/dist/types/button/index.d.ts.map +1 -0
  128. package/dist/types/combo-box/combo-box-fuzzy.d.ts +11 -0
  129. package/dist/types/combo-box/combo-box-fuzzy.d.ts.map +1 -0
  130. package/dist/types/combo-box/combo-box.d.ts +50 -0
  131. package/dist/types/combo-box/combo-box.d.ts.map +1 -0
  132. package/dist/types/combo-box/index.d.ts +3 -0
  133. package/dist/types/combo-box/index.d.ts.map +1 -0
  134. package/dist/types/field/field.d.ts +14 -0
  135. package/dist/types/field/field.d.ts.map +1 -0
  136. package/dist/types/field/index.d.ts +2 -0
  137. package/dist/types/field/index.d.ts.map +1 -0
  138. package/dist/types/govt-banner/govt-banner.d.ts +39 -0
  139. package/dist/types/govt-banner/govt-banner.d.ts.map +1 -0
  140. package/dist/types/govt-banner/index.d.ts +2 -0
  141. package/dist/types/govt-banner/index.d.ts.map +1 -0
  142. package/dist/types/hooks/index.d.ts +2 -0
  143. package/dist/types/hooks/index.d.ts.map +1 -0
  144. package/dist/types/hooks/use-callback-ref.d.ts +6 -0
  145. package/dist/types/hooks/use-callback-ref.d.ts.map +1 -0
  146. package/dist/types/hooks/use-controllable-state.d.ts +11 -0
  147. package/dist/types/hooks/use-controllable-state.d.ts.map +1 -0
  148. package/dist/types/index.d.mts +16 -0
  149. package/dist/types/index.d.ts +16 -0
  150. package/dist/types/index.d.ts.map +1 -0
  151. package/dist/types/input/index.d.ts +2 -0
  152. package/dist/types/input/index.d.ts.map +1 -0
  153. package/dist/types/input/input.d.ts +9 -0
  154. package/dist/types/input/input.d.ts.map +1 -0
  155. package/dist/types/ripple/index.d.ts +3 -0
  156. package/dist/types/ripple/index.d.ts.map +1 -0
  157. package/dist/types/ripple/ripple.d.ts +10 -0
  158. package/dist/types/ripple/ripple.d.ts.map +1 -0
  159. package/dist/types/ripple/use-ripple.d.ts +15 -0
  160. package/dist/types/ripple/use-ripple.d.ts.map +1 -0
  161. package/dist/types/skip-nav-link/index.d.ts +2 -0
  162. package/dist/types/skip-nav-link/index.d.ts.map +1 -0
  163. package/dist/types/skip-nav-link/skip-nav-link.d.ts +11 -0
  164. package/dist/types/skip-nav-link/skip-nav-link.d.ts.map +1 -0
  165. package/dist/types/spinner/index.d.ts +3 -0
  166. package/dist/types/spinner/index.d.ts.map +1 -0
  167. package/dist/types/spinner/spinner.d.ts +4 -0
  168. package/dist/types/spinner/spinner.d.ts.map +1 -0
  169. package/dist/types/spinner/use-spinner.d.ts +66 -0
  170. package/dist/types/spinner/use-spinner.d.ts.map +1 -0
  171. package/dist/types/system/react-utils/context.d.ts +27 -0
  172. package/dist/types/system/react-utils/context.d.ts.map +1 -0
  173. package/dist/types/system/react-utils/index.d.ts +2 -0
  174. package/dist/types/system/react-utils/index.d.ts.map +1 -0
  175. package/dist/types/system/types.d.ts +63 -0
  176. package/dist/types/system/types.d.ts.map +1 -0
  177. package/dist/types/system/utils.d.ts +856 -0
  178. package/dist/types/system/utils.d.ts.map +1 -0
  179. package/dist/types/tag-field/index.d.ts +2 -0
  180. package/dist/types/tag-field/index.d.ts.map +1 -0
  181. package/dist/types/tag-field/tag-field-list.d.ts +22 -0
  182. package/dist/types/tag-field/tag-field-list.d.ts.map +1 -0
  183. package/dist/types/tag-field/tag-field-root.d.ts +14 -0
  184. package/dist/types/tag-field/tag-field-root.d.ts.map +1 -0
  185. package/dist/types/tag-field/tag-field-state-context.d.ts +12 -0
  186. package/dist/types/tag-field/tag-field-state-context.d.ts.map +1 -0
  187. package/dist/types/tag-field/tag-field-tag-list.d.ts +17 -0
  188. package/dist/types/tag-field/tag-field-tag-list.d.ts.map +1 -0
  189. package/dist/types/tag-field/tag-field-trigger.d.ts +8 -0
  190. package/dist/types/tag-field/tag-field-trigger.d.ts.map +1 -0
  191. package/dist/types/tag-field/tag-field.d.ts +3 -0
  192. package/dist/types/tag-field/tag-field.d.ts.map +1 -0
  193. package/dist/types/tag-field/types.d.ts +71 -0
  194. package/dist/types/tag-field/types.d.ts.map +1 -0
  195. package/dist/types/tag-field/use-tag-field-state.d.ts +35 -0
  196. package/dist/types/tag-field/use-tag-field-state.d.ts.map +1 -0
  197. package/dist/types/tag-field/use-tag-field.d.ts +48 -0
  198. package/dist/types/tag-field/use-tag-field.d.ts.map +1 -0
  199. package/dist/types/text-area/index.d.ts +2 -0
  200. package/dist/types/text-area/index.d.ts.map +1 -0
  201. package/dist/types/text-area/text-area.d.ts +9 -0
  202. package/dist/types/text-area/text-area.d.ts.map +1 -0
  203. package/dist/types/text-area-field/index.d.ts +2 -0
  204. package/dist/types/text-area-field/index.d.ts.map +1 -0
  205. package/dist/types/text-area-field/text-area-field.d.ts +12 -0
  206. package/dist/types/text-area-field/text-area-field.d.ts.map +1 -0
  207. package/dist/types/text-field/index.d.ts +2 -0
  208. package/dist/types/text-field/index.d.ts.map +1 -0
  209. package/dist/types/text-field/text-field.d.ts +12 -0
  210. package/dist/types/text-field/text-field.d.ts.map +1 -0
  211. package/dist/types/toggle/index.d.ts +2 -0
  212. package/dist/types/toggle/index.d.ts.map +1 -0
  213. package/dist/types/toggle/toggle.d.ts +22 -0
  214. package/dist/types/toggle/toggle.d.ts.map +1 -0
  215. package/package.json +93 -0
@@ -0,0 +1,273 @@
1
+ "use strict";
2
+ "use client";
3
+ import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
4
+ import { useMemo, useCallback } from 'react';
5
+ import { comboBoxItemStyles, cn, comboBoxStyles, composeTailwindRenderProps, composeRenderProps, comboBoxClearButtonStyles } from '@opengovsg/oui-theme';
6
+ import { useMessageFormatter } from 'react-aria';
7
+ import { UNSTABLE_ListLayout, ComboBox as ComboBox$1, Input, Button, UNSTABLE_Virtualizer, Popover, ListBox, ListBoxItem, Text } from 'react-aria-components';
8
+ import { Label, FieldGroup, Description, FieldError } from '../field/field.js';
9
+ import ChevronUp from '../node_modules/.pnpm/lucide-react@0.475.0_react@19.0.0/node_modules/lucide-react/dist/esm/icons/chevron-up.js';
10
+ import ChevronDown from '../node_modules/.pnpm/lucide-react@0.475.0_react@19.0.0/node_modules/lucide-react/dist/esm/icons/chevron-down.js';
11
+ import X from '../node_modules/.pnpm/lucide-react@0.475.0_react@19.0.0/node_modules/lucide-react/dist/esm/icons/x.js';
12
+
13
+ const calculateEstimatedRowHeight = (size) => {
14
+ switch (size) {
15
+ case "xs":
16
+ return 44;
17
+ case "sm":
18
+ return 44;
19
+ case "md":
20
+ return 48;
21
+ }
22
+ };
23
+ const i18nStrings = {
24
+ "en-SG": {
25
+ clear: "Clear",
26
+ empty: "No matching results"
27
+ },
28
+ "zh-SG": {
29
+ clear: "\u6E05\u9664",
30
+ empty: "\u6CA1\u6709\u5339\u914D\u7684\u7ED3\u679C"
31
+ },
32
+ "ms-SG": {
33
+ clear: "Jelas",
34
+ empty: "Tiada hasil yang sepadan"
35
+ },
36
+ "ta-SG": {
37
+ clear: "\u0BA4\u0BC6\u0BB3\u0BBF\u0BB5\u0BC1",
38
+ 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"
39
+ }
40
+ };
41
+ function ComboBoxEmptyState({
42
+ size,
43
+ className
44
+ }) {
45
+ const styles = comboBoxItemStyles({ size });
46
+ const formatMessage = useMessageFormatter(i18nStrings);
47
+ return /* @__PURE__ */ jsx(
48
+ "span",
49
+ {
50
+ className: styles.container({
51
+ className: cn("cursor-default italic", className)
52
+ }),
53
+ children: formatMessage("empty")
54
+ }
55
+ );
56
+ }
57
+ function ComboBox({
58
+ label,
59
+ description,
60
+ errorMessage,
61
+ classNames,
62
+ itemClassNames,
63
+ size,
64
+ listLayoutOptions,
65
+ children,
66
+ dependencies,
67
+ onClear,
68
+ renderEmptyState: renderEmptyStateProp,
69
+ ...props
70
+ }) {
71
+ const formatMessage = useMessageFormatter(i18nStrings);
72
+ const styles = comboBoxStyles({ size });
73
+ const layout = useMemo(() => {
74
+ return new UNSTABLE_ListLayout({
75
+ estimatedRowHeight: calculateEstimatedRowHeight(size ?? "md"),
76
+ ...listLayoutOptions
77
+ });
78
+ }, [listLayoutOptions, size]);
79
+ const renderEmptyState = useCallback(
80
+ (props2) => {
81
+ if (renderEmptyStateProp) {
82
+ return renderEmptyStateProp(props2);
83
+ }
84
+ return /* @__PURE__ */ jsx(ComboBoxEmptyState, { size, className: classNames?.emptyState });
85
+ },
86
+ [classNames?.emptyState, renderEmptyStateProp, size]
87
+ );
88
+ return /* @__PURE__ */ jsx(
89
+ ComboBox$1,
90
+ {
91
+ className: composeTailwindRenderProps(
92
+ props.className ?? classNames?.base,
93
+ styles.container()
94
+ ),
95
+ shouldFocusWrap: true,
96
+ allowsEmptyCollection: true,
97
+ ...props,
98
+ children: ({ isOpen, isDisabled: isComboBoxDisabled }) => /* @__PURE__ */ jsxs(Fragment, { children: [
99
+ /* @__PURE__ */ jsx(
100
+ Label,
101
+ {
102
+ size,
103
+ className: styles.label({ className: classNames?.label, size }),
104
+ children: label
105
+ }
106
+ ),
107
+ /* @__PURE__ */ jsxs("div", { className: "flex flex-row", children: [
108
+ /* @__PURE__ */ jsxs(
109
+ FieldGroup,
110
+ {
111
+ className: composeRenderProps(
112
+ classNames?.group,
113
+ (className, renderProps) => styles.group({
114
+ ...renderProps,
115
+ className,
116
+ size,
117
+ isClearable: !!onClear
118
+ })
119
+ ),
120
+ children: [
121
+ /* @__PURE__ */ jsx(
122
+ Input,
123
+ {
124
+ className: composeRenderProps(
125
+ classNames?.field,
126
+ (className, renderProps) => styles.field({ ...renderProps, className, size })
127
+ )
128
+ }
129
+ ),
130
+ /* @__PURE__ */ jsx(
131
+ Button,
132
+ {
133
+ className: composeRenderProps(
134
+ classNames?.expandButton,
135
+ (className, renderProps) => styles.expandButton({ ...renderProps, className, size })
136
+ ),
137
+ children: isOpen ? /* @__PURE__ */ jsx(
138
+ ChevronUp,
139
+ {
140
+ className: styles.icon({
141
+ className: classNames?.icon,
142
+ size
143
+ })
144
+ }
145
+ ) : /* @__PURE__ */ jsx(
146
+ ChevronDown,
147
+ {
148
+ className: styles.icon({
149
+ className: classNames?.icon,
150
+ size
151
+ })
152
+ }
153
+ )
154
+ }
155
+ )
156
+ ]
157
+ }
158
+ ),
159
+ !!onClear && /* @__PURE__ */ jsx(
160
+ Button,
161
+ {
162
+ slot: null,
163
+ onPress: onClear,
164
+ isDisabled: isComboBoxDisabled,
165
+ "aria-label": formatMessage("clear"),
166
+ className: composeRenderProps(
167
+ classNames?.clearButton,
168
+ (className, renderProps) => comboBoxClearButtonStyles({
169
+ ...renderProps,
170
+ className,
171
+ size,
172
+ isInactive: !props.inputValue,
173
+ isDisabled: renderProps.isDisabled
174
+ })
175
+ ),
176
+ children: /* @__PURE__ */ jsx(
177
+ X,
178
+ {
179
+ className: styles.icon({
180
+ className: classNames?.icon,
181
+ size
182
+ })
183
+ }
184
+ )
185
+ }
186
+ )
187
+ ] }),
188
+ description && /* @__PURE__ */ jsx(Description, { size, children: description }),
189
+ /* @__PURE__ */ jsx(FieldError, { size, children: errorMessage }),
190
+ /* @__PURE__ */ jsx(UNSTABLE_Virtualizer, { layout, children: /* @__PURE__ */ jsx(
191
+ Popover,
192
+ {
193
+ className: composeRenderProps(
194
+ classNames?.popover,
195
+ (className, renderProps) => styles.popover({ ...renderProps, className })
196
+ ),
197
+ children: /* @__PURE__ */ jsx(
198
+ ListBox,
199
+ {
200
+ className: composeRenderProps(
201
+ classNames?.list,
202
+ (className, renderProps) => styles.list({ ...renderProps, className })
203
+ ),
204
+ dependencies,
205
+ renderEmptyState,
206
+ children: (item) => {
207
+ if (children) {
208
+ return children(item);
209
+ }
210
+ return /* @__PURE__ */ jsx(
211
+ ComboBoxItem,
212
+ {
213
+ size,
214
+ id: item.value,
215
+ label: item.name,
216
+ textValue: item.name,
217
+ description: item.description,
218
+ classNames: itemClassNames
219
+ }
220
+ );
221
+ }
222
+ }
223
+ )
224
+ }
225
+ ) })
226
+ ] })
227
+ }
228
+ );
229
+ }
230
+ function ComboBoxItem({
231
+ className,
232
+ size,
233
+ description,
234
+ label,
235
+ classNames,
236
+ ...props
237
+ }) {
238
+ const styles = comboBoxItemStyles({ size });
239
+ return /* @__PURE__ */ jsx(
240
+ ListBoxItem,
241
+ {
242
+ ...props,
243
+ className: composeRenderProps(
244
+ className ?? classNames?.container,
245
+ (className2, renderProps) => styles.container({ ...renderProps, className: className2 })
246
+ ),
247
+ children: (renderProps) => {
248
+ return /* @__PURE__ */ jsxs(Fragment, { children: [
249
+ /* @__PURE__ */ jsx(
250
+ Text,
251
+ {
252
+ className: styles.label({ className: classNames?.label }),
253
+ slot: "label",
254
+ children: typeof label === "function" ? label(renderProps) : label
255
+ }
256
+ ),
257
+ description && /* @__PURE__ */ jsx(
258
+ Text,
259
+ {
260
+ className: styles.description({
261
+ className: classNames?.description
262
+ }),
263
+ slot: "description",
264
+ children: typeof description === "function" ? description(renderProps) : description
265
+ }
266
+ )
267
+ ] });
268
+ }
269
+ }
270
+ );
271
+ }
272
+
273
+ export { ComboBox, ComboBoxEmptyState, ComboBoxItem };
@@ -0,0 +1,3 @@
1
+ "use strict";
2
+ export { ComboBox, ComboBoxEmptyState, ComboBoxItem } from './combo-box.js';
3
+ export { ComboBoxFuzzy } from './combo-box-fuzzy.js';
@@ -0,0 +1,58 @@
1
+ "use strict";
2
+ "use client";
3
+ import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
4
+ import { labelStyles, descriptionStyles, fieldErrorStyles, composeRenderProps, fieldGroupStyles } from '@opengovsg/oui-theme';
5
+ import { Label as Label$1, Text, FieldError as FieldError$1, Group } from 'react-aria-components';
6
+ import CircleAlert from '../node_modules/.pnpm/lucide-react@0.475.0_react@19.0.0/node_modules/lucide-react/dist/esm/icons/circle-alert.js';
7
+
8
+ function Label({ size, className, ...props }) {
9
+ return /* @__PURE__ */ jsx(Label$1, { ...props, className: labelStyles({ className, size }) });
10
+ }
11
+ function Description({ size, className, ...props }) {
12
+ return /* @__PURE__ */ jsx(
13
+ Text,
14
+ {
15
+ ...props,
16
+ slot: "description",
17
+ className: descriptionStyles({ className, size })
18
+ }
19
+ );
20
+ }
21
+ function FieldError({
22
+ children,
23
+ className,
24
+ size,
25
+ classNames,
26
+ ...props
27
+ }) {
28
+ const styles = fieldErrorStyles({ size });
29
+ if (!children) return null;
30
+ return /* @__PURE__ */ jsx(
31
+ FieldError$1,
32
+ {
33
+ ...props,
34
+ className: composeRenderProps(
35
+ className ?? classNames?.text,
36
+ (className2, renderProps) => styles.text({ ...renderProps, className: className2 })
37
+ ),
38
+ children: /* @__PURE__ */ jsxs(Fragment, { children: [
39
+ /* @__PURE__ */ jsx(CircleAlert, { className: styles.icon({ className: classNames?.icon }) }),
40
+ children
41
+ ] })
42
+ }
43
+ );
44
+ }
45
+ function FieldGroup(props) {
46
+ return /* @__PURE__ */ jsx(
47
+ Group,
48
+ {
49
+ ...props,
50
+ className: composeRenderProps(
51
+ props.className,
52
+ (className, renderProps) => fieldGroupStyles({ ...renderProps, className })
53
+ )
54
+ }
55
+ );
56
+ }
57
+
58
+ export { Description, FieldError, FieldGroup, Label };
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ export { Description, FieldError, FieldGroup, Label } from './field.js';
@@ -0,0 +1,257 @@
1
+ "use strict";
2
+ "use client";
3
+ import { jsxs, jsx } from 'react/jsx-runtime';
4
+ import { useRef } from 'react';
5
+ import { govtBannerStyles, dataAttr, twMerge } from '@opengovsg/oui-theme';
6
+ import { useMessageFormatter, useDisclosure, useButton, useFocusRing, mergeProps } from 'react-aria';
7
+ import { useDisclosureState } from 'react-stately';
8
+ import ChevronDown from '../node_modules/.pnpm/lucide-react@0.475.0_react@19.0.0/node_modules/lucide-react/dist/esm/icons/chevron-down.js';
9
+ import Landmark from '../node_modules/.pnpm/lucide-react@0.475.0_react@19.0.0/node_modules/lucide-react/dist/esm/icons/landmark.js';
10
+ import ExternalLink from '../node_modules/.pnpm/lucide-react@0.475.0_react@19.0.0/node_modules/lucide-react/dist/esm/icons/external-link.js';
11
+ import Lock from '../node_modules/.pnpm/lucide-react@0.475.0_react@19.0.0/node_modules/lucide-react/dist/esm/icons/lock.js';
12
+
13
+ const i18nStrings = {
14
+ "en-SG": {
15
+ mainLabel: "A Singapore Government Agency Website",
16
+ identifyLabel: "How to identify",
17
+ environmentLabel: "[NOTE: THIS IS A {environment} WEBSITE]",
18
+ officialLinkHeader: "Official website links end with .gov.sg",
19
+ officialLinkContent: "Government agencies communicate via <boldThis>.gov.sg</boldThis> websites (e.g. go.gov.sg/open).",
20
+ officialLinkTrusted: "Trusted websites",
21
+ secureHeader: "Secure websites use HTTPS",
22
+ secureContent: "Look for a <boldThis>lock</boldThis> {icon} or https:// as an added precaution. Share sensitive information only on official, secure websites."
23
+ },
24
+ "zh-SG": {
25
+ mainLabel: "A Singapore Government Agency Website",
26
+ identifyLabel: "How to identify",
27
+ environmentLabel: "[NOTE: THIS IS A {environment} WEBSITE]",
28
+ officialLinkHeader: "Official website links end with .gov.sg",
29
+ officialLinkContent: "Government agencies communicate via <boldThis>.gov.sg</boldThis> websites (e.g. go.gov.sg/open).",
30
+ officialLinkTrusted: "Trusted websites",
31
+ secureHeader: "Secure websites use HTTPS",
32
+ secureContent: "Look for a <boldThis>lock</boldThis> {icon} or https:// as an added precaution. Share sensitive information only on official, secure websites."
33
+ },
34
+ "ms-SG": {
35
+ mainLabel: "A Singapore Government Agency Website",
36
+ identifyLabel: "How to identify",
37
+ environmentLabel: "[NOTE: THIS IS A {environment} WEBSITE]",
38
+ officialLinkHeader: "Official website links end with .gov.sg",
39
+ officialLinkContent: "Government agencies communicate via <boldThis>.gov.sg</boldThis> websites (e.g. go.gov.sg/open).",
40
+ officialLinkTrusted: "Trusted websites",
41
+ secureHeader: "Secure websites use HTTPS",
42
+ secureContent: "Look for a <boldThis>lock</boldThis> {icon} or https:// as an added precaution. Share sensitive information only on official, secure websites."
43
+ },
44
+ "ta-SG": {
45
+ mainLabel: "A Singapore Government Agency Website",
46
+ identifyLabel: "How to identify",
47
+ environmentLabel: "[NOTE: THIS IS A {environment} WEBSITE]",
48
+ officialLinkHeader: "Official website links end with .gov.sg",
49
+ officialLinkContent: "Government agencies communicate via <boldThis>.gov.sg</boldThis> websites (e.g. go.gov.sg/open).",
50
+ officialLinkTrusted: "Trusted websites",
51
+ secureHeader: "Secure websites use HTTPS",
52
+ secureContent: "Look for a <boldThis>lock</boldThis> {icon} or https:// as an added precaution. Share sensitive information only on official, secure websites."
53
+ }
54
+ };
55
+ function GovtBanner({
56
+ environment,
57
+ classNames,
58
+ ...props
59
+ }) {
60
+ const formatMessage = useMessageFormatter(i18nStrings);
61
+ const state = useDisclosureState(props);
62
+ const panelRef = useRef(null);
63
+ const triggerRef = useRef(null);
64
+ const { buttonProps: triggerProps, panelProps } = useDisclosure(
65
+ props,
66
+ state,
67
+ panelRef
68
+ );
69
+ const { buttonProps } = useButton(triggerProps, triggerRef);
70
+ const { isFocusVisible, focusProps } = useFocusRing();
71
+ const slots = govtBannerStyles();
72
+ return /* @__PURE__ */ jsxs(
73
+ "div",
74
+ {
75
+ className: slots.banner({ className: classNames?.banner }),
76
+ role: "banner",
77
+ children: [
78
+ /* @__PURE__ */ jsxs(
79
+ "div",
80
+ {
81
+ className: slots.mainContentContainer({
82
+ className: classNames?.mainContentContainer
83
+ }),
84
+ children: [
85
+ /* @__PURE__ */ jsxs(
86
+ "svg",
87
+ {
88
+ className: slots.crest({ className: classNames?.crest }),
89
+ version: "1.1",
90
+ viewBox: "0 0 32 32",
91
+ xmlns: "http://www.w3.org/2000/svg",
92
+ children: [
93
+ /* @__PURE__ */ jsx("path", { d: "M5.896 11.185c0 0-0.949 1.341 0.294 3.075 0 0 0.196-0.883 2.159-0.883h2.356c2.225 0 3.893-2.126 2.846-4.319 0 0 1.57 0.164 2.095-0.818 0.523-0.981-0.033-1.374-0.818-1.374h-3.959c0 0.704-1.341 0.802-1.341 0h-2.225c0 0-1.669 0-1.701 1.407 0 0 0.377-0.229 0.752-0.261v0.375c0 0-0.458 0.082-0.671 0.197-0.212 0.114-0.523 0.425-0.228 1.227 0.294 0.801 0.409 1.079 0.409 1.079s0.475-0.41 1.244-0.41h0.9c1.602 0 1.308 1.554-0.295 1.554s-1.815-0.85-1.815-0.85z" }),
94
+ /* @__PURE__ */ jsx("path", { d: "M14.255 9.566c0 0 0.54 0.033 0.932-0.31 0 0 3.55 2.765-1.717 8.326-5.268 5.562-1.195 9.162-1.195 9.162s-0.948 0.915-0.409 2.699c0 0-2.191-1.237-3.867-3.338-2.422-3.036-3.902-7.681 2.749-11.386 0 0 4.389-2.208 3.506-5.153z" }),
95
+ /* @__PURE__ */ jsx("path", { d: "M8.829 6.343c0 0 0.709-1.265 2.355-1.265 1.298 0 1.594-0.666 1.594-0.666s0.566-1.079 3.424-1.079c2.619 0 4.384 0.873 5.812 2.039 0 0-3.85-2.388-7.645 0.971h-5.54z" }),
96
+ /* @__PURE__ */ jsx("path", { d: "M24.839 14.348c-0.109-3.948-3.163-8.179-9.728-7.939 6.413-5.431 17.537 6.695 8.375 13.066 0 0 1.533-2.186 1.353-5.126z" }),
97
+ /* @__PURE__ */ jsx("path", { d: "M16.093 6.845c8.005-0.24 10.863 9.357 5.693 13.676l-5.191 2.509c0 0-0.676-2.181 1.833-4.734 2.509-2.551 4.929-7.328-2.006-10.469 0 0 0.131-0.654-0.327-0.981z" }),
98
+ /* @__PURE__ */ jsx("path", { d: "M15.678 9.004c0 0 0.393-0.371 0.524-0.676 5.954 2.486 5.017 6.697 1.461 10.23-2.181 2.246-1.505 4.668-1.505 4.668s-2.66 1.657-3.577 3.097c0 0-3.852-3.28 1.483-8.724 5.235-5.344 1.614-8.594 1.614-8.594z" })
99
+ ]
100
+ }
101
+ ),
102
+ /* @__PURE__ */ jsxs(
103
+ "div",
104
+ {
105
+ className: slots.mainContent({ className: classNames?.mainContent }),
106
+ children: [
107
+ /* @__PURE__ */ jsx("span", { children: formatMessage("mainLabel") }),
108
+ environment ? /* @__PURE__ */ jsx("b", { children: formatMessage("environmentLabel", {
109
+ environment: environment.toUpperCase()
110
+ }) }) : null,
111
+ /* @__PURE__ */ jsxs(
112
+ "button",
113
+ {
114
+ className: slots.identifyButton({
115
+ className: classNames?.identifyButton
116
+ }),
117
+ "data-focus-visible": dataAttr(isFocusVisible),
118
+ ref: triggerRef,
119
+ type: "button",
120
+ ...mergeProps(buttonProps, focusProps),
121
+ children: [
122
+ /* @__PURE__ */ jsx("span", { className: slots.link({ className: classNames?.link }), children: formatMessage("identifyLabel") }),
123
+ /* @__PURE__ */ jsx(
124
+ ChevronDown,
125
+ {
126
+ className: slots.chevron({ className: classNames?.chevron })
127
+ }
128
+ )
129
+ ]
130
+ }
131
+ )
132
+ ]
133
+ }
134
+ )
135
+ ]
136
+ }
137
+ ),
138
+ /* @__PURE__ */ jsx("div", { ref: panelRef, ...panelProps, children: /* @__PURE__ */ jsxs("div", { className: slots.panel({ className: classNames?.panel }), children: [
139
+ /* @__PURE__ */ jsxs(
140
+ "div",
141
+ {
142
+ className: slots.panelGroup({
143
+ className: classNames?.panelGroup
144
+ }),
145
+ children: [
146
+ /* @__PURE__ */ jsx(
147
+ Landmark,
148
+ {
149
+ className: slots.panelIcon({ className: classNames?.panelIcon })
150
+ }
151
+ ),
152
+ /* @__PURE__ */ jsxs(
153
+ "div",
154
+ {
155
+ className: slots.panelSection({
156
+ className: classNames?.panelSection
157
+ }),
158
+ children: [
159
+ /* @__PURE__ */ jsx(
160
+ "div",
161
+ {
162
+ className: slots.panelHeader({
163
+ className: classNames?.panelHeader
164
+ }),
165
+ children: formatMessage("officialLinkHeader")
166
+ }
167
+ ),
168
+ /* @__PURE__ */ jsxs("article", { children: [
169
+ formatMessage("officialLinkContent", {
170
+ boldThis: (content) => /* @__PURE__ */ jsx("b", { children: content })
171
+ }),
172
+ " ",
173
+ /* @__PURE__ */ jsxs(
174
+ "a",
175
+ {
176
+ className: slots.link({ className: classNames?.link }),
177
+ href: "https://www.gov.sg/trusted-sites#govsites",
178
+ rel: "noreferrer",
179
+ target: "_blank",
180
+ children: [
181
+ formatMessage("officialLinkTrusted", {}),
182
+ /* @__PURE__ */ jsx(
183
+ ExternalLink,
184
+ {
185
+ "aria-hidden": true,
186
+ className: slots.inlineIcon({
187
+ className: twMerge("ml-0.5", classNames?.inlineIcon)
188
+ })
189
+ }
190
+ )
191
+ ]
192
+ }
193
+ )
194
+ ] })
195
+ ]
196
+ }
197
+ )
198
+ ]
199
+ }
200
+ ),
201
+ /* @__PURE__ */ jsxs(
202
+ "div",
203
+ {
204
+ className: slots.panelGroup({
205
+ className: classNames?.panelGroup
206
+ }),
207
+ children: [
208
+ /* @__PURE__ */ jsx(
209
+ Lock,
210
+ {
211
+ className: slots.panelIcon({ className: classNames?.panelIcon })
212
+ }
213
+ ),
214
+ /* @__PURE__ */ jsxs(
215
+ "div",
216
+ {
217
+ className: slots.panelSection({
218
+ className: classNames?.panelSection
219
+ }),
220
+ children: [
221
+ /* @__PURE__ */ jsx(
222
+ "p",
223
+ {
224
+ className: slots.panelHeader({
225
+ className: classNames?.panelHeader
226
+ }),
227
+ children: formatMessage("secureHeader")
228
+ }
229
+ ),
230
+ /* @__PURE__ */ jsx("article", { children: formatMessage("secureContent", {
231
+ boldThis: (content) => /* @__PURE__ */ jsx("b", { children: content }),
232
+ icon: /* @__PURE__ */ jsxs("span", { "aria-hidden": true, children: [
233
+ "(",
234
+ /* @__PURE__ */ jsx(
235
+ Lock,
236
+ {
237
+ className: slots.inlineIcon({
238
+ className: classNames?.inlineIcon
239
+ })
240
+ }
241
+ ),
242
+ ")"
243
+ ] })
244
+ }) })
245
+ ]
246
+ }
247
+ )
248
+ ]
249
+ }
250
+ )
251
+ ] }) })
252
+ ]
253
+ }
254
+ );
255
+ }
256
+
257
+ export { GovtBanner };
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ export { GovtBanner } from './govt-banner.js';
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ export { useControllableState } from './use-controllable-state.js';
@@ -0,0 +1,15 @@
1
+ "use strict";
2
+ "use client";
3
+ import { useRef, useInsertionEffect, useCallback } from 'react';
4
+
5
+ function useCallbackRef(callback, deps = []) {
6
+ const callbackRef = useRef(() => {
7
+ throw new Error("Cannot call an event handler while rendering.");
8
+ });
9
+ useInsertionEffect(() => {
10
+ callbackRef.current = callback;
11
+ });
12
+ return useCallback((...args) => callbackRef.current?.(...args), deps);
13
+ }
14
+
15
+ export { useCallbackRef };
@@ -0,0 +1,35 @@
1
+ "use strict";
2
+ "use client";
3
+ import { useState } from 'react';
4
+ import { useCallbackRef } from './use-callback-ref.js';
5
+
6
+ function useControllableState(props) {
7
+ const {
8
+ value: valueProp,
9
+ defaultValue,
10
+ onChange,
11
+ shouldUpdate = (prev, next) => prev !== next
12
+ } = props;
13
+ const onChangeProp = useCallbackRef(onChange);
14
+ const shouldUpdateProp = useCallbackRef(shouldUpdate);
15
+ const [uncontrolledState, setUncontrolledState] = useState(defaultValue);
16
+ const controlled = valueProp !== void 0;
17
+ const value = controlled ? valueProp : uncontrolledState;
18
+ const setValue = useCallbackRef(
19
+ (next) => {
20
+ const setter = next;
21
+ const nextValue = typeof next === "function" ? setter(value) : next;
22
+ if (!shouldUpdateProp(value, nextValue)) {
23
+ return;
24
+ }
25
+ if (!controlled) {
26
+ setUncontrolledState(nextValue);
27
+ }
28
+ onChangeProp(nextValue);
29
+ },
30
+ [controlled, onChangeProp, value, shouldUpdateProp]
31
+ );
32
+ return [value, setValue];
33
+ }
34
+
35
+ export { useControllableState };
@@ -0,0 +1,19 @@
1
+ "use strict";
2
+ export { useControllableState } from './hooks/use-controllable-state.js';
3
+ export { Button } from './button/button.js';
4
+ export { GovtBanner } from './govt-banner/govt-banner.js';
5
+ export { Ripple } from './ripple/ripple.js';
6
+ export { useRipple } from './ripple/use-ripple.js';
7
+ export { Spinner } from './spinner/spinner.js';
8
+ export { useSpinner } from './spinner/use-spinner.js';
9
+ export { Toggle } from './toggle/toggle.js';
10
+ export { SkipNavLink } from './skip-nav-link/skip-nav-link.js';
11
+ export { Input } from './input/input.js';
12
+ export { TextField } from './text-field/text-field.js';
13
+ export { Description, FieldError, FieldGroup, Label } from './field/field.js';
14
+ export { TextArea } from './text-area/text-area.js';
15
+ export { TextAreaField } from './text-area-field/text-area-field.js';
16
+ export { ComboBox, ComboBoxEmptyState, ComboBoxItem } from './combo-box/combo-box.js';
17
+ export { ComboBoxFuzzy } from './combo-box/combo-box-fuzzy.js';
18
+ export { Banner } from './banner/banner.js';
19
+ export { TagField } from './tag-field/tag-field.js';
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ export { Input } from './input.js';