@opengovsg/oui 0.0.21 → 0.0.23

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 (55) hide show
  1. package/dist/cjs/button/button.cjs +1 -1
  2. package/dist/cjs/calendar/calendar-month-day-selector.cjs +4 -3
  3. package/dist/cjs/date-picker/date-picker.cjs +34 -9
  4. package/dist/cjs/field/field.cjs +1 -1
  5. package/dist/cjs/file-dropzone/contexts.cjs +18 -0
  6. package/dist/cjs/file-dropzone/file-dropzone.cjs +311 -0
  7. package/dist/cjs/file-dropzone/file-info.cjs +146 -0
  8. package/dist/cjs/file-dropzone/index.cjs +13 -0
  9. package/dist/cjs/file-dropzone/types.cjs +3 -0
  10. package/dist/cjs/file-dropzone/utils.cjs +31 -0
  11. package/dist/cjs/index.cjs +43 -34
  12. package/dist/cjs/node_modules/.pnpm/lucide-react@0.475.0_react@19.0.0/node_modules/lucide-react/dist/esm/icons/plus.cjs +22 -0
  13. package/dist/cjs/node_modules/.pnpm/lucide-react@0.475.0_react@19.0.0/node_modules/lucide-react/dist/esm/icons/trash-2.cjs +25 -0
  14. package/dist/cjs/node_modules/.pnpm/lucide-react@0.475.0_react@19.0.0/node_modules/lucide-react/dist/esm/icons/upload.cjs +23 -0
  15. package/dist/cjs/number-field/index.cjs +8 -0
  16. package/dist/cjs/number-field/number-field.cjs +136 -0
  17. package/dist/esm/button/button.js +1 -1
  18. package/dist/esm/calendar/calendar-month-day-selector.js +4 -3
  19. package/dist/esm/date-picker/date-picker.js +34 -9
  20. package/dist/esm/field/field.js +1 -1
  21. package/dist/esm/file-dropzone/contexts.js +13 -0
  22. package/dist/esm/file-dropzone/file-dropzone.js +309 -0
  23. package/dist/esm/file-dropzone/file-info.js +144 -0
  24. package/dist/esm/file-dropzone/index.js +4 -0
  25. package/dist/esm/file-dropzone/types.js +1 -0
  26. package/dist/esm/file-dropzone/utils.js +28 -0
  27. package/dist/esm/index.js +13 -9
  28. package/dist/esm/node_modules/.pnpm/lucide-react@0.475.0_react@19.0.0/node_modules/lucide-react/dist/esm/icons/plus.js +17 -0
  29. package/dist/esm/node_modules/.pnpm/lucide-react@0.475.0_react@19.0.0/node_modules/lucide-react/dist/esm/icons/trash-2.js +20 -0
  30. package/dist/esm/node_modules/.pnpm/lucide-react@0.475.0_react@19.0.0/node_modules/lucide-react/dist/esm/icons/upload.js +18 -0
  31. package/dist/esm/number-field/index.js +2 -0
  32. package/dist/esm/number-field/number-field.js +134 -0
  33. package/dist/types/calendar/calendar-month-day-selector.d.ts.map +1 -1
  34. package/dist/types/date-picker/date-picker.d.ts +5 -2
  35. package/dist/types/date-picker/date-picker.d.ts.map +1 -1
  36. package/dist/types/file-dropzone/contexts.d.ts +4 -0
  37. package/dist/types/file-dropzone/contexts.d.ts.map +1 -0
  38. package/dist/types/file-dropzone/file-dropzone.d.ts +82 -0
  39. package/dist/types/file-dropzone/file-dropzone.d.ts.map +1 -0
  40. package/dist/types/file-dropzone/file-info.d.ts +9 -0
  41. package/dist/types/file-dropzone/file-info.d.ts.map +1 -0
  42. package/dist/types/file-dropzone/index.d.ts +7 -0
  43. package/dist/types/file-dropzone/index.d.ts.map +1 -0
  44. package/dist/types/file-dropzone/types.d.ts +24 -0
  45. package/dist/types/file-dropzone/types.d.ts.map +1 -0
  46. package/dist/types/file-dropzone/utils.d.ts +8 -0
  47. package/dist/types/file-dropzone/utils.d.ts.map +1 -0
  48. package/dist/types/index.d.mts +2 -0
  49. package/dist/types/index.d.ts +2 -0
  50. package/dist/types/index.d.ts.map +1 -1
  51. package/dist/types/number-field/index.d.ts +3 -0
  52. package/dist/types/number-field/index.d.ts.map +1 -0
  53. package/dist/types/number-field/number-field.d.ts +24 -0
  54. package/dist/types/number-field/number-field.d.ts.map +1 -0
  55. package/package.json +4 -3
