@parallelworks/ui 0.77.0 → 0.79.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 (268) hide show
  1. package/README.md +42 -6
  2. package/dist/access/AccessDrawer.d.ts +49 -7
  3. package/dist/access/AccessDrawer.js +243 -38
  4. package/dist/access/AccessList.d.ts +19 -1
  5. package/dist/access/AccessList.js +220 -9
  6. package/dist/access/GrantView.d.ts +3 -1
  7. package/dist/access/GrantView.js +17 -4
  8. package/dist/access/PrincipalPicker.js +5 -5
  9. package/dist/access/focus.js +1 -1
  10. package/dist/access/index.d.ts +2 -2
  11. package/dist/access/index.js +2 -2
  12. package/dist/access/strings.d.ts +25 -1
  13. package/dist/access/strings.js +27 -3
  14. package/dist/access/types.d.ts +26 -0
  15. package/dist/ai/components/AllocationSelector.js +1 -1
  16. package/dist/ai/components/AttachmentManager.js +5 -5
  17. package/dist/ai/components/AttachmentUpload.js +2 -2
  18. package/dist/ai/components/BranchNavigator.js +1 -1
  19. package/dist/ai/components/ChatActivity.js +1 -1
  20. package/dist/ai/components/ChatEmptyState.js +3 -3
  21. package/dist/ai/components/ChatInput.js +3 -5
  22. package/dist/ai/components/ChatLayout.js +1 -1
  23. package/dist/ai/components/ChatMessage.js +1 -1
  24. package/dist/ai/components/ChatMessageList.js +23 -8
  25. package/dist/ai/components/ChatSidebar.js +3 -3
  26. package/dist/ai/components/ChatThread.js +4 -4
  27. package/dist/ai/components/ComposerAddMenu.js +9 -20
  28. package/dist/ai/components/ModelSelector.js +3 -3
  29. package/dist/ai/components/PastedText.js +5 -5
  30. package/dist/ai/components/SessionView.js +1 -1
  31. package/dist/ai/components/ShareDialog.js +3 -3
  32. package/dist/ai/components/SlashMenu.d.ts +31 -4
  33. package/dist/ai/components/SlashMenu.js +36 -63
  34. package/dist/ai/components/agent/ActivityLine.js +1 -1
  35. package/dist/ai/components/agent/AgentMessageParts.js +13 -13
  36. package/dist/ai/components/conversationActions.js +3 -3
  37. package/dist/ai/core/ChatProvider.js +1 -1
  38. package/dist/ai/core/config.js +1 -1
  39. package/dist/ai/ui/ConversationSidebar.js +3 -3
  40. package/dist/ai/ui/sidebar.js +3 -3
  41. package/dist/assets/yaml.worker-DOBV2lND.js +884 -0
  42. package/dist/components/ActionMenu.d.ts +38 -9
  43. package/dist/components/ActionMenu.js +48 -22
  44. package/dist/components/Avatar.d.ts +66 -6
  45. package/dist/components/Avatar.js +130 -18
  46. package/dist/components/Breadcrumbs.d.ts +4 -0
  47. package/dist/components/Breadcrumbs.js +26 -10
  48. package/dist/components/Button.d.ts +3 -2
  49. package/dist/components/Button.js +11 -1
  50. package/dist/components/Callout.d.ts +3 -2
  51. package/dist/components/Callout.js +3 -2
  52. package/dist/components/Card.d.ts +33 -9
  53. package/dist/components/Card.js +24 -8
  54. package/dist/components/Checkbox.d.ts +3 -1
  55. package/dist/components/Checkbox.js +4 -2
  56. package/dist/components/ColorInput.js +1 -1
  57. package/dist/components/Combobox.d.ts +23 -0
  58. package/dist/components/Combobox.js +252 -86
  59. package/dist/components/ConfirmModal.d.ts +28 -2
  60. package/dist/components/ConfirmModal.js +100 -15
  61. package/dist/components/ContextMenu.d.ts +29 -2
  62. package/dist/components/ContextMenu.js +60 -8
  63. package/dist/components/CopyButton.d.ts +21 -8
  64. package/dist/components/CopyButton.js +29 -9
  65. package/dist/components/CreateModal.d.ts +20 -4
  66. package/dist/components/CreateModal.js +28 -17
  67. package/dist/components/DatePicker.d.ts +31 -1
  68. package/dist/components/DatePicker.js +178 -47
  69. package/dist/components/DescriptionList.d.ts +13 -3
  70. package/dist/components/DescriptionList.js +43 -11
  71. package/dist/components/Disclosure.d.ts +10 -2
  72. package/dist/components/Disclosure.js +18 -7
  73. package/dist/components/Drawer.js +5 -5
  74. package/dist/components/EmptyState.d.ts +12 -4
  75. package/dist/components/EmptyState.js +18 -10
  76. package/dist/components/ErrorPage.d.ts +40 -0
  77. package/dist/components/ErrorPage.js +101 -0
  78. package/dist/components/ExternalLink.d.ts +4 -1
  79. package/dist/components/ExternalLink.js +4 -5
  80. package/dist/components/Field.d.ts +21 -6
  81. package/dist/components/Field.js +32 -16
  82. package/dist/components/FileButton.d.ts +19 -0
  83. package/dist/components/FileButton.js +32 -0
  84. package/dist/components/HoverCard.d.ts +26 -6
  85. package/dist/components/HoverCard.js +11 -5
  86. package/dist/components/IconButton.js +4 -2
  87. package/dist/components/InfoTip.js +3 -3
  88. package/dist/components/Input.d.ts +33 -3
  89. package/dist/components/Input.js +149 -14
  90. package/dist/components/Kbd.d.ts +40 -0
  91. package/dist/components/Kbd.js +168 -0
  92. package/dist/components/Listbox.d.ts +103 -0
  93. package/dist/components/Listbox.js +190 -0
  94. package/dist/components/Loader.d.ts +8 -2
  95. package/dist/components/Loader.js +16 -1
  96. package/dist/components/Markdown.js +1 -1
  97. package/dist/components/MarkdownImpl.js +1 -1
  98. package/dist/components/Menu.d.ts +20 -2
  99. package/dist/components/Menu.js +48 -19
  100. package/dist/components/MenuEntries.d.ts +41 -4
  101. package/dist/components/MenuEntries.js +266 -39
  102. package/dist/components/Meter.d.ts +50 -11
  103. package/dist/components/Meter.js +71 -21
  104. package/dist/components/Modal.d.ts +9 -3
  105. package/dist/components/Modal.js +68 -29
  106. package/dist/components/OneTimeCodeInput.js +1 -1
  107. package/dist/components/PageHeader.js +111 -7
  108. package/dist/components/PageHeaderAction.d.ts +8 -3
  109. package/dist/components/PageHeaderAction.js +122 -34
  110. package/dist/components/Pagination.d.ts +13 -1
  111. package/dist/components/Pagination.js +90 -19
  112. package/dist/components/Popover.d.ts +16 -2
  113. package/dist/components/Popover.js +20 -21
  114. package/dist/components/Provider.d.ts +172 -5
  115. package/dist/components/Provider.js +157 -14
  116. package/dist/components/RefreshButton.d.ts +13 -6
  117. package/dist/components/RefreshButton.js +17 -9
  118. package/dist/components/RunStatusIcon.d.ts +16 -7
  119. package/dist/components/RunStatusIcon.js +21 -8
  120. package/dist/components/Section.d.ts +11 -4
  121. package/dist/components/Section.js +33 -22
  122. package/dist/components/SegmentedControl.d.ts +16 -3
  123. package/dist/components/SegmentedControl.js +7 -3
  124. package/dist/components/Select.d.ts +19 -3
  125. package/dist/components/Select.js +114 -68
  126. package/dist/components/SelectionCopy.d.ts +10 -0
  127. package/dist/components/SelectionCopy.js +105 -0
  128. package/dist/components/SettingModeOption.js +1 -1
  129. package/dist/components/SettingsCard.js +1 -1
  130. package/dist/components/Skeleton.js +1 -1
  131. package/dist/components/StatusBadge.d.ts +55 -10
  132. package/dist/components/StatusBadge.js +91 -15
  133. package/dist/components/StickyBar.js +1 -1
  134. package/dist/components/Table.d.ts +22 -4
  135. package/dist/components/Table.js +46 -24
  136. package/dist/components/Tabs.d.ts +9 -4
  137. package/dist/components/Tabs.js +9 -4
  138. package/dist/components/Tag.d.ts +49 -0
  139. package/dist/components/Tag.js +199 -0
  140. package/dist/components/ThemeEditor.js +1 -1
  141. package/dist/components/Toast.js +1 -1
  142. package/dist/components/ToggleGroup.d.ts +4 -1
  143. package/dist/components/ToggleGroup.js +30 -13
  144. package/dist/components/Tooltip.d.ts +9 -3
  145. package/dist/components/Tooltip.js +55 -39
  146. package/dist/components/buttonClasses.d.ts +5 -2
  147. package/dist/components/buttonClasses.js +11 -10
  148. package/dist/components/chart.d.ts +69 -0
  149. package/dist/components/chart.js +145 -0
  150. package/dist/components/comboboxItems.d.ts +7 -1
  151. package/dist/components/comboboxItems.js +6 -2
  152. package/dist/components/dismiss.d.ts +5 -1
  153. package/dist/components/dismiss.js +6 -2
  154. package/dist/components/floating.d.ts +4 -4
  155. package/dist/components/floating.js +5 -5
  156. package/dist/components/headerActionsFit.d.ts +37 -0
  157. package/dist/components/headerActionsFit.js +81 -0
  158. package/dist/components/pageHeaderStore.d.ts +3 -0
  159. package/dist/components/pageHeaderStore.js +3 -0
  160. package/dist/components/pathBreaks.js +2 -2
  161. package/dist/components/popupContainer.d.ts +17 -0
  162. package/dist/components/popupContainer.js +69 -0
  163. package/dist/components/relativeTime.d.ts +21 -10
  164. package/dist/components/relativeTime.js +50 -22
  165. package/dist/components/segmented.d.ts +18 -4
  166. package/dist/components/segmented.js +48 -6
  167. package/dist/components/typedDate.d.ts +5 -0
  168. package/dist/components/typedDate.js +50 -0
  169. package/dist/components/useClosingValue.d.ts +4 -0
  170. package/dist/components/useClosingValue.js +12 -0
  171. package/dist/components/useCopy.d.ts +6 -0
  172. package/dist/components/useCopy.js +3 -3
  173. package/dist/components/useNarrow.d.ts +2 -0
  174. package/dist/components/useNarrow.js +16 -0
  175. package/dist/editor/Editor.js +1 -1
  176. package/dist/editor/FormCodePanel.js +1 -1
  177. package/dist/editor/Monaco.js +1 -1
  178. package/dist/editor/workers.js +1 -1
  179. package/dist/file-explorer/FileExplorer.js +16 -15
  180. package/dist/file-explorer/FileExplorerContext.js +2 -2
  181. package/dist/file-explorer/FilePreview/Viewer.js +3 -3
  182. package/dist/file-explorer/FilePreview/index.js +2 -2
  183. package/dist/file-explorer/FileRowsWindow.js +3 -3
  184. package/dist/file-explorer/FileTable.js +1 -1
  185. package/dist/file-explorer/LoadMoreRow.js +1 -1
  186. package/dist/file-explorer/TreeView.js +5 -5
  187. package/dist/file-explorer/helpers.js +2 -2
  188. package/dist/file-explorer/toasts.js +2 -2
  189. package/dist/form/Fields/CheckboxGroupField.js +1 -1
  190. package/dist/form/Fields/DropdownField.js +1 -1
  191. package/dist/form/Fields/DurationField.js +2 -2
  192. package/dist/form/Fields/MultiDropdownField.js +1 -1
  193. package/dist/form/Fields/NumberField.js +1 -1
  194. package/dist/form/Fields/ObjectField.js +1 -1
  195. package/dist/form/Fields/RangeField.js +1 -1
  196. package/dist/form/Fields/StringField.js +1 -1
  197. package/dist/form/Form.js +3 -3
  198. package/dist/form/FormLayout.js +1 -1
  199. package/dist/form/Wizard/WizardContainer.js +1 -1
  200. package/dist/form/Wizard/WizardNavigation.js +1 -1
  201. package/dist/form/Wizard/WizardStepContent.js +1 -1
  202. package/dist/form/fieldRegistry.js +1 -1
  203. package/dist/form/formEditing.js +1 -1
  204. package/dist/format.d.ts +17 -7
  205. package/dist/format.js +39 -16
  206. package/dist/graph/AnnotationBanner.js +2 -2
  207. package/dist/graph/Connectors.js +5 -5
  208. package/dist/graph/DependencyGraph.js +10 -9
  209. package/dist/graph/GraphEditor.js +4 -4
  210. package/dist/graph/GraphEditorDialogs.js +13 -12
  211. package/dist/graph/GraphNode.js +1 -1
  212. package/dist/graph/InputDialog.js +5 -5
  213. package/dist/graph/InputsEditor.js +10 -9
  214. package/dist/graph/MatrixGroup.js +2 -2
  215. package/dist/graph/ProblemPageLink.d.ts +9 -0
  216. package/dist/graph/ProblemPageLink.js +21 -0
  217. package/dist/graph/ProblemsButton.js +26 -16
  218. package/dist/graph/Reveal.js +1 -1
  219. package/dist/graph/RunWarningsList.js +21 -12
  220. package/dist/graph/ShortcutsButton.js +25 -8
  221. package/dist/graph/StepSummaries.js +1 -1
  222. package/dist/graph/TreeView.js +2 -2
  223. package/dist/graph/WorkflowSettingsDialog.js +3 -3
  224. package/dist/graph/editorApi.d.ts +10 -0
  225. package/dist/graph/editorFields.js +3 -3
  226. package/dist/graph/editorPrimitives.js +1 -1
  227. package/dist/graph/editorRows.js +8 -6
  228. package/dist/graph/editorStrings.d.ts +1 -0
  229. package/dist/graph/editorStrings.js +1 -0
  230. package/dist/graph/fieldProblems.js +2 -2
  231. package/dist/graph/inputRefs.js +7 -6
  232. package/dist/graph/runWarnings.d.ts +12 -1
  233. package/dist/graph/stepWith.js +2 -2
  234. package/dist/index.d.ts +30 -21
  235. package/dist/index.js +20 -12
  236. package/dist/list/ActionToolbar.d.ts +4 -0
  237. package/dist/list/ActionToolbar.js +35 -12
  238. package/dist/list/ListFilterBar.d.ts +42 -0
  239. package/dist/list/ListFilterBar.js +789 -0
  240. package/dist/list/ListPage.d.ts +42 -4
  241. package/dist/list/ListPage.js +56 -22
  242. package/dist/list/ListTable.d.ts +27 -3
  243. package/dist/list/ListTable.js +48 -23
  244. package/dist/list/ListToolbar.d.ts +31 -0
  245. package/dist/list/ListToolbar.js +43 -0
  246. package/dist/list/ListViewControls.d.ts +8 -4
  247. package/dist/list/ListViewControls.js +22 -14
  248. package/dist/list/UserHoverCard.d.ts +8 -2
  249. package/dist/list/UserHoverCard.js +26 -13
  250. package/dist/list/filterModel.d.ts +122 -0
  251. package/dist/list/filterModel.js +308 -0
  252. package/dist/list/index.d.ts +6 -2
  253. package/dist/list/index.js +6 -2
  254. package/dist/list/listSearch.d.ts +1 -1
  255. package/dist/list/listSearch.js +8 -4
  256. package/dist/list/listView.d.ts +24 -2
  257. package/dist/list/listView.js +47 -45
  258. package/dist/list/rowMenu.d.ts +10 -5
  259. package/dist/list/rowMenu.js +17 -7
  260. package/dist/list/useListFilters.d.ts +68 -0
  261. package/dist/list/useListFilters.js +252 -0
  262. package/dist/logviewer/LogViewer.js +4 -4
  263. package/dist/styles/theme.css +94 -0
  264. package/dist/styles.css +1 -1
  265. package/package.json +11 -11
  266. package/dist/assets/yaml.worker-k9AdOqzf.js +0 -1441
  267. package/dist/components/fullscreen.d.ts +0 -4
  268. package/dist/components/fullscreen.js +0 -18
