@parallelworks/ui 0.50.0 → 0.52.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 (240) hide show
  1. package/README.md +204 -18
  2. package/dist/ai/agent/toolStrings.d.ts +2 -0
  3. package/dist/ai/agent/toolStrings.js +20 -18
  4. package/dist/ai/ai.css +12 -0
  5. package/dist/ai/components/AllocationSelector.js +5 -1
  6. package/dist/ai/components/AttachmentManager.js +51 -42
  7. package/dist/ai/components/AttachmentUpload.d.ts +4 -2
  8. package/dist/ai/components/AttachmentUpload.js +9 -9
  9. package/dist/ai/components/BlockedGroupBanner.js +8 -14
  10. package/dist/ai/components/BranchNavigator.js +11 -12
  11. package/dist/ai/components/ChatEmptyState.js +12 -19
  12. package/dist/ai/components/ChatInput.d.ts +4 -3
  13. package/dist/ai/components/ChatInput.js +27 -13
  14. package/dist/ai/components/ChatMessage.js +45 -121
  15. package/dist/ai/components/ChatMessageList.d.ts +5 -2
  16. package/dist/ai/components/ChatMessageList.js +89 -51
  17. package/dist/ai/components/ChatSidebar.js +11 -7
  18. package/dist/ai/components/ChatThread.js +1 -13
  19. package/dist/ai/components/DragOverlay.js +3 -3
  20. package/dist/ai/components/MessageAttachments.d.ts +10 -0
  21. package/dist/ai/components/MessageAttachments.js +78 -0
  22. package/dist/ai/components/ModelSelector.js +4 -4
  23. package/dist/ai/components/PastedText.js +2 -2
  24. package/dist/ai/components/ProviderIssueBanner.js +19 -23
  25. package/dist/ai/components/ShareDialog.js +2 -2
  26. package/dist/ai/components/agent/ActivityLine.d.ts +0 -2
  27. package/dist/ai/components/agent/ActivityLine.js +8 -51
  28. package/dist/ai/components/agent/AgentMessageParts.js +117 -56
  29. package/dist/ai/core/ChatProvider.d.ts +16 -5
  30. package/dist/ai/core/ChatProvider.js +41 -8
  31. package/dist/ai/core/config.js +4 -3
  32. package/dist/ai/index.d.ts +1 -1
  33. package/dist/ai/index.js +3 -3
  34. package/dist/ai/strings.d.ts +29 -3
  35. package/dist/ai/strings.js +81 -26
  36. package/dist/ai/types.d.ts +4 -0
  37. package/dist/ai/ui/Notice.d.ts +2 -2
  38. package/dist/ai/ui/Notice.js +29 -62
  39. package/dist/ai/ui/sidebar.d.ts +5 -3
  40. package/dist/ai/ui/sidebar.js +21 -9
  41. package/dist/components/ActionMenu.d.ts +1 -0
  42. package/dist/components/ActionMenu.js +6 -1
  43. package/dist/components/AppLink.d.ts +26 -0
  44. package/dist/components/AppLink.js +51 -0
  45. package/dist/components/Avatar.d.ts +2 -1
  46. package/dist/components/Avatar.js +4 -2
  47. package/dist/components/Button.d.ts +15 -5
  48. package/dist/components/Button.js +47 -40
  49. package/dist/components/Callout.d.ts +31 -7
  50. package/dist/components/Callout.js +51 -24
  51. package/dist/components/Card.d.ts +11 -6
  52. package/dist/components/Card.js +14 -8
  53. package/dist/components/Checkbox.js +2 -1
  54. package/dist/components/ColorInput.js +5 -3
  55. package/dist/components/Combobox.js +49 -19
  56. package/dist/components/ConfirmModal.d.ts +19 -8
  57. package/dist/components/ConfirmModal.js +31 -53
  58. package/dist/components/CopyButton.d.ts +38 -0
  59. package/dist/components/CopyButton.js +68 -0
  60. package/dist/components/CreateModal.js +118 -111
  61. package/dist/components/DatePicker.js +12 -8
  62. package/dist/components/DescriptionList.d.ts +51 -17
  63. package/dist/components/DescriptionList.js +117 -31
  64. package/dist/components/Disclosure.js +1 -1
  65. package/dist/components/Drawer.js +10 -16
  66. package/dist/components/Field.d.ts +15 -5
  67. package/dist/components/Field.js +41 -9
  68. package/dist/components/IconButton.d.ts +14 -5
  69. package/dist/components/IconButton.js +25 -14
  70. package/dist/components/InfoTip.d.ts +4 -1
  71. package/dist/components/InfoTip.js +2 -1
  72. package/dist/components/Input.d.ts +14 -8
  73. package/dist/components/Input.js +46 -31
  74. package/dist/components/Loader.js +1 -1
  75. package/dist/components/MenuEntries.d.ts +43 -12
  76. package/dist/components/MenuEntries.js +34 -19
  77. package/dist/components/Meter.js +5 -4
  78. package/dist/components/Modal.d.ts +28 -4
  79. package/dist/components/Modal.js +37 -14
  80. package/dist/components/Overview.d.ts +20 -12
  81. package/dist/components/Overview.js +14 -9
  82. package/dist/components/PageHeader.d.ts +47 -65
  83. package/dist/components/PageHeader.js +275 -153
  84. package/dist/components/PageHeaderAction.d.ts +67 -0
  85. package/dist/components/PageHeaderAction.js +107 -0
  86. package/dist/components/Pagination.js +6 -16
  87. package/dist/components/Popover.js +3 -2
  88. package/dist/components/Provider.d.ts +79 -19
  89. package/dist/components/Provider.js +140 -130
  90. package/dist/components/Radio.js +2 -1
  91. package/dist/components/RefreshButton.js +7 -8
  92. package/dist/components/RequiredMark.js +1 -1
  93. package/dist/components/RunStatusIcon.js +2 -2
  94. package/dist/components/Section.js +1 -1
  95. package/dist/components/Select.d.ts +4 -9
  96. package/dist/components/Select.js +24 -11
  97. package/dist/components/SettingModeOption.d.ts +1 -1
  98. package/dist/components/SettingModeOption.js +7 -1
  99. package/dist/components/SettingsCard.d.ts +5 -3
  100. package/dist/components/SettingsCard.js +27 -20
  101. package/dist/components/Slider.js +1 -1
  102. package/dist/components/StatusBadge.js +2 -2
  103. package/dist/components/StatusIcons.js +2 -2
  104. package/dist/components/Switch.js +5 -4
  105. package/dist/components/Table.d.ts +30 -20
  106. package/dist/components/Table.js +50 -73
  107. package/dist/components/Tabs.d.ts +3 -7
  108. package/dist/components/Tabs.js +6 -10
  109. package/dist/components/ThemeEditor.js +24 -14
  110. package/dist/components/Toast.d.ts +11 -3
  111. package/dist/components/Toast.js +47 -22
  112. package/dist/components/buttonClasses.js +2 -2
  113. package/dist/components/comboboxItems.d.ts +4 -0
  114. package/dist/components/comboboxItems.js +6 -1
  115. package/dist/components/dismiss.d.ts +12 -0
  116. package/dist/components/dismiss.js +19 -0
  117. package/dist/components/fieldBox.d.ts +4 -0
  118. package/dist/components/fieldBox.js +7 -3
  119. package/dist/components/floating.d.ts +3 -3
  120. package/dist/components/floating.js +1 -1
  121. package/dist/components/markdownCodeBreaks.js +3 -4
  122. package/dist/components/pageHeaderStore.d.ts +41 -0
  123. package/dist/components/pageHeaderStore.js +67 -0
  124. package/dist/components/pathBreaks.d.ts +8 -0
  125. package/dist/components/pathBreaks.js +28 -0
  126. package/dist/components/segmented.js +1 -1
  127. package/dist/components/shortcutKey.d.ts +2 -1
  128. package/dist/components/shortcutKey.js +19 -2
  129. package/dist/components/splitter.js +1 -1
  130. package/dist/components/tone.d.ts +5 -2
  131. package/dist/components/tone.js +15 -6
  132. package/dist/components/useCssIsDark.js +40 -18
  133. package/dist/components/useTheme.js +9 -10
  134. package/dist/dev.d.ts +9 -0
  135. package/dist/dev.js +14 -0
  136. package/dist/editor/Editor.d.ts +3 -2
  137. package/dist/editor/Editor.js +11 -2
  138. package/dist/editor/EditorField.d.ts +2 -1
  139. package/dist/editor/EditorField.js +11 -29
  140. package/dist/editor/FormCodePanel.d.ts +7 -3
  141. package/dist/editor/FormCodePanel.js +14 -7
  142. package/dist/editor/Monaco.d.ts +14 -5
  143. package/dist/editor/Monaco.js +163 -112
  144. package/dist/editor/index.d.ts +5 -5
  145. package/dist/editor/index.js +3 -3
  146. package/dist/editor/themes.d.ts +8 -5
  147. package/dist/editor/themes.js +58 -30
  148. package/dist/editor/yaml.d.ts +6 -2
  149. package/dist/editor/yaml.js +11 -2
  150. package/dist/file-explorer/FileExplorer.js +143 -124
  151. package/dist/file-explorer/FileExplorerContext.js +1 -1
  152. package/dist/file-explorer/FilePreview/StreamedBadge.js +3 -1
  153. package/dist/file-explorer/FilePreview/Viewer.js +2 -2
  154. package/dist/file-explorer/FilePreview/index.js +4 -4
  155. package/dist/file-explorer/FileRow.js +1 -1
  156. package/dist/file-explorer/FileRowsWindow.js +34 -3
  157. package/dist/file-explorer/FileTable.js +3 -1
  158. package/dist/file-explorer/TreeView.js +37 -14
  159. package/dist/file-explorer/helpers.d.ts +2 -1
  160. package/dist/file-explorer/helpers.js +21 -20
  161. package/dist/file-explorer/toasts.js +27 -19
  162. package/dist/file-explorer/treeRows.d.ts +6 -0
  163. package/dist/file-explorer/treeRows.js +19 -1
  164. package/dist/file-explorer/useNearEnd.js +3 -6
  165. package/dist/form/Fields/CheckboxGroupField.js +12 -5
  166. package/dist/form/Fields/DurationField.js +1 -1
  167. package/dist/form/Fields/LabelField.js +1 -1
  168. package/dist/form/Fields/ObjectField.d.ts +1 -1
  169. package/dist/form/Fields/ObjectField.js +3 -2
  170. package/dist/form/Fields/StringField.js +16 -29
  171. package/dist/form/Fields/TextAreaField.js +3 -4
  172. package/dist/form/Form.js +3 -8
  173. package/dist/form/Wizard/WizardNavigation.js +1 -4
  174. package/dist/form/Wizard/WizardStepIndicator.js +1 -1
  175. package/dist/form/Wizard/utils.js +1 -1
  176. package/dist/form/fieldFrame.d.ts +1 -1
  177. package/dist/form/fieldFrame.js +2 -2
  178. package/dist/form/types/fieldComponentTypes.d.ts +2 -1
  179. package/dist/graph/AnnotationBanner.d.ts +1 -2
  180. package/dist/graph/AnnotationBanner.js +30 -32
  181. package/dist/graph/Connectors.js +4 -1
  182. package/dist/graph/DependencyGraph.js +2 -2
  183. package/dist/graph/GraphEditor.js +12 -10
  184. package/dist/graph/GraphEditorDialogs.js +2 -2
  185. package/dist/graph/GraphNode.js +7 -4
  186. package/dist/graph/InputDialog.js +1 -1
  187. package/dist/graph/InputsEditor.js +14 -11
  188. package/dist/graph/MatrixGroup.js +9 -3
  189. package/dist/graph/ProblemsButton.js +2 -2
  190. package/dist/graph/Reveal.js +18 -10
  191. package/dist/graph/ShortcutsButton.d.ts +11 -2
  192. package/dist/graph/ShortcutsButton.js +15 -4
  193. package/dist/graph/TreeView.js +35 -18
  194. package/dist/graph/WorkflowSettingsDialog.js +1 -1
  195. package/dist/graph/editorChrome.js +1 -1
  196. package/dist/graph/editorFields.js +1 -1
  197. package/dist/graph/editorRows.js +16 -10
  198. package/dist/graph/editorStrings.d.ts +7 -0
  199. package/dist/graph/editorStrings.js +8 -1
  200. package/dist/graph/fieldProblems.js +1 -1
  201. package/dist/graph/inputRefs.js +1 -1
  202. package/dist/graph/settingsViews.js +11 -18
  203. package/dist/graph/stepWith.js +2 -2
  204. package/dist/icons.d.ts +2 -0
  205. package/dist/icons.js +4 -2
  206. package/dist/index.d.ts +12 -12
  207. package/dist/index.js +16 -16
  208. package/dist/list/ActionToolbar.d.ts +44 -8
  209. package/dist/list/ActionToolbar.js +301 -102
  210. package/dist/list/ListPage.d.ts +15 -23
  211. package/dist/list/ListPage.js +46 -45
  212. package/dist/list/ListTable.d.ts +32 -7
  213. package/dist/list/ListTable.js +48 -12
  214. package/dist/list/ListViewControls.js +2 -2
  215. package/dist/list/UserHoverCard.js +7 -15
  216. package/dist/list/index.d.ts +2 -2
  217. package/dist/list/index.js +2 -2
  218. package/dist/list/listSearch.js +12 -10
  219. package/dist/list/listView.d.ts +10 -1
  220. package/dist/list/listView.js +15 -1
  221. package/dist/list/rowMenu.d.ts +2 -2
  222. package/dist/logviewer/LogViewer.d.ts +4 -2
  223. package/dist/logviewer/LogViewer.js +88 -70
  224. package/dist/logviewer/logviewer.css +3 -2
  225. package/dist/reducedMotion.d.ts +5 -0
  226. package/dist/reducedMotion.js +20 -0
  227. package/dist/safeUrl.d.ts +1 -1
  228. package/dist/safeUrl.js +4 -2
  229. package/dist/styles/theme.css +24 -10
  230. package/dist/styles.css +1 -1
  231. package/dist/theme/derive.d.ts +1 -1
  232. package/dist/theme/derive.js +46 -21
  233. package/dist/theme/fit.js +10 -4
  234. package/package.json +1 -1
  235. package/dist/components/Breadcrumbs.d.ts +0 -37
  236. package/dist/components/Breadcrumbs.js +0 -90
  237. package/dist/components/CopyToClipboard.d.ts +0 -17
  238. package/dist/components/CopyToClipboard.js +0 -66
  239. package/dist/components/Sort.d.ts +0 -9
  240. package/dist/components/Sort.js +0 -42