@@ -0,0 +1,309 @@
1
+ "use strict";
2
+ "use client";
3
+ import { jsx, jsxs } from 'react/jsx-runtime';
4
+ import { useCallback, useMemo, useEffect } from 'react';
5
+ import { useFormValidationState } from '@react-stately/form';
6
+ import { useField, useId } from 'react-aria';
7
+ import { Provider, LabelContext, GroupContext, TextContext, FieldErrorContext, Group } from 'react-aria-components';
8
+ import { useDropzone } from 'react-dropzone';
9
+ import { fileDropzoneStyles, dataAttr } from '@opengovsg/oui-theme';
10
+ import { mapPropsVariants } from '../system/utils.js';
11
+ import { FileDropzoneStyleContext, FileDropzoneStateContext, useFileDropzoneStateContext, useFileDropzoneStyleContext } from './contexts.js';
12
+ import { FileInfo } from './file-info.js';
13
+ import { formatErrorMessage, formatBytes } from './utils.js';
14
+ import { useControllableState } from '../hooks/use-controllable-state.js';
15
+ import Upload from '../node_modules/.pnpm/lucide-react@0.475.0_react@19.0.0/node_modules/lucide-react/dist/esm/icons/upload.js';
16
+ import { Label, Description, FieldError } from '../field/field.js';
17
+
18
+ const FileDropzone = (originalProps) => {
19
+ const [props, variantProps] = mapPropsVariants(
20
+ originalProps,
21
+ fileDropzoneStyles.variantKeys
22
+ );
23
+ const {
24
+ name,
25
+ allowedMimeTypes = [],
26
+ maxFileSize = Number.POSITIVE_INFINITY,
27
+ minFileSize = 0,
28
+ showFileSizeText = true,
29
+ maxFiles = 1,
30
+ isDisabled,
31
+ isReadOnly,
32
+ classNames,
33
+ itemClassNames,
34
+ validator,
35
+ showRejectedFiles,
36
+ onError,
37
+ errorMessage,
38
+ label,
39
+ description,
40
+ children,
41
+ hideDropzoneOnValue = maxFiles === 1,
42
+ imagePreview = "small"
43
+ } = props;
44
+ const [value, setValue] = useControllableState({
45
+ value: props.value,
46
+ defaultValue: props.defaultValue || [],
47
+ onChange: props.onChange
48
+ });
49
+ const [rejections, setRejections] = useControllableState({
50
+ value: props.rejections,
51
+ defaultValue: [],
52
+ onChange: props.onRejection
53
+ });
54
+ const validationState = useFormValidationState({
55
+ ...props,
56
+ value
57
+ });
58
+ const { isInvalid, validationErrors, validationDetails } = validationState.displayValidation;
59
+ const { labelProps, fieldProps, descriptionProps, errorMessageProps } = useField({
60
+ ...props,
61
+ isInvalid,
62
+ errorMessage: props.errorMessage || validationErrors
63
+ });
64
+ const slots = fileDropzoneStyles(variantProps);
65
+ const fileSizeTextId = useId();
66
+ const formatError = useCallback(
67
+ (error) => formatErrorMessage(error, {
68
+ maxFileSize,
69
+ minFileSize,
70
+ maxFiles
71
+ }),
72
+ [maxFileSize, maxFiles, minFileSize]
73
+ );
74
+ const onDrop = useCallback(
75
+ (acceptedFiles, fileRejections) => {
76
+ const files = acceptedFiles;
77
+ if (showRejectedFiles) {
78
+ const invalidFiles = fileRejections.map(({ file, errors }) => {
79
+ file.errors = errors;
80
+ return file;
81
+ });
82
+ setRejections(invalidFiles);
83
+ }
84
+ setValue(files);
85
+ if (onError && fileRejections.length > 0) {
86
+ const firstError = fileRejections[0].errors[0];
87
+ onError(formatError(firstError));
88
+ }
89
+ },
90
+ [formatError, onError, setRejections, setValue, showRejectedFiles]
91
+ );
92
+ const handleRemoveFile = useCallback(
93
+ (fileName) => {
94
+ setValue((files) => files.filter((file) => file.name !== fileName));
95
+ },
96
+ [setValue]
97
+ );
98
+ const handleRemoveRejection = useCallback(
99
+ (fileName) => {
100
+ setRejections(
101
+ (rejections2) => rejections2.filter((file) => file.name !== fileName)
102
+ );
103
+ },
104
+ [setRejections]
105
+ );
106
+ const { getInputProps, ...dropzoneState } = useDropzone({
107
+ validator,
108
+ accept: allowedMimeTypes.reduce(
109
+ (acc, type) => ({ ...acc, [type]: [] }),
110
+ {}
111
+ ),
112
+ onError: (e) => onError?.(e.message),
113
+ onDrop,
114
+ disabled: isDisabled,
115
+ noDrag: isReadOnly,
116
+ // Prevent ref hijack when there is a label
117
+ noClick: true,
118
+ noKeyboard: true,
119
+ maxSize: maxFileSize,
120
+ minSize: minFileSize,
121
+ maxFiles,
122
+ multiple: maxFiles !== 1
123
+ });
124
+ const fileSizeText = useMemo(() => {
125
+ const notDefaultMaxFileSize = maxFileSize !== Number.POSITIVE_INFINITY;
126
+ const notDefaultMinFileSize = minFileSize !== 0;
127
+ const shouldShow = showFileSizeText && (notDefaultMaxFileSize || notDefaultMinFileSize);
128
+ if (!shouldShow) return null;
129
+ if (notDefaultMaxFileSize && notDefaultMinFileSize) {
130
+ return `File size must be between ${formatBytes(minFileSize, 2)} and ${formatBytes(
131
+ maxFileSize,
132
+ 2
133
+ )}`;
134
+ }
135
+ if (notDefaultMaxFileSize) {
136
+ return `Maximum file size: ${formatBytes(maxFileSize, 2)}`;
137
+ }
138
+ if (notDefaultMinFileSize) {
139
+ return `Minimum file size: ${formatBytes(minFileSize, 2)}`;
140
+ }
141
+ return null;
142
+ }, [maxFileSize, minFileSize, showFileSizeText]);
143
+ const triggerFileSelector = useCallback(() => {
144
+ if (isDisabled || isReadOnly) return;
145
+ dropzoneState.inputRef.current?.click();
146
+ }, [dropzoneState, isDisabled, isReadOnly]);
147
+ useEffect(() => {
148
+ if (value.length <= maxFiles) {
149
+ let changed = false;
150
+ const newFiles = value.map((file) => {
151
+ if (file.errors?.some((e) => e.code === "too-many-files")) {
152
+ file.errors = file.errors.filter((e) => e.code !== "too-many-files");
153
+ changed = true;
154
+ }
155
+ return file;
156
+ });
157
+ if (changed) {
158
+ setValue(newFiles);
159
+ }
160
+ }
161
+ }, [maxFiles, setValue, value]);
162
+ const inputProps = useMemo(() => {
163
+ const inputProps2 = { ...fieldProps, name };
164
+ if (fileSizeText) {
165
+ inputProps2["aria-describedby"] = inputProps2["aria-describedby"] ? `${inputProps2["aria-describedby"]} ${fileSizeTextId}` : fileSizeTextId;
166
+ }
167
+ return getInputProps(inputProps2);
168
+ }, [fieldProps, getInputProps, fileSizeTextId, name, fileSizeText]);
169
+ const showDropzone = useMemo(() => {
170
+ if (hideDropzoneOnValue) {
171
+ return value.length < maxFiles;
172
+ }
173
+ return true;
174
+ }, [hideDropzoneOnValue, maxFiles, value.length]);
175
+ return /* @__PURE__ */ jsx(
176
+ Provider,
177
+ {
178
+ values: [
179
+ [
180
+ FileDropzoneStyleContext,
181
+ { slots, classNames, itemClassNames, ...variantProps }
182
+ ],
183
+ [
184
+ FileDropzoneStateContext,
185
+ {
186
+ isDisabled,
187
+ isReadOnly,
188
+ maxFiles,
189
+ maxFileSize,
190
+ showDropzone,
191
+ files: value,
192
+ handleRemoveFile,
193
+ handleRemoveRejection,
194
+ formatError,
195
+ inputProps,
196
+ triggerFileSelector,
197
+ ...dropzoneState
198
+ }
199
+ ],
200
+ [LabelContext, labelProps],
201
+ [
202
+ GroupContext,
203
+ {
204
+ role: "presentation",
205
+ isInvalid,
206
+ isDisabled: props.isDisabled || false
207
+ }
208
+ ],
209
+ [
210
+ TextContext,
211
+ {
212
+ slots: {
213
+ fileSize: {},
214
+ description: descriptionProps,
215
+ errorMessage: errorMessageProps
216
+ }
217
+ }
218
+ ],
219
+ [FieldErrorContext, { isInvalid, validationErrors, validationDetails }]
220
+ ],
221
+ children: /* @__PURE__ */ jsxs(Group, { className: slots.base({ className: classNames?.base }), children: [
222
+ label && /* @__PURE__ */ jsx(Label, { size: variantProps.size, children: label }),
223
+ showDropzone && /* @__PURE__ */ jsx(FileDropzoneDropzone, {}),
224
+ value.map((file) => {
225
+ if (typeof children === "function") {
226
+ return children({
227
+ file,
228
+ removeFile: () => handleRemoveFile(file.name)
229
+ });
230
+ }
231
+ return /* @__PURE__ */ jsx(FileInfo, { imagePreview, file }, file.name);
232
+ }),
233
+ rejections.length >= 1 && rejections.map((rj) => /* @__PURE__ */ jsx(FileInfo, { imagePreview, file: rj }, rj.name)),
234
+ fileSizeText && /* @__PURE__ */ jsx(
235
+ Description,
236
+ {
237
+ size: variantProps.size,
238
+ id: fileSizeTextId,
239
+ slot: "fileSize",
240
+ children: fileSizeText
241
+ }
242
+ ),
243
+ description && /* @__PURE__ */ jsx(Description, { size: variantProps.size, children: description }),
244
+ errorMessage && /* @__PURE__ */ jsx(FieldError, { size: variantProps.size, children: errorMessage })
245
+ ] })
246
+ }
247
+ );
248
+ };
249
+ const FileDropzoneDropzone = () => {
250
+ const {
251
+ maxFiles,
252
+ getRootProps,
253
+ inputProps,
254
+ triggerFileSelector,
255
+ isDisabled,
256
+ isDragActive
257
+ } = useFileDropzoneStateContext();
258
+ const { slots, classNames } = useFileDropzoneStyleContext();
259
+ return /* @__PURE__ */ jsxs(
260
+ "div",
261
+ {
262
+ ...getRootProps({
263
+ "aria-disabled": isDisabled,
264
+ className: slots.group({
265
+ className: classNames?.group
266
+ })
267
+ }),
268
+ tabIndex: isDisabled ? void 0 : 0,
269
+ onClick: triggerFileSelector,
270
+ onKeyDown: (e) => {
271
+ if (e.key === "Enter" || e.key === " ") {
272
+ e.preventDefault();
273
+ triggerFileSelector();
274
+ }
275
+ },
276
+ children: [
277
+ /* @__PURE__ */ jsx("input", { ...inputProps }),
278
+ /* @__PURE__ */ jsxs(
279
+ "div",
280
+ {
281
+ "data-dragging": dataAttr(isDragActive),
282
+ className: slots.dropzone({ className: classNames?.dropzone }),
283
+ children: [
284
+ /* @__PURE__ */ jsx(Upload, { className: slots.icon({ className: classNames?.icon }) }),
285
+ /* @__PURE__ */ jsxs("div", { className: slots.text({ className: classNames?.text }), children: [
286
+ /* @__PURE__ */ jsxs(
287
+ "span",
288
+ {
289
+ className: slots.dropzoneHighlight({
290
+ className: classNames?.dropzoneHighlight
291
+ }),
292
+ children: [
293
+ "Choose ",
294
+ maxFiles === 1 ? `file` : `files`
295
+ ]
296
+ }
297
+ ),
298
+ " ",
299
+ "or drag and drop here"
300
+ ] })
301
+ ]
302
+ }
303
+ )
304
+ ]
305
+ }
306
+ );
307
+ };
308
+
309
+ export { FileDropzone };
@@ -0,0 +1,144 @@
1
+ "use strict";
2
+ "use client";
3
+ import { jsxs, jsx } from 'react/jsx-runtime';
4
+ import { useState, useEffect } from 'react';
5
+ import { fileInfoDropzoneStyles, cn } from '@opengovsg/oui-theme';
6
+ import { useFileDropzoneStateContext, useFileDropzoneStyleContext } from './contexts.js';
7
+ import { formatBytes } from './utils.js';
8
+ import Trash2 from '../node_modules/.pnpm/lucide-react@0.475.0_react@19.0.0/node_modules/lucide-react/dist/esm/icons/trash-2.js';
9
+ import { Button } from '../button/button.js';
10
+
11
+ const FileInfo = ({ file, imagePreview, classNames }) => {
12
+ const {
13
+ handleRemoveFile,
14
+ handleRemoveRejection,
15
+ formatError,
16
+ isDisabled,
17
+ isReadOnly
18
+ } = useFileDropzoneStateContext();
19
+ const { size, variant, itemClassNames } = useFileDropzoneStyleContext();
20
+ const readableFileSize = formatBytes(file.size, 2);
21
+ const styles = fileInfoDropzoneStyles({
22
+ size,
23
+ variant,
24
+ imagePreview: imagePreview ?? void 0
25
+ });
26
+ const [previewSrc, setPreviewSrc] = useState("");
27
+ useEffect(() => {
28
+ let objectUrl = "";
29
+ if (file.type.startsWith("image/")) {
30
+ objectUrl = URL.createObjectURL(file);
31
+ setPreviewSrc(objectUrl);
32
+ }
33
+ return () => URL.revokeObjectURL(objectUrl);
34
+ }, [file]);
35
+ return /* @__PURE__ */ jsxs(
36
+ "div",
37
+ {
38
+ className: styles.base({
39
+ className: cn(itemClassNames?.base, classNames?.base)
40
+ }),
41
+ children: [
42
+ /* @__PURE__ */ jsxs("div", { className: "sr-only", children: [
43
+ "File attached: ",
44
+ file.name,
45
+ " with file size of ",
46
+ readableFileSize
47
+ ] }),
48
+ imagePreview && previewSrc && /* @__PURE__ */ jsx(
49
+ "div",
50
+ {
51
+ className: styles.imageContainer({
52
+ className: cn(
53
+ itemClassNames?.imageContainer,
54
+ classNames?.imageContainer
55
+ )
56
+ }),
57
+ children: /* @__PURE__ */ jsx(
58
+ "img",
59
+ {
60
+ src: previewSrc,
61
+ alt: `Image preview of uploaded file: ${file.name}`,
62
+ className: styles.image({
63
+ className: cn(itemClassNames?.image, classNames?.image)
64
+ })
65
+ }
66
+ )
67
+ }
68
+ ),
69
+ /* @__PURE__ */ jsxs(
70
+ "div",
71
+ {
72
+ className: styles.container({
73
+ className: cn(itemClassNames?.container, classNames?.container)
74
+ }),
75
+ children: [
76
+ /* @__PURE__ */ jsxs(
77
+ "div",
78
+ {
79
+ className: styles.textContainer({
80
+ className: cn(
81
+ itemClassNames?.textContainer,
82
+ classNames?.textContainer
83
+ )
84
+ }),
85
+ children: [
86
+ /* @__PURE__ */ jsx(
87
+ "p",
88
+ {
89
+ title: file.name,
90
+ className: styles.name({
91
+ className: cn(itemClassNames?.name, classNames?.name)
92
+ }),
93
+ children: file.name
94
+ }
95
+ ),
96
+ /* @__PURE__ */ jsx(
97
+ "p",
98
+ {
99
+ className: styles.size({
100
+ className: cn(itemClassNames?.size, classNames?.size)
101
+ }),
102
+ children: readableFileSize
103
+ }
104
+ ),
105
+ file.errors?.length && /* @__PURE__ */ jsx(
106
+ "p",
107
+ {
108
+ className: styles.error({
109
+ className: cn(itemClassNames?.error, classNames?.error)
110
+ }),
111
+ children: file.errors.map(formatError).join(", ")
112
+ }
113
+ )
114
+ ]
115
+ }
116
+ ),
117
+ /* @__PURE__ */ jsx(
118
+ Button,
119
+ {
120
+ isDisabled: isDisabled || isReadOnly,
121
+ isIconOnly: !file.errors?.length,
122
+ size: size === "md" ? "md" : "xs",
123
+ variant: "clear",
124
+ color: file.errors?.length ? "main" : "critical",
125
+ "aria-label": "Remove file",
126
+ className: styles.actionButton({
127
+ className: cn(
128
+ itemClassNames?.actionButton,
129
+ classNames?.actionButton
130
+ )
131
+ }),
132
+ onPress: () => file.errors?.length ? handleRemoveRejection(file.name) : handleRemoveFile(file.name),
133
+ children: file.errors?.length ? "Dismiss" : /* @__PURE__ */ jsx(Trash2, {})
134
+ }
135
+ )
136
+ ]
137
+ }
138
+ )
139
+ ]
140
+ }
141
+ );
142
+ };
143
+
144
+ export { FileInfo };
@@ -0,0 +1,4 @@
1
+ "use strict";
2
+ export { FileDropzone } from './file-dropzone.js';
3
+ export { FileInfo } from './file-info.js';
4
+ export { formatBytes, formatErrorMessage } from './utils.js';
@@ -0,0 +1 @@
1
+ "use strict";
@@ -0,0 +1,28 @@
1
+ "use strict";
2
+ import { ErrorCode } from 'react-dropzone';
3
+
4
+ const formatBytes = (bytes, decimals = 2, size) => {
5
+ const k = 1e3;
6
+ const dm = decimals < 0 ? 0 : decimals;
7
+ const sizes = ["bytes", "KB", "MB", "GB", "TB", "PB", "EB", "ZB", "YB"];
8
+ if (bytes === 0 || bytes === void 0)
9
+ return size !== void 0 ? `0 ${size}` : "0 bytes";
10
+ const i = size !== void 0 ? sizes.indexOf(size) : Math.floor(Math.log(bytes) / Math.log(k));
11
+ return parseFloat((bytes / Math.pow(k, i)).toFixed(dm)) + " " + sizes[i];
12
+ };
13
+ const formatErrorMessage = (error, config) => {
14
+ const { maxFileSize, minFileSize, maxFiles } = config;
15
+ switch (error.code) {
16
+ case ErrorCode.FileTooLarge:
17
+ return `You have exceeded the size limit, please upload a file below ${formatBytes(maxFileSize, 2)}`;
18
+ case ErrorCode.FileTooSmall:
19
+ return `Please upload a file above ${formatBytes(minFileSize, 2)}`;
20
+ case ErrorCode.TooManyFiles:
21
+ return `Maximum number of files allowed is ${maxFiles}.`;
22
+ default: {
23
+ return error.message;
24
+ }
25
+ }
26
+ };
27
+
28
+ export { formatBytes, formatErrorMessage };
package/dist/esm/index.js CHANGED
@@ -1,37 +1,37 @@
1
1
  "use strict";
