@opengovsg/oui 0.0.49 → 0.0.51

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 (35) hide show
  1. package/dist/cjs/banner/banner.cjs +1 -1
  2. package/dist/cjs/date-picker/date-picker.cjs +3 -2
  3. package/dist/cjs/date-range-picker/date-range-picker.cjs +1 -1
  4. package/dist/cjs/file-dropzone/file-dropzone.cjs +65 -11
  5. package/dist/cjs/file-dropzone/file-info.cjs +1 -1
  6. package/dist/cjs/file-dropzone/utils.cjs +18 -0
  7. package/dist/cjs/index.cjs +38 -38
  8. package/dist/cjs/modal/modal-content.cjs +1 -1
  9. package/dist/cjs/number-field/number-field.cjs +1 -1
  10. package/dist/cjs/range-calendar/range-calendar.cjs +1 -1
  11. package/dist/cjs/search-field/search-field.cjs +7 -4
  12. package/dist/cjs/select/select.cjs +1 -1
  13. package/dist/cjs/sidebar/sidebar-list.cjs +1 -1
  14. package/dist/esm/banner/banner.js +1 -1
  15. package/dist/esm/date-picker/date-picker.js +3 -2
  16. package/dist/esm/date-range-picker/date-range-picker.js +1 -1
  17. package/dist/esm/file-dropzone/file-dropzone.js +66 -12
  18. package/dist/esm/file-dropzone/file-info.js +1 -1
  19. package/dist/esm/file-dropzone/utils.js +17 -1
  20. package/dist/esm/index.js +11 -11
  21. package/dist/esm/modal/modal-content.js +1 -1
  22. package/dist/esm/number-field/number-field.js +1 -1
  23. package/dist/esm/range-calendar/range-calendar.js +1 -1
  24. package/dist/esm/search-field/search-field.js +7 -4
  25. package/dist/esm/select/select.js +1 -1
  26. package/dist/esm/sidebar/sidebar-list.js +1 -1
  27. package/dist/types/file-dropzone/file-dropzone.d.ts +12 -0
  28. package/dist/types/file-dropzone/file-dropzone.d.ts.map +1 -1
  29. package/dist/types/file-dropzone/index.d.ts +1 -0
  30. package/dist/types/file-dropzone/index.d.ts.map +1 -1
  31. package/dist/types/file-dropzone/utils.d.ts +18 -0
  32. package/dist/types/file-dropzone/utils.d.ts.map +1 -1
  33. package/dist/types/search-field/search-field.d.ts +5 -0
  34. package/dist/types/search-field/search-field.d.ts.map +1 -1
  35. package/package.json +5 -5
@@ -7,10 +7,10 @@ var $670gB$react = require('react');
7
7
  var reactAria = require('react-aria');
8
8
  var reactStately = require('react-stately');
9
9
  var ouiTheme = require('@opengovsg/oui-theme');
10
+ var button = require('../button/button.cjs');
10
11
  var i18n = require('./i18n.cjs');
11
12
  var circleAlert = require('../node_modules/.pnpm/lucide-react@0.475.0_react@19.2.3/node_modules/lucide-react/dist/esm/icons/circle-alert.cjs');
12
13
  var info = require('../node_modules/.pnpm/lucide-react@0.475.0_react@19.2.3/node_modules/lucide-react/dist/esm/icons/info.cjs');
13
- var button = require('../button/button.cjs');
14
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
15
 