@@ -1,23 +1,36 @@
1
- import type { ReactNode } from 'react';
2
- import { type SegmentLayout } from './segmented.js';
1
+ import type { HTMLAttributes, ReactNode } from 'react';
2
+ import { type SegmentLayout, type SegmentTone } from './segmented.js';
3
3
  export interface SegmentedOption<T extends string> {
4
4
  value: T;
5
5
  label: string;
6
6
  icon?: ReactNode;
7
7
  /** Beside the label, or in the corner when only the icon shows. */
8
8
  badge?: ReactNode;
9
+ /** How many things the choice holds, as a pill after the label. */
10
+ count?: number | undefined;
11
+ /** Colors the label and the count, for a choice that needs attention. */
12
+ tone?: SegmentTone | undefined;
13
+ /** Can't be chosen now; it still shows, and the rest still work. */
14
+ disabled?: boolean | undefined;
9
15
  testId?: string;
10
16
  }
17
+ /** What else reaches the group's root element, such as `onContextMenu` for a
18
+ * menu on the whole control, `id` or `aria-describedby`. Its look and its
19
+ * value stay the control's own. */
20
+ export type SegmentedControlRootProps = Omit<HTMLAttributes<HTMLDivElement>, 'children' | 'className' | 'style' | 'defaultValue' | 'onChange' | 'dir' | 'aria-label'>;
11
21
  /** A few mutually exclusive choices side by side, one always current, such as
12
22
  * a time range or what to group by. To move between views or pages, use
13
23
  * `Tabs` with `variant="segmented"`, which looks the same. To filter a list
14
24
  * by values that may all be off, or several at once, use `ToggleGroup`. Name
15
25
  * it with `label`, or leave that out inside a `Field group`, whose legend
16
26
  * names it. */