@@ -1,12 +1,13 @@
1
1
  import { cx } from "../cx.js";
2
2
  import { ChevronRightIcon, FolderIcon, FolderOpenIcon } from "../icons.js";
3
+ import { isDev } from "../dev.js";
3
4
  import { positionKeys } from "../components/keys.js";
4
5
  import { useStrings } from "../components/Provider.js";
5
6
  import { Skeleton } from "../components/Skeleton.js";
6
7
  import { getParentPath } from "./lib/utils.js";
7
8
  import { canPreview } from "./FilePreview/previewType.js";
8
9
  import { getNodeIcon } from "./helpers.js";
9
- import { findRowIndex, flattenTreeRows, nextFileLimit, stepRow } from "./treeRows.js";
10
+ import { edgeRow, findRowIndex, firstChildRow, flattenTreeRows, nextFileLimit, parentRow, stepRow } from "./treeRows.js";
10
11
  import { Fragment, jsx, jsxs } from "react/jsx-runtime";
11
12
  import { memo, useCallback, useEffect, useMemo, useRef, useState } from "react";
12
13
  import { useVirtualizer } from "@tanstack/react-virtual";
@@ -24,6 +25,7 @@ function rowHeight(row) {
24
25
  * of truth for rendering, arrow keys and ARIA. */
25
26
  function TreeView({ rootNodes, parentToChildrenMap, expandedPaths, selectedPath, loadingPaths, onToggleExpand, onSelect, onDropToFolder, onContextMenu, onPreviewFile, paging }) {
26
27
  const [scrollEl, setScrollEl] = useState(null);
28
+ const treeLabel = useStrings().fileExplorer.chrome.folders;
27
29
  const [fileLimits, setFileLimits] = useState(() => /* @__PURE__ */ new Map());
28
30
  const incompletePaths = paging?.incompletePaths;
29
31
  const rows = useMemo(() => flattenTreeRows(rootNodes, parentToChildrenMap, expandedPaths, {
@@ -73,11 +75,11 @@ function TreeView({ rootNodes, parentToChildrenMap, expandedPaths, selectedPath,
73
75
  getItemKey: getRowKey,
74
76
  overscan: 10
75
77
  });
76
- const move = useCallback((from, direction) => {
78
+ const move = useCallback((from, pick) => {
77
79
  const cursorIndex = findRowIndex(rows, cursorRef.current ?? "");
78
80
  const index = cursorIndex >= 0 ? cursorIndex : findRowIndex(rows, from.path);
79
81
  if (index === -1) return;
80
- const target = stepRow(rows, index, direction);
82
+ const target = pick(index);
81
83
  if (!target) return;
82
84
  cursorRef.current = target.node.path;
83
85
  pendingNavRef.current.add(target.node.path);
@@ -110,14 +112,23 @@ function TreeView({ rootNodes, parentToChildrenMap, expandedPaths, selectedPath,
110
112
  onPreviewFile(node);
111
113
  return;
112
114
  }
113
- if (e.key === "ArrowDown") {
115
+ const target = {
116
+ ArrowDown: (i) => stepRow(rows, i, 1),
117
+ ArrowUp: (i) => stepRow(rows, i, -1),
118
+ ArrowRight: (i) => firstChildRow(rows, i),
119
+ ArrowLeft: (i) => parentRow(rows, i),
120
+ Home: () => edgeRow(rows, "first"),
121
+ End: () => edgeRow(rows, "last")
122
+ }[e.key];
123
+ if (target) {
114
124
  e.preventDefault();
115
- move(node, 1);
116
- } else if (e.key === "ArrowUp") {
117
- e.preventDefault();
118
- move(node, -1);
125
+ move(node, target);
119
126
  }
120
- }, [move, onPreviewFile]);
127
+ }, [
128
+ move,
129
+ onPreviewFile,
130
+ rows
131
+ ]);
121
132
  const items = virtualizer.getVirtualItems();
122
133
  useTreePitchAudit(scrollEl, rows, items);
123
134
  const renderRow = (index, top, height) => {
@@ -167,6 +178,7 @@ function TreeView({ rootNodes, parentToChildrenMap, expandedPaths, selectedPath,
167
178
  ref: setScrollEl,
168
179
  className: "overflow-auto flex-1 px-2 py-2",
169
180
  role: "tree",
181
+ "aria-label": treeLabel,
170
182
  onDragOver: (e) => e.preventDefault(),
171
183
  onDrop: (e) => e.preventDefault(),
172
184
  children: /* @__PURE__ */ jsx("div", {
@@ -212,7 +224,7 @@ function TreeMoreRow({ depth, hiddenFiles, partial, loading, failed, onReveal })
212
224
  style: { paddingLeft: depth * INDENT_PER_LEVEL + ROW_PAD_FILE },
213
225
  children: loading ? /* @__PURE__ */ jsx("span", { children: t.loadingMore }) : /* @__PURE__ */ jsx("button", {
214
226
  type: "button",
215
- className: cx("cursor-pointer underline", failed ? "text-red-500" : "theme-link"),
227
+ className: cx("cursor-pointer underline", failed ? "text-(--theme-error-text)" : "theme-link"),
216
228
  onClick: onReveal,
217
229
  children: label()
218
230
  })
@@ -285,9 +297,9 @@ function useSpringLoadedDrop({ node, dropPath, isDirectory, isExpanded, onToggle
285
297
  }
286
298
  };
287
299
  }
288
- /** Keys a row handles itself; the arrows that move between rows delegate upward,
289
- * where the flat array is. The set is deliberately narrow:
290
- * no Home/End, no typeahead, and ArrowLeft/Right only toggle a directory. */
300
+ /** Keys a row handles itself: Enter, Space, and Right or Left on a folder that
301
+ * can open or close. The keys that move between rows delegate upward, where
302
+ * the flat array is. There is no typeahead. */
291
303
  function dispatchRowKey(e, { node, isDirectory, isExpanded, onSelect, onToggleExpand, onDelegate }) {
292
304
  if (e.key === "Enter") {
293
305
  e.preventDefault();
@@ -363,7 +375,18 @@ var TreeRowItem = memo(function TreeRowItem({ row, isSelected, onToggleExpand, o
363
375
  /** The height constants must equal the rendered pitch, or the scrollbar
364
376
  * drifts from the content. Reports the measured value to use. */
365
377
  function useTreePitchAudit(scrollEl, rows, items) {
366
- useEffect(() => {}, [
378
+ useEffect(() => {
379
+ if (!isDev() || !scrollEl || items.length < 2) return;
380
+ for (const item of items) {
381
+ const row = rows[item.index];
382
+ const el = scrollEl.querySelector(`[data-index="${item.index}"]`);
383
+ if (row?.kind !== "node" || !(el instanceof HTMLElement)) continue;
384
+ const inner = el.firstElementChild?.lastElementChild;
385
+ const measured = inner ? inner.getBoundingClientRect().height : 0;
386
+ if (measured > 30.5) console.warn(`TreeView: TREE_ROW_HEIGHT is 30 but a row's content measures ${measured}. Set TREE_ROW_HEIGHT = ${Math.ceil(measured)} in TreeView.tsx.`);
387
+ return;
388
+ }
389
+ }, [
367
390
  scrollEl,
368
391
  rows,
369
392
  items
@@ -19,6 +19,7 @@ declare function CorsIssuePreview({ selectedStorage, onRefresh, }: {
19
19
  selectedStorage: TStorage | null;
20
20
  onRefresh?: CorsAwareRefresh | undefined;
21
21
  }): JSX.Element;
22
+ declare function CorsPropagatingPreview(): JSX.Element;
22
23
  declare function NoDataAvailablePreview({ selectedStorage, error, onRefresh, connectionIssueMessage, className, canWrite, }: {
23
24
  selectedStorage: TStorage | null;
24
25
  error?: Error | null;
@@ -39,4 +40,4 @@ interface IShareFileButtonProps {
39
40
  onShare: (node: TreeNode) => Promise<void>;
40
41
  }
41
42
  declare function ShareFileButton({ node, onShare }: IShareFileButtonProps): JSX.Element;
42
- export { CorsIssuePreview, DragDropZone, getNodeIcon, NoDataAvailablePreview, NoFileSelectedPreview, NotFoundPreview, renderUploadNodes, ShareFileButton, SIDEBAR_WIDTH_DEFAULT, SIDEBAR_WIDTH_STORAGE_KEY, SkeletonPreview, };
43
+ export { CorsIssuePreview, CorsPropagatingPreview, DragDropZone, getNodeIcon, NoDataAvailablePreview, NoFileSelectedPreview, NotFoundPreview, renderUploadNodes, ShareFileButton, SIDEBAR_WIDTH_DEFAULT, SIDEBAR_WIDTH_STORAGE_KEY, SkeletonPreview, };
@@ -3,7 +3,7 @@ import { CustomizeIcon, DiskIcon, FileIcon, FileTextIcon, FolderIcon, ImageIcon,
3
3
  import { toast } from "../components/Toast.js";
4
4
  import { usePersistedState, useProvisionCorsRules, useSlots, useStrings } from "../components/Provider.js";
5
5
  import { Button } from "../components/Button.js";
6
- import Callout from "../components/Callout.js";
6
+ import { Callout } from "../components/Callout.js";
7
7
  import { ProgressBar } from "../components/Meter.js";
8
8
  import { Skeleton } from "../components/Skeleton.js";
9
9
  import { formatBytes } from "../format.js";
@@ -219,20 +219,17 @@ function CorsIssuePreview({ selectedStorage, onRefresh }) {
219
219
  return /* @__PURE__ */ jsxs("div", {
220
220
  className: "flex flex-col items-center justify-center max-w-lg mx-auto",
221
221
  children: [/* @__PURE__ */ jsxs(Callout, {
222
- className: "text-left",
223
- type: "info",
222
+ className: "my-4 text-left",
223
+ tone: "info",
224
+ title: t.explanation.title,
224
225
  children: [
225
- /* @__PURE__ */ jsx("h4", {
226
- className: "font-semibold mb-2",
227
- children: t.explanation.title
228
- }),
229
226
  /* @__PURE__ */ jsx("p", {
230
227
  className: "mb-2",
231
228
  children: t.explanation.description
232
229
  }),
233
230
  /* @__PURE__ */ jsx("p", { children: t.explanation.action }),
234
231
  /* @__PURE__ */ jsx("p", {
235
- className: "mt-2 text-sm italic",
232
+ className: "mt-2 italic",
236
233
  children: t.explanation.note
237
234
  })
238
235
  ]
@@ -264,32 +261,33 @@ function CorsPropagatingPreview() {
264
261
  return /* @__PURE__ */ jsxs("div", {
265
262
  role: "status",
266
263
  "aria-live": "polite",
267
- className: "flex flex-col items-center justify-center max-w-md mx-auto px-6 py-8 animate-[fadeInUp_400ms_ease-out]",
264
+ className: "flex flex-col items-center justify-center max-w-md mx-auto px-6 py-8 motion-safe:animate-[fadeInUp_400ms_ease-out]",
268
265
  children: [
269
266
  /* @__PURE__ */ jsxs("div", {
267
+ "aria-hidden": "true",
270
268
  className: "relative w-28 h-28 mb-6 flex items-center justify-center",
271
269
  children: [
272
270
  /* @__PURE__ */ jsx("span", {
273
- className: "absolute inline-flex h-full w-full rounded-full bg-blue-400/30 animate-ping",
271
+ className: "absolute inline-flex h-full w-full rounded-full bg-(--theme-info)/30 motion-safe:animate-ping",
274
272
  style: { animationDuration: "2.4s" }
275
273
  }),
276
274
  /* @__PURE__ */ jsx("span", {
277
- className: "absolute inline-flex h-2/3 w-2/3 rounded-full bg-blue-500/40 animate-ping",
275
+ className: "absolute inline-flex h-2/3 w-2/3 rounded-full bg-(--theme-info)/40 motion-safe:animate-ping",
278
276
  style: {
279
277
  animationDuration: "2.4s",
280
278
  animationDelay: "0.6s"
281
279
  }
282
280
  }),
283
281
  /* @__PURE__ */ jsx("span", {
284
- className: "absolute inline-flex h-1/3 w-1/3 rounded-full bg-blue-500/60 animate-ping",
282
+ className: "absolute inline-flex h-1/3 w-1/3 rounded-full bg-(--theme-info)/60 motion-safe:animate-ping",
285
283
  style: {
286
284
  animationDuration: "2.4s",
287
285
  animationDelay: "1.2s"
288
286
  }
289
287
  }),
290
288
  /* @__PURE__ */ jsx("span", {
291
- className: "relative inline-flex items-center justify-center w-8 h-8 rounded-full bg-blue-500 shadow-[0_0_24px_rgba(59,130,246,0.55)]",
292
- children: /* @__PURE__ */ jsx("span", { className: "absolute inline-flex h-2 w-2 rounded-full bg-white animate-pulse" })
289
+ className: "relative inline-flex items-center justify-center w-8 h-8 rounded-full bg-(--theme-info) shadow-[0_0_24px_color-mix(in_oklab,var(--theme-info)_55%,transparent)]",
290
+ children: /* @__PURE__ */ jsx("span", { className: "absolute inline-flex h-2 w-2 rounded-full bg-(--theme-panel-bg) motion-safe:animate-pulse" })
293
291
  })
294
292
  ]
295
293
  }),
@@ -349,7 +347,7 @@ function PropagationStage({ status, label }) {
349
347
  return /* @__PURE__ */ jsxs("li", {
350
348
  className: "flex flex-col items-center gap-1.5",
351
349
  children: [/* @__PURE__ */ jsxs("span", {
352
- className: cx("relative flex items-center justify-center w-6 h-6 rounded-full border transition-colors", status === "done" && "bg-green-500 border-green-500 text-white", status === "active" && "border-blue-500", status === "pending" && "theme-border"),
350
+ className: cx("relative flex items-center justify-center w-6 h-6 rounded-full border transition-colors", status === "done" && "bg-(--theme-success-solid) border-(--theme-success-solid) text-white", status === "active" && "border-(--theme-info)", status === "pending" && "theme-border"),
353
351
  children: [
354
352
  status === "done" && /* @__PURE__ */ jsx("svg", {
355
353
  viewBox: "0 0 16 16",
@@ -362,7 +360,7 @@ function PropagationStage({ status, label }) {
362
360
  "aria-hidden": "true",
363
361
  children: /* @__PURE__ */ jsx("polyline", { points: "3.5 8.5 6.5 11.5 12.5 5" })
364
362
  }),
365
- status === "active" && /* @__PURE__ */ jsxs(Fragment, { children: [/* @__PURE__ */ jsx("span", { className: "absolute inline-flex h-full w-full animate-ping rounded-full bg-blue-400/60" }), /* @__PURE__ */ jsx("span", { className: "relative inline-flex h-2 w-2 rounded-full bg-blue-500" })] }),
363
+ status === "active" && /* @__PURE__ */ jsxs(Fragment, { children: [/* @__PURE__ */ jsx("span", { className: "absolute inline-flex h-full w-full motion-safe:animate-ping rounded-full bg-(--theme-info)/60" }), /* @__PURE__ */ jsx("span", { className: "relative inline-flex h-2 w-2 rounded-full bg-(--theme-info)" })] }),
366
364
  status === "pending" && /* @__PURE__ */ jsx("span", { className: "inline-flex h-1.5 w-1.5 rounded-full theme-muted-text opacity-60" })
367
365
  ]
368
366
  }), /* @__PURE__ */ jsx("span", {
@@ -374,7 +372,7 @@ function PropagationStage({ status, label }) {
374
372
  function PropagationConnector({ active }) {
375
373
  return /* @__PURE__ */ jsx("span", {
376
374
  "aria-hidden": "true",
377
- className: cx("h-px w-8 -mt-5 transition-colors", active ? "bg-blue-500" : "theme-border border-t")
375
+ className: cx("h-px w-8 -mt-5 transition-colors", active ? "bg-(--theme-info)" : "theme-border border-t")
378
376
  });
379
377
  }
380
378
  function NoDataAvailablePreview({ selectedStorage, error, onRefresh, connectionIssueMessage = null, className, canWrite = true }) {
@@ -409,8 +407,11 @@ function NoDataAvailablePreview({ selectedStorage, error, onRefresh, connectionI
409
407
  className: "flex flex-col items-center justify-center max-w-md p-8",
410
408
  children: [
411
409
  /* @__PURE__ */ jsx("div", {
412
- className: "inline-flex items-center justify-center w-14 h-14 rounded-full bg-amber-500/10 mb-4",
413
- children: /* @__PURE__ */ jsx(WarningIcon, { className: "h-6 w-6 text-amber-500" })
410
+ className: "inline-flex items-center justify-center w-14 h-14 rounded-full bg-(--theme-warning-muted) mb-4",
411
+ children: /* @__PURE__ */ jsx(WarningIcon, {
412
+ "aria-hidden": "true",
413
+ className: "h-6 w-6 text-(--theme-warning)"
414
+ })
414
415
  }),
415
416
  /* @__PURE__ */ jsx("h2", {
416
417
  className: "text-base font-semibold mb-1",
@@ -532,4 +533,4 @@ async function addCorsRules({ provision, strings, csp, type, username, storageNa
532
533
  toast.warning(strings.corsPropagating);
533
534
  }
534
535
  //#endregion
535
- export { CorsIssuePreview, DragDropZone, NoDataAvailablePreview, NoFileSelectedPreview, NotFoundPreview, SIDEBAR_WIDTH_STORAGE_KEY, ShareFileButton, SkeletonPreview, getNodeIcon, renderUploadNodes };
536
+ export { CorsIssuePreview, CorsPropagatingPreview, DragDropZone, NoDataAvailablePreview, NoFileSelectedPreview, NotFoundPreview, SIDEBAR_WIDTH_STORAGE_KEY, ShareFileButton, SkeletonPreview, getNodeIcon, renderUploadNodes };
@@ -1,8 +1,10 @@
1
1
  import { cx } from "../cx.js";
2
2
  import { ChevronDownIcon, ChevronUpIcon, CloseIcon, ExpandVerticalIcon, MinimizeIcon, SuccessIcon, UploadIcon, WarningIcon } from "../icons.js";
3
+ import { toneIcon } from "../components/tone.js";
3
4
  import { useStrings } from "../components/Provider.js";
4
5
  import { Button } from "../components/Button.js";
5
6
  import { IconButton } from "../components/IconButton.js";
7
+ import { Callout } from "../components/Callout.js";
6
8
  import { ProgressBar } from "../components/Meter.js";
7
9
  import { formatBytes, formatTimeLeft } from "../format.js";
8
10
  import { Fragment, jsx, jsxs } from "react/jsx-runtime";
@@ -11,28 +13,34 @@ import { useState } from "react";
11
13
  function getSessionStatusInfo(session, queueLength, strings) {
12
14
  switch (session.status) {
13
15
  case "queued": return {
14
- icon: /* @__PURE__ */ jsx(UploadIcon, { className: "w-5 h-5 text-blue-600" }),
16
+ icon: /* @__PURE__ */ jsx(UploadIcon, { className: cx("w-5 h-5", toneIcon.info) }),
15
17
  title: strings.inQueue(session.queueIndex + 1, queueLength),
16
18
  shortTitle: strings.queuedShort(session.queueIndex + 1, queueLength),
17
- bgColor: "bg-blue-100"
19
+ bgColor: "bg-(--theme-info-muted)"
18
20
  };
19
21
  case "uploading": return {
20
- icon: /* @__PURE__ */ jsx(UploadIcon, { className: "w-5 h-5 text-blue-600" }),
22
+ icon: /* @__PURE__ */ jsx(UploadIcon, { className: cx("w-5 h-5", toneIcon.info) }),
21
23
  title: strings.uploading,
22
24
  shortTitle: strings.uploading,
23
- bgColor: "bg-blue-100"
25
+ bgColor: "bg-(--theme-info-muted)"
24
26
  };
25
27
  case "completed": return {
26
- icon: /* @__PURE__ */ jsx(SuccessIcon, { className: "w-5 h-5 text-green-600" }),
28
+ icon: /* @__PURE__ */ jsx(SuccessIcon, { className: cx("w-5 h-5", toneIcon.success) }),
27
29
  title: strings.completeTitle,
28
30
  shortTitle: strings.completed,
29
- bgColor: "bg-green-100"
31
+ bgColor: "bg-(--theme-success-muted)"
30
32
  };
31
33
  case "failed": return {
32
- icon: /* @__PURE__ */ jsx(WarningIcon, { className: "w-5 h-5 text-red-600" }),
34
+ icon: /* @__PURE__ */ jsx(WarningIcon, { className: cx("w-5 h-5", toneIcon.error) }),
33
35
  title: strings.failedTitle,
34
36
  shortTitle: strings.failed,
35
- bgColor: "bg-red-100"
37
+ bgColor: "bg-(--theme-error-muted)"
38
+ };
39
+ case "canceled": return {
40
+ icon: /* @__PURE__ */ jsx(CloseIcon, { className: "w-5 h-5 theme-muted-text" }),
41
+ title: strings.canceled,
42
+ shortTitle: strings.canceled,
43
+ bgColor: "bg-(--theme-muted-panel-bg)"
36
44
  };
37
45
  default: return {
38
46
  icon: /* @__PURE__ */ jsx(UploadIcon, { className: "w-5 h-5 theme-muted-text" }),
@@ -178,6 +186,7 @@ function UploadSessionToast({ session, queueLength, onCancel, onCancelFile }) {
178
186
  }), /* @__PURE__ */ jsx("button", {
179
187
  type: "button",
180
188
  "aria-label": strings.expandDetails,
189
+ "aria-expanded": false,
181
190
  className: "flex items-center justify-between text-xs theme-muted-text hover:theme-text cursor-pointer",
182
191
  onClick: handleExpandClick,
183
192
  title: strings.expandDetails,
@@ -221,6 +230,7 @@ function UploadSessionToast({ session, queueLength, onCancel, onCancelFile }) {
221
230
  }), /* @__PURE__ */ jsx("button", {
222
231
  type: "button",
223
232
  "aria-label": strings.minimizeDetails,
233
+ "aria-expanded": true,
224
234
  className: "flex items-center justify-between text-xs theme-muted-text hover:theme-text cursor-pointer mr-2",
225
235
  onClick: handleExpandClick,
226
236
  title: strings.minimizeDetails,
@@ -250,15 +260,11 @@ function UploadSessionToast({ session, queueLength, onCancel, onCancelFile }) {
250
260
  ]
251
261
  })
252
262
  }),
253
- isUploading && /* @__PURE__ */ jsx("div", {
254
- className: "mb-4 p-3 bg-amber-50 border border-amber-200 rounded-lg",
255
- children: /* @__PURE__ */ jsxs("div", {
256
- className: "flex gap-2",
257
- children: [/* @__PURE__ */ jsx(WarningIcon, { className: "w-4 h-4 text-amber-600 flex-shrink-0 mt-0.5" }), /* @__PURE__ */ jsx("p", {
258
- className: "text-xs text-amber-800",
259
- children: strings.keepPageOpen
260
- })]
261
- })
263
+ isUploading && /* @__PURE__ */ jsx(Callout, {
264
+ tone: "warning",
265
+ size: "sm",
266
+ className: "mb-4",
267
+ children: strings.keepPageOpen
262
268
  }),
263
269
  session.uploadNodes.length > 1 && isUploading && /* @__PURE__ */ jsx(ProgressBar, {
264
270
  value: totalProgress,
@@ -271,6 +277,7 @@ function UploadSessionToast({ session, queueLength, onCancel, onCancelFile }) {
271
277
  children: [/* @__PURE__ */ jsxs("button", {
272
278
  type: "button",
273
279
  className: "flex items-center justify-between text-xs theme-muted-text hover:theme-text cursor-pointer",
280
+ "aria-expanded": isFileListExpanded,
274
281
  onClick: () => setIsExpanded(!isFileListExpanded),
275
282
  children: [/* @__PURE__ */ jsx("span", { children: strings.fileCount(session.uploadNodes.length) }), isFileListExpanded ? /* @__PURE__ */ jsx(ChevronUpIcon, { className: "w-4 h-4" }) : /* @__PURE__ */ jsx(ChevronDownIcon, { className: "w-4 h-4" })]
276
283
  }), isFileListExpanded && /* @__PURE__ */ jsx("div", {
@@ -294,10 +301,11 @@ function UploadSessionToast({ session, queueLength, onCancel, onCancelFile }) {
294
301
  /* @__PURE__ */ jsxs("div", {
295
302
  className: "flex items-center justify-end",
296
303
  children: [shouldShowSessionCancelButton && /* @__PURE__ */ jsx(Button, {
297
- variant: "danger",
304
+ variant: "outline",
298
305
  size: "xs",
306
+ className: "*:text-(--theme-error-text)",
299
307
  onClick: handleCancelClick,
300
- children: common.cancel
308
+ children: /* @__PURE__ */ jsx("span", { children: common.cancel })
301
309
  }), showCancelConfirm && /* @__PURE__ */ jsxs("div", {
302
310
  className: "flex items-center space-x-2",
303
311
  children: [
@@ -32,4 +32,10 @@ export declare function nextFileLimit(current: number | undefined): number;
32
32
  export declare function findRowIndex(rows: readonly TreeRow[], path: string): number;
33
33
  /** The next selectable row in `direction`, skipping skeleton and more rows. */
34
34
  export declare function stepRow(rows: readonly TreeRow[], from: number, direction: 1 | -1): TreeRow | undefined;
35
+ /** The row's parent: the nearest row above it one level up, or undefined at a root. */
36
+ export declare function parentRow(rows: readonly TreeRow[], index: number): TreeRow | undefined;
37
+ /** An open folder's first child row, or undefined when it shows none yet. */
38
+ export declare function firstChildRow(rows: readonly TreeRow[], index: number): TreeRow | undefined;
39
+ /** The first or last selectable row, for Home and End. */
40
+ export declare function edgeRow(rows: readonly TreeRow[], edge: 'first' | 'last'): TreeRow | undefined;
35
41
  export {};
@@ -69,5 +69,23 @@ function stepRow(rows, from, direction) {
69
69
  if (row?.kind === "node") return row;
70
70
  }
71
71
  }
72
+ /** The row's parent: the nearest row above it one level up, or undefined at a root. */
73
+ function parentRow(rows, index) {
74
+ const depth = rows[index]?.depth ?? 0;
75
+ for (let i = index - 1; i >= 0; i--) {
76
+ const row = rows[i];
77
+ if (row?.kind === "node" && row.depth < depth) return row.depth === depth - 1 ? row : void 0;
78
+ }
79
+ }
80
+ /** An open folder's first child row, or undefined when it shows none yet. */
81
+ function firstChildRow(rows, index) {
82
+ const depth = rows[index]?.depth ?? 0;
83
+ const next = rows[index + 1];
84
+ return next?.kind === "node" && next.depth === depth + 1 ? next : void 0;
85
+ }
86
+ /** The first or last selectable row, for Home and End. */
87
+ function edgeRow(rows, edge) {
88
+ return edge === "first" ? stepRow(rows, -1, 1) : stepRow(rows, rows.length, -1);
89
+ }
72
90
  //#endregion
73
- export { findRowIndex, flattenTreeRows, nextFileLimit, stepRow };
91
+ export { edgeRow, findRowIndex, firstChildRow, flattenTreeRows, nextFileLimit, parentRow, stepRow };
@@ -1,16 +1,13 @@
1
- import { useEffect, useRef } from "react";
1
+ import { useEffect, useEffectEvent } from "react";
2
2
  //#region src/file-explorer/useNearEnd.ts
3
3
  /** Fires once the element comes within 100px of the bottom of `root`. */
4
4
  function useNearEnd(ref, { active, root, onNear }) {
5
- const latestOnNear = useRef(onNear);
6
- useEffect(() => {
7
- latestOnNear.current = onNear;
8
- }, [onNear]);
5
+ const near = useEffectEvent(onNear);
9
6
  useEffect(() => {
10
7
  const el = ref.current;
11
8
  if (!active || !el) return;
12
9
  const observer = new IntersectionObserver((entries) => {
13
- if (entries.some((entry) => entry.isIntersecting)) latestOnNear.current();
10
+ if (entries.some((entry) => entry.isIntersecting)) near();
14
11
  }, {
15
12
  root,
16
13
  rootMargin: "100px"
@@ -5,7 +5,7 @@ import { fieldFrame } from "../fieldFrame.js";
5
5
  import { useFieldValue } from "../useFieldValue.js";
6
6
  import { fieldOption } from "./fieldOption.js";
7
7
  import { jsx, jsxs } from "react/jsx-runtime";
8
- import { useState } from "react";
8
+ import { useId, useState } from "react";
9
9
  //#region src/form/Fields/CheckboxGroupField.tsx
10
10
  function impliedFrom(values, implies = {}) {
11
11
  const result = /* @__PURE__ */ new Set();
@@ -19,6 +19,7 @@ function CheckboxGroupField(props) {
19
19
  const { field, error, disabled, onChange } = props;
20
20
  const [value, change] = useFieldValue(field.name ?? "");
21
21
  const implies = field.implies;
22
+ const uid = useId();
22
23
  const rawOf = new Map((field.options ?? []).map((choice) => {
23
24
  const option = fieldOption(choice);
24
25
  return [option.value, option.raw];
@@ -40,26 +41,32 @@ function CheckboxGroupField(props) {
40
41
  return /* @__PURE__ */ jsx(Field, {
41
42
  ...fieldFrame(props, { group: true }),
42
43
  children: /* @__PURE__ */ jsx("div", {
43
- className: "flex min-w-0 max-w-lg flex-col gap-1",
44
- children: field.options?.map((raw) => {
44
+ className: "flex min-w-0 max-w-lg flex-col",
45
+ children: field.options?.map((raw, index) => {
45
46
  const option = fieldOption(raw);
46
47
  const locked = forced.has(option.value);
47
48
  const optionDisabled = disabled || locked;
49
+ const labelId = `${uid}label${index}`;
50
+ const descriptionId = option.description && `${uid}description${index}`;
48
51
  return /* @__PURE__ */ jsxs(FieldOption, {
49
52
  disabled: optionDisabled,
50
- className: cx("-mx-2 flex items-start gap-2.5 rounded-md px-2 py-1.5 transition-colors", !optionDisabled && "hover:bg-(--theme-hover) has-[:focus-visible]:bg-(--theme-hover)"),
53
+ className: cx("-mx-2 flex items-start gap-2.5 rounded-md px-2 py-2 transition-colors", !optionDisabled && "hover:bg-(--theme-hover) has-[:focus-visible]:bg-(--theme-hover)"),
51
54
  children: [/* @__PURE__ */ jsx(Checkbox, {
52
55
  checked: manual.includes(option.value) || locked,
53
56
  disabled: optionDisabled,
54
57
  onCheckedChange: () => handleToggle(option.value),
55
58
  "aria-invalid": error !== void 0 || void 0,
59
+ "aria-labelledby": labelId,
60
+ "aria-describedby": descriptionId || void 0,
56
61
  className: "mt-0.5"
57
62
  }), /* @__PURE__ */ jsxs("div", {
58
63
  className: "flex min-w-0 flex-col",
59
64
  children: [/* @__PURE__ */ jsx("span", {
60
- className: "font-medium leading-tight theme-text",
65
+ id: labelId,
66
+ className: "font-medium leading-5 theme-text",
61
67
  children: option.label
62
68
  }), option.description && /* @__PURE__ */ jsx("span", {
69
+ id: descriptionId,
63
70
  className: "mt-0.5 text-xs leading-snug theme-muted-text",
64
71
  children: option.description
65
72
  })]
@@ -1,7 +1,7 @@
1
1
  import { useStrings } from "../../components/Provider.js";
2
+ import { fieldBox } from "../../components/fieldBox.js";
2
3
  import { Checkbox } from "../../components/Checkbox.js";
3
4
  import { Field, FieldOption } from "../../components/Field.js";
4
- import { fieldBox } from "../../components/fieldBox.js";
5
5
  import { fieldFrame } from "../fieldFrame.js";
6
6
  import { useFieldValue } from "../useFieldValue.js";
7
7
  import { formatDurationText, parseDurationText } from "../utils/duration.js";
@@ -10,7 +10,7 @@ function LabelField(props) {
10
10
  whiteSpace: "pre-wrap",
11
11
  ...field.size ? { fontSize: `${field.size}px` } : {}
12
12
  },
13
- className: cx("relative", "text-md", field.bold !== false ? "font-bold" : ""),
13
+ className: cx("text-base", field.bold !== false && "font-bold"),
14
14
  children: field.text?.toString().replace(/(\r)/g, "").replace(/(\\n)/g, "\n") || label
15
15
  })
16
16
  });
@@ -4,4 +4,4 @@ export interface IObjectField extends BaseField {
4
4
  type: 'object';
5
5
  options: DynamicFormSchema;
6
6
  }
7
- export default function ObjectField({ field, label, tooltipComponent, labelPosition, spaceCompact, }: FieldComponentProps<IObjectField>): import("react").JSX.Element;
7
+ export default function ObjectField({ field, label, help, labelPosition, spaceCompact, }: FieldComponentProps<IObjectField>): import("react").JSX.Element;
@@ -1,15 +1,16 @@
1
+ import { InfoTip } from "../../components/InfoTip.js";
1
2
  import { Section } from "../../components/Section.js";
2
3
  import { FieldsFromOptions, resolveMetaOverrides } from "../Form.js";
3
4
  import { jsx } from "react/jsx-runtime";
4
5
  import { useMemo } from "react";
5
6
  //#region src/form/Fields/ObjectField.tsx
6
- function ObjectField({ field, label, tooltipComponent, labelPosition, spaceCompact }) {
7
+ function ObjectField({ field, label, help, labelPosition, spaceCompact }) {
7
8
  const fieldName = field.name ?? "";
8
9
  const meta = resolveMetaOverrides(field.options, labelPosition, spaceCompact ?? false);
9
10
  const parentInfo = useMemo(() => ({ fieldNamePrefix: `${fieldName}.` }), [fieldName]);
10
11
  return /* @__PURE__ */ jsx(Section, {
11
12
  title: field.label || label,
12
- beside: tooltipComponent,
13
+ beside: help && /* @__PURE__ */ jsx(InfoTip, { text: help }),
13
14
  collapsible: !field.noCollapse,
14
15
  defaultOpen: !field.collapsed,
15
16
  children: /* @__PURE__ */ jsx(FieldsFromOptions, {
@@ -1,16 +1,14 @@
1
- import { cx } from "../../cx.js";
2
- import { Field, RevealToggle } from "../../components/Field.js";
3
- import { fieldBox } from "../../components/fieldBox.js";
1
+ import { Field } from "../../components/Field.js";
2
+ import { Input } from "../../components/Input.js";
4
3
  import { fieldFrame } from "../fieldFrame.js";
5
4
  import { useFieldValue } from "../useFieldValue.js";
6
5
  import { getPlaceholder } from "../utils/getPlaceholder.js";
7
- import { jsx, jsxs } from "react/jsx-runtime";
8
- import { useMemo, useState } from "react";
6
+ import { jsx } from "react/jsx-runtime";
7
+ import { useMemo } from "react";
9
8
  //#region src/form/Fields/StringField.tsx
10
9
  function StringField(props) {
11
10
  const { field, disabled, onChange } = props;
12
11
  const [value, change] = useFieldValue(field.name ?? "");
13
- const [revealed, setRevealed] = useState(false);
14
12
  const password = field.type === "password";
15
13
  const fallback = field.default ?? "";
16
14
  const disallowed = useMemo(() => {
@@ -31,29 +29,18 @@ function StringField(props) {
31
29
  };
32
30
  return /* @__PURE__ */ jsx(Field, {
33
31
  ...fieldFrame(props),
34
- children: (control) => {
35
- const input = /* @__PURE__ */ jsx("input", {
36
- ...control,
37
- "data-1p-ignore": true,
38
- className: cx(fieldBox(), password && "pr-9"),
39
- name: field.name,
40
- value: password && value === fallback ? "" : value ?? "",
41
- type: password && !revealed ? "password" : "text",
42
- disabled,
43
- placeholder: password && field.placeholder === void 0 ? "•".repeat(fallback.toString().length > 0 ? 16 : 0) : getPlaceholder(field.placeholder, field.default),
44
- minLength: field.minLength,
45
- maxLength: field.maxLength,
46
- onChange: handleChange
47
- });
48
- return password ? /* @__PURE__ */ jsxs("div", {
49
- className: "relative w-full",
50
- children: [input, /* @__PURE__ */ jsx(RevealToggle, {
51
- revealed,
52
- onRevealedChange: setRevealed,
53
- disabled
54
- })]
55
- }) : input;
56
- }
32
+ children: (control) => /* @__PURE__ */ jsx(Input, {
33
+ ...control,
34
+ "data-1p-ignore": true,
35
+ name: field.name,
36
+ value: password && value === fallback ? "" : value ?? "",
37
+ type: password ? "password" : "text",
38
+ disabled,
39
+ placeholder: password && field.placeholder === void 0 ? "•".repeat(fallback.toString().length > 0 ? 16 : 0) : getPlaceholder(field.placeholder, field.default),
40
+ minLength: field.minLength,
41
+ maxLength: field.maxLength,
42
+ onChange: handleChange
43
+ })
57
44
  });
58
45
  }
59
46
  //#endregion
@@ -1,6 +1,5 @@
1
- import { cx } from "../../cx.js";
2
1
  import { Field } from "../../components/Field.js";
3
- import { fieldBox } from "../../components/fieldBox.js";
2
+ import { Textarea } from "../../components/Input.js";
4
3
  import { fieldFrame } from "../fieldFrame.js";
5
4
  import { useFieldValue } from "../useFieldValue.js";
6
5
  import { getPlaceholder } from "../utils/getPlaceholder.js";
@@ -11,9 +10,9 @@ function TextAreaField(props) {
11
10
  const [value, change] = useFieldValue(field.name ?? "");
12
11
  return /* @__PURE__ */ jsx(Field, {
13
12
  ...fieldFrame(props),
14
- children: (control) => /* @__PURE__ */ jsx("textarea", {
13
+ children: (control) => /* @__PURE__ */ jsx(Textarea, {
15
14
  ...control,
16
- className: cx(fieldBox({ multiline: true }), "h-20 resize-y"),
15
+ className: "h-20 min-h-20",
17
16
  name: field.name,
18
17
  value: value ?? "",
19
18
  placeholder: getPlaceholder(field.placeholder, field.default),