@surflane/ui 0.1.0 → 0.2.0

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 (85) hide show
  1. package/README.md +8 -8
  2. package/dist/advanced-forms.d.ts +2 -2
  3. package/dist/advanced-forms.js +39 -39
  4. package/dist/app-shell.d.ts +1 -1
  5. package/dist/app-shell.js +11 -11
  6. package/dist/button.d.ts +5 -5
  7. package/dist/button.js +12 -12
  8. package/dist/chart.d.ts +3 -3
  9. package/dist/chart.js +36 -34
  10. package/dist/commands.d.ts +5 -5
  11. package/dist/commands.js +17 -17
  12. package/dist/content.d.ts +2 -2
  13. package/dist/content.js +66 -28
  14. package/dist/context-overlays.d.ts +3 -3
  15. package/dist/context-overlays.js +11 -11
  16. package/dist/data.d.ts +1 -1
  17. package/dist/data.js +18 -18
  18. package/dist/date-picker.d.ts +8 -8
  19. package/dist/date-picker.js +18 -18
  20. package/dist/dialog-focus.js +7 -7
  21. package/dist/dialog.d.ts +5 -5
  22. package/dist/dialog.js +16 -16
  23. package/dist/feedback.d.ts +5 -5
  24. package/dist/feedback.js +20 -20
  25. package/dist/file-upload.d.ts +9 -9
  26. package/dist/file-upload.js +64 -63
  27. package/dist/filter-bar.d.ts +1 -1
  28. package/dist/filter-bar.js +9 -9
  29. package/dist/form-state.d.ts +1 -1
  30. package/dist/form-state.js +11 -11
  31. package/dist/forms.d.ts +5 -5
  32. package/dist/forms.js +32 -32
  33. package/dist/foundations.d.ts +10 -10
  34. package/dist/foundations.js +26 -26
  35. package/dist/icon.d.ts +7 -7
  36. package/dist/icon.js +22 -22
  37. package/dist/index.d.ts +37 -37
  38. package/dist/index.js +38 -38
  39. package/dist/input-extensions.d.ts +3 -3
  40. package/dist/input-extensions.js +21 -21
  41. package/dist/input.d.ts +2 -2
  42. package/dist/input.js +7 -7
  43. package/dist/markdown.d.ts +2 -2
  44. package/dist/markdown.js +38 -38
  45. package/dist/menu.d.ts +2 -2
  46. package/dist/menu.js +19 -19
  47. package/dist/messages.d.ts +2 -2
  48. package/dist/messages.js +18 -18
  49. package/dist/navigation-menu.d.ts +2 -2
  50. package/dist/navigation-menu.js +16 -16
  51. package/dist/navigation.d.ts +5 -5
  52. package/dist/navigation.js +40 -40
  53. package/dist/otp-field.d.ts +1 -1
  54. package/dist/otp-field.js +14 -14
  55. package/dist/pagination.d.ts +2 -2
  56. package/dist/pagination.js +12 -12
  57. package/dist/panels.d.ts +8 -8
  58. package/dist/panels.js +39 -39
  59. package/dist/parts.d.ts +2 -2
  60. package/dist/parts.js +8 -8
  61. package/dist/popover.d.ts +3 -3
  62. package/dist/popover.js +6 -6
  63. package/dist/scroll-area.d.ts +1 -1
  64. package/dist/scroll-area.js +20 -20
  65. package/dist/select.d.ts +8 -8
  66. package/dist/select.js +21 -21
  67. package/dist/sizing.d.ts +3 -3
  68. package/dist/sizing.js +9 -9
  69. package/dist/slot.d.ts +1 -1
  70. package/dist/slot.js +4 -4
  71. package/dist/status.d.ts +4 -4
  72. package/dist/status.js +8 -8
  73. package/dist/syntax-engine.js +43 -43
  74. package/dist/syntax-highlighter.d.ts +2 -2
  75. package/dist/syntax-highlighter.js +32 -32
  76. package/dist/toast.d.ts +4 -4
  77. package/dist/toast.js +33 -33
  78. package/dist/tone-transition.d.ts +1 -1
  79. package/dist/tone-transition.js +17 -17
  80. package/dist/tooltip.d.ts +1 -1
  81. package/dist/tooltip.js +4 -4
  82. package/dist/tree.d.ts +4 -4
  83. package/dist/tree.js +60 -60
  84. package/package.json +2 -2
  85. package/src/styles.css +233 -142
@@ -1,16 +1,16 @@
1
- import * as React from "react";
2
- import { Field } from "./forms.js";
3
- export type UploadState = "ready" | "uploading" | "success" | "error" | "canceled";
1
+ import * as React from 'react';
2
+ import { Field } from './forms.js';
3
+ export type UploadState = 'ready' | 'uploading' | 'success' | 'error' | 'canceled';
4
4
  export type UploadTransport = (file: File, context: {
5
5
  signal: AbortSignal;
6
6
  onProgress: (percent: number | null) => void;
7
7
  }) => Promise<void>;
8
8
  export type FileRejection = {
9
9
  file: File;
10
- reason: "type" | "size" | "count" | "duplicate";
10
+ reason: 'type' | 'size' | 'count' | 'duplicate';
11
11
  };
12
12
  export type FileChangeDetails = {
13
- reason: "select" | "drop" | "remove";
13
+ reason: 'select' | 'drop' | 'remove';
14
14
  isCanceled: boolean;
15
15
  cancel: () => void;
16
16
  };
@@ -30,12 +30,12 @@ export type FileUploadLabels = {
30
30
  reset: string;
31
31
  progress: (file: File) => string;
32
32
  };