2
- export { Toggle } from './toggle/toggle.js';
3
- export { useControllableState } from './hooks/use-controllable-state.js';
4
- export { Button } from './button/button.js';
5
- export { GovtBanner } from './govt-banner/govt-banner.js';
6
2
  export { Ripple } from './ripple/ripple.js';
7
3
  export { useRipple } from './ripple/use-ripple.js';
8
4
  export { Spinner } from './spinner/spinner.js';
9
5
  export { useSpinner } from './spinner/use-spinner.js';
6
+ export { Toggle } from './toggle/toggle.js';
10
7
  export { SkipNavLink } from './skip-nav-link/skip-nav-link.js';
11
- export { Input } from './input/input.js';
12
8
  export { TextField } from './text-field/text-field.js';
13
- export { Description, FieldError, FieldErrorIcon, FieldGroup, Label } from './field/field.js';
14
9
  export { TextArea } from './text-area/text-area.js';
15
10
  export { TextAreaField } from './text-area-field/text-area-field.js';
16
11
  export { ComboBox, ComboBoxEmptyState } from './combo-box/combo-box.js';
17
12
  export { ComboBoxFuzzy } from './combo-box/combo-box-fuzzy.js';
18
13
  export { ComboBoxItem } from './combo-box/combo-box-item.js';