17
- export declare function SegmentedControl<T extends string>({ label, options, value, onValueChange, fill, iconOnly, testId, }: SegmentLayout & {
27
+ export declare function SegmentedControl<T extends string>({ label, options, value, onValueChange, fill, iconOnly, size, disabled, testId, ...rest }: SegmentedControlRootProps & SegmentLayout & {
18
28
  label?: string | undefined;
19
29
  options: SegmentedOption<T>[];
20
30
  value: T;
21
31
  onValueChange?: (value: T) => void;
32
+ /** None of the choices can be changed now, such as for a reader without
33
+ * the right to; the current one still shows. */
34
+ disabled?: boolean | undefined;
22
35
  testId?: string;
23
36
  }): import("react").JSX.Element;
@@ -10,16 +10,19 @@ import { ToggleGroup } from "@base-ui/react/toggle-group";
10
10
  * by values that may all be off, or several at once, use `ToggleGroup`. Name
11
11
  * it with `label`, or leave that out inside a `Field group`, whose legend
12
12
  * names it. */
13
- function SegmentedControl({ label, options, value, onValueChange, fill = false, iconOnly = false, testId }) {
13
+ function SegmentedControl({ label, options, value, onValueChange, fill = false, iconOnly = false, size = "md", disabled = false, testId, ...rest }) {
14
14
  const layout = {
15
15
  fill,
16
- iconOnly
16
+ iconOnly,
17
+ size
17
18
  };
18
19
  return /* @__PURE__ */ jsx(ToggleGroup, {
20
+ ...rest,
19
21
  "aria-label": label,
20
22
  "data-testid": testId,
21
23
  className: segmentGroupClassName(layout),
22
24
  orientation: iconOnly ? "vertical" : "horizontal",
25
+ disabled,
23
26
  value: [value],
24
27
  onValueChange: ([next]) => {
25
28
  if (next !== void 0) onValueChange?.(next);
@@ -30,8 +33,9 @@ function SegmentedControl({ label, options, value, onValueChange, fill = false,
30
33
  disabled: !iconOnly,
31
34
  children: /* @__PURE__ */ jsx(Toggle, {
32
35
  value: option.value,
36
+ disabled: option.disabled,
33
37
  "data-testid": option.testId,
34
- className: segmentClassName(option.value === value, layout),
38
+ className: segmentClassName(option.value === value, layout, option.tone),
35
39
  children: /* @__PURE__ */ jsx(SegmentContent, {
36
40
  ...option,
37
41
  iconOnly
@@ -1,11 +1,15 @@
1
1
  import { Select as BaseSelect } from '@base-ui/react/select';
2
- import { type ReactElement, type ReactNode } from 'react';
2
+ import { type KeyboardEventHandler, type ReactElement, type ReactNode } from 'react';
3
3
  import { type ComboboxItem } from './comboboxItems.js';
4
4
  import { type FieldBoxSize } from './fieldBox.js';
5
5
  /** An option of a Select: the same shape as a Combobox's, so a list moves between them as is. */
6
6
  export type SelectItem<Value> = ComboboxItem<Value>;
7
- export type SelectProps<Value, Multiple extends boolean | undefined = false> = Omit<BaseSelect.Root.Props<Value, Multiple>, 'items' | 'children'> & {
7
+ type SelectValueChange<Value, Multiple extends boolean | undefined> = (value: Multiple extends true ? Value[] : Value, details: BaseSelect.Root.ChangeEventDetails) => void;
8
+ export type SelectProps<Value, Multiple extends boolean | undefined = false> = Omit<BaseSelect.Root.Props<Value, Multiple>, 'items' | 'children' | 'onValueChange'> & {
8
9
  items: readonly SelectItem<Value>[];
10
+ /** Called with the value picked. A single Select never passes null unless an item's value is
11
+ * null, such as a "None" option, so the value is always one of the items'. */
12
+ onValueChange?: SelectValueChange<Value, Multiple> | undefined;
9
13
  placeholder?: string | undefined;
10
14
  /** Applied to the trigger. */
11
15
  className?: string | undefined;
@@ -22,10 +26,22 @@ export type SelectProps<Value, Multiple extends boolean | undefined = false> = O
22
26
  /** `sm` for dense places such as toolbars and table cells, `lg` for a form that stands alone,
23
27
  * such as sign-in. */
24
28
  size?: FieldBoxSize | undefined;
29
+ /** `fill` takes the width of its row, as a form's fields do; `content` takes the width of its
30
+ * longest label, as in a toolbar or beside text. By default it fills inside a Field and
31
+ * sizes to its content anywhere else. */
32
+ width?: 'fill' | 'content' | undefined;
33
+ /** Why the field can't be changed, with `disabled`: shown as a tooltip and read after its
34
+ * name. The field stays focusable, so the keyboard reaches the reason too. */
35
+ disabledReason?: string | undefined;
36
+ /** The edge of the field the open list lines up with, when the list is wider. */
37
+ align?: 'start' | 'end' | undefined;
38
+ /** On the trigger, such as to keep a key from a host's own shortcuts. */
39
+ onKeyDown?: KeyboardEventHandler<HTMLElement> | undefined;
25
40
  /** The item a person is on as they move through the open list, then undefined once it
26
41
  * closes, such as to preview a theme before it is chosen. */
27
42
  onItemHighlighted?: ((value: Value | undefined) => void) | undefined;
28
43
  };
29
44
  /** Picks one value, or several with `multiple`, from a short list. Use
30
45
  * Combobox when the list is long enough to need filtering. */
31
- export declare function Select<Value, Multiple extends boolean | undefined = false>({ items, placeholder, className, 'aria-label': ariaLabel, 'aria-labelledby': labelledBy, 'aria-describedby': describedBy, 'aria-invalid': invalid, 'aria-required': required, trigger, triggerTooltip, size, onItemHighlighted, ...rootProps }: SelectProps<Value, Multiple>): import("react").JSX.Element;
46
+ export declare function Select<Value, Multiple extends boolean | undefined = false>({ items, placeholder, className, 'aria-label': ariaLabel, 'aria-labelledby': labelledBy, 'aria-describedby': describedBy, 'aria-invalid': invalid, 'aria-required': required, trigger, triggerTooltip, size, width, disabledReason, align, onKeyDown, onItemHighlighted, onValueChange, ...rootProps }: SelectProps<Value, Multiple>): import("react").JSX.Element;
47
+ export {};
@@ -1,101 +1,147 @@
1
1
  import { cx } from "../cx.js";
2
2
  import { CheckIcon, ChevronDownIcon } from "../icons.js";
3
3
  import { panelClassName, positionerClassName } from "./floating.js";
4
- import { useFullscreenContainer } from "./fullscreen.js";
4
+ import { usePopupContainer } from "./popupContainer.js";
5
5
  import { Tooltip } from "./Tooltip.js";
6
6
  import { fieldBox } from "./fieldBox.js";
7
- import { optionNaming, pickerItemClassName } from "./comboboxItems.js";
7
+ import { useFieldControl } from "./Field.js";
8
+ import { optionNaming, pickerEndClassName, pickerItemClassName } from "./comboboxItems.js";
8
9
  import { OptionDescription } from "./OptionDescription.js";
9
- import { jsx, jsxs } from "react/jsx-runtime";
10
10
  import { useId } from "react";
11
+ import { Fragment as Fragment$1, jsx, jsxs } from "react/jsx-runtime";
11
12
  import { Select } from "@base-ui/react/select";
12
13
  //#region src/components/Select.tsx
13
14
  var triggerClassName = "flex cursor-pointer items-center justify-between gap-2 pr-1.5 text-left";
15
+ var explainedDisabledClassName = "cursor-not-allowed hover:border-(--theme-border-field) bg-(--theme-input-disabled-bg) text-(--theme-placeholder)";
14
16
  /** Picks one value, or several with `multiple`, from a short list. Use
15
17
  * Combobox when the list is long enough to need filtering. */
16
- function Select$1({ items, placeholder, className, "aria-label": ariaLabel, "aria-labelledby": labelledBy, "aria-describedby": describedBy, "aria-invalid": invalid, "aria-required": required, trigger, triggerTooltip, size = "md", onItemHighlighted, ...rootProps }) {
17
- const fullscreen = useFullscreenContainer();
18
+ function Select$1({ items, placeholder, className, "aria-label": ariaLabel, "aria-labelledby": labelledBy, "aria-describedby": describedBy, "aria-invalid": invalid, "aria-required": required, trigger, triggerTooltip, size = "md", width, disabledReason, align = "start", onKeyDown, onItemHighlighted, onValueChange, ...rootProps }) {
19
+ const portal = usePopupContainer();
18
20
  const uid = useId();
21
+ const inField = useFieldControl() !== null;
22
+ const content = (width ?? (inField ? "fill" : "content")) === "content";
19
23
  const labelOf = (value) => items.find((item) => Object.is(item.value, value))?.label;
24
+ const explained = Boolean(rootProps.disabled && disabledReason);
25
+ const reasonId = `${uid}reason`;
20
26
  const triggerProps = {
21
27
  "aria-label": ariaLabel,
22
28
  "aria-labelledby": labelledBy,
23
- "aria-describedby": describedBy,
29
+ "aria-describedby": cx(describedBy, explained && reasonId) || void 0,
24
30
  "aria-invalid": invalid || void 0,
25
- "aria-required": required || void 0
31
+ "aria-required": required || void 0,
32
+ "aria-disabled": explained || void 0,
33
+ onKeyDown
26
34
  };
35
+ const nullable = items.some((item) => item.value === null);
36
+ const tip = explained ? disabledReason : triggerTooltip;
27
37
  return /* @__PURE__ */ jsxs(Select.Root, {
28
38
  items,
29
39
  ...rootProps,
40
+ disabled: explained ? false : rootProps.disabled,
41
+ readOnly: explained || rootProps.readOnly,
42
+ ...explained && { open: false },
43
+ onValueChange: (next, details) => {
44
+ if (next === null && !rootProps.multiple && !nullable) return;
45
+ onValueChange?.(next, details);
46
+ },
30
47
  onOpenChange: (open, details) => {
31
48
  rootProps.onOpenChange?.(open, details);
32
49
  if (!open) onItemHighlighted?.(void 0);
33
50
  },
34
- children: [trigger ? /* @__PURE__ */ jsx(Tooltip, {
35
- content: triggerTooltip,
36
- children: /* @__PURE__ */ jsx(Select.Trigger, {
37
- ...triggerProps,
38
- render: trigger
39
- })
40
- }) : /* @__PURE__ */ jsxs(Select.Trigger, {
41
- ...triggerProps,
42
- className: cx(fieldBox({ size }), triggerClassName, className),
43
- children: [/* @__PURE__ */ jsx(Select.Value, {
44
- placeholder,
45
- className: "truncate data-placeholder:text-(--theme-placeholder)",
46
- children: rootProps.multiple ? (values) => values.length > 0 ? values.map(labelOf).join(", ") : placeholder : void 0
47
- }), /* @__PURE__ */ jsx(Select.Icon, {
48
- className: "shrink-0 text-(--theme-muted-text-color)",
49
- children: /* @__PURE__ */ jsx(ChevronDownIcon, { "aria-hidden": "true" })
50
- })]
51
- }), /* @__PURE__ */ jsx(Select.Portal, {
52
- container: fullscreen,
53
- children: /* @__PURE__ */ jsx(Select.Positioner, {
54
- alignItemWithTrigger: false,
55
- sideOffset: 4,
56
- className: positionerClassName,
57
- children: /* @__PURE__ */ jsx(Select.Popup, {
58
- className: cx("min-w-(--anchor-width) max-w-[min(20rem,var(--available-width))]", panelClassName),
59
- children: /* @__PURE__ */ jsx(Select.List, {
60
- className: cx("max-h-[min(15rem,var(--available-height))] overflow-y-auto", "p-1"),
61
- children: items.map((item, index) => /* @__PURE__ */ jsxs(Select.Item, {
62
- value: item.value,
63
- disabled: item.disabled,
64
- ...optionNaming(`${uid}${index}`, item),
65
- onFocus: onItemHighlighted && (() => onItemHighlighted(item.value)),
66
- className: pickerItemClassName,
67
- children: [
68
- item.icon && /* @__PURE__ */ jsx("span", {
69
- className: "flex shrink-0 items-center",
70
- children: item.icon
71
- }),
72
- /* @__PURE__ */ jsxs("span", {
73
- className: "flex min-w-0 flex-col",
74
- children: [/* @__PURE__ */ jsxs("span", {
75
- className: "flex min-w-0 items-center gap-2",
76
- children: [/* @__PURE__ */ jsx(Select.ItemText, {
77
- id: `${uid}${index}label`,
78
- className: "truncate",
79
- children: item.label
80
- }), item.badge]
81
- }), /* @__PURE__ */ jsx(OptionDescription, {
82
- id: `${uid}${index}description`,
83
- item
84
- })]
85
- }),
86
- /* @__PURE__ */ jsx(Select.ItemIndicator, {
87
- className: "ml-auto flex shrink-0 items-center",
88
- children: /* @__PURE__ */ jsx(CheckIcon, {
89
- "aria-hidden": "true",
90
- className: "size-3.5"
51
+ children: [
52
+ trigger ? /* @__PURE__ */ jsx(Tooltip, {
53
+ content: tip,
54
+ children: /* @__PURE__ */ jsx(Select.Trigger, {
55
+ ...triggerProps,
56
+ render: trigger
57
+ })
58
+ }) : /* @__PURE__ */ jsx(Tooltip, {
59
+ content: tip,
60
+ children: /* @__PURE__ */ jsxs(Select.Trigger, {
61
+ ...triggerProps,
62
+ className: cx(fieldBox({ size }), triggerClassName, content && "w-fit max-w-full", explained && explainedDisabledClassName, className),
63
+ children: [/* @__PURE__ */ jsx(Select.Value, {
64
+ placeholder,
65
+ className: cx("truncate data-placeholder:text-(--theme-placeholder)", content && !rootProps.multiple && "grid"),
66
+ children: rootProps.multiple ? (values) => values.length > 0 ? values.map(labelOf).join(", ") : placeholder : content ? (value) => /* @__PURE__ */ jsxs(Fragment$1, { children: [/* @__PURE__ */ jsx("span", {
67
+ className: "col-start-1 row-start-1 truncate",
68
+ children: (value === null ? void 0 : labelOf(value)) ?? placeholder
69
+ }), [placeholder, ...items.map((item) => item.label)].map((label, index) => label && /* @__PURE__ */ jsx("span", {
70
+ "aria-hidden": "true",
71
+ className: "invisible col-start-1 row-start-1 h-0 overflow-hidden whitespace-nowrap",
72
+ children: label
73
+ }, index))] }) : void 0
74
+ }), /* @__PURE__ */ jsx(Select.Icon, {
75
+ className: "shrink-0 text-(--theme-muted-text-color)",
76
+ children: /* @__PURE__ */ jsx(ChevronDownIcon, { "aria-hidden": "true" })
77
+ })]
78
+ })
79
+ }),
80
+ explained && /* @__PURE__ */ jsx("span", {
81
+ id: reasonId,
82
+ hidden: true,
83
+ children: disabledReason
84
+ }),
85
+ /* @__PURE__ */ jsx(Select.Portal, {
86
+ ...portal,
87
+ children: /* @__PURE__ */ jsx(Select.Positioner, {
88
+ alignItemWithTrigger: false,
89
+ align,
90
+ sideOffset: 4,
91
+ className: positionerClassName,
92
+ children: /* @__PURE__ */ jsx(Select.Popup, {
93
+ className: cx("min-w-(--anchor-width) max-w-[min(20rem,var(--available-width))]", panelClassName),
94
+ children: /* @__PURE__ */ jsx(Select.List, {
95
+ className: cx("max-h-[min(15rem,var(--available-height))] overflow-y-auto", "p-1"),
96
+ children: items.map((item, index) => /* @__PURE__ */ jsxs(Select.Item, {
97
+ value: item.value,
98
+ disabled: item.disabled,
99
+ ...optionNaming(`${uid}${index}`, item),
100
+ onFocus: onItemHighlighted && (() => onItemHighlighted(item.value)),
101
+ className: pickerItemClassName,
102
+ children: [
103
+ item.icon && /* @__PURE__ */ jsx("span", {
104
+ className: "flex shrink-0 items-center",
105
+ children: item.icon
106
+ }),
107
+ /* @__PURE__ */ jsxs("span", {
108
+ className: "flex min-w-0 flex-col",
109
+ children: [/* @__PURE__ */ jsxs("span", {
110
+ className: "flex min-w-0 items-center gap-2",
111
+ children: [/* @__PURE__ */ jsx(Select.ItemText, {
112
+ id: `${uid}${index}label`,
113
+ className: "truncate",
114
+ children: item.label
115
+ }), item.badge]
116
+ }), /* @__PURE__ */ jsx(OptionDescription, {
117
+ id: `${uid}${index}description`,
118
+ item
119
+ })]
120
+ }),
121
+ /* @__PURE__ */ jsxs("span", {
122
+ className: pickerEndClassName,
123
+ children: [item.hint && /* @__PURE__ */ jsx("span", {
124
+ id: `${uid}${index}hint`,
125
+ className: "text-xs tabular-nums text-(--theme-muted-text-color)",
126
+ children: item.hint
127
+ }), /* @__PURE__ */ jsx("span", {
128
+ className: cx("flex items-center", item.hint && "w-3.5"),
129
+ children: /* @__PURE__ */ jsx(Select.ItemIndicator, {
130
+ className: "flex items-center",
131
+ children: /* @__PURE__ */ jsx(CheckIcon, {
132
+ "aria-hidden": "true",
133
+ className: "size-3.5"
134
+ })
135
+ })
136
+ })]
91
137
  })
92
- })
93
- ]
94
- }, String(item.value)))
138
+ ]
139
+ }, String(item.value)))
140
+ })
95
141
  })
96
142
  })
97
143
  })
98
- })]
144
+ ]
99
145
  });
100
146
  }
101
147
  //#endregion
@@ -0,0 +1,10 @@
1
+ import { type ReactNode } from 'react';
2
+ /** Text to read and copy from in part, such as a run's YAML or a log: selecting some of it
3
+ * shows a Copy button under the end of the selection, which copies just that and says so.
4
+ * The button is a real one inside the block, so Tab reaches it after the text; a selection
5
+ * made from the keyboard shows it too, and Escape or a press elsewhere puts it away. The
6
+ * browser's own copy keeps working. */
7
+ export declare function SelectionCopy({ children, className, }: {
8
+ children: ReactNode;
9
+ className?: string | undefined;
10
+ }): import("react").JSX.Element;
@@ -0,0 +1,105 @@
1
+ import { cx } from "../cx.js";
2
+ import { buttonClasses } from "./buttonClasses.js";
3
+ import { CopyIcon } from "../icons.js";
4
+ import { useStrings } from "./Provider.js";
5
+ import { useCopy } from "./useCopy.js";
6
+ import { useCallback, useEffect, useRef, useState } from "react";
7
+ import { jsx, jsxs } from "react/jsx-runtime";
8
+ //#region src/components/SelectionCopy.tsx
9
+ var EDGE = 40;
10
+ /** Text to read and copy from in part, such as a run's YAML or a log: selecting some of it
11
+ * shows a Copy button under the end of the selection, which copies just that and says so.
12
+ * The button is a real one inside the block, so Tab reaches it after the text; a selection
13
+ * made from the keyboard shows it too, and Escape or a press elsewhere puts it away. The
14
+ * browser's own copy keeps working. */
15
+ function SelectionCopy({ children, className }) {
16
+ const { common: t } = useStrings();
17
+ const { copy } = useCopy();
18
+ const root = useRef(null);
19
+ const pointerDown = useRef(false);
20
+ const [place, setPlace] = useState(null);
21
+ const read = useCallback(() => {
22
+ const el = root.current;
23
+ const selection = typeof window === "undefined" ? null : window.getSelection();
24
+ if (!el || !selection || selection.isCollapsed || selection.rangeCount === 0) {
25
+ setPlace(null);
26
+ return;
27
+ }
28
+ const range = selection.getRangeAt(0);
29
+ const text = selection.toString();
30
+ if (!el.contains(range.commonAncestorContainer) || !text.trim()) {
31
+ setPlace(null);
32
+ return;
33
+ }
34
+ const rects = range.getClientRects();
35
+ const end = rects[rects.length - 1] ?? range.getBoundingClientRect();
36
+ const box = el.getBoundingClientRect();
37
+ const x = end.right - box.left;
38
+ setPlace({
39
+ x: box.width > 80 ? Math.min(Math.max(x, EDGE), box.width - EDGE) : box.width / 2,
40
+ y: end.bottom - box.top + 4,
41
+ text
42
+ });
43
+ }, []);
44
+ useEffect(() => {
45
+ const onChange = () => {
46
+ if (!pointerDown.current) read();
47
+ };
48
+ const onUp = () => {
49
+ if (pointerDown.current) {
50
+ pointerDown.current = false;
51
+ read();
52
+ }
53
+ };
54
+ document.addEventListener("selectionchange", onChange);
55
+ document.addEventListener("pointerup", onUp);
56
+ return () => {
57
+ document.removeEventListener("selectionchange", onChange);
58
+ document.removeEventListener("pointerup", onUp);
59
+ };
60
+ }, [read]);
61
+ useEffect(() => {
62
+ if (!place) return;
63
+ const onKey = (e) => {
64
+ if (e.key === "Escape") setPlace(null);
65
+ };
66
+ document.addEventListener("keydown", onKey);
67
+ return () => document.removeEventListener("keydown", onKey);
68
+ }, [place]);
69
+ const copySelection = async () => {
70
+ if (!place) return;
71
+ if (await copy(place.text)) {
72
+ window.getSelection()?.removeAllRanges();
73
+ setPlace(null);
74
+ }
75
+ };
76
+ return /* @__PURE__ */ jsxs("div", {
77
+ ref: root,
78
+ className: cx("relative", className),
79
+ onPointerDown: (e) => {
80
+ if (!e.target.closest?.("[data-selection-copy]")) {
81
+ pointerDown.current = true;
82
+ setPlace(null);
83
+ }
84
+ },
85
+ onScrollCapture: () => setPlace(null),
86
+ children: [children, place && /* @__PURE__ */ jsxs("button", {
87
+ type: "button",
88
+ "data-selection-copy": "",
89
+ "aria-label": t.copySelection,
90
+ onMouseDown: (e) => e.preventDefault(),
91
+ onClick: () => void copySelection(),
92
+ className: cx(buttonClasses({
93
+ variant: "secondary",
94
+ size: "xs"
95
+ }), "absolute z-10 -translate-x-1/2 shadow-(--theme-shadow)"),
96
+ style: {
97
+ left: place.x,
98
+ top: place.y
99
+ },
100
+ children: [/* @__PURE__ */ jsx(CopyIcon, { "aria-hidden": "true" }), t.copy]
101
+ })]
102
+ });
103
+ }
104
+ //#endregion
105
+ export { SelectionCopy };
@@ -1,7 +1,7 @@
1
1
  import { cx } from "../cx.js";
2
2
  import { Radio } from "./Radio.js";
3
- import { jsx, jsxs } from "react/jsx-runtime";
4
3
  import { useId } from "react";
4
+ import { jsx, jsxs } from "react/jsx-runtime";
5
5
  //#region src/components/SettingModeOption.tsx
6
6
  /** A named and described choice in a SettingsCard, picking between modes such
7
7
  * as default or custom. Stack them in a `RadioGroup`, which holds the value. */
@@ -1,6 +1,6 @@
1
1
  import { cx } from "../cx.js";
2
- import { jsx, jsxs } from "react/jsx-runtime";
3
2
  import { createContext, useContext } from "react";
3
+ import { jsx, jsxs } from "react/jsx-runtime";
4
4
  //#region src/components/SettingsCard.tsx
5
5
  var HeadingLevel = createContext(3);
6
6
  /** A page's settings, grouped: a titled panel of SettingRows, each ruled off from
@@ -1,6 +1,6 @@
1
1
  import { cx } from "../cx.js";
2
- import { positionKeys } from "./keys.js";
3
2
  import { useStrings } from "./Provider.js";
3
+ import { positionKeys } from "./keys.js";
4
4
  import { jsx, jsxs } from "react/jsx-runtime";
5
5
  //#region src/components/Skeleton.tsx
6
6
  /** The shape of content still loading. Hidden from assistive technology, so
@@ -1,25 +1,70 @@
1
- import type { ReactNode } from 'react';
1
+ import type { ReactElement, ReactNode } from 'react';
2
2
  import { type Tone } from './tone.js';
3
- /** A badge's tone. */
4
- export type BadgeVariant = Tone;
5
- interface StatusBadgeProps {
3
+ /** A badge's tone: a status, or the theme's accent for something set apart that
4
+ * isn't a status, such as "New". */
5
+ export type BadgeVariant = Tone | 'accent';
6
+ /** How loud a badge is: `soft` tints it, `solid` fills it for the one thing that
7
+ * must catch the eye, and `outline` leaves only its edge and text. */
8
+ export type BadgeEmphasis = 'soft' | 'solid' | 'outline';
9
+ /** A badge's outline: a `pill`, or a squarer `tag` for a label such as "Beta". */
10
+ export type BadgeShape = 'pill' | 'tag';
11
+ declare const sizeClasses: {
12
+ readonly sm: 'gap-1 py-px text-[10px] leading-3.5';
13
+ readonly md: 'gap-1.5 py-0.5 text-[11px] leading-4';
14
+ };
15
+ export type BadgeSize = keyof typeof sizeClasses;
16
+ export interface StatusBadgeProps {
6
17
  /** Badge content */
7
18
  children: ReactNode;
8
19
  /** Visual variant */
9
- variant?: BadgeVariant;
20
+ variant?: BadgeVariant | undefined;
21
+ /** `soft` (the default) tints it; `solid` fills it; `outline` draws only its edge. */
22
+ emphasis?: BadgeEmphasis | undefined;
23
+ /** `pill` (the default), or `tag` for a squarer label such as "Preview". */
24
+ shape?: BadgeShape | undefined;
25
+ /** Uppercase, tracked letters, for a short label such as "Beta". */
26
+ caps?: boolean | undefined;
27
+ /** Cuts a long label off with an ellipsis instead of growing past its cell. */
28
+ truncate?: boolean | undefined;
10
29
  /** Show animated pulse indicator */
11
- pulse?: boolean;
30
+ pulse?: boolean | undefined;
12
31
  /** Show a still indicator in the variant's color */
13
- dot?: boolean;
32
+ dot?: boolean | undefined;
14
33
  /** Size */
15
- size?: 'sm' | 'md';
34
+ size?: BadgeSize | undefined;
35
+ /** Renders the badge as this element, such as a link to what it names. */
36
+ render?: ReactElement | undefined;
16
37
  /** Additional class */
17
- className?: string;
38
+ className?: string | undefined;
18
39
  }
19
40
  /** A line of text in a variant's color, for a status that stands beside a
20
41
  * dot rather than inside a badge. */
21
42
  export declare function statusTextClass(variant: BadgeVariant): string;
22
- export declare function StatusBadge({ children, variant, pulse, dot, size, className, }: StatusBadgeProps): import("react").JSX.Element;
43
+ /** A short status or label in a tone, such as "Running" or "Preview". */
44
+ export declare function StatusBadge({ children, variant, emphasis, shape, caps, truncate, pulse, dot, size, render, className, }: StatusBadgeProps): ReactElement<unknown, string | import("react").JSXElementConstructor<any>>;
45
+ export interface CountBadgeProps {
46
+ count: number;
47
+ /** Above it, the count reads as `max` and a plus, such as "99+". */
48
+ max?: number | undefined;
49
+ /** Its tone, `accent` by default. A host with a color of its own, such as one
50
+ * for work waiting on an agent, passes it in `className`. */
51
+ variant?: BadgeVariant | undefined;
52
+ /** `solid` (the default) for a count that asks for attention, such as unread
53
+ * messages; `soft` for one that only informs, such as a tab's total. */
54
+ emphasis?: Exclude<BadgeEmphasis, 'outline'> | undefined;
55
+ size?: BadgeSize | undefined;
56
+ /** Read after the number by assistive technology, such as "unread", when the
57
+ * text around it doesn't say what it counts. */
58
+ label?: string | undefined;
59
+ /** Shows a zero; otherwise a count of zero renders nothing. */
60
+ showZero?: boolean | undefined;
61
+ /** The locale the number is written in; the browser's own without it. */
62
+ locale?: string | undefined;
63
+ className?: string | undefined;
64
+ }
65
+ /** A number beside a link or tab, such as unread messages or items waiting,
66
+ * capped at `max` so a big count doesn't widen what it sits in. */
67
+ export declare function CountBadge({ count, max, variant, emphasis, size, label, showZero, locale, className, }: CountBadgeProps): import("react").JSX.Element | null;
23
68
  interface StatusDotProps {
24
69
  variant?: BadgeVariant;
25
70
  pulse?: boolean;