16
16
  const Banner = ({
@@ -6,13 +6,14 @@ var jsxRuntime = require('react/jsx-runtime');
6
6
  var $670gB$react = require('react');
7
7
  var reactAriaComponents = require('react-aria-components');
8
8
  var ouiTheme = require('@opengovsg/oui-theme');
9
+ var button = require('../button/button.cjs');
10
+ var calendar$1 = require('../calendar/calendar.cjs');
11
+ require('@internationalized/date');
9
12
  var dateField = require('../date-field/date-field.cjs');
10
13
  var field = require('../field/field.cjs');
11
14
  var popover = require('../popover/popover.cjs');
12
15
  var utils = require('../system/utils.cjs');
13
16
  var calendar = require('../node_modules/.pnpm/lucide-react@0.475.0_react@19.2.3/node_modules/lucide-react/dist/esm/icons/calendar.cjs');
14
- var calendar$1 = require('../calendar/calendar.cjs');
15
- var button = require('../button/button.cjs');
16
17
 
17
18
  function DatePicker(originalProps) {
18
19
  const [
@@ -7,13 +7,13 @@ var $670gB$react = require('react');
7
7
  var date = require('@internationalized/date');
8
8
  var reactAriaComponents = require('react-aria-components');
9
9
  var ouiTheme = require('@opengovsg/oui-theme');
10
+ var button = require('../button/button.cjs');
10
11
  var dateField = require('../date-field/date-field.cjs');
11
12
  var field = require('../field/field.cjs');
12
13
  var popover = require('../popover/popover.cjs');
13
14
  var rangeCalendar = require('../range-calendar/range-calendar.cjs');
14
15
  var utils = require('../system/utils.cjs');
15
16
  var calendar = require('../node_modules/.pnpm/lucide-react@0.475.0_react@19.2.3/node_modules/lucide-react/dist/esm/icons/calendar.cjs');
16
- var button = require('../button/button.cjs');
17
17
 
18
18
  function DateRangePicker(originalProps) {
19
19
  const [
@@ -3,11 +3,11 @@
3
3
  'use strict';
4
4
 
5
5
  var jsxRuntime = require('react/jsx-runtime');
6
+ var reactDropzone = require('react-dropzone');
6
7
  var $670gB$react = require('react');
7
8
  var form = require('@react-stately/form');
8
9
  var reactAria = require('react-aria');
9
10
  var reactAriaComponents = require('react-aria-components');
10
- var reactDropzone = require('react-dropzone');
11
11
  var ouiTheme = require('@opengovsg/oui-theme');
12
12
  var field = require('../field/field.cjs');
13
13
  var useControllableState = require('../hooks/use-controllable-state.cjs');
@@ -27,6 +27,8 @@ const FileDropzone = (originalProps) => {
27
27
  allowedMimeTypes = [],
28
28
  fileSizeBase = "binary",
29
29
  maxFileSize = Number.POSITIVE_INFINITY,
30
+ maxFileSizeByType = [],
31
+ fileSizeText: fileSizeTextOverride,
30
32
  minFileSize = 0,
31
33
  showFileSizeText = true,
32
34
  maxFiles = 1,
@@ -67,13 +69,48 @@ const FileDropzone = (originalProps) => {
67
69
  const slots = ouiTheme.fileDropzoneStyles(variantProps);
68
70
  const fileSizeTextId = reactAria.useId();
69
71
  const formatError = $670gB$react.useCallback(
70
- (error) => utils$1.formatErrorMessage(error, {
71
- maxFileSize,
72
- minFileSize,
73
- maxFiles,
74
- fileSizeBase
75
- }),
76
- [fileSizeBase, maxFileSize, maxFiles, minFileSize]
72
+ (error) => {
73
+ if (maxFileSizeByType.length > 0 && error.code === reactDropzone.ErrorCode.FileTooLarge) {
74
+ return error.message;
75
+ }
76
+ return utils$1.formatErrorMessage(error, {
77
+ maxFileSize,
78
+ minFileSize,
79
+ maxFiles,
80
+ fileSizeBase
81
+ });
82
+ },
83
+ [fileSizeBase, maxFileSize, maxFileSizeByType, maxFiles, minFileSize]
84
+ );
85
+ const effectiveMaxSize = $670gB$react.useMemo(() => {
86
+ if (maxFileSizeByType.length > 0) return Number.POSITIVE_INFINITY;
87
+ return maxFileSize;
88
+ }, [maxFileSize, maxFileSizeByType]);
89
+ const composedValidator = $670gB$react.useCallback(
90
+ (file) => {
91
+ const errors = [];
92
+ if (maxFileSizeByType.length > 0) {
93
+ const limit = utils$1.resolveMaxFileSize(file.type, maxFileSizeByType, maxFileSize);
94
+ if (limit !== Number.POSITIVE_INFINITY && file.size > limit) {
95
+ errors.push({
96
+ code: reactDropzone.ErrorCode.FileTooLarge,
97
+ message: `You have exceeded the size limit, please upload a file below ${utils$1.formatBytes(limit, 2, fileSizeBase)}`
98
+ });
99
+ }
100
+ }
101
+ if (validator) {
102
+ const externalErrors = validator(file);
103
+ if (externalErrors) {
104
+ if (Array.isArray(externalErrors)) {
105
+ errors.push(...externalErrors);
106
+ } else {
107
+ errors.push(externalErrors);
108
+ }
109
+ }
110
+ }
111
+ return errors.length > 0 ? errors : null;
112
+ },
113
+ [maxFileSizeByType, maxFileSize, fileSizeBase, validator]
77
114
  );
78
115
  const onDrop = $670gB$react.useCallback(
79
116
  (acceptedFiles, fileRejections) => {
@@ -108,7 +145,7 @@ const FileDropzone = (originalProps) => {
108
145
  [setRejections]
109
146
  );
110
147
  const { getInputProps, ...dropzoneState } = reactDropzone.useDropzone({
111
- validator,
148
+ validator: composedValidator,
112
149
  accept: allowedMimeTypes.reduce(
113
150
  (acc, type) => ({ ...acc, [type]: [] }),
114
151
  {}
@@ -120,12 +157,29 @@ const FileDropzone = (originalProps) => {
120
157
  // Prevent ref hijack when there is a label
121
158
  noClick: true,
122
159
  noKeyboard: true,
123
- maxSize: maxFileSize,
160
+ maxSize: effectiveMaxSize,
124
161
  minSize: minFileSize,
125
162
  maxFiles,
126
163
  multiple: maxFiles !== 1
127
164
  });
128
165
  const fileSizeText = $670gB$react.useMemo(() => {
166
+ if (!showFileSizeText) return null;
167
+ if (fileSizeTextOverride) return fileSizeTextOverride;
168
+ if (maxFileSizeByType.length > 0) {
169
+ const parts = [];
170
+ for (const rule of maxFileSizeByType) {
171
+ const sizeStr = utils$1.formatBytes(rule.maxFileSize, 2, fileSizeBase);
172
+ const label2 = rule.label ?? rule.mimeTypes.join(", ");
173
+ parts.push(`${sizeStr} for ${label2}`);
174
+ }
175
+ const notDefaultMaxFileSize2 = maxFileSize !== Number.POSITIVE_INFINITY;
176
+ if (notDefaultMaxFileSize2) {
177
+ parts.push(
178
+ `${utils$1.formatBytes(maxFileSize, 2, fileSizeBase)} for other accepted files`
179
+ );
180
+ }
181
+ return parts.length > 0 ? `Maximum file size: ${parts.join(", ")}` : null;
182
+ }
129
183
  const notDefaultMaxFileSize = maxFileSize !== Number.POSITIVE_INFINITY;
130
184
  const notDefaultMinFileSize = minFileSize !== 0;
131
185
  const shouldShow = showFileSizeText && (notDefaultMaxFileSize || notDefaultMinFileSize);
@@ -144,7 +198,7 @@ const FileDropzone = (originalProps) => {
144
198
  return `Minimum file size: ${utils$1.formatBytes(minFileSize, 2, fileSizeBase)}`;
145
199
  }
146
200
  return null;
147
- }, [maxFileSize, minFileSize, showFileSizeText, fileSizeBase]);
201
+ }, [maxFileSize, maxFileSizeByType, minFileSize, showFileSizeText, fileSizeBase, fileSizeTextOverride]);
148
202
  const triggerFileSelector = $670gB$react.useCallback(() => {
149
203
  if (isDisabled || isReadOnly) return;
150
204
  dropzoneState.inputRef.current?.click();
@@ -5,10 +5,10 @@
5
5
  var jsxRuntime = require('react/jsx-runtime');
6
6
  var $670gB$react = require('react');
7
7
  var ouiTheme = require('@opengovsg/oui-theme');
8
+ var button = require('../button/button.cjs');
8
9
  var contexts = require('./contexts.cjs');
9
10
  var utils = require('./utils.cjs');
10
11
  var trash2 = require('../node_modules/.pnpm/lucide-react@0.475.0_react@19.2.3/node_modules/lucide-react/dist/esm/icons/trash-2.cjs');
11
- var button = require('../button/button.cjs');
12
12
 
13
13
  const FileInfo = ({ file, imagePreview, classNames }) => {
14
14
  const {
@@ -3,6 +3,22 @@
3
3
 
4
4
  var reactDropzone = require('react-dropzone');
5
5
 
6
+ const matchesMimeType = (fileType, pattern) => {
7
+ if (pattern === "*" || pattern === "*/*") return true;
8
+ if (pattern.endsWith("/*")) {
9
+ const prefix = pattern.slice(0, pattern.indexOf("/"));
10
+ return fileType.startsWith(prefix + "/");
11
+ }
12
+ return fileType === pattern;
13
+ };
14
+ const resolveMaxFileSize = (fileType, rules, defaultMaxSize) => {
15
+ for (const rule of rules) {
16
+ if (rule.mimeTypes.some((pattern) => matchesMimeType(fileType, pattern))) {
17
+ return rule.maxFileSize;
18
+ }
19
+ }
20
+ return defaultMaxSize;
21
+ };
6
22
  const formatBytes = (bytes, decimals = 2, base = "binary", size) => {
7
23
  const k = base === "binary" ? 1024 : 1e3;
8
24
  const dm = decimals < 0 ? 0 : decimals;
@@ -29,3 +45,5 @@ const formatErrorMessage = (error, config) => {
29
45
 
30
46
  exports.formatBytes = formatBytes;
31
47
  exports.formatErrorMessage = formatErrorMessage;
48
+ exports.matchesMimeType = matchesMimeType;
49
+ exports.resolveMaxFileSize = resolveMaxFileSize;
@@ -3,6 +3,7 @@
3
3
 
4
4
  var useControllableState = require('./hooks/use-controllable-state.cjs');
5
5
  var useDraggable = require('./hooks/use-draggable.cjs');
6
+ var button = require('./button/button.cjs');
6
7
  var govtBanner = require('./govt-banner/govt-banner.cjs');
7
8
  var ripple = require('./ripple/ripple.cjs');
8
9
  var useRipple = require('./ripple/use-ripple.cjs');
@@ -19,11 +20,17 @@ var comboBox = require('./combo-box/combo-box.cjs');
19
20
  var comboBoxFuzzy = require('./combo-box/combo-box-fuzzy.cjs');
20
21
  var comboBoxItem = require('./combo-box/combo-box-item.cjs');
21
22
  var comboBoxVariantContext = require('./combo-box/combo-box-variant-context.cjs');
23
+ var banner = require('./banner/banner.cjs');
22
24
  var tagField = require('./tag-field/tag-field.cjs');
23
25
  var tagFieldItem = require('./tag-field/tag-field-item.cjs');
24
26
  var select = require('./select/select.cjs');
25
27
  var selectItem = require('./select/select-item.cjs');
26
28
  var selectVariantContext = require('./select/select-variant-context.cjs');
29
+ var badge = require('./badge/badge.cjs');
30
+ var calendar = require('./calendar/calendar.cjs');
31
+ var calendarStyleContext = require('./calendar/calendar-style-context.cjs');
32
+ var utils$1 = require('./calendar/utils.cjs');
33
+ var date = require('@internationalized/date');
27
34
  var rangeCalendar = require('./range-calendar/range-calendar.cjs');
28
35
  var menu = require('./menu/menu.cjs');
29
36
  var popover = require('./popover/popover.cjs');
@@ -31,6 +38,8 @@ var tabs = require('./tabs/tabs.cjs');
31
38
  var dateField = require('./date-field/date-field.cjs');
32
39
  var datePicker = require('./date-picker/date-picker.cjs');
33
40
  var dateRangePicker = require('./date-range-picker/date-range-picker.cjs');
41
+ var checkbox = require('./checkbox/checkbox.cjs');
42
+ var checkboxGroupStyleContext = require('./checkbox/checkbox-group-style-context.cjs');
34
43
  var pagination = require('./pagination/pagination.cjs');
35
44
  var paginationCursor = require('./pagination/pagination-cursor.cjs');
36
45
  var paginationItem = require('./pagination/pagination-item.cjs');
@@ -57,9 +66,11 @@ var navbarItem = require('./navbar/navbar-item.cjs');
57
66
  var useNavbar = require('./navbar/use-navbar.cjs');
58
67
  var navbarContext = require('./navbar/navbar-context.cjs');
59
68
  var index = require('./avatar/index.cjs');
69
+ var accordion = require('./accordion/accordion.cjs');
60
70
  var timeField = require('./time-field/time-field.cjs');
61
71
  var searchField = require('./search-field/search-field.cjs');
62
72
  var link = require('./link/link.cjs');
73
+ var breadcrumbs = require('./breadcrumbs/breadcrumbs.cjs');
63
74
  var sidebar = require('./sidebar/sidebar.cjs');
64
75
  var sidebarRoot = require('./sidebar/sidebar-root.cjs');
65
76
  var sidebarItem = require('./sidebar/sidebar-item.cjs');
@@ -70,27 +81,17 @@ var phoneNumberField = require('./phone-number-field/phone-number-field.cjs');
70
81
  var BasePhoneInput = require('react-phone-number-input');
71
82
  var infobox = require('./infobox/infobox.cjs');
72
83
  var radio = require('./radio-group/radio.cjs');
73
- var accordion = require('./accordion/accordion.cjs');
74
84
  var avatarContext = require('./avatar/avatar-context.cjs');
75
85
  var avatar = require('./avatar/avatar.cjs');
76
86
  var avatarGroup = require('./avatar/avatar-group.cjs');
77
87
  var avatarGroupContext = require('./avatar/avatar-group-context.cjs');
78
- var badge = require('./badge/badge.cjs');
79
- var banner = require('./banner/banner.cjs');
80
- var breadcrumbs = require('./breadcrumbs/breadcrumbs.cjs');
81
- var button = require('./button/button.cjs');
82
- var calendar = require('./calendar/calendar.cjs');
83
- var date = require('@internationalized/date');
84
- var calendarStyleContext = require('./calendar/calendar-style-context.cjs');
85
- var checkbox = require('./checkbox/checkbox.cjs');
86
- var checkboxGroupStyleContext = require('./checkbox/checkbox-group-style-context.cjs');
87
- var utils$1 = require('./calendar/utils.cjs');
88
88
  var sonner = require('sonner');
89
89
 
90
90
 
91
91
 
92
92
  exports.useControllableState = useControllableState.useControllableState;
93
93
  exports.useDraggable = useDraggable.useDraggable;
94
+ exports.Button = button.Button;
94
95
  exports.GovtBanner = govtBanner.GovtBanner;
95
96
  exports.Ripple = ripple.Ripple;
96
97
  exports.useRipple = useRipple.useRipple;
@@ -113,12 +114,26 @@ exports.ComboBoxFuzzy = comboBoxFuzzy.ComboBoxFuzzy;
113
114
  exports.ComboBoxItem = comboBoxItem.ComboBoxItem;
114
115
  exports.ComboBoxVariantContext = comboBoxVariantContext.ComboBoxVariantContext;
115
116
  exports.useComboBoxVariantContext = comboBoxVariantContext.useComboBoxVariantContext;
117
+ exports.Banner = banner.Banner;
116
118
  exports.TagField = tagField.TagField;
117
119
  exports.TagFieldItem = tagFieldItem.TagFieldItem;
118
120
  exports.Select = select.Select;
119
121
  exports.SelectItem = selectItem.SelectItem;
120
122
  exports.SelectVariantContext = selectVariantContext.SelectVariantContext;
121
123
  exports.useSelectVariantContext = selectVariantContext.useSelectVariantContext;
124
+ exports.Badge = badge.Badge;
125
+ exports.Calendar = calendar.Calendar;
126
+ exports.CalendarStateWrapper = calendar.CalendarStateWrapper;
127
+ exports.CalendarStyleContext = calendarStyleContext.CalendarStyleContext;
128
+ exports.useCalendarStyleContext = calendarStyleContext.useCalendarStyleContext;
129
+ exports.getEraFormat = utils$1.getEraFormat;
130
+ exports.useGenerateLocalizedMonths = utils$1.useGenerateLocalizedMonths;
131
+ exports.useGenerateLocalizedYears = utils$1.useGenerateLocalizedYears;
132
+ exports.useLocalizedMonthYear = utils$1.useLocalizedMonthYear;
133
+ Object.defineProperty(exports, "CalendarDate", {
134
+ enumerable: true,
135
+ get: function () { return date.CalendarDate; }
136
+ });
122
137
  exports.RangeCalendar = rangeCalendar.RangeCalendar;
123
138
  exports.RangeCalendarCell = rangeCalendar.RangeCalendarCell;
124
139
  exports.RangeCalendarStateWrapper = rangeCalendar.RangeCalendarStateWrapper;
@@ -142,6 +157,10 @@ exports.DateField = dateField.DateField;
142
157
  exports.DateInput = dateField.DateInput;
143
158
  exports.DatePicker = datePicker.DatePicker;
144
159
  exports.DateRangePicker = dateRangePicker.DateRangePicker;
160
+ exports.Checkbox = checkbox.Checkbox;
161
+ exports.CheckboxGroup = checkbox.CheckboxGroup;
162
+ exports.CheckboxGroupStyleContext = checkboxGroupStyleContext.CheckboxGroupStyleContext;
163
+ exports.useCheckboxGroupStyleContext = checkboxGroupStyleContext.useCheckboxGroupStyleContext;
145
164
  exports.Pagination = pagination.Pagination;
146
165
  exports.PaginationCursor = paginationCursor.PaginationCursor;
147
166
  exports.PaginationItem = paginationItem.PaginationItem;
@@ -172,9 +191,17 @@ exports.useNavbar = useNavbar.useNavbar;
172
191
  exports.NavbarProvider = navbarContext.NavbarProvider;
173
192
  exports.useNavbarContext = navbarContext.useNavbarContext;
174
193
  exports.Avatar = index.Avatar;
194
+ exports.Accordion = accordion.Accordion;
195
+ exports.AccordionContent = accordion.AccordionContent;
196
+ exports.AccordionHeader = accordion.AccordionHeader;
197
+ exports.AccordionItem = accordion.AccordionItem;
198
+ exports.AccordionStyleContext = accordion.AccordionStyleContext;
199
+ exports.useAccordionStyleContext = accordion.useAccordionStyleContext;
175
200
  exports.TimeField = timeField.TimeField;
176
201
  exports.SearchField = searchField.SearchField;
177
202
  exports.Link = link.Link;
203
+ exports.Breadcrumb = breadcrumbs.Breadcrumb;
204
+ exports.Breadcrumbs = breadcrumbs.Breadcrumbs;
178
205
  exports.Sidebar = sidebar.Sidebar;
179
206
  exports.generateSidebarItems = sidebar.generateSidebarItems;
180
207
  exports.SidebarRoot = sidebarRoot.SidebarRoot;
@@ -210,12 +237,6 @@ Object.defineProperty(exports, "parsePhoneNumber", {
210
237
  exports.Infobox = infobox.Infobox;
211
238
  exports.Radio = radio.Radio;
212
239
  exports.RadioGroup = radio.RadioGroup;
213
- exports.Accordion = accordion.Accordion;
214
- exports.AccordionContent = accordion.AccordionContent;
215
- exports.AccordionHeader = accordion.AccordionHeader;
216
- exports.AccordionItem = accordion.AccordionItem;
217
- exports.AccordionStyleContext = accordion.AccordionStyleContext;
218
- exports.useAccordionStyleContext = accordion.useAccordionStyleContext;
219
240
  exports.AvatarContext = avatarContext.AvatarContext;
220
241
  exports.useAvatarContext = avatarContext.useAvatarContext;
221
242
  exports.AvatarFallback = avatar.AvatarFallback;
@@ -224,27 +245,6 @@ exports.AvatarRoot = avatar.AvatarRoot;
224
245
  exports.AvatarGroup = avatarGroup.AvatarGroup;
225
246
  exports.AvatarGroupProvider = avatarGroupContext.AvatarGroupProvider;
226
247
  exports.useAvatarGroup = avatarGroupContext.useAvatarGroup;
227
- exports.Badge = badge.Badge;
228
- exports.Banner = banner.Banner;
229
- exports.Breadcrumb = breadcrumbs.Breadcrumb;
230
- exports.Breadcrumbs = breadcrumbs.Breadcrumbs;
231
- exports.Button = button.Button;
232
- exports.Calendar = calendar.Calendar;
233
- exports.CalendarStateWrapper = calendar.CalendarStateWrapper;
234
- Object.defineProperty(exports, "CalendarDate", {
235
- enumerable: true,
236
- get: function () { return date.CalendarDate; }
237
- });
238
- exports.CalendarStyleContext = calendarStyleContext.CalendarStyleContext;
239
- exports.useCalendarStyleContext = calendarStyleContext.useCalendarStyleContext;
240
- exports.Checkbox = checkbox.Checkbox;
241
- exports.CheckboxGroup = checkbox.CheckboxGroup;
242
- exports.CheckboxGroupStyleContext = checkboxGroupStyleContext.CheckboxGroupStyleContext;
243
- exports.useCheckboxGroupStyleContext = checkboxGroupStyleContext.useCheckboxGroupStyleContext;
244
- exports.getEraFormat = utils$1.getEraFormat;
245
- exports.useGenerateLocalizedMonths = utils$1.useGenerateLocalizedMonths;
246
- exports.useGenerateLocalizedYears = utils$1.useGenerateLocalizedYears;
247
- exports.useLocalizedMonthYear = utils$1.useLocalizedMonthYear;
248
248
  Object.defineProperty(exports, "toast", {
249
249
  enumerable: true,
250
250
  get: function () { return sonner.toast; }
@@ -7,10 +7,10 @@ var $670gB$react = require('react');
7
7
  var reactAria = require('react-aria');
8
8
  var reactAriaComponents = require('react-aria-components');
9
9
  var ouiTheme = require('@opengovsg/oui-theme');
10
+ var button = require('../button/button.cjs');
10
11
  var i18n = require('./i18n.cjs');
11
12
  var modalVariantContext = require('./modal-variant-context.cjs');
12
13
  var x = require('../node_modules/.pnpm/lucide-react@0.475.0_react@19.2.3/node_modules/lucide-react/dist/esm/icons/x.cjs');
13
- var button = require('../button/button.cjs');
14
14
 
15
15
  function ModalContent({
16
16
  closeButtonContent: closeButtonContentProp,
@@ -5,12 +5,12 @@
5
5
  var jsxRuntime = require('react/jsx-runtime');
6
6
  var reactAriaComponents = require('react-aria-components');
7
7
  var ouiTheme = require('@opengovsg/oui-theme');
8
+ var button = require('../button/button.cjs');
8
9
  var field = require('../field/field.cjs');
9
10
  var input = require('../input/input.cjs');
10
11
  var utils = require('../system/utils.cjs');
11
12
  var minus = require('../node_modules/.pnpm/lucide-react@0.475.0_react@19.2.3/node_modules/lucide-react/dist/esm/icons/minus.cjs');
12
13
  var plus = require('../node_modules/.pnpm/lucide-react@0.475.0_react@19.2.3/node_modules/lucide-react/dist/esm/icons/plus.cjs');
13
- var button = require('../button/button.cjs');
14
14
 
15
15
  function NumberField(originalProps) {
16
16
  const [
@@ -8,12 +8,12 @@ var date = require('@internationalized/date');
8
8
  var reactAriaComponents = require('react-aria-components');
9
9
  var useDeepCompare = require('use-deep-compare');
10
10
  var ouiTheme = require('@opengovsg/oui-theme');
11
+ var calendarStyleContext = require('../calendar/calendar-style-context.cjs');
11
12
  var agnosticCalendarStateContext = require('../calendar/agnostic-calendar-state-context.cjs');
12
13
  var calendarBottomContent = require('../calendar/calendar-bottom-content.cjs');
13
14
  var calendarGridHeader = require('../calendar/calendar-grid-header.cjs');
14
15
  var calendarHeader = require('../calendar/calendar-header.cjs');
15
16
  var utils = require('../system/utils.cjs');
16
- var calendarStyleContext = require('../calendar/calendar-style-context.cjs');
17
17
 
18
18
  const RangeCalendar = utils.forwardRefGeneric(function RangeCalendar2(originalProps, ref) {
19
19
  const [props, variantProps] = utils.mapPropsVariants(
@@ -5,13 +5,13 @@ var jsxRuntime = require('react/jsx-runtime');
5
5
  var reactAria = require('react-aria');
6
6
  var reactAriaComponents = require('react-aria-components');
7
7
  var ouiTheme = require('@opengovsg/oui-theme');
8
+ var button = require('../button/button.cjs');
8
9
  var field = require('../field/field.cjs');
9
10
  var input = require('../input/input.cjs');
10
11
  var utils = require('../system/utils.cjs');
11
12
  var i18n = require('./i18n.cjs');
12
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');
13
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');
14
- var button = require('../button/button.cjs');
15
15
 
16
16
  function SearchField(originalProps) {
17
17
  const [
@@ -22,6 +22,7 @@ function SearchField(originalProps) {
22
22
  searchIcon,
23
23
  inputProps,
24
24
  classNames,
25
+ clearIcon,
25
26
  ...props
26
27
  },
27
28
  variantProps
@@ -68,7 +69,7 @@ function SearchField(originalProps) {
68
69
  ...inputProps
69
70
  }
70
71
  ),
71
- /* @__PURE__ */ jsxRuntime.jsx(
72
+ clearIcon !== null && /* @__PURE__ */ jsxRuntime.jsx(
72
73
  button.Button,
73
74
  {
74
75
  isIconOnly: true,
@@ -76,8 +77,10 @@ function SearchField(originalProps) {
76
77
  variant: "clear",
77
78
  color: "sub",
78
79
  size: variantProps.size,
79
- className: styles.clearButton({ className: classNames?.clearButton }),
80
- children: /* @__PURE__ */ jsxRuntime.jsx(x.default, { "aria-hidden": true })
80
+ className: styles.clearButton({
81
+ className: classNames?.clearButton
82
+ }),
83
+ children: clearIcon ?? /* @__PURE__ */ jsxRuntime.jsx(x.default, { "aria-hidden": true })
81
84
  }
82
85
  )
83
86
  ] }),
@@ -7,6 +7,7 @@ var $670gB$react = require('react');
7
7
  var reactAria = require('react-aria');
8
8
  var reactAriaComponents = require('react-aria-components');
9
9
  var ouiTheme = require('@opengovsg/oui-theme');
10
+ var button = require('../button/button.cjs');
10
11
  var field = require('../field/field.cjs');
11
12
  var popover = require('../popover/popover.cjs');
12
13
  var sizing = require('../system/react-utils/sizing.cjs');
@@ -14,7 +15,6 @@ var utils = require('../system/utils.cjs');
14
15
  var i18n = require('./i18n.cjs');
15
16
  var selectVariantContext = require('./select-variant-context.cjs');
16
17
  var chevronDown = require('../node_modules/.pnpm/lucide-react@0.475.0_react@19.2.3/node_modules/lucide-react/dist/esm/icons/chevron-down.cjs');
17
- var button = require('../button/button.cjs');
18
18
 
19
19
  const calculateEstimatedRowHeight = (size) => {
20
20
  switch (size) {
@@ -8,11 +8,11 @@ var reactAria = require('react-aria');
8
8
  var reactAriaComponents = require('react-aria-components');
9
9
  var reactStately = require('react-stately');
10
10
  var ouiTheme = require('@opengovsg/oui-theme');
11
+ var button = require('../button/button.cjs');
11
12
  var utils = require('../system/utils.cjs');
12
13
  var context = require('./context.cjs');
13
14
  var i18n = require('./i18n.cjs');
14
15
  var chevronDown = require('../node_modules/.pnpm/lucide-react@0.475.0_react@19.2.3/node_modules/lucide-react/dist/esm/icons/chevron-down.cjs');
15
- var button = require('../button/button.cjs');
16
16
 
17
17
  const SidebarListSection = ({
18
18
  onlyCaretToggle,
@@ -5,10 +5,10 @@ import { useMemo, useRef } from 'react';
5
5
  import { useLocalizedStringFormatter, useDisclosure } from 'react-aria';
6
6
  import { useDisclosureState } from 'react-stately';
7
7
  import { bannerStyles } from '@opengovsg/oui-theme';
8
+ import { Button } from '../button/button.js';
8
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
- import { Button } from '../button/button.js';
12
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';
13
13
 
14
14
  const Banner = ({
@@ -4,13 +4,14 @@ import { jsxs, jsx } from 'react/jsx-runtime';
4
4
  import { useMemo } from 'react';
5
5
  import { DatePicker as DatePicker$1, Dialog } from 'react-aria-components';
6
6
  import { datePickerStyles, composeTailwindRenderProps } from '@opengovsg/oui-theme';
7
+ import { Button } from '../button/button.js';
8
+ import { Calendar as Calendar$1 } from '../calendar/calendar.js';
9
+ import '@internationalized/date';
7
10
  import { DateInput } from '../date-field/date-field.js';
8
11
  import { Label, FieldGroup, Description, FieldError } from '../field/field.js';
9
12
  import { Popover } from '../popover/popover.js';
10
13
  import { mapPropsVariants } from '../system/utils.js';
11
14
  import Calendar from '../node_modules/.pnpm/lucide-react@0.475.0_react@19.2.3/node_modules/lucide-react/dist/esm/icons/calendar.js';
12
- import { Calendar as Calendar$1 } from '../calendar/calendar.js';
13
- import { Button } from '../button/button.js';
14
15
 
15
16
  function DatePicker(originalProps) {
16
17
  const [
@@ -5,13 +5,13 @@ import { useMemo } from 'react';
5
5
  import { CalendarDate } from '@internationalized/date';
6
6
  import { DateRangePicker as DateRangePicker$1, Dialog } from 'react-aria-components';
7
7
  import { dateRangePickerStyles, composeTailwindRenderProps } from '@opengovsg/oui-theme';
8
+ import { Button } from '../button/button.js';
8
9
  import { DateInput } from '../date-field/date-field.js';
9
10
  import { Label, FieldGroup, Description, FieldError } from '../field/field.js';
10
11
  import { Popover } from '../popover/popover.js';
11
12
  import { RangeCalendar } from '../range-calendar/range-calendar.js';
12
13
  import { mapPropsVariants } from '../system/utils.js';
13
14
  import Calendar from '../node_modules/.pnpm/lucide-react@0.475.0_react@19.2.3/node_modules/lucide-react/dist/esm/icons/calendar.js';
14
- import { Button } from '../button/button.js';
15
15
 
16
16
  function DateRangePicker(originalProps) {
17
17
  const [
@@ -1,18 +1,18 @@
1
1
  "use strict";
2
2
  "use client";
3
3
  import { jsx, jsxs } from 'react/jsx-runtime';
4
+ import { ErrorCode, useDropzone } from 'react-dropzone';
4
5
  import { useCallback, useMemo, useEffect } from 'react';
5
6
  import { useFormValidationState } from '@react-stately/form';
6
7
  import { useField, useId } from 'react-aria';
7
8
  import { Provider, LabelContext, GroupContext, TextContext, FieldErrorContext, Group } from 'react-aria-components';
8
- import { useDropzone } from 'react-dropzone';
9
9
  import { fileDropzoneStyles, dataAttr } from '@opengovsg/oui-theme';
10
10
  import { Label, Description, FieldError } from '../field/field.js';
11
11
  import { useControllableState } from '../hooks/use-controllable-state.js';
12
12
  import { mapPropsVariants } from '../system/utils.js';
13
13
  import { FileDropzoneStyleContext, FileDropzoneStateContext, useFileDropzoneStateContext, useFileDropzoneStyleContext } from './contexts.js';
14
14
  import { FileInfo } from './file-info.js';
15
- import { formatErrorMessage, formatBytes } from './utils.js';
15
+ import { formatErrorMessage, resolveMaxFileSize, formatBytes } from './utils.js';
16
16
  import Upload from '../node_modules/.pnpm/lucide-react@0.475.0_react@19.2.3/node_modules/lucide-react/dist/esm/icons/upload.js';
17
17
 
18
18
  const FileDropzone = (originalProps) => {
@@ -25,6 +25,8 @@ const FileDropzone = (originalProps) => {
25
25
  allowedMimeTypes = [],
26
26
  fileSizeBase = "binary",
27
27
  maxFileSize = Number.POSITIVE_INFINITY,
28
+ maxFileSizeByType = [],
29
+ fileSizeText: fileSizeTextOverride,
28
30
  minFileSize = 0,
29
31
  showFileSizeText = true,
30
32
  maxFiles = 1,
@@ -65,13 +67,48 @@ const FileDropzone = (originalProps) => {
65
67
  const slots = fileDropzoneStyles(variantProps);
66
68
  const fileSizeTextId = useId();
67
69
  const formatError = useCallback(
68
- (error) => formatErrorMessage(error, {
69
- maxFileSize,
70
- minFileSize,
71
- maxFiles,
72
- fileSizeBase
73
- }),
74
- [fileSizeBase, maxFileSize, maxFiles, minFileSize]
70
+ (error) => {
71
+ if (maxFileSizeByType.length > 0 && error.code === ErrorCode.FileTooLarge) {
72
+ return error.message;
73
+ }
74
+ return formatErrorMessage(error, {
75
+ maxFileSize,
76
+ minFileSize,
77
+ maxFiles,
78
+ fileSizeBase
79
+ });
80
+ },
81
+ [fileSizeBase, maxFileSize, maxFileSizeByType, maxFiles, minFileSize]
82
+ );
83
+ const effectiveMaxSize = useMemo(() => {
84
+ if (maxFileSizeByType.length > 0) return Number.POSITIVE_INFINITY;
85
+ return maxFileSize;
86
+ }, [maxFileSize, maxFileSizeByType]);
87
+ const composedValidator = useCallback(
88
+ (file) => {
89
+ const errors = [];
90
+ if (maxFileSizeByType.length > 0) {
91
+ const limit = resolveMaxFileSize(file.type, maxFileSizeByType, maxFileSize);
92
+ if (limit !== Number.POSITIVE_INFINITY && file.size > limit) {
93
+ errors.push({
94
+ code: ErrorCode.FileTooLarge,
95
+ message: `You have exceeded the size limit, please upload a file below ${formatBytes(limit, 2, fileSizeBase)}`
96
+ });
97
+ }
98
+ }
99
+ if (validator) {
100
+ const externalErrors = validator(file);
101
+ if (externalErrors) {
102
+ if (Array.isArray(externalErrors)) {
103
+ errors.push(...externalErrors);
104
+ } else {
105
+ errors.push(externalErrors);
106
+ }
107
+ }
108
+ }
109
+ return errors.length > 0 ? errors : null;
110
+ },
111
+ [maxFileSizeByType, maxFileSize, fileSizeBase, validator]
75
112
  );
76
113
  const onDrop = useCallback(
77
114
  (acceptedFiles, fileRejections) => {
@@ -106,7 +143,7 @@ const FileDropzone = (originalProps) => {
106
143
  [setRejections]
107
144
  );
108
145
  const { getInputProps, ...dropzoneState } = useDropzone({
109
- validator,
146
+ validator: composedValidator,
110
147
  accept: allowedMimeTypes.reduce(
111
148
  (acc, type) => ({ ...acc, [type]: [] }),
112
149
  {}
@@ -118,12 +155,29 @@ const FileDropzone = (originalProps) => {
118
155
  // Prevent ref hijack when there is a label
119
156
  noClick: true,
120
157
  noKeyboard: true,
121
- maxSize: maxFileSize,
158
+ maxSize: effectiveMaxSize,
122
159
  minSize: minFileSize,
123
160
  maxFiles,
124
161
  multiple: maxFiles !== 1
125
162
  });
126
163
  const fileSizeText = useMemo(() => {
164
+ if (!showFileSizeText) return null;
165
+ if (fileSizeTextOverride) return fileSizeTextOverride;
166
+ if (maxFileSizeByType.length > 0) {
167
+ const parts = [];
168
+ for (const rule of maxFileSizeByType) {
169
+ const sizeStr = formatBytes(rule.maxFileSize, 2, fileSizeBase);
170
+ const label2 = rule.label ?? rule.mimeTypes.join(", ");
171
+ parts.push(`${sizeStr} for ${label2}`);
172
+ }
173
+ const notDefaultMaxFileSize2 = maxFileSize !== Number.POSITIVE_INFINITY;
174
+ if (notDefaultMaxFileSize2) {
175
+ parts.push(
176
+ `${formatBytes(maxFileSize, 2, fileSizeBase)} for other accepted files`
177
+ );
178
+ }
179
+ return parts.length > 0 ? `Maximum file size: ${parts.join(", ")}` : null;
180
+ }
127
181
  const notDefaultMaxFileSize = maxFileSize !== Number.POSITIVE_INFINITY;
128
182
  const notDefaultMinFileSize = minFileSize !== 0;
129
183
  const shouldShow = showFileSizeText && (notDefaultMaxFileSize || notDefaultMinFileSize);
@@ -142,7 +196,7 @@ const FileDropzone = (originalProps) => {
142
196
  return `Minimum file size: ${formatBytes(minFileSize, 2, fileSizeBase)}`;
143
197
  }
144
198
  return null;
145
- }, [maxFileSize, minFileSize, showFileSizeText, fileSizeBase]);
199
+ }, [maxFileSize, maxFileSizeByType, minFileSize, showFileSizeText, fileSizeBase, fileSizeTextOverride]);
146
200
  const triggerFileSelector = useCallback(() => {
147
201
  if (isDisabled || isReadOnly) return;
148
202
  dropzoneState.inputRef.current?.click();
@@ -3,10 +3,10 @@
3
3
  import { jsxs, jsx } from 'react/jsx-runtime';
4
4
  import { useState, useEffect } from 'react';
5
5
  import { fileInfoDropzoneStyles, cn } from '@opengovsg/oui-theme';
6
+ import { Button } from '../button/button.js';
6
7
  import { useFileDropzoneStateContext, useFileDropzoneStyleContext } from './contexts.js';
7
8
  import { formatBytes } from './utils.js';
8
9
  import Trash2 from '../node_modules/.pnpm/lucide-react@0.475.0_react@19.2.3/node_modules/lucide-react/dist/esm/icons/trash-2.js';
9
- import { Button } from '../button/button.js';
10
10
 
11
11
  const FileInfo = ({ file, imagePreview, classNames }) => {
12
12
  const {
@@ -1,6 +1,22 @@
1
1
  "use strict";
2
2
  import { ErrorCode } from 'react-dropzone';
3
3
 
4
+ const matchesMimeType = (fileType, pattern) => {
5
+ if (pattern === "*" || pattern === "*/*") return true;
6
+ if (pattern.endsWith("/*")) {
7
+ const prefix = pattern.slice(0, pattern.indexOf("/"));
8
+ return fileType.startsWith(prefix + "/");
9
+ }
10
+ return fileType === pattern;
11
+ };
12
+ const resolveMaxFileSize = (fileType, rules, defaultMaxSize) => {
13
+ for (const rule of rules) {
14
+ if (rule.mimeTypes.some((pattern) => matchesMimeType(fileType, pattern))) {
15
+ return rule.maxFileSize;
16
+ }
17
+ }
18
+ return defaultMaxSize;
19
+ };
4
20
  const formatBytes = (bytes, decimals = 2, base = "binary", size) => {
5
21
  const k = base === "binary" ? 1024 : 1e3;
6
22
  const dm = decimals < 0 ? 0 : decimals;
@@ -25,4 +41,4 @@ const formatErrorMessage = (error, config) => {
25
41
  }
26
42
  };
27
43
 
28
- export { formatBytes, formatErrorMessage };
44
+ export { formatBytes, formatErrorMessage, matchesMimeType, resolveMaxFileSize };
package/dist/esm/index.js CHANGED
@@ -1,6 +1,7 @@
1
1
  "use strict";
2
2
  export { useControllableState } from './hooks/use-controllable-state.js';
3
3
  export { useDraggable } from './hooks/use-draggable.js';
4
+ export { Button } from './button/button.js';
4
5
  export { GovtBanner } from './govt-banner/govt-banner.js';
5
6
  export { Ripple } from './ripple/ripple.js';
6
7
  export { useRipple } from './ripple/use-ripple.js';
@@ -17,11 +18,17 @@ export { ComboBox, ComboBoxEmptyState } from './combo-box/combo-box.js';
17
18
  export { ComboBoxFuzzy } from './combo-box/combo-box-fuzzy.js';
18
19
  export { ComboBoxItem } from './combo-box/combo-box-item.js';
19
20
  export { ComboBoxVariantContext, useComboBoxVariantContext } from './combo-box/combo-box-variant-context.js';
21
+ export { Banner } from './banner/banner.js';
20
22
  export { TagField } from './tag-field/tag-field.js';
21
23
  export { TagFieldItem } from './tag-field/tag-field-item.js';
22
24
  export { Select } from './select/select.js';
23
25
  export { SelectItem } from './select/select-item.js';
24
26
  export { SelectVariantContext, useSelectVariantContext } from './select/select-variant-context.js';
27
+ export { Badge } from './badge/badge.js';
28
+ export { Calendar, CalendarStateWrapper } from './calendar/calendar.js';
29
+ export { CalendarStyleContext, useCalendarStyleContext } from './calendar/calendar-style-context.js';
30
+ export { getEraFormat, useGenerateLocalizedMonths, useGenerateLocalizedYears, useLocalizedMonthYear } from './calendar/utils.js';
31
+ export { CalendarDate } from '@internationalized/date';
25
32
  export { RangeCalendar, RangeCalendarCell, RangeCalendarStateWrapper } from './range-calendar/range-calendar.js';
26
33
  export { Menu, MenuItem, MenuSection, MenuSeparator, MenuTrigger, MenuVariantContext, SubmenuTrigger, useMenuVariantContext } from './menu/menu.js';
27
34
  export { Popover } from './popover/popover.js';
@@ -29,6 +36,8 @@ export { Tab, TabList, TabPanel, TabPanels, Tabs, TabsVariantContext, useTabsVar
29
36
  export { DateField, DateInput } from './date-field/date-field.js';
30
37
  export { DatePicker } from './date-picker/date-picker.js';
31
38
  export { DateRangePicker } from './date-range-picker/date-range-picker.js';
39
+ export { Checkbox, CheckboxGroup } from './checkbox/checkbox.js';
40
+ export { CheckboxGroupStyleContext, useCheckboxGroupStyleContext } from './checkbox/checkbox-group-style-context.js';
32
41
  export { Pagination } from './pagination/pagination.js';
33
42
  export { PaginationCursor } from './pagination/pagination-cursor.js';
34
43
  export { PaginationItem } from './pagination/pagination-item.js';
@@ -55,9 +64,11 @@ export { NavbarItem } from './navbar/navbar-item.js';
55
64
  export { useNavbar } from './navbar/use-navbar.js';
56
65
  export { NavbarProvider, useNavbarContext } from './navbar/navbar-context.js';
57
66
  export { Avatar } from './avatar/index.js';
67
+ export { Accordion, AccordionContent, AccordionHeader, AccordionItem, AccordionStyleContext, useAccordionStyleContext } from './accordion/accordion.js';
58
68
  export { TimeField } from './time-field/time-field.js';
59
69
  export { SearchField } from './search-field/search-field.js';
60
70
  export { Link } from './link/link.js';
71
+ export { Breadcrumb, Breadcrumbs } from './breadcrumbs/breadcrumbs.js';
61
72
  export { Sidebar, generateSidebarItems } from './sidebar/sidebar.js';
62
73
  export { SidebarRoot } from './sidebar/sidebar-root.js';
63
74
  export { SidebarItem } from './sidebar/sidebar-item.js';
@@ -68,19 +79,8 @@ export { CountrySelect, FlagComponent, PhoneInput, PhoneNumberField } from './ph
68
79
  export { formatPhoneNumber, formatPhoneNumberIntl, isPossiblePhoneNumber, isValidPhoneNumber, parsePhoneNumber } from 'react-phone-number-input';
69
80
  export { Infobox } from './infobox/infobox.js';
70
81
  export { Radio, RadioGroup } from './radio-group/radio.js';
71
- export { Accordion, AccordionContent, AccordionHeader, AccordionItem, AccordionStyleContext, useAccordionStyleContext } from './accordion/accordion.js';
72
82
  export { AvatarContext, useAvatarContext } from './avatar/avatar-context.js';
73
83
  export { AvatarFallback, AvatarImage, AvatarRoot } from './avatar/avatar.js';
74
84
  export { AvatarGroup } from './avatar/avatar-group.js';
75
85
  export { AvatarGroupProvider, useAvatarGroup } from './avatar/avatar-group-context.js';
76
- export { Badge } from './badge/badge.js';
77
- export { Banner } from './banner/banner.js';
78
- export { Breadcrumb, Breadcrumbs } from './breadcrumbs/breadcrumbs.js';
79
- export { Button } from './button/button.js';
80
- export { Calendar, CalendarStateWrapper } from './calendar/calendar.js';
81
- export { CalendarDate } from '@internationalized/date';
82
- export { CalendarStyleContext, useCalendarStyleContext } from './calendar/calendar-style-context.js';
83
- export { Checkbox, CheckboxGroup } from './checkbox/checkbox.js';
84
- export { CheckboxGroupStyleContext, useCheckboxGroupStyleContext } from './checkbox/checkbox-group-style-context.js';
85
- export { getEraFormat, useGenerateLocalizedMonths, useGenerateLocalizedYears, useLocalizedMonthYear } from './calendar/utils.js';
86
86
  export { toast } from 'sonner';
@@ -5,10 +5,10 @@ import { useContext, isValidElement } from 'react';
5
5
  import { useLocalizedStringFormatter } from 'react-aria';
6
6
  import { Dialog } from 'react-aria-components';
7
7
  import { cn } from '@opengovsg/oui-theme';
8
+ import { Button } from '../button/button.js';
8
9
  import { i18nStrings } from './i18n.js';
9
10
  import { ModalVariantContext } from './modal-variant-context.js';
10
11
  import X from '../node_modules/.pnpm/lucide-react@0.475.0_react@19.2.3/node_modules/lucide-react/dist/esm/icons/x.js';
11
- import { Button } from '../button/button.js';
12
12
 
13
13
  function ModalContent({
14
14
  closeButtonContent: closeButtonContentProp,
@@ -3,12 +3,12 @@
3
3
  import { jsxs, jsx, Fragment } from 'react/jsx-runtime';
4
4
  import { NumberField as NumberField$1 } from 'react-aria-components';
5
5
  import { numberFieldStyles, fieldBorderStyles, cn, composeTailwindRenderProps, dataAttr } from '@opengovsg/oui-theme';
6
+ import { Button } from '../button/button.js';
6
7
  import { Label, FieldGroup, Description, FieldError } from '../field/field.js';
7
8
  import { Input } from '../input/input.js';
8
9
  import { mapPropsVariants } from '../system/utils.js';
9
10
  import Minus from '../node_modules/.pnpm/lucide-react@0.475.0_react@19.2.3/node_modules/lucide-react/dist/esm/icons/minus.js';
10
11
  import Plus from '../node_modules/.pnpm/lucide-react@0.475.0_react@19.2.3/node_modules/lucide-react/dist/esm/icons/plus.js';
11
- import { Button } from '../button/button.js';
12
12
 
13
13
  function NumberField(originalProps) {
14
14
  const [
@@ -6,12 +6,12 @@ import { CalendarDate, today, getLocalTimeZone, getDayOfWeek } from '@internatio
6
6
  import { RangeCalendar as RangeCalendar$1, Provider, CalendarGrid, CalendarGridBody, Text, RangeCalendarStateContext, useLocale, CalendarCell } from 'react-aria-components';
7
7
  import { useDeepCompareMemo } from 'use-deep-compare';
8
8
  import { calendarStyles, composeRenderProps, cn, dataAttr } from '@opengovsg/oui-theme';
9
+ import { CalendarStyleContext, useCalendarStyleContext } from '../calendar/calendar-style-context.js';
9
10
  import { AgnosticCalendarStateContext } from '../calendar/agnostic-calendar-state-context.js';
10
11
  import { CalendarBottomContent } from '../calendar/calendar-bottom-content.js';
11
12
  import { CalendarGridHeader } from '../calendar/calendar-grid-header.js';
12
13
  import { CalendarHeader } from '../calendar/calendar-header.js';
13
14
  import { forwardRefGeneric, mapPropsVariants } from '../system/utils.js';
14
- import { CalendarStyleContext, useCalendarStyleContext } from '../calendar/calendar-style-context.js';
15
15
 
16
16
  const RangeCalendar = forwardRefGeneric(function RangeCalendar2(originalProps, ref) {
17
17
  const [props, variantProps] = mapPropsVariants(
@@ -3,13 +3,13 @@ import { jsxs, jsx } from 'react/jsx-runtime';
3
3
  import { useLocalizedStringFormatter } from 'react-aria';
4
4
  import { SearchField as SearchField$1 } from 'react-aria-components';
5
5
  import { searchFieldStyles, composeRenderProps } from '@opengovsg/oui-theme';
6
+ import { Button } from '../button/button.js';
6
7
  import { Label, FieldGroup, Description, FieldError } from '../field/field.js';
7
8
  import { Input } from '../input/input.js';
8
9
  import { mapPropsVariants } from '../system/utils.js';
9
10
  import { i18nStrings } from './i18n.js';
10
11
  import Search from '../node_modules/.pnpm/lucide-react@0.475.0_react@19.2.3/node_modules/lucide-react/dist/esm/icons/search.js';
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
- import { Button } from '../button/button.js';
13
13
 
14
14
  function SearchField(originalProps) {
15
15
  const [
@@ -20,6 +20,7 @@ function SearchField(originalProps) {
20
20
  searchIcon,
21
21
  inputProps,
22
22
  classNames,
23
+ clearIcon,
23
24
  ...props
24
25
  },
25
26
  variantProps
@@ -66,7 +67,7 @@ function SearchField(originalProps) {
66
67
  ...inputProps
67
68
  }
68
69
  ),
69
- /* @__PURE__ */ jsx(
70
+ clearIcon !== null && /* @__PURE__ */ jsx(
70
71
  Button,
71
72
  {
72
73
  isIconOnly: true,
@@ -74,8 +75,10 @@ function SearchField(originalProps) {
74
75
  variant: "clear",
75
76
  color: "sub",
76
77
  size: variantProps.size,
77
- className: styles.clearButton({ className: classNames?.clearButton }),
78
- children: /* @__PURE__ */ jsx(X, { "aria-hidden": true })
78
+ className: styles.clearButton({
79
+ className: classNames?.clearButton
80
+ }),
81
+ children: clearIcon ?? /* @__PURE__ */ jsx(X, { "aria-hidden": true })
79
82
  }
80
83
  )
81
84
  ] }),
@@ -5,6 +5,7 @@ import { useMemo, isValidElement, cloneElement } from 'react';
5
5
  import { useLocalizedStringFormatter } from 'react-aria';
6
6
  import { useFilter, Virtualizer, ListLayout, ListBox, Provider, Select as Select$1, SelectValue, Autocomplete, SearchField, Input } from 'react-aria-components';
7
7
  import { selectStyles, cn, composeRenderProps } from '@opengovsg/oui-theme';
8
+ import { Button } from '../button/button.js';
8
9
  import { Label, Description, FieldError } from '../field/field.js';
9
10
  import { Popover } from '../popover/popover.js';
10
11
  import { useElementWidth } from '../system/react-utils/sizing.js';
@@ -12,7 +13,6 @@ import { mapPropsVariants } from '../system/utils.js';
12
13
  import { i18nStrings } from './i18n.js';
13
14
  import { SelectVariantContext } from './select-variant-context.js';
14
15
  import ChevronDown from '../node_modules/.pnpm/lucide-react@0.475.0_react@19.2.3/node_modules/lucide-react/dist/esm/icons/chevron-down.js';
15
- import { Button } from '../button/button.js';
16
16
 
17
17
  const calculateEstimatedRowHeight = (size) => {
18
18
  switch (size) {
@@ -6,11 +6,11 @@ import { useLocalizedStringFormatter } from 'react-aria';
6
6
  import { Disclosure, DisclosurePanel, Provider, Link, Button as Button$1 } from 'react-aria-components';
7
7
  import { useDisclosureState } from 'react-stately';
8
8
  import { dataAttr } from '@opengovsg/oui-theme';
9
+ import { Button } from '../button/button.js';
9
10
  import { forwardRef } from '../system/utils.js';
10
11
  import { useSidebarStyleContext, useSidebarCollapseContext, SidebarNestContext, useSidebarNestContext } from './context.js';
11
12
  import { i18nStrings } from './i18n.js';
12
13
  import ChevronDown from '../node_modules/.pnpm/lucide-react@0.475.0_react@19.2.3/node_modules/lucide-react/dist/esm/icons/chevron-down.js';
13
- import { Button } from '../button/button.js';
14
14
 
15
15
  const SidebarListSection = ({
16
16
  onlyCaretToggle,
@@ -4,6 +4,7 @@ import type { DropzoneOptions } from "react-dropzone";
4
4
  import type { FileDropzoneSlots, FileInfoDropzoneSlots, SlotsToClasses, VariantProps } from "@opengovsg/oui-theme";
5
5
  import { fileDropzoneStyles } from "@opengovsg/oui-theme";
6
6
  import type { FileItem } from "./types";
7
+ import type { MaxFileSizeRule } from "./utils";
7
8
  export interface FileItemsRenderProps {
8
9
  file: FileItem;
9
10
  removeFile: () => void;
@@ -39,6 +40,17 @@ export interface FileDropzoneProps extends Omit<AriaFieldProps, "validate">, Inp
39
40
  * @default Number.POSITIVE_INFINITY
40
41
  */
41
42
  maxFileSize?: number;
43
+ /**
44
+ * Per-MIME-type maximum file size rules.
45
+ * Rules are matched in order; first match wins.
46
+ * Falls back to `maxFileSize` for unmatched types.
47
+ */
48
+ maxFileSizeByType?: MaxFileSizeRule[];
49
+ /**
50
+ * Custom file size text to display below the dropzone.
51
+ * If provided, overrides the auto-generated text.
52
+ */
53
+ fileSizeText?: string;
42
54
  /**
43
55
  * Minimum upload size of each file allowed in bytes.
44
56
  * @default 0
@@ -1 +1 @@
1
- {"version":3,"file":"file-dropzone.d.ts","sourceRoot":"","sources":["../../../src/file-dropzone/file-dropzone.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,SAAS,EAAE,UAAU,EAAE,MAAM,qBAAqB,CAAA;AAChE,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,YAAY,CAAA;AAChD,OAAO,KAAK,EAAE,eAAe,EAA4B,MAAM,gBAAgB,CAAA;AAe/E,OAAO,KAAK,EACV,iBAAiB,EACjB,qBAAqB,EACrB,cAAc,EACd,YAAY,EACb,MAAM,sBAAsB,CAAA;AAC7B,OAAO,EAAY,kBAAkB,EAAE,MAAM,sBAAsB,CAAA;AAEnE,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAA;AAavC,MAAM,WAAW,oBAAoB;IACnC,IAAI,EAAE,QAAQ,CAAA;IACd,UAAU,EAAE,MAAM,IAAI,CAAA;CACvB;AAED,MAAM,WAAW,iBACf,SAAQ,IAAI,CAAC,cAAc,EAAE,UAAU,CAAC,EACtC,SAAS,EACT,UAAU,CAAC,QAAQ,EAAE,CAAC,EACtB,YAAY,CAAC,OAAO,kBAAkB,CAAC;IACzC,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,KAAK,CAAC,EAAE,KAAK,CAAC,SAAS,CAAA;IACvB,WAAW,CAAC,EAAE,KAAK,CAAC,SAAS,CAAA;IAC7B,YAAY,CAAC,EAAE,KAAK,CAAC,SAAS,CAAA;IAE9B,SAAS,CAAC,EAAE,eAAe,CAAC,WAAW,CAAC,CAAA;IACxC,UAAU,CAAC,EAAE,cAAc,CAAC,iBAAiB,CAAC,CAAA;IAC9C,cAAc,CAAC,EAAE,cAAc,CAAC,qBAAqB,CAAC,CAAA;IACtD,sCAAsC;IACtC,KAAK,CAAC,EAAE,QAAQ,EAAE,CAAA;IAClB,wCAAwC;IACxC,YAAY,CAAC,EAAE,QAAQ,EAAE,CAAA;IACzB,iCAAiC;IACjC,QAAQ,CAAC,EAAE,CAAC,KAAK,EAAE,QAAQ,EAAE,KAAK,IAAI,CAAA;IACtC;;;;OAIG;IACH,gBAAgB,CAAC,EAAE,MAAM,EAAE,CAAA;IAC3B;;;;OAIG;IACH,YAAY,CAAC,EAAE,QAAQ,GAAG,SAAS,CAAA;IAEnC;;;OAGG;IACH,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB;;;OAGG;IACH,WAAW,CAAC,EAAE,MAAM,CAAA;IAEpB;;;OAGG;IACH,gBAAgB,CAAC,EAAE,OAAO,CAAA;IAC1B;;;OAGG;IACH,QAAQ,CAAC,EAAE,MAAM,CAAA;IAEjB;;OAEG;IACH,iBAAiB,CAAC,EAAE,OAAO,CAAA;IAE3B;;OAEG;IACH,UAAU,CAAC,EAAE,QAAQ,EAAE,CAAA;IAEvB;;OAEG;IACH,WAAW,CAAC,EAAE,CAAC,UAAU,EAAE,QAAQ,EAAE,KAAK,IAAI,CAAA;IAC9C;;;OAGG;IACH,OAAO,CAAC,EAAE,CAAC,YAAY,EAAE,MAAM,KAAK,IAAI,CAAA;IACxC,QAAQ,CAAC,EAAE,CAAC,MAAM,EAAE,oBAAoB,KAAK,KAAK,CAAC,SAAS,CAAA;IAE5D;;;OAGG;IACH,mBAAmB,CAAC,EAAE,OAAO,CAAA;IAE7B;;;;OAIG;IACH,YAAY,CAAC,EAAE,OAAO,GAAG,OAAO,GAAG,IAAI,CAAA;CACxC;AAED,eAAO,MAAM,YAAY,kBAAmB,iBAAiB,4CA4Q5D,CAAA"}
1
+ {"version":3,"file":"file-dropzone.d.ts","sourceRoot":"","sources":["../../../src/file-dropzone/file-dropzone.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,SAAS,EAAE,UAAU,EAAE,MAAM,qBAAqB,CAAA;AAChE,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,YAAY,CAAA;AAChD,OAAO,KAAK,EAAE,eAAe,EAA4B,MAAM,gBAAgB,CAAA;AAgB/E,OAAO,KAAK,EACV,iBAAiB,EACjB,qBAAqB,EACrB,cAAc,EACd,YAAY,EACb,MAAM,sBAAsB,CAAA;AAC7B,OAAO,EAAY,kBAAkB,EAAE,MAAM,sBAAsB,CAAA;AAEnE,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAA;AAWvC,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,SAAS,CAAA;AAG9C,MAAM,WAAW,oBAAoB;IACnC,IAAI,EAAE,QAAQ,CAAA;IACd,UAAU,EAAE,MAAM,IAAI,CAAA;CACvB;AAED,MAAM,WAAW,iBACf,SAAQ,IAAI,CAAC,cAAc,EAAE,UAAU,CAAC,EACtC,SAAS,EACT,UAAU,CAAC,QAAQ,EAAE,CAAC,EACtB,YAAY,CAAC,OAAO,kBAAkB,CAAC;IACzC,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,KAAK,CAAC,EAAE,KAAK,CAAC,SAAS,CAAA;IACvB,WAAW,CAAC,EAAE,KAAK,CAAC,SAAS,CAAA;IAC7B,YAAY,CAAC,EAAE,KAAK,CAAC,SAAS,CAAA;IAE9B,SAAS,CAAC,EAAE,eAAe,CAAC,WAAW,CAAC,CAAA;IACxC,UAAU,CAAC,EAAE,cAAc,CAAC,iBAAiB,CAAC,CAAA;IAC9C,cAAc,CAAC,EAAE,cAAc,CAAC,qBAAqB,CAAC,CAAA;IACtD,sCAAsC;IACtC,KAAK,CAAC,EAAE,QAAQ,EAAE,CAAA;IAClB,wCAAwC;IACxC,YAAY,CAAC,EAAE,QAAQ,EAAE,CAAA;IACzB,iCAAiC;IACjC,QAAQ,CAAC,EAAE,CAAC,KAAK,EAAE,QAAQ,EAAE,KAAK,IAAI,CAAA;IACtC;;;;OAIG;IACH,gBAAgB,CAAC,EAAE,MAAM,EAAE,CAAA;IAC3B;;;;OAIG;IACH,YAAY,CAAC,EAAE,QAAQ,GAAG,SAAS,CAAA;IAEnC;;;OAGG;IACH,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB;;;;OAIG;IACH,iBAAiB,CAAC,EAAE,eAAe,EAAE,CAAA;IACrC;;;OAGG;IACH,YAAY,CAAC,EAAE,MAAM,CAAA;IACrB;;;OAGG;IACH,WAAW,CAAC,EAAE,MAAM,CAAA;IAEpB;;;OAGG;IACH,gBAAgB,CAAC,EAAE,OAAO,CAAA;IAC1B;;;OAGG;IACH,QAAQ,CAAC,EAAE,MAAM,CAAA;IAEjB;;OAEG;IACH,iBAAiB,CAAC,EAAE,OAAO,CAAA;IAE3B;;OAEG;IACH,UAAU,CAAC,EAAE,QAAQ,EAAE,CAAA;IAEvB;;OAEG;IACH,WAAW,CAAC,EAAE,CAAC,UAAU,EAAE,QAAQ,EAAE,KAAK,IAAI,CAAA;IAC9C;;;OAGG;IACH,OAAO,CAAC,EAAE,CAAC,YAAY,EAAE,MAAM,KAAK,IAAI,CAAA;IACxC,QAAQ,CAAC,EAAE,CAAC,MAAM,EAAE,oBAAoB,KAAK,KAAK,CAAC,SAAS,CAAA;IAE5D;;;OAGG;IACH,mBAAmB,CAAC,EAAE,OAAO,CAAA;IAE7B;;;;OAIG;IACH,YAAY,CAAC,EAAE,OAAO,GAAG,OAAO,GAAG,IAAI,CAAA;CACxC;AAED,eAAO,MAAM,YAAY,kBAAmB,iBAAiB,4CAkV5D,CAAA"}
@@ -4,4 +4,5 @@ export type { FileInfoProps } from "./file-info";
4
4
  export type { FileDropzoneProps, FileItemsRenderProps } from "./file-dropzone";
5
5
  export type { FileItem } from "./types";
6
6
  export { formatBytes, formatErrorMessage } from "./utils";
7
+ export type { MaxFileSizeRule } from "./utils";
7
8
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/file-dropzone/index.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAA;AAC9C,OAAO,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAA;AAEtC,YAAY,EAAE,aAAa,EAAE,MAAM,aAAa,CAAA;AAChD,YAAY,EAAE,iBAAiB,EAAE,oBAAoB,EAAE,MAAM,iBAAiB,CAAA;AAE9E,YAAY,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAA;AAEvC,OAAO,EAAE,WAAW,EAAE,kBAAkB,EAAE,MAAM,SAAS,CAAA"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/file-dropzone/index.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAA;AAC9C,OAAO,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAA;AAEtC,YAAY,EAAE,aAAa,EAAE,MAAM,aAAa,CAAA;AAChD,YAAY,EAAE,iBAAiB,EAAE,oBAAoB,EAAE,MAAM,iBAAiB,CAAA;AAE9E,YAAY,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAA;AAEvC,OAAO,EAAE,WAAW,EAAE,kBAAkB,EAAE,MAAM,SAAS,CAAA;AAEzD,YAAY,EAAE,eAAe,EAAE,MAAM,SAAS,CAAA"}
@@ -1,4 +1,22 @@
1
1
  import type { FileRejection } from "react-dropzone";
2
+ export interface MaxFileSizeRule {
3
+ /** MIME types this rule applies to (e.g. ["application/zip"]) */
4
+ mimeTypes: string[];
5
+ /** Max file size in bytes for these types */
6
+ maxFileSize: number;
7
+ /** Display label for fileSizeText (e.g. ".zip files"). Falls back to raw mime type string. */
8
+ label?: string;
9
+ }
10
+ /**
11
+ * Check if a file's MIME type matches a pattern.
12
+ * Supports exact matches ("application/zip") and wildcards ("image/*").
13
+ */
14
+ export declare const matchesMimeType: (fileType: string, pattern: string) => boolean;
15
+ /**
16
+ * Resolve the effective max file size for a given file type.
17
+ * Iterates rules in order; first match wins. Falls back to defaultMaxSize.
18
+ */
19
+ export declare const resolveMaxFileSize: (fileType: string, rules: MaxFileSizeRule[], defaultMaxSize: number) => number;
2
20
  export declare const formatBytes: (bytes: number, decimals?: number, base?: "binary" | "decimal", size?: "bytes" | "KB" | "MB" | "GB" | "TB" | "PB" | "EB" | "ZB" | "YB") => string;
3
21
  export declare const formatErrorMessage: (error: FileRejection["errors"][number], config: {
4
22
  maxFileSize: number;
@@ -1 +1 @@
1
- {"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../../../src/file-dropzone/utils.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAA;AAGnD,eAAO,MAAM,WAAW,UACf,MAAM,4BAEP,QAAQ,GAAG,SAAS,SACnB,OAAO,GAAG,IAAI,GAAG,IAAI,GAAG,IAAI,GAAG,IAAI,GAAG,IAAI,GAAG,IAAI,GAAG,IAAI,GAAG,IAAI,WAavE,CAAA;AAED,eAAO,MAAM,kBAAkB,UACtB,aAAa,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,UAC9B;IACN,WAAW,EAAE,MAAM,CAAA;IACnB,WAAW,EAAE,MAAM,CAAA;IACnB,QAAQ,EAAE,MAAM,CAAA;IAChB,YAAY,EAAE,QAAQ,GAAG,SAAS,CAAA;CACnC,WAgBF,CAAA"}
1
+ {"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../../../src/file-dropzone/utils.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAA;AAGnD,MAAM,WAAW,eAAe;IAC9B,iEAAiE;IACjE,SAAS,EAAE,MAAM,EAAE,CAAA;IACnB,6CAA6C;IAC7C,WAAW,EAAE,MAAM,CAAA;IACnB,8FAA8F;IAC9F,KAAK,CAAC,EAAE,MAAM,CAAA;CACf;AAED;;;GAGG;AACH,eAAO,MAAM,eAAe,aAChB,MAAM,WACP,MAAM,KACd,OAOF,CAAA;AAED;;;GAGG;AACH,eAAO,MAAM,kBAAkB,aACnB,MAAM,SACT,eAAe,EAAE,kBACR,MAAM,KACrB,MAOF,CAAA;AAED,eAAO,MAAM,WAAW,UACf,MAAM,4BAEP,QAAQ,GAAG,SAAS,SACnB,OAAO,GAAG,IAAI,GAAG,IAAI,GAAG,IAAI,GAAG,IAAI,GAAG,IAAI,GAAG,IAAI,GAAG,IAAI,GAAG,IAAI,WAavE,CAAA;AAED,eAAO,MAAM,kBAAkB,UACtB,aAAa,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,UAC9B;IACN,WAAW,EAAE,MAAM,CAAA;IACnB,WAAW,EAAE,MAAM,CAAA;IACnB,QAAQ,EAAE,MAAM,CAAA;IAChB,YAAY,EAAE,QAAQ,GAAG,SAAS,CAAA;CACnC,WAgBF,CAAA"}
@@ -10,6 +10,11 @@ export interface SearchFieldProps extends AriaSearchFieldProps, SearchFieldVaria
10
10
  searchIcon?: React.ReactNode | null;
11
11
  inputProps?: Partial<InputProps>;
12
12
  classNames?: SlotsToClasses<SearchFieldSlots>;
13
+ /**
14
+ * The icon to show in the clear button. Defaults to an `XIcon`. Set to `null` to hide the clear button.
15
+ * @example Can also be used to provide a spinner icon while the search is loading.
16
+ */
17
+ clearIcon?: React.ReactNode;
13
18
  }
14
19
  export declare function SearchField(originalProps: SearchFieldProps): import("react/jsx-runtime").JSX.Element;
15
20
  //# sourceMappingURL=search-field.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"search-field.d.ts","sourceRoot":"","sources":["../../../src/search-field/search-field.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,gBAAgB,IAAI,oBAAoB,EACxC,gBAAgB,EACjB,MAAM,uBAAuB,CAAA;AAK9B,OAAO,KAAK,EACV,gBAAgB,EAChB,uBAAuB,EACvB,cAAc,EACf,MAAM,sBAAsB,CAAA;AAG7B,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,UAAU,CAAA;AAO1C,MAAM,WAAW,gBACf,SAAQ,oBAAoB,EAC1B,uBAAuB;IACzB,KAAK,CAAC,EAAE,KAAK,CAAC,SAAS,CAAA;IACvB,WAAW,CAAC,EAAE,KAAK,CAAC,SAAS,CAAA;IAC7B,YAAY,CAAC,EACT,KAAK,CAAC,SAAS,GACf,CAAC,CAAC,UAAU,EAAE,gBAAgB,KAAK,KAAK,CAAC,SAAS,CAAC,CAAA;IACvD;yCACqC;IACrC,UAAU,CAAC,EAAE,KAAK,CAAC,SAAS,GAAG,IAAI,CAAA;IACnC,UAAU,CAAC,EAAE,OAAO,CAAC,UAAU,CAAC,CAAA;IAChC,UAAU,CAAC,EAAE,cAAc,CAAC,gBAAgB,CAAC,CAAA;CAC9C;AAED,wBAAgB,WAAW,CAAC,aAAa,EAAE,gBAAgB,2CAwE1D"}
1
+ {"version":3,"file":"search-field.d.ts","sourceRoot":"","sources":["../../../src/search-field/search-field.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,gBAAgB,IAAI,oBAAoB,EACxC,gBAAgB,EACjB,MAAM,uBAAuB,CAAA;AAK9B,OAAO,KAAK,EACV,gBAAgB,EAChB,uBAAuB,EACvB,cAAc,EACf,MAAM,sBAAsB,CAAA;AAG7B,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,UAAU,CAAA;AAO1C,MAAM,WAAW,gBACf,SAAQ,oBAAoB,EAC1B,uBAAuB;IACzB,KAAK,CAAC,EAAE,KAAK,CAAC,SAAS,CAAA;IACvB,WAAW,CAAC,EAAE,KAAK,CAAC,SAAS,CAAA;IAC7B,YAAY,CAAC,EACT,KAAK,CAAC,SAAS,GACf,CAAC,CAAC,UAAU,EAAE,gBAAgB,KAAK,KAAK,CAAC,SAAS,CAAC,CAAA;IACvD;yCACqC;IACrC,UAAU,CAAC,EAAE,KAAK,CAAC,SAAS,GAAG,IAAI,CAAA;IACnC,UAAU,CAAC,EAAE,OAAO,CAAC,UAAU,CAAC,CAAA;IAChC,UAAU,CAAC,EAAE,cAAc,CAAC,gBAAgB,CAAC,CAAA;IAE7C;;;OAGG;IACH,SAAS,CAAC,EAAE,KAAK,CAAC,SAAS,CAAA;CAC5B;AAED,wBAAgB,WAAW,CAAC,aAAa,EAAE,gBAAgB,2CA6E1D"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@opengovsg/oui",
3
- "version": "0.0.49",
3
+ "version": "0.0.51",
4
4
  "sideEffects": false,
5
5
  "license": "SEE LICENSE IN LICENSE.md",
6
6
  "type": "module",
@@ -51,10 +51,10 @@
51
51
  "tsx": "^4.21.0",
52
52
  "typescript": "5.7.3",
53
53
  "@oui/chromatic": "0.0.0",
54
- "@oui/eslint-config": "0.0.0",
55
54
  "@oui/prettier-config": "0.0.0",
56
- "@oui/typescript-config": "0.0.0",
57
- "@opengovsg/oui-theme": "0.0.49"
55
+ "@oui/eslint-config": "0.0.0",
56
+ "@opengovsg/oui-theme": "0.0.51",
57
+ "@oui/typescript-config": "0.0.0"
58
58
  },
59
59
  "dependencies": {
60
60
  "@internationalized/date": "^3.10.1",
@@ -90,7 +90,7 @@
90
90
  "motion": ">=11.12.0 || >=12.0.0-alpha.1",
91
91
  "react": ">= 18",
92
92
  "react-aria-components": "^1.14.0",
93
- "@opengovsg/oui-theme": "0.0.49"
93
+ "@opengovsg/oui-theme": "0.0.51"
94
94
  },
95
95
  "scripts": {
96
96
  "build": "tsx ../../tooling/build-scripts/main.ts --dts --clean",