19
14
  export { ComboBoxVariantContext, useComboBoxVariantContext } from './combo-box/combo-box-variant-context.js';
20
- export { Banner } from './banner/banner.js';
21
15
  export { TagField } from './tag-field/tag-field.js';
22
16
  export { TagFieldItem } from './tag-field/tag-field-item.js';
23
17
  export { Select } from './select/select.js';
24
18
  export { SelectItem } from './select/select-item.js';
25
19
  export { SelectVariantContext, useSelectVariantContext } from './select/select-variant-context.js';
20
+ export { Menu, MenuItem, MenuSection, MenuSeparator, MenuTrigger, MenuVariantContext, SubmenuTrigger, useMenuVariantContext } from './menu/menu.js';
21
+ export { Tab, TabList, TabPanel, Tabs, TabsVariantContext, useTabsVariantContext } from './tabs/tabs.js';
22
+ export { useControllableState } from './hooks/use-controllable-state.js';
23
+ export { Button } from './button/button.js';
24
+ export { GovtBanner } from './govt-banner/govt-banner.js';
25
+ export { Input } from './input/input.js';
26
+ export { Description, FieldError, FieldErrorIcon, FieldGroup, Label } from './field/field.js';
27
+ export { Banner } from './banner/banner.js';
26
28
  export { Badge } from './badge/badge.js';