33
- export type FileUploadProps = Omit<React.ComponentPropsWithoutRef<typeof Field.Root>, "children" | "name" | "onDragEnter" | "onDragLeave" | "onDragOver" | "onDrop"> & Pick<React.HTMLAttributes<HTMLDivElement>, "onDragEnter" | "onDragLeave" | "onDragOver" | "onDrop"> & {
33
+ export type FileUploadProps = Omit<React.ComponentPropsWithoutRef<typeof Field.Root>, 'children' | 'name' | 'onDragEnter' | 'onDragLeave' | 'onDragOver' | 'onDrop'> & Pick<React.HTMLAttributes<HTMLDivElement>, 'onDragEnter' | 'onDragLeave' | 'onDragOver' | 'onDrop'> & {
34
34
  label: React.ReactNode;
35
35
  description?: React.ReactNode;
36
36
  name?: string;
37
37
  form?: string;
38
- capture?: React.InputHTMLAttributes<HTMLInputElement>["capture"];
38
+ capture?: React.InputHTMLAttributes<HTMLInputElement>['capture'];
39
39
  accept?: string;
40
40
  multiple?: boolean;
41
41
  required?: boolean;
@@ -47,8 +47,8 @@ export type FileUploadProps = Omit<React.ComponentPropsWithoutRef<typeof Field.R
47
47
  onReject?: (rejections: FileRejection[]) => void;
48
48
  transport?: UploadTransport;
49
49
  getUploadError?: (error: unknown) => string;
50
- labels?: Partial<Omit<FileUploadLabels, "status">> & {
51
- status?: Partial<FileUploadLabels["status"]>;
50
+ labels?: Partial<Omit<FileUploadLabels, 'status'>> & {
51
+ status?: Partial<FileUploadLabels['status']>;
52
52
  };
53
53
  };
54
54
  /** Native selection/validation and a cancellable transport adapter; no network request is built in. */
@@ -1,32 +1,32 @@
1
- "use client";
1
+ 'use client';
2
2
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
3
- import * as React from "react";
4
- import { Field } from "./forms.js";
5
- import { Button } from "./button.js";
6
- import { Progress } from "./feedback.js";
7
- import { StatusBadge } from "./status.js";
8
- import { skin } from "./parts.js";
9
- import { useResetValue, useRootRef } from "./form-state.js";
3
+ import * as React from 'react';
4
+ import { Field } from './forms.js';
5
+ import { Button } from './button.js';
6
+ import { Progress } from './feedback.js';
7
+ import { StatusBadge } from './status.js';
8
+ import { skin } from './parts.js';
9
+ import { useResetValue, useRootRef } from './form-state.js';
10
10
  const labelsDefault = {
11
- choose: "Choose files",
12
- drop: "or drop files here",
13
- upload: "Upload",
14
- retry: "Retry",
15
- cancel: "Cancel",
16
- remove: "Remove",
11
+ choose: 'Choose files',
12
+ drop: 'or drop files here',
13
+ upload: 'Upload',
14
+ retry: 'Retry',
15
+ cancel: 'Cancel',
16
+ remove: 'Remove',
17
17
  status: {
18
- ready: "Ready",
19
- uploading: "Uploading",
20
- success: "Uploaded",
21
- error: "Failed",
22
- canceled: "Canceled",
18
+ ready: 'Ready',
19
+ uploading: 'Uploading',
20
+ success: 'Uploaded',
21
+ error: 'Failed',
22
+ canceled: 'Canceled',
23
23
  },
24
- rejection: ({ file, reason }) => `${file.name}: ${reason === "type" ? "file type is not accepted" : reason === "size" ? "file is too large" : reason === "count" ? "file limit reached" : "file is already selected"}.`,
25
- changed: (count) => `${count} file${count === 1 ? "" : "s"} selected.`,
24
+ rejection: ({ file, reason }) => `${file.name}: ${reason === 'type' ? 'file type is not accepted' : reason === 'size' ? 'file is too large' : reason === 'count' ? 'file limit reached' : 'file is already selected'}.`,
25
+ changed: (count) => `${count} file${count === 1 ? '' : 's'} selected.`,
26
26
  complete: (file) => `${file.name}: upload complete.`,
27
27
  canceled: (file) => `${file.name}: upload canceled.`,
28
28
  failed: (file) => `${file.name}: upload failed.`,
29
- reset: "Files reset.",
29
+ reset: 'Files reset.',
30
30
  progress: (file) => `${file.name} upload progress`,
31
31
  };
32
32
  function signature(file) {
@@ -34,22 +34,22 @@ function signature(file) {
34
34
  }
35
35
  function accepts(file, accept) {
36
36
  const rules = accept
37
- .split(",")
37
+ .split(',')
38
38
  .map((rule) => rule.trim().toLowerCase())
39
39
  .filter(Boolean);
40
40
  return (!rules.length ||
41
- rules.some((rule) => rule.startsWith(".")
41
+ rules.some((rule) => rule.startsWith('.')
42
42
  ? file.name.toLowerCase().endsWith(rule)
43
- : rule.endsWith("/*")
43
+ : rule.endsWith('/*')
44
44
  ? file.type.toLowerCase().startsWith(rule.slice(0, -1))
45
45
  : file.type.toLowerCase() === rule));
46
46
  }
47
47
  function sizeLabel(bytes) {
48
- const unit = bytes >= 1024 * 1024 ? "MB" : bytes >= 1024 ? "KB" : "B";
49
- return `${new Intl.NumberFormat(undefined, { maximumFractionDigits: 1 }).format(bytes / (unit === "MB" ? 1024 * 1024 : unit === "KB" ? 1024 : 1))} ${unit}`;
48
+ const unit = bytes >= 1024 * 1024 ? 'MB' : bytes >= 1024 ? 'KB' : 'B';
49
+ return `${new Intl.NumberFormat(undefined, { maximumFractionDigits: 1 }).format(bytes / (unit === 'MB' ? 1024 * 1024 : unit === 'KB' ? 1024 : 1))} ${unit}`;
50
50
  }
51
51
  /** Native selection/validation and a cancellable transport adapter; no network request is built in. */
52
- export const FileUpload = React.forwardRef(function FileUpload({ label, description, name, form, accept = "", capture, multiple = false, required = false, maxFiles = Infinity, maxFileSize = Infinity, files: controlled, defaultFiles = [], onFilesChange, onReject, transport, getUploadError, labels: customLabels, disabled = false, className, onDragEnter, onDragLeave, onDragOver, onDrop, ...props }, forwardedRef) {
52
+ export const FileUpload = React.forwardRef(function FileUpload({ label, description, name, form, accept = '', capture, multiple = false, required = false, maxFiles = Infinity, maxFileSize = Infinity, files: controlled, defaultFiles = [], onFilesChange, onReject, transport, getUploadError, labels: customLabels, disabled = false, className, onDragEnter, onDragLeave, onDragOver, onDrop, ...props }, forwardedRef) {
53
53
  const labels = {
54
54
  ...labelsDefault,
55
55
  ...customLabels,
@@ -57,7 +57,7 @@ export const FileUpload = React.forwardRef(function FileUpload({ label, descript
57
57
  };
58
58
  const [root, ref] = useRootRef(forwardedRef), input = React.useRef(null);
59
59
  const uid = React.useId(), inputId = `${uid}-input`, errorId = `${uid}-selection-errors`;
60
- const [metadata, setMetadata] = React.useState(new Map()), [rejections, setRejections] = React.useState([]), [announcement, announce] = React.useState(""), [dragging, setDragging] = React.useState(false);
60
+ const [metadata, setMetadata] = React.useState(new Map()), [rejections, setRejections] = React.useState([]), [announcement, announce] = React.useState(''), [dragging, setDragging] = React.useState(false);
61
61
  const notifying = React.useRef(false), lastSynced = React.useRef(null), skipNotifyFor = React.useRef(null);
62
62
  const primaryButtons = React.useRef(new WeakMap()), removeButtons = React.useRef(new WeakMap()), focusRemove = React.useRef(null), focusPicker = React.useRef(null);
63
63
  const requests = React.useRef(new Map()), mounted = React.useRef(false), dragDepth = React.useRef(0);
@@ -93,7 +93,7 @@ export const FileUpload = React.forwardRef(function FileUpload({ label, descript
93
93
  input.current) {
94
94
  notifying.current = true;
95
95
  try {
96
- input.current.dispatchEvent(new Event("change", { bubbles: true }));
96
+ input.current.dispatchEvent(new Event('change', { bubbles: true }));
97
97
  }
98
98
  finally {
99
99
  notifying.current = false;
@@ -142,11 +142,12 @@ export const FileUpload = React.forwardRef(function FileUpload({ label, descript
142
142
  return;
143
143
  requests.current.delete(file);
144
144
  request.controller.abort();
145
- update(file, { status: "canceled", progress: null });
145
+ update(file, { status: 'canceled', progress: null });
146
146
  announce(labels.canceled(file));
147
147
  }
148
148
  React.useEffect(() => {
149
149
  if (disabled) {
150
+ ;
150
151
  [...requests.current.keys()].forEach(cancel);
151
152
  dragDepth.current = 0;
152
153
  setDragging(false);
@@ -194,13 +195,13 @@ export const FileUpload = React.forwardRef(function FileUpload({ label, descript
194
195
  for (const file of incoming) {
195
196
  let rejection;
196
197
  if (!accepts(file, accept))
197
- rejection = "type";
198
+ rejection = 'type';
198
199
  else if (file.size > maxFileSize)
199
- rejection = "size";
200
+ rejection = 'size';
200
201
  else if (next.some((current) => signature(current) === signature(file)))
201
- rejection = "duplicate";
202
+ rejection = 'duplicate';
202
203
  else if (next.length >= limit)
203
- rejection = "count";
204
+ rejection = 'count';
204
205
  if (rejection)
205
206
  rejected.push({ file, reason: rejection });
206
207
  else
@@ -228,14 +229,14 @@ export const FileUpload = React.forwardRef(function FileUpload({ label, descript
228
229
  requests.current.get(file) === request &&
229
230
  !request.controller.signal.aborted &&
230
231
  latestFiles.current.includes(file);
231
- update(file, { status: "uploading", progress: null });
232
+ update(file, { status: 'uploading', progress: null });
232
233
  try {
233
234
  await transport(file, {
234
235
  signal: request.controller.signal,
235
236
  onProgress(percent) {
236
237
  if (current())
237
238
  update(file, {
238
- status: "uploading",
239
+ status: 'uploading',
239
240
  progress: percent === null || !Number.isFinite(percent)
240
241
  ? null
241
242
  : Math.max(0, Math.min(100, percent)),
@@ -246,18 +247,18 @@ export const FileUpload = React.forwardRef(function FileUpload({ label, descript
246
247
  if (primaryButtons.current.get(file) ===
247
248
  input.current?.ownerDocument.activeElement)
248
249
  focusRemove.current = file;
249
- update(file, { status: "success", progress: 100 });
250
+ update(file, { status: 'success', progress: 100 });
250
251
  announce(labels.complete(file));
251
252
  }
252
253
  }
253
254
  catch (error) {
254
255
  if (current()) {
255
- let message = "Upload failed. Try again.";
256
+ let message = 'Upload failed. Try again.';
256
257
  try {
257
258
  message = getUploadError?.(error) || message;
258
259
  }
259
260
  catch { }
260
- update(file, { status: "error", progress: null, error: message });
261
+ update(file, { status: 'error', progress: null, error: message });
261
262
  announce(labels.failed(file));
262
263
  }
263
264
  }
@@ -266,8 +267,8 @@ export const FileUpload = React.forwardRef(function FileUpload({ label, descript
266
267
  requests.current.delete(file);
267
268
  }
268
269
  }
269
- const hasFiles = (event) => Array.from(event.dataTransfer.types).includes("Files");
270
- return (_jsxs(Field.Root, { ...props, ref: ref, name: name, disabled: disabled, className: skin("pui-field pui-file-upload", className), "data-dragging": dragging || undefined, children: [_jsx(Field.Label, { children: label }), description != null && description !== false && (_jsx(Field.Description, { children: description })), _jsxs("div", { className: "pui-file-dropzone", onDragEnter: (event) => {
270
+ const hasFiles = (event) => Array.from(event.dataTransfer.types).includes('Files');
271
+ return (_jsxs(Field.Root, { ...props, ref: ref, name: name, disabled: disabled, className: skin('pui-field pui-file-upload', className), "data-dragging": dragging || undefined, children: [_jsx(Field.Label, { children: label }), description != null && description !== false && (_jsx(Field.Description, { children: description })), _jsxs("div", { className: 'pui-file-dropzone', onDragEnter: (event) => {
271
272
  onDragEnter?.(event);
272
273
  if (!event.defaultPrevented && hasFiles(event) && !disabled) {
273
274
  event.preventDefault();
@@ -283,7 +284,7 @@ export const FileUpload = React.forwardRef(function FileUpload({ label, descript
283
284
  onDragOver?.(event);
284
285
  if (hasFiles(event)) {
285
286
  event.preventDefault();
286
- event.dataTransfer.dropEffect = disabled ? "none" : "copy";
287
+ event.dataTransfer.dropEffect = disabled ? 'none' : 'copy';
287
288
  }
288
289
  }, onDrop: (event) => {
289
290
  onDrop?.(event);
@@ -291,53 +292,53 @@ export const FileUpload = React.forwardRef(function FileUpload({ label, descript
291
292
  setDragging(false);
292
293
  if (!event.defaultPrevented && hasFiles(event)) {
293
294
  event.preventDefault();
294
- select(Array.from(event.dataTransfer.files), "drop");
295
+ select(Array.from(event.dataTransfer.files), 'drop');
295
296
  }
296
- }, children: [_jsx(Field.Control, { ref: input, id: inputId, name: name, form: form, type: "file", accept: accept, capture: capture, multiple: multiple, required: required, disabled: disabled, className: "pui-file-native", "aria-describedby": errorId, onKeyDown: (event) => {
297
- if (event.key === "Enter")
297
+ }, children: [_jsx(Field.Control, { ref: input, id: inputId, name: name, form: form, type: 'file', accept: accept, capture: capture, multiple: multiple, required: required, disabled: disabled, className: 'pui-file-native', "aria-describedby": errorId, onKeyDown: (event) => {
298
+ if (event.key === 'Enter')
298
299
  event.preventBaseUIHandler();
299
300
  }, onChange: (event) => {
300
301
  if (!notifying.current) {
301
302
  event.preventBaseUIHandler();
302
- select(Array.from(event.currentTarget.files ?? []), "select");
303
+ select(Array.from(event.currentTarget.files ?? []), 'select');
303
304
  }
304
- } }), _jsxs("label", { htmlFor: inputId, className: "pui-button pui-file-trigger", "data-variant": "outline", "data-disabled": disabled || undefined, children: [_jsx("svg", { width: "16", height: "16", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "1.6", "aria-hidden": "true", children: _jsx("path", { d: "M12 16V3m-5 5 5-5 5 5M4 16v5h16v-5" }) }), labels.choose] }), _jsx("p", { className: "pui-file-drop-hint", children: labels.drop })] }), _jsx("div", { id: errorId, role: "alert", className: "pui-file-errors", children: rejections.length > 0 && (_jsx("ul", { children: rejections.map((rejection, index) => (_jsx("li", { children: labels.rejection(rejection) }, index))) })) }), _jsx(Field.Error, {}), files.length > 0 && (_jsx("ul", { className: "pui-file-list", role: "list", children: files.map((file) => {
305
+ } }), _jsxs("label", { htmlFor: inputId, className: 'pui-button pui-file-trigger', "data-variant": 'outline', "data-disabled": disabled || undefined, children: [_jsx("svg", { width: '16', height: '16', viewBox: '0 0 24 24', fill: 'none', stroke: 'currentColor', strokeWidth: '1.6', "aria-hidden": 'true', children: _jsx("path", { d: 'M12 16V3m-5 5 5-5 5 5M4 16v5h16v-5' }) }), labels.choose] }), _jsx("p", { className: 'pui-file-drop-hint', children: labels.drop })] }), _jsx("div", { id: errorId, role: 'alert', className: 'pui-file-errors', children: rejections.length > 0 && (_jsx("ul", { children: rejections.map((rejection, index) => (_jsx("li", { children: labels.rejection(rejection) }, index))) })) }), _jsx(Field.Error, {}), files.length > 0 && (_jsx("ul", { className: 'pui-file-list', role: 'list', children: files.map((file) => {
305
306
  const state = metadata.get(file) ?? {
306
- status: "ready",
307
+ status: 'ready',
307
308
  progress: null,
308
309
  };
309
310
  if (!identities.current.has(file))
310
311
  identities.current.set(file, `${uid}-${++nextId.current}`);
311
312
  const itemId = identities.current.get(file);
312
- return (_jsxs("li", { className: "pui-file-item", children: [_jsxs("div", { className: "pui-file-info", children: [_jsx("strong", { children: file.name }), _jsx("span", { children: sizeLabel(file.size) }), _jsx(StatusBadge, { tone: state.status === "success"
313
- ? "success"
314
- : state.status === "error"
315
- ? "danger"
316
- : state.status === "uploading"
317
- ? "progress"
318
- : "neutral", children: labels.status[state.status] })] }), state.status === "uploading" && (_jsx(Progress.Root, { value: state.progress, "aria-label": labels.progress(file), children: _jsx(Progress.Track, { children: _jsx(Progress.Indicator, {}) }) })), state.error && (_jsx("p", { id: `${itemId}-error`, className: "pui-file-upload-error", children: state.error })), _jsxs("div", { className: "pui-file-actions", children: [transport && state.status !== "success" && (_jsx(Button, { ref: (node) => {
313
+ return (_jsxs("li", { className: 'pui-file-item', children: [_jsxs("div", { className: 'pui-file-info', children: [_jsx("strong", { children: file.name }), _jsx("span", { children: sizeLabel(file.size) }), _jsx(StatusBadge, { tone: state.status === 'success'
314
+ ? 'success'
315
+ : state.status === 'error'
316
+ ? 'danger'
317
+ : state.status === 'uploading'
318
+ ? 'progress'
319
+ : 'neutral', children: labels.status[state.status] })] }), state.status === 'uploading' && (_jsx(Progress.Root, { value: state.progress, "aria-label": labels.progress(file), children: _jsx(Progress.Track, { children: _jsx(Progress.Indicator, {}) }) })), state.error && (_jsx("p", { id: `${itemId}-error`, className: 'pui-file-upload-error', children: state.error })), _jsxs("div", { className: 'pui-file-actions', children: [transport && state.status !== 'success' && (_jsx(Button, { ref: (node) => {
319
320
  if (node)
320
321
  primaryButtons.current.set(file, node);
321
322
  else
322
323
  primaryButtons.current.delete(file);
323
- }, type: "button", size: "sm", variant: "outline", disabled: disabled, "aria-describedby": state.error ? `${itemId}-error` : undefined, "aria-label": `${state.status === "uploading" ? labels.cancel : state.status === "ready" ? labels.upload : labels.retry} ${file.name}`, onClick: () => {
324
- if (state.status === "uploading")
324
+ }, type: 'button', size: 'sm', variant: 'outline', disabled: disabled, "aria-describedby": state.error ? `${itemId}-error` : undefined, "aria-label": `${state.status === 'uploading' ? labels.cancel : state.status === 'ready' ? labels.upload : labels.retry} ${file.name}`, onClick: () => {
325
+ if (state.status === 'uploading')
325
326
  cancel(file);
326
327
  else
327
328
  void upload(file);
328
- }, children: state.status === "uploading"
329
+ }, children: state.status === 'uploading'
329
330
  ? labels.cancel
330
- : state.status === "ready"
331
+ : state.status === 'ready'
331
332
  ? labels.upload
332
- : labels.retry })), _jsx(Button, { type: "button", size: "sm", variant: "ghost", ref: (node) => {
333
+ : labels.retry })), _jsx(Button, { type: 'button', size: 'sm', variant: 'ghost', ref: (node) => {
333
334
  if (node)
334
335
  removeButtons.current.set(file, node);
335
336
  else
336
337
  removeButtons.current.delete(file);
337
338
  }, disabled: disabled, "aria-label": `${labels.remove} ${file.name}`, onClick: () => {
338
339
  setRejections([]);
339
- if (commit(files.filter((current) => current !== file), "remove"))
340
+ if (commit(files.filter((current) => current !== file), 'remove'))
340
341
  focusPicker.current = file;
341
342
  }, children: labels.remove })] })] }, itemId));
342
- }) })), _jsx("span", { className: "pui-visually-hidden", role: "status", children: announcement })] }));
343
+ }) })), _jsx("span", { className: 'pui-visually-hidden', role: 'status', children: announcement })] }));
343
344
  });
@@ -1,4 +1,4 @@
1
- import * as React from "react";
1
+ import * as React from 'react';
2
2
  export declare const FilterBar: {
3
3
  Root: React.ForwardRefExoticComponent<Omit<React.DetailedHTMLProps<React.FormHTMLAttributes<HTMLFormElement>, HTMLFormElement>, "ref"> & {
4
4
  label: string;
@@ -1,22 +1,22 @@
1
- "use client";
1
+ 'use client';
2
2
  import { jsx as _jsx } from "react/jsx-runtime";
3
- import * as React from "react";
4
- const cx = (base, extra) => [base, extra].filter(Boolean).join(" ");
3
+ import * as React from 'react';
4
+ const cx = (base, extra) => [base, extra].filter(Boolean).join(' ');
5
5
  /** Layout only: filtering, routing and async results remain controlled by the caller. */
6
6
  const Root = React.forwardRef(function FilterBarRoot({ label, className, ...props }, ref) {
7
- return (_jsx("form", { ...props, ref: ref, role: "search", "aria-label": label, className: cx("pui-filter-bar", className) }));
7
+ return (_jsx("form", { ...props, ref: ref, role: 'search', "aria-label": label, className: cx('pui-filter-bar', className) }));
8
8
  });
9
9
  const Controls = React.forwardRef(function FilterBarControls({ className, ...props }, ref) {
10
- return (_jsx("div", { ...props, ref: ref, className: cx("pui-filter-bar-controls", className) }));
10
+ return (_jsx("div", { ...props, ref: ref, className: cx('pui-filter-bar-controls', className) }));
11
11
  });
12
- const Field = React.forwardRef(function FilterBarField({ width = "filter", className, ...props }, ref) {
13
- return (_jsx("label", { ...props, ref: ref, "data-width": width, className: cx("pui-filter-bar-field", className) }));
12
+ const Field = React.forwardRef(function FilterBarField({ width = 'filter', className, ...props }, ref) {
13
+ return (_jsx("label", { ...props, ref: ref, "data-width": width, className: cx('pui-filter-bar-field', className) }));
14
14
  });
15
15
  const Actions = React.forwardRef(function FilterBarActions({ className, ...props }, ref) {
16
- return (_jsx("div", { ...props, ref: ref, className: cx("pui-filter-bar-actions", className) }));
16
+ return (_jsx("div", { ...props, ref: ref, className: cx('pui-filter-bar-actions', className) }));
17
17
  });
18
18
  const Summary = React.forwardRef(function FilterBarSummary({ className, ...props }, ref) {
19
- return (_jsx("div", { role: "status", "aria-atomic": "true", ...props, ref: ref, className: cx("pui-filter-bar-summary", className) }));
19
+ return (_jsx("div", { role: 'status', "aria-atomic": 'true', ...props, ref: ref, className: cx('pui-filter-bar-summary', className) }));
20
20
  });
21
21
  export const FilterBar = { Root, Controls, Field, Actions, Summary };
22
22
  // Flat names for React Server Components, which cannot dot into client exports.
@@ -1,4 +1,4 @@
1
- import * as React from "react";
1
+ import * as React from 'react';
2
2
  /** Share the actual DOM node, including React 19 callback-ref cleanup semantics. */
3
3
  export declare function useRootRef<Element extends HTMLElement>(forwarded: React.Ref<Element> | undefined): readonly [React.RefObject<Element | null>, (node: Element | null) => () => void];
4
4
  /** Reset stateful primitives with their native form, without firing change callbacks. */
@@ -1,19 +1,19 @@
1
- "use client";
2
- import * as React from "react";
1
+ 'use client';
2
+ import * as React from 'react';
3
3
  /** Share the actual DOM node, including React 19 callback-ref cleanup semantics. */
4
4
  export function useRootRef(forwarded) {
5
5
  const element = React.useRef(null);
6
6
  const attach = React.useCallback((node) => {
7
7
  element.current = node;
8
- const cleanup = typeof forwarded === "function" ? forwarded(node) : undefined;
9
- if (forwarded && typeof forwarded !== "function")
8
+ const cleanup = typeof forwarded === 'function' ? forwarded(node) : undefined;
9
+ if (forwarded && typeof forwarded !== 'function')
10
10
  forwarded.current = node;
11
11
  return () => {
12
12
  if (element.current === node)
13
13
  element.current = null;
14
- if (typeof cleanup === "function")
14
+ if (typeof cleanup === 'function')
15
15
  cleanup();
16
- else if (typeof forwarded === "function")
16
+ else if (typeof forwarded === 'function')
17
17
  forwarded(null);
18
18
  else if (forwarded)
19
19
  forwarded.current = null;
@@ -30,9 +30,9 @@ export function useResetValue(controlled, initial, element, formId, afterReset)
30
30
  React.useEffect(() => {
31
31
  const node = element.current;
32
32
  const owner = (formId ? node?.ownerDocument.getElementById(formId) : undefined) ??
33
- node?.closest("form") ??
34
- Array.from(node?.querySelectorAll("input") ?? []).find((input) => input.form)?.form;
35
- if (!owner || owner.tagName !== "FORM")
33
+ node?.closest('form') ??
34
+ Array.from(node?.querySelectorAll('input') ?? []).find((input) => input.form)?.form;
35
+ if (!owner || owner.tagName !== 'FORM')
36
36
  return;
37
37
  const pending = new Set();
38
38
  const reset = (event) => {
@@ -49,9 +49,9 @@ export function useResetValue(controlled, initial, element, formId, afterReset)
49
49
  }, 0);
50
50
  pending.add(timer);
51
51
  };
52
- owner.addEventListener("reset", reset);
52
+ owner.addEventListener('reset', reset);
53
53
  return () => {
54
- owner.removeEventListener("reset", reset);
54
+ owner.removeEventListener('reset', reset);
55
55
  pending.forEach(clearTimeout);
56
56
  };
57
57
  }, [element, formId]);
package/dist/forms.d.ts CHANGED
@@ -1,8 +1,8 @@
1
- import * as React from "react";
2
- import { type ComponentSize } from "./sizing.js";
3
- import { Form as BaseForm } from "@base-ui/react/form";
4
- import { Radio as BaseRadio } from "@base-ui/react/radio";
5
- import { RadioGroup as BaseRadioGroup } from "@base-ui/react/radio-group";
1
+ import * as React from 'react';
2
+ import { type ComponentSize } from './sizing.js';
3
+ import { Form as BaseForm } from '@base-ui/react/form';
4
+ import { Radio as BaseRadio } from '@base-ui/react/radio';
5
+ import { RadioGroup as BaseRadioGroup } from '@base-ui/react/radio-group';
6
6
  declare const FieldRoot: React.ForwardRefExoticComponent<Omit<Omit<Omit<import("@base-ui/react/field").FieldRootProps, "ref"> & React.RefAttributes<HTMLDivElement>, "ref">, "size"> & {
7
7
  size?: ComponentSize;
8
8
  } & React.RefAttributes<HTMLDivElement>>;
package/dist/forms.js CHANGED
@@ -1,23 +1,23 @@
1
- "use client";
1
+ 'use client';
2
2
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
3
- import * as React from "react";
4
- import { useComponentSize } from "./sizing.js";
5
- import { Field as BaseField } from "@base-ui/react/field";
6
- import { Fieldset as BaseFieldset } from "@base-ui/react/fieldset";
7
- import { Form as BaseForm } from "@base-ui/react/form";
8
- import { Checkbox as BaseCheckbox } from "@base-ui/react/checkbox";
9
- import { CheckboxGroup as BaseCheckboxGroup } from "@base-ui/react/checkbox-group";
10
- import { Radio as BaseRadio } from "@base-ui/react/radio";
11
- import { RadioGroup as BaseRadioGroup } from "@base-ui/react/radio-group";
12
- import { Switch as BaseSwitch } from "@base-ui/react/switch";
3
+ import * as React from 'react';
4
+ import { useComponentSize } from './sizing.js';
5
+ import { Field as BaseField } from '@base-ui/react/field';
6
+ import { Fieldset as BaseFieldset } from '@base-ui/react/fieldset';
7
+ import { Form as BaseForm } from '@base-ui/react/form';
8
+ import { Checkbox as BaseCheckbox } from '@base-ui/react/checkbox';
9
+ import { CheckboxGroup as BaseCheckboxGroup } from '@base-ui/react/checkbox-group';
10
+ import { Radio as BaseRadio } from '@base-ui/react/radio';
11
+ import { RadioGroup as BaseRadioGroup } from '@base-ui/react/radio-group';
12
+ import { Switch as BaseSwitch } from '@base-ui/react/switch';
13
13
  const ChoiceResetPaint = React.createContext(0);
14
- import { skin, part } from "./parts.js";
15
- const FieldRoot = part(BaseField.Root, "pui-field");
16
- const FieldLabel = part(BaseField.Label, "pui-field-label");
17
- const FieldControl = part(BaseField.Control, "pui-input");
18
- const FieldDescription = part(BaseField.Description, "pui-field-description");
19
- const FieldError = part(BaseField.Error, "pui-field-error");
20
- const FieldItem = part(BaseField.Item, "pui-field-item");
14
+ import { skin, part } from './parts.js';
15
+ const FieldRoot = part(BaseField.Root, 'pui-field');
16
+ const FieldLabel = part(BaseField.Label, 'pui-field-label');
17
+ const FieldControl = part(BaseField.Control, 'pui-input');
18
+ const FieldDescription = part(BaseField.Description, 'pui-field-description');
19
+ const FieldError = part(BaseField.Error, 'pui-field-error');
20
+ const FieldItem = part(BaseField.Item, 'pui-field-item');
21
21
  export const Field = {
22
22
  ...BaseField,
23
23
  Root: FieldRoot,
@@ -29,31 +29,31 @@ export const Field = {
29
29
  };
30
30
  export const Fieldset = {
31
31
  ...BaseFieldset,
32
- Root: part(BaseFieldset.Root, "pui-fieldset"),
33
- Legend: part(BaseFieldset.Legend, "pui-fieldset-legend"),
32
+ Root: part(BaseFieldset.Root, 'pui-fieldset'),
33
+ Legend: part(BaseFieldset.Legend, 'pui-fieldset-legend'),
34
34
  };
35
35
  export function Form({ className, ...props }) {
36
- return (_jsx(BaseForm, { ...props, className: skin("pui-form", className) }));
36
+ return _jsx(BaseForm, { ...props, className: skin('pui-form', className) });
37
37
  }
38
38
  export const Textarea = React.forwardRef(function Textarea({ className, size, ...props }, ref) {
39
39
  const scheme = useComponentSize(size);
40
- return (_jsx("textarea", { "data-ui-size": scheme, ...props, ref: ref, className: ["pui-input pui-textarea", className]
40
+ return (_jsx("textarea", { "data-ui-size": scheme, ...props, ref: ref, className: ['pui-input pui-textarea', className]
41
41
  .filter(Boolean)
42
- .join(" ") }));
42
+ .join(' ') }));
43
43
  });
44
- import { useRootRef, useResetValue } from "./form-state.js";
44
+ import { useRootRef, useResetValue } from './form-state.js';
45
45
  const CheckboxRoot = React.forwardRef(function CheckboxRoot({ checked, defaultChecked = false, onCheckedChange, className, form, ...props }, ref) {
46
46
  React.useContext(ChoiceResetPaint);
47
47
  const [element, attach] = useRootRef(ref);
48
48
  const [selected, setSelected] = useResetValue(checked, defaultChecked, element, form);
49
- return (_jsx(BaseCheckbox.Root, { ...props, form: form, ref: attach, checked: selected, className: skin("pui-checkbox", className), onCheckedChange: (next, event) => {
49
+ return (_jsx(BaseCheckbox.Root, { ...props, form: form, ref: attach, checked: selected, className: skin('pui-checkbox', className), onCheckedChange: (next, event) => {
50
50
  onCheckedChange?.(next, event);
51
51
  if (checked === undefined && !event.isCanceled)
52
52
  setSelected(next);
53
53
  } }));
54
54
  });
55
55
  const CheckboxIndicator = React.forwardRef(function CheckboxIndicator({ className, children, ...props }, ref) {
56
- return (_jsx(BaseCheckbox.Indicator, { ...props, ref: ref, className: skin("pui-checkbox-indicator", className), children: children ?? (_jsxs("svg", { width: "14", height: "14", viewBox: "0 0 20 20", fill: "none", stroke: "currentColor", strokeWidth: "2", "aria-hidden": "true", children: [_jsx("path", { className: "pui-checkbox-check", d: "m4 10 4 4 8-8" }), _jsx("path", { className: "pui-checkbox-mixed", d: "M4 10h12" })] })) }));
56
+ return (_jsx(BaseCheckbox.Indicator, { ...props, ref: ref, className: skin('pui-checkbox-indicator', className), children: children ?? (_jsxs("svg", { width: '14', height: '14', viewBox: '0 0 20 20', fill: 'none', stroke: 'currentColor', strokeWidth: '2', "aria-hidden": 'true', children: [_jsx("path", { className: 'pui-checkbox-check', d: 'm4 10 4 4 8-8' }), _jsx("path", { className: 'pui-checkbox-mixed', d: 'M4 10h12' })] })) }));
57
57
  });
58
58
  export const Checkbox = {
59
59
  ...BaseCheckbox,
@@ -63,7 +63,7 @@ export const Checkbox = {
63
63
  export const CheckboxGroup = React.forwardRef(function CheckboxGroup({ value, defaultValue = [], onValueChange, className, ...props }, ref) {
64
64
  const [element, attach] = useRootRef(ref);
65
65
  const [selected, setSelected, revision] = useResetValue(value, defaultValue, element);
66
- return (_jsx(ChoiceResetPaint.Provider, { value: revision, children: _jsx(BaseCheckboxGroup, { ...props, ref: attach, value: selected, className: skin("pui-choice-group", className), onValueChange: (next, event) => {
66
+ return (_jsx(ChoiceResetPaint.Provider, { value: revision, children: _jsx(BaseCheckboxGroup, { ...props, ref: attach, value: selected, className: skin('pui-choice-group', className), onValueChange: (next, event) => {
67
67
  onValueChange?.(next, event);
68
68
  if (value === undefined && !event.isCanceled)
69
69
  setSelected(next);
@@ -72,7 +72,7 @@ export const CheckboxGroup = React.forwardRef(function CheckboxGroup({ value, de
72
72
  export function RadioGroup({ value, defaultValue, onValueChange, className, form, ref, ...props }) {
73
73
  const [element, attach] = useRootRef(ref);
74
74
  const [selected, setSelected, revision] = useResetValue(value, defaultValue ?? null, element, form);
75
- return (_jsx(ChoiceResetPaint.Provider, { value: revision, children: _jsx(BaseRadioGroup, { ...props, form: form, ref: attach, value: selected, className: skin("pui-choice-group", className), onValueChange: (next, event) => {
75
+ return (_jsx(ChoiceResetPaint.Provider, { value: revision, children: _jsx(BaseRadioGroup, { ...props, form: form, ref: attach, value: selected, className: skin('pui-choice-group', className), onValueChange: (next, event) => {
76
76
  onValueChange?.(next, event);
77
77
  if (value === undefined && !event.isCanceled)
78
78
  setSelected(next);
@@ -80,17 +80,17 @@ export function RadioGroup({ value, defaultValue, onValueChange, className, form
80
80
  }
81
81
  const RadioRoot = React.forwardRef(function RadioRoot({ className, ...props }, ref) {
82
82
  React.useContext(ChoiceResetPaint);
83
- return (_jsx(BaseRadio.Root, { ...props, ref: ref, className: skin("pui-radio", className) }));
83
+ return (_jsx(BaseRadio.Root, { ...props, ref: ref, className: skin('pui-radio', className) }));
84
84
  });
85
85
  export const Radio = {
86
86
  ...BaseRadio,
87
87
  Root: RadioRoot,
88
- Indicator: part(BaseRadio.Indicator, "pui-radio-indicator"),
88
+ Indicator: part(BaseRadio.Indicator, 'pui-radio-indicator'),
89
89
  };
90
90
  const SwitchRoot = React.forwardRef(function SwitchRoot({ checked, defaultChecked = false, onCheckedChange, className, form, ...props }, ref) {
91
91
  const [element, attach] = useRootRef(ref);
92
92
  const [selected, setSelected] = useResetValue(checked, defaultChecked, element, form);
93
- return (_jsx(BaseSwitch.Root, { ...props, form: form, ref: attach, checked: selected, className: skin("pui-switch", className), onCheckedChange: (next, event) => {
93
+ return (_jsx(BaseSwitch.Root, { ...props, form: form, ref: attach, checked: selected, className: skin('pui-switch', className), onCheckedChange: (next, event) => {
94
94
  onCheckedChange?.(next, event);
95
95
  if (checked === undefined && !event.isCanceled)
96
96
  setSelected(next);
@@ -99,7 +99,7 @@ const SwitchRoot = React.forwardRef(function SwitchRoot({ checked, defaultChecke
99
99
  export const Switch = {
100
100
  ...BaseSwitch,
101
101
  Root: SwitchRoot,
102
- Thumb: part(BaseSwitch.Thumb, "pui-switch-thumb"),
102
+ Thumb: part(BaseSwitch.Thumb, 'pui-switch-thumb'),
103
103
  };
104
104
  // Flat names for React Server Components, which cannot dot into client exports.
105
105
  export { CheckboxIndicator, CheckboxRoot, FieldControl, FieldDescription, FieldError, FieldItem, FieldLabel, FieldRoot, RadioRoot, SwitchRoot, };