27
29
  export { CalendarDate } from '@internationalized/date';
28
30
  export { Calendar, CalendarStateWrapper } from './calendar/calendar.js';
29
31
  export { CalendarStyleContext, useCalendarStyleContext } from './calendar/calendar-style-context.js';
30
32
  export { getEraFormat, useGenerateLocalizedMonths, useGenerateLocalizedYears, useLocalizedMonthYear } from './calendar/utils.js';
31
33
  export { RangeCalendar, RangeCalendarCell, RangeCalendarStateWrapper } from './range-calendar/range-calendar.js';
32
- export { Menu, MenuItem, MenuSection, MenuSeparator, MenuTrigger, MenuVariantContext, SubmenuTrigger, useMenuVariantContext } from './menu/menu.js';
33
34
  export { Popover } from './popover/popover.js';
34
- export { Tab, TabList, TabPanel, Tabs, TabsVariantContext, useTabsVariantContext } from './tabs/tabs.js';
35
35
  export { DateField, DateInput } from './date-field/date-field.js';
36
36
  export { DatePicker } from './date-picker/date-picker.js';
37
37
  export { DateRangePicker } from './date-range-picker/date-range-picker.js';
@@ -42,3 +42,7 @@ export { Pagination } from './pagination/pagination.js';
42
42
  export { PaginationCursor } from './pagination/pagination-cursor.js';
43
43
  export { PaginationItem } from './pagination/pagination-item.js';
44
44
  export { CURSOR_TRANSITION_TIMEOUT, usePagination } from './pagination/use-pagination.js';
45
+ export { FileDropzone } from './file-dropzone/file-dropzone.js';
46
+ export { FileInfo } from './file-dropzone/file-info.js';
47
+ export { formatBytes, formatErrorMessage } from './file-dropzone/utils.js';
48
+ export { NumberField } from './number-field/number-field.js';
@@ -0,0 +1,17 @@
1
+ import createLucideIcon from '../createLucideIcon.js';
2
+
3
+ /**
4
+ * @license lucide-react v0.475.0 - ISC
5
+ *
6
+ * This source code is licensed under the ISC license.
7
+ * See the LICENSE file in the root directory of this source tree.
8
+ */
9
+
10
+
11
+ const __iconNode = [
12
+ ["path", { d: "M5 12h14", key: "1ays0h" }],
13
+ ["path", { d: "M12 5v14", key: "s699le" }]
14
+ ];
15
+ const Plus = createLucideIcon("Plus", __iconNode);
16
+
17
+ export { __iconNode, Plus as default };
@@ -0,0 +1,20 @@
1
+ import createLucideIcon from '../createLucideIcon.js';
2
+
3
+ /**
4
+ * @license lucide-react v0.475.0 - ISC
5
+ *
6
+ * This source code is licensed under the ISC license.
7
+ * See the LICENSE file in the root directory of this source tree.
8
+ */
9
+
10
+
11
+ const __iconNode = [
12
+ ["path", { d: "M3 6h18", key: "d0wm0j" }],
13
+ ["path", { d: "M19 6v14c0 1-1 2-2 2H7c-1 0-2-1-2-2V6", key: "4alrt4" }],
14
+ ["path", { d: "M8 6V4c0-1 1-2 2-2h4c1 0 2 1 2 2v2", key: "v07s0e" }],
15
+ ["line", { x1: "10", x2: "10", y1: "11", y2: "17", key: "1uufr5" }],
16
+ ["line", { x1: "14", x2: "14", y1: "11", y2: "17", key: "xtxkd" }]
17
+ ];
18
+ const Trash2 = createLucideIcon("Trash2", __iconNode);
19
+
20
+ export { __iconNode, Trash2 as default };
@@ -0,0 +1,18 @@
1
+ import createLucideIcon from '../createLucideIcon.js';
2
+
3
+ /**
4
+ * @license lucide-react v0.475.0 - ISC
5
+ *
6
+ * This source code is licensed under the ISC license.
7
+ * See the LICENSE file in the root directory of this source tree.
8
+ */
9
+
10
+
11
+ const __iconNode = [
12
+ ["path", { d: "M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4", key: "ih7n3h" }],
13
+ ["polyline", { points: "17 8 12 3 7 8", key: "t8dd8p" }],
14
+ ["line", { x1: "12", x2: "12", y1: "3", y2: "15", key: "widbto" }]
15
+ ];
16
+ const Upload = createLucideIcon("Upload", __iconNode);
17
+
18
+ export { __iconNode, Upload as default };
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ export { NumberField } from './number-field.js';