@parallelworks/ui 0.17.0 → 0.19.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 (169) hide show
  1. package/README.md +86 -6
  2. package/dist/ai/adapter/memoryStore.d.ts +8 -0
  3. package/dist/ai/adapter/mock/index.d.ts +2 -0
  4. package/dist/ai/adapter/mock/index.js +81 -0
  5. package/dist/ai/adapter/mock/mockAdapter.d.ts +4 -0
  6. package/dist/ai/adapter/openai/createOpenAIStream.d.ts +9 -0
  7. package/dist/ai/adapter/openai/errors.d.ts +3 -0
  8. package/dist/ai/adapter/openai/index.d.ts +6 -0
  9. package/dist/ai/adapter/openai/index.js +334 -0
  10. package/dist/ai/adapter/openai/openaiAdapter.d.ts +9 -0
  11. package/dist/ai/adapter/openai/responses.d.ts +4 -0
  12. package/dist/ai/adapter/openai/sse.d.ts +24 -0
  13. package/dist/ai/adapter/openai/wire.d.ts +40 -0
  14. package/dist/ai/adapter/types.d.ts +131 -0
  15. package/dist/ai/agent/classifier.d.ts +2 -0
  16. package/dist/ai/agent/diff.d.ts +35 -0
  17. package/dist/ai/agent/diffHighlight.d.ts +6 -0
  18. package/dist/ai/agent/index.d.ts +6 -0
  19. package/dist/ai/agent/permissions.d.ts +11 -0
  20. package/dist/ai/agent/toolfmt.d.ts +18 -0
  21. package/dist/ai/agent/transcript.d.ts +38 -0
  22. package/dist/ai/ai.css +325 -0
  23. package/dist/ai/components/AllocationSelector.d.ts +4 -0
  24. package/dist/ai/components/AttachmentManager.d.ts +1 -0
  25. package/dist/ai/components/AttachmentUpload.d.ts +24 -0
  26. package/dist/ai/components/BlockedGroupBanner.d.ts +1 -0
  27. package/dist/ai/components/BranchNavigator.d.ts +8 -0
  28. package/dist/ai/components/ChatEmptyState.d.ts +3 -0
  29. package/dist/ai/components/ChatInput.d.ts +45 -0
  30. package/dist/ai/components/ChatLayout.d.ts +5 -0
  31. package/dist/ai/components/ChatMessage.d.ts +24 -0
  32. package/dist/ai/components/ChatMessageList.d.ts +35 -0
  33. package/dist/ai/components/ChatSidebar.d.ts +5 -0
  34. package/dist/ai/components/ChatThread.d.ts +3 -0
  35. package/dist/ai/components/ComposerChrome.d.ts +18 -0
  36. package/dist/ai/components/ComposerFrame.d.ts +16 -0
  37. package/dist/ai/components/DragOverlay.d.ts +5 -0
  38. package/dist/ai/components/ModelSelector.d.ts +6 -0
  39. package/dist/ai/components/ShareDialog.d.ts +11 -0
  40. package/dist/ai/components/SlashMenu.d.ts +28 -0
  41. package/dist/ai/components/agent/ActivityLine.d.ts +21 -0
  42. package/dist/ai/components/agent/AgentMessageParts.d.ts +54 -0
  43. package/dist/ai/components/agent/PermissionPicker.d.ts +11 -0
  44. package/dist/ai/components/attachmentKeys.d.ts +4 -0
  45. package/dist/ai/core/ChatProvider.d.ts +66 -0
  46. package/dist/ai/core/KeyboardShortcutsProvider.d.ts +5 -0
  47. package/dist/ai/core/chatReducer.d.ts +114 -0
  48. package/dist/ai/core/config.d.ts +47 -0
  49. package/dist/ai/core/events.d.ts +1 -0
  50. package/dist/ai/core/exportConversation.d.ts +4 -0
  51. package/dist/ai/core/greeting.d.ts +3 -0
  52. package/dist/ai/core/parts.d.ts +11 -0
  53. package/dist/ai/core/useDragDrop.d.ts +14 -0
  54. package/dist/ai/core/useKeyboardShortcuts.d.ts +12 -0
  55. package/dist/ai/core/useSSEStream.d.ts +34 -0
  56. package/dist/ai/index.d.ts +40 -0
  57. package/dist/ai/index.js +6645 -0
  58. package/dist/ai/strings.d.ts +167 -0
  59. package/dist/ai/types.d.ts +236 -0
  60. package/dist/ai/ui/Avatar.d.ts +8 -0
  61. package/dist/ai/ui/Dropdown.d.ts +31 -0
  62. package/dist/ai/ui/Markdown.d.ts +8 -0
  63. package/dist/ai/ui/Notice.d.ts +21 -0
  64. package/dist/ai/ui/buttons.d.ts +1 -0
  65. package/dist/ai/ui/codeBreaks.d.ts +16 -0
  66. package/dist/ai/ui/prose.d.ts +1 -0
  67. package/dist/ai/ui/sidebar.d.ts +81 -0
  68. package/dist/ai/utils.d.ts +4 -0
  69. package/dist/assets/{editor.worker-CuBRIwi-.js → editor.worker-BmHUIVG4.js} +194 -163
  70. package/dist/assets/{json.worker-8ytS02vz.js → json.worker-D8bJ92nw.js} +384 -338
  71. package/dist/assets/{yaml.worker-DJC-VUcv.js → yaml.worker-C4gyGAko.js} +15657 -13823
  72. package/dist/chunks/{CodePreviewEditor-UAtnpmOV.js → CodePreviewEditor-YqQBz1YL.js} +2 -2
  73. package/dist/chunks/ConfirmModal-aOR4O1QE.js +79 -0
  74. package/dist/chunks/{lib-CUTRDpa6.js → FieldWrapper-Cszwg-4B.js} +52 -55
  75. package/dist/chunks/{CreateModal-BbV5cTj7.js → Markdown-CM-FenNE.js} +25 -97
  76. package/dist/chunks/Monaco-DJ8MW-Dq.js +110 -0
  77. package/dist/chunks/{PageHeader-MxuOs9cH.js → PageHeader-0kG_iypP.js} +170 -105
  78. package/dist/chunks/{Provider-DHmZ3v9i.js → Provider-CDYurraE.js} +60 -24
  79. package/dist/chunks/{SwitchToggle-BRQoEwLZ.js → SwitchToggle-DShNdcao.js} +143 -140
  80. package/dist/chunks/{Table-C6JdFFiJ.js → Table-DU2MW8xz.js} +6 -4
  81. package/dist/chunks/{Tooltip-n9w7Tkt1.js → Tooltip-K5HJr4_p.js} +32 -5
  82. package/dist/chunks/duration-BOv8Phl8.js +17 -0
  83. package/dist/chunks/{editor-mNznodJN.js → editor-Dk1rbV75.js} +33 -19
  84. package/dist/chunks/focus-D_iZJTW1.js +7 -0
  85. package/dist/chunks/{list-7k0eaI5N.js → list-CJm875m7.js} +497 -379
  86. package/dist/chunks/logviewer-BTKuQWzw.js +828 -0
  87. package/dist/chunks/memoryStore-CC91S5LP.js +152 -0
  88. package/dist/chunks/types-Yy0NrerF.js +11 -0
  89. package/dist/components/AddMenu.d.ts +1 -0
  90. package/dist/components/Avatar.d.ts +13 -0
  91. package/dist/components/Breadcrumbs.d.ts +1 -1
  92. package/dist/components/Dropdown.d.ts +3 -1
  93. package/dist/components/EmptyState.d.ts +1 -1
  94. package/dist/components/Indicator.d.ts +2 -2
  95. package/dist/components/Input.d.ts +1 -1
  96. package/dist/components/LetterBadge.d.ts +1 -1
  97. package/dist/components/MarkdownImpl.d.ts +1 -1
  98. package/dist/components/Provider.d.ts +18 -65
  99. package/dist/components/SettingRow.d.ts +1 -1
  100. package/dist/components/SettingsGroup.d.ts +1 -1
  101. package/dist/components/focus.d.ts +2 -0
  102. package/dist/components/keys.d.ts +12 -0
  103. package/dist/duration.d.ts +3 -0
  104. package/dist/editor/Monaco.d.ts +1 -20
  105. package/dist/editor/index.d.ts +2 -1
  106. package/dist/editor/index.js +2 -2
  107. package/dist/editor/yaml.d.ts +5 -0
  108. package/dist/engine.d.ts +98 -0
  109. package/dist/file-explorer/FileExplorer.d.ts +11 -2
  110. package/dist/file-explorer/FileExplorerContext.d.ts +1 -1
  111. package/dist/file-explorer/FilePreview/CodePreviewEditor.d.ts +1 -1
  112. package/dist/file-explorer/FilePreview/previewType.d.ts +1 -1
  113. package/dist/file-explorer/FileRow.d.ts +1 -1
  114. package/dist/file-explorer/helpers.d.ts +4 -4
  115. package/dist/file-explorer/index.d.ts +3 -3
  116. package/dist/file-explorer/index.js +632 -665
  117. package/dist/file-explorer/lib/types.d.ts +6 -1
  118. package/dist/file-explorer/lib/utils.d.ts +1 -3
  119. package/dist/file-explorer/useNearEnd.d.ts +1 -1
  120. package/dist/form/FieldWrapper.d.ts +2 -1
  121. package/dist/form/Fields/ResourceOptionIcon.d.ts +1 -1
  122. package/dist/form/Form.d.ts +7 -22
  123. package/dist/form/index.d.ts +11 -12
  124. package/dist/form/index.js +1333 -1454
  125. package/dist/form/lib.d.ts +6 -1
  126. package/dist/form/types/fieldComponentTypes.d.ts +4 -2
  127. package/dist/form/types/fieldTypes.d.ts +6 -20
  128. package/dist/form/useParsedOpts.d.ts +2 -2
  129. package/dist/form/utils/{slurmDuration.d.ts → duration.d.ts} +2 -2
  130. package/dist/{workflow → graph}/MatrixGroup.d.ts +2 -2
  131. package/dist/{workflow → graph}/index.d.ts +1 -1
  132. package/dist/{workflow → graph}/index.js +220 -185
  133. package/dist/{workflow → graph}/types.d.ts +3 -3
  134. package/dist/icons.d.ts +20 -21
  135. package/dist/icons.js +3 -3
  136. package/dist/index.d.ts +38 -39
  137. package/dist/index.js +355 -354
  138. package/dist/list/ListTable.d.ts +1 -1
  139. package/dist/list/ListViewControls.d.ts +2 -2
  140. package/dist/list/RowContextMenu.d.ts +9 -9
  141. package/dist/list/UserHoverCard.d.ts +45 -0
  142. package/dist/list/index.d.ts +9 -8
  143. package/dist/list/index.js +3 -3
  144. package/dist/logviewer/LogViewer.d.ts +1 -1
  145. package/dist/logviewer/index.d.ts +1 -0
  146. package/dist/logviewer/index.js +2 -742
  147. package/dist/logviewer/segments.d.ts +9 -0
  148. package/dist/styles/Geist-Variable.woff2 +0 -0
  149. package/dist/styles/GeistMono-Variable.woff2 +0 -0
  150. package/dist/styles/base.css +57 -0
  151. package/dist/styles/fonts.css +15 -0
  152. package/dist/styles/theme.css +9 -41
  153. package/dist/styles.css +1 -1
  154. package/dist/theme/index.js +2 -2
  155. package/package.json +45 -20
  156. package/LICENSE +0 -21
  157. package/dist/chunks/Monaco-DVyIpyv4.js +0 -1046
  158. package/dist/editor/usesGitlab.d.ts +0 -97
  159. package/dist/form/Fields/BucketReadOnlyField.d.ts +0 -7
  160. package/dist/form/types/workflow-schema.d.ts +0 -1145
  161. package/dist/form/utils/pwResolver.d.ts +0 -18
  162. package/dist/chunks/{BareModal-BqroLbZ5.js → BareModal-BtRiQezg.js} +1 -1
  163. package/dist/chunks/{MarkdownImpl-Bq4QhrtA.js → MarkdownImpl-CyeTVvSt.js} +1 -1
  164. /package/dist/{workflow → graph}/AnnotationBanner.d.ts +0 -0
  165. /package/dist/{workflow → graph}/Collapse.d.ts +0 -0
  166. /package/dist/{workflow → graph}/DependencyGraph.d.ts +0 -0
  167. /package/dist/{workflow → graph}/JobSummary.d.ts +0 -0
  168. /package/dist/{workflow → graph}/Reveal.d.ts +0 -0
  169. /package/dist/{workflow → graph}/TreeView.d.ts +0 -0
@@ -1,14 +1,14 @@
1
+ import { n as useLink, o as usePersistedState, r as useNavigation, u as useStrings } from "./Provider-CDYurraE.js";
1
2
  import { CheckIcon, ChevronDownIcon, ChevronLeftIcon, ChevronRightIcon, ChevronUpIcon, DisplayIcon, ErrorIcon, FilterIcon, MenuIcon, SearchIcon, XIcon } from "../icons.js";
2
- import { a as usePersistedState, n as useLink, r as useNavigation, u as useStrings } from "./Provider-DHmZ3v9i.js";
3
- import { n as TOOLTIP_ID, r as TooltipInfo } from "./Tooltip-n9w7Tkt1.js";
4
- import { _ as useRowMenuActive, c as PageHeader, p as rowContextMenuProps, u as MoreButton } from "./PageHeader-MxuOs9cH.js";
5
- import { n as Table } from "./Table-C6JdFFiJ.js";
3
+ import { n as TOOLTIP_ID, r as TooltipInfo, s as positionKeys } from "./Tooltip-K5HJr4_p.js";
4
+ import { _ as useRowMenuActive, c as PageHeader, f as rowContextMenuProps, u as MoreButton, w as Avatar } from "./PageHeader-0kG_iypP.js";
5
+ import { n as Table } from "./Table-DU2MW8xz.js";
6
+ import { Menu, MenuButton, MenuItem, MenuItems } from "@headlessui/react";
6
7
  import cx from "classnames";
7
- import { Fragment, jsx, jsxs } from "react/jsx-runtime";
8
- import { Children, Fragment as Fragment$1, cloneElement, createContext, isValidElement, useCallback, useContext, useEffect, useLayoutEffect, useMemo, useRef, useState } from "react";
8
+ import { Children, Fragment, cloneElement, createContext, isValidElement, useCallback, useContext, useEffect, useLayoutEffect, useMemo, useRef, useState } from "react";
9
9
  import { useLocalStorage } from "usehooks-ts";
10
+ import { Fragment as Fragment$1, jsx, jsxs } from "react/jsx-runtime";
10
11
  import { createPortal } from "react-dom";
11
- import { Menu, MenuButton, MenuItem, MenuItems } from "@headlessui/react";
12
12
  //#region src/list/ActionToolbar.tsx
13
13
  var OverflowMenuContext = createContext(false);
14
14
  /** Omits data-tooltip-content when absent — react-tooltip treats an explicit undefined as an empty tooltip anchor. */
@@ -20,7 +20,7 @@ function tipProps(content, place) {
20
20
  };
21
21
  }
22
22
  function ToolbarItemView({ item }) {
23
- if ("element" in item) return /* @__PURE__ */ jsx(Fragment, { children: item.element });
23
+ if ("element" in item) return /* @__PURE__ */ jsx(Fragment$1, { children: item.element });
24
24
  return /* @__PURE__ */ jsx(ToolbarButton, { action: item });
25
25
  }
26
26
  function ToolbarButton({ action }) {
@@ -30,7 +30,7 @@ function ToolbarButton({ action }) {
30
30
  const className = cx("inline-flex items-center gap-x-0.5 h-9 px-2 rounded-md text-[13.5px] uppercase font-semibold transition-colors whitespace-nowrap", "bg-(--theme-element) text-(--theme-element-text)", action.disabled ? "opacity-50 cursor-not-allowed" : "cursor-pointer hover:bg-(--theme-element-hover)");
31
31
  const tooltipProps = tipProps(action.disabled ? action.disabledTooltip : action.enabledTooltip, "bottom");
32
32
  const Icon = action.icon;
33
- const content = /* @__PURE__ */ jsxs(Fragment, { children: [/* @__PURE__ */ jsx("div", {
33
+ const content = /* @__PURE__ */ jsxs(Fragment$1, { children: [/* @__PURE__ */ jsx("div", {
34
34
  className: "h-6 flex items-center",
35
35
  children: /* @__PURE__ */ jsx(Icon, { className: cx("w-auto", action.iconClassName) })
36
36
  }), action.label] });
@@ -64,7 +64,7 @@ function OverflowRow({ item }) {
64
64
  const Icon = item.icon;
65
65
  const className = cx("flex w-full items-center gap-x-1 px-4 py-2 text-[13px] uppercase font-semibold link hover:theme-hover", item.disabled && "opacity-50 cursor-not-allowed");
66
66
  const tooltipProps = tipProps(item.disabled ? item.disabledTooltip : item.enabledTooltip, "left");
67
- const content = /* @__PURE__ */ jsxs(Fragment, { children: [/* @__PURE__ */ jsx("div", {
67
+ const content = /* @__PURE__ */ jsxs(Fragment$1, { children: [/* @__PURE__ */ jsx("div", {
68
68
  className: "w-5 h-6 flex items-center",
69
69
  children: /* @__PURE__ */ jsx(Icon, { className: cx(item.iconClassName) })
70
70
  }), item.label] });
@@ -106,7 +106,7 @@ function OverflowMenu({ items }) {
106
106
  className: "z-50 min-w-56 rounded-md border theme-border bg-(--theme-app-bg) shadow-lg py-1 focus:outline-none",
107
107
  children: /* @__PURE__ */ jsx(OverflowMenuContext.Provider, {
108
108
  value: true,
109
- children: items.map((item) => "element" in item ? /* @__PURE__ */ jsx(Fragment$1, { children: item.element }, item.key) : /* @__PURE__ */ jsx(OverflowRow, { item }, item.key))
109
+ children: items.map((item) => "element" in item ? /* @__PURE__ */ jsx(Fragment, { children: item.element }, item.key) : /* @__PURE__ */ jsx(OverflowRow, { item }, item.key))
110
110
  })
111
111
  })]
112
112
  });
@@ -177,7 +177,7 @@ function ActionToolbar({ groups, right = [], sticky = false }) {
177
177
  className: cx("flex items-center gap-2.5", sticky && cx("sticky top-10 z-10 bg-(--theme-app-bg)", "py-1.5")),
178
178
  children: [visibleGroups.length > 0 && /* @__PURE__ */ jsx("div", {
179
179
  className: "flex items-center gap-2.5 shrink-0",
180
- children: visibleGroups.map((group, i) => /* @__PURE__ */ jsxs(Fragment$1, { children: [i > 0 && /* @__PURE__ */ jsx("div", { className: "w-px h-5 bg-(--theme-border)" }), /* @__PURE__ */ jsx("div", {
180
+ children: visibleGroups.map((group, i) => /* @__PURE__ */ jsxs(Fragment, { children: [i > 0 && /* @__PURE__ */ jsx("div", { className: "w-px h-5 bg-(--theme-border)" }), /* @__PURE__ */ jsx("div", {
181
181
  className: "flex items-center gap-1",
182
182
  children: group.map((item) => /* @__PURE__ */ jsx(ToolbarItemView, { item }, item.key))
183
183
  })] }, group[0]?.key ?? i))
@@ -185,6 +185,74 @@ function ActionToolbar({ groups, right = [], sticky = false }) {
185
185
  });
186
186
  }
187
187
  //#endregion
188
+ //#region src/list/HoverCard.tsx
189
+ function useHoverCard() {
190
+ const triggerRef = useRef(null);
191
+ const [coords, setCoords] = useState(null);
192
+ const openTimer = useRef(void 0);
193
+ const closeTimer = useRef(void 0);
194
+ useEffect(() => () => {
195
+ clearTimeout(openTimer.current);
196
+ clearTimeout(closeTimer.current);
197
+ }, []);
198
+ const scheduleOpen = () => {
199
+ clearTimeout(closeTimer.current);
200
+ openTimer.current = setTimeout(() => {
201
+ const rect = triggerRef.current?.getBoundingClientRect();
202
+ if (rect) setCoords({
203
+ x: rect.left,
204
+ y: rect.bottom
205
+ });
206
+ }, 350);
207
+ };
208
+ const scheduleClose = () => {
209
+ clearTimeout(openTimer.current);
210
+ closeTimer.current = setTimeout(() => setCoords(null), 150);
211
+ };
212
+ const keepOpen = () => clearTimeout(closeTimer.current);
213
+ return {
214
+ triggerRef,
215
+ coords,
216
+ scheduleOpen,
217
+ scheduleClose,
218
+ keepOpen
219
+ };
220
+ }
221
+ function HoverCardSurface({ x, y, widthClassName, padded = true, relayoutKey, onKeepOpen, onLeave, children }) {
222
+ const ref = useRef(null);
223
+ const [pos, setPos] = useState(null);
224
+ useLayoutEffect(() => {
225
+ if (!ref.current) return;
226
+ const { width, height } = ref.current.getBoundingClientRect();
227
+ const pad = 8;
228
+ const left = Math.max(pad, Math.min(x, window.innerWidth - width - pad));
229
+ const top = y + 8 + height + pad > window.innerHeight ? Math.max(pad, y - 8 - height) : y + 8;
230
+ setPos({
231
+ left,
232
+ top
233
+ });
234
+ }, [
235
+ x,
236
+ y,
237
+ relayoutKey
238
+ ]);
239
+ return createPortal(/* @__PURE__ */ jsx("div", {
240
+ ref,
241
+ role: "none",
242
+ onMouseEnter: onKeepOpen,
243
+ onMouseLeave: onLeave,
244
+ onFocus: onKeepOpen,
245
+ onBlur: onLeave,
246
+ className: cx("fixed z-[9999] overflow-hidden rounded-xl border border-(--theme-border) bg-(--theme-panel-bg) shadow-xl backdrop-blur-xl", padded && "p-3", widthClassName),
247
+ style: {
248
+ left: pos?.left ?? x,
249
+ top: pos?.top ?? y + 8,
250
+ visibility: pos ? "visible" : "hidden"
251
+ },
252
+ children
253
+ }), document.querySelector(".ds-root") ?? document.body);
254
+ }
255
+ //#endregion
188
256
  //#region src/list/ListTable.tsx
189
257
  var NAME_TEXT = "font-medium text-[13px] leading-tight text-(--theme-app) truncate";
190
258
  var SUBTITLE_TEXT = "text-xs leading-tight text-(--theme-muted-text-color) truncate";
@@ -205,7 +273,7 @@ var listTableFixedProps = {
205
273
  };
206
274
  function NameCell({ icon, name, subtitle, href, badge, title }) {
207
275
  const Link = useLink();
208
- const inner = /* @__PURE__ */ jsxs(Fragment, { children: [icon, /* @__PURE__ */ jsxs("div", {
276
+ const inner = /* @__PURE__ */ jsxs(Fragment$1, { children: [icon, /* @__PURE__ */ jsxs("div", {
209
277
  className: "min-w-0",
210
278
  children: [/* @__PURE__ */ jsxs("div", {
211
279
  className: "flex min-w-0 items-center gap-1.5",
@@ -274,7 +342,7 @@ function ListSkeleton({ rows = 6 }) {
274
342
  role: "status",
275
343
  "aria-label": loading,
276
344
  className: "divide-y border-b border-(--theme-border) divide-(--theme-border)",
277
- children: [Array.from({ length: rows }).map((_, i) => /* @__PURE__ */ jsxs("div", {
345
+ children: [positionKeys(rows, "skeleton").map((key) => /* @__PURE__ */ jsxs("div", {
278
346
  "aria-hidden": "true",
279
347
  className: "flex items-center gap-3 px-4 py-2.5 animate-pulse",
280
348
  children: [
@@ -285,7 +353,7 @@ function ListSkeleton({ rows = 6 }) {
285
353
  }),
286
354
  /* @__PURE__ */ jsx("div", { className: "ml-auto h-3 w-20 rounded bg-(--theme-muted-panel-bg)" })
287
355
  ]
288
- }, i)), /* @__PURE__ */ jsx("span", {
356
+ }, key)), /* @__PURE__ */ jsx("span", {
289
357
  className: "sr-only",
290
358
  children: loading
291
359
  })]
@@ -332,7 +400,7 @@ function ListActionsHeader({ view, actionCount = 0, className }) {
332
400
  width,
333
401
  minWidth: width
334
402
  },
335
- className: cx("py-2 text-right @max-[43rem]:w-[52px]! @max-[43rem]:min-w-[52px]!", className),
403
+ className: cx("relative py-2 text-right @max-[43rem]:w-[52px]! @max-[43rem]:min-w-[52px]!", className),
336
404
  children: /* @__PURE__ */ jsx("span", {
337
405
  className: "sr-only",
338
406
  children: "Actions"
@@ -381,8 +449,9 @@ function ListRowActionsProvider({ view, children }) {
381
449
  });
382
450
  }
383
451
  function ListPage({ section = "main", shellPadded, embedded = false, breadcrumbs, title, titleAction, actions, toolbar, view, children }) {
452
+ const cancelShellPadding = shellPadded ?? SECTION_SHELL_PADDED[section];
384
453
  return /* @__PURE__ */ jsxs("div", {
385
- className: cx("flex h-full min-h-0 flex-col", (shellPadded ?? SECTION_SHELL_PADDED[section]) && "-m-4"),
454
+ className: cx("flex h-full min-h-0 flex-col", cancelShellPadding && "-m-4"),
386
455
  children: [embedded ? toolbar && /* @__PURE__ */ jsx("div", {
387
456
  className: "px-4 py-1.5",
388
457
  children: toolbar
@@ -462,7 +531,7 @@ function ListRow({ href, onActivate, items, goTo, openMenu, pinnedActions, selec
462
531
  }
463
532
  /** Name column min-width is by role, not position, so a leading checkbox doesn't shift it. */
464
533
  function ListColumns({ view }) {
465
- return /* @__PURE__ */ jsxs(Fragment, { children: [view.visibleColumns.map((col, i) => /* @__PURE__ */ jsx(Table.Header, {
534
+ return /* @__PURE__ */ jsxs(Fragment$1, { children: [view.visibleColumns.map((col, i) => /* @__PURE__ */ jsx(Table.Header, {
466
535
  caps: false,
467
536
  className: cx(col.headerClassName, view.columnClasses[i]),
468
537
  style: col.alwaysVisible ? { minWidth: 200 } : void 0,
@@ -475,252 +544,46 @@ function useListNavigate() {
475
544
  return useNavigation().goTo;
476
545
  }
477
546
  //#endregion
478
- //#region src/list/listView.tsx
479
- var PRIORITY_SHOW_CLASS = {
480
- low: "hidden @[52rem]:table-cell",
481
- medium: "hidden @[36rem]:table-cell"
482
- };
483
- function columnResponsiveClass(col) {
484
- return col.priority ? PRIORITY_SHOW_CLASS[col.priority] : "";
547
+ //#region src/list/textEntry.ts
548
+ /** Guards list-page shortcuts from firing inside inputs, terminals, editors, and dialogs. */
549
+ function isTextEntryContext(target) {
550
+ const el = target;
551
+ if (!el) return false;
552
+ if (el.tagName === "INPUT" || el.tagName === "TEXTAREA" || el.isContentEditable) return true;
553
+ return Boolean(el.closest?.(".xterm, .monaco-editor, .cm-editor, [role=\"dialog\"]"));
485
554
  }
486
- var DEFAULT_ORDER = "__default";
487
- var FAVORITE_ORDER = "__favorite";
488
- /** Persisted grouping + column-visibility + field-filter state for a list page,
489
- * driving the shared Display/Filter menus. */
490
- function useListView({ storageKey, sharedFiltersKey, columns, groupBys = [], defaultGroupBy, orderBys = [], defaultOrderBy, facets = [], actions = [], actionCount, defaultShowColumnHeaders = false, defaultShowActions = true, isFavorite, isOn, createdAt }) {
491
- const t = useStrings().list;
492
- const tiebreak = orderBys[0]?.compare;
493
- const effectiveOrderBys = useMemo(() => {
494
- if (!isFavorite) return orderBys;
495
- const favoriteRank = (row) => isFavorite(row) ? 0 : 1;
496
- const onRank = (row) => isOn?.(row) ? 0 : 1;
497
- const createdMs = (row) => {
498
- const v = createdAt?.(row);
499
- return v === null || v === void 0 || Number.isNaN(v) ? 0 : v;
555
+ //#endregion
556
+ //#region src/list/ListViewControls.tsx
557
+ /** Shared chrome for the toolbar control buttons (Filter, Display, Search) so
558
+ * they read as a consistent button cluster — matched by ListSearchControl. */
559
+ var listControlButtonClasses = "relative flex h-7 w-7 items-center justify-center rounded-md border border-(--theme-border) text-(--theme-muted-text-color) hover:bg-(--theme-muted-panel-bg) hover:text-(--theme-app) transition-colors";
560
+ var FLYOUT = "min-w-44 rounded-lg border border-(--theme-border) bg-(--theme-app-bg) py-1 shadow-lg";
561
+ /** Toggle pill shared by the Display menu's column + pinned-action pickers. */
562
+ function pillClass(on) {
563
+ return cx("whitespace-nowrap rounded-full border px-2.5 py-1 text-[12px] transition-colors", on ? "border-transparent bg-(--theme-muted-panel-bg) text-(--theme-app)" : "border-(--theme-border) text-(--theme-muted-text-color) hover:bg-(--theme-muted-panel-bg) hover:text-(--theme-app)");
564
+ }
565
+ var SECTION_LABEL = "mb-2 text-[11px] font-medium uppercase tracking-wide text-(--theme-muted-text-color)";
566
+ /** Portals into .ds-root so the panel escapes the toolbar's overflow clipping. */
567
+ function AnchoredPopover({ icon, label, active, shortcut, panelClassName, children }) {
568
+ const btnRef = useRef(null);
569
+ const panelRef = useRef(null);
570
+ const [pos, setPos] = useState(null);
571
+ const close = useCallback(() => setPos(null), []);
572
+ const open = useCallback(() => {
573
+ const r = btnRef.current?.getBoundingClientRect();
574
+ if (r) setPos({
575
+ right: Math.max(8, Math.round(window.innerWidth - r.right)),
576
+ top: Math.round(r.bottom) + 4
577
+ });
578
+ }, []);
579
+ useEffect(() => {
580
+ if (!pos) return;
581
+ const onKey = (e) => {
582
+ if (e.key === "Escape") close();
500
583
  };
501
- const newestFirst = (a, b) => createdMs(b) - createdMs(a);
502
- return [...[{
503
- value: DEFAULT_ORDER,
504
- label: t.orderDefault,
505
- compare: (a, b) => onRank(a) - onRank(b) || favoriteRank(a) - favoriteRank(b) || newestFirst(a, b) || (tiebreak?.(a, b) ?? 0)
506
- }, {
507
- value: FAVORITE_ORDER,
508
- label: t.orderFavorites,
509
- compare: (a, b) => favoriteRank(a) - favoriteRank(b) || (tiebreak?.(a, b) ?? 0)
510
- }], ...orderBys];
511
- }, [
512
- orderBys,
513
- isFavorite,
514
- isOn,
515
- createdAt,
516
- tiebreak,
517
- t
518
- ]);
519
- const defaultGroupByValue = defaultGroupBy ?? groupBys[0]?.value ?? "";
520
- const defaultOrderByValue = isFavorite ? DEFAULT_ORDER : defaultOrderBy ?? orderBys[0]?.value ?? "";
521
- const defaultHiddenKeys = useMemo(() => columns.filter((c) => c.defaultHidden && !c.alwaysVisible).map((c) => c.key), [columns]);
522
- const defaultPinnedKeys = useMemo(() => actions.filter((a) => a.defaultPinned).map((a) => a.key), [actions]);
523
- const [hiddenKeys, setHiddenKeys] = usePersistedState(`${storageKey}:hiddenColumns`, defaultHiddenKeys);
524
- const [pinnedKeys, setPinnedKeys] = usePersistedState(`${storageKey}:pinnedActions`, defaultPinnedKeys);
525
- const [groupBy, setGroupBy] = usePersistedState(`${storageKey}:groupBy`, defaultGroupByValue);
526
- const [showColumnHeaders, setShowColumnHeaders] = usePersistedState(`${storageKey}:showColumnHeaders`, defaultShowColumnHeaders);
527
- const [showActions, setShowActions] = usePersistedState(`${storageKey}:showActions`, defaultShowActions);
528
- const [alwaysShowActions, setAlwaysShowActions] = usePersistedState(`${storageKey}:alwaysShowActions`, false);
529
- const [orderBy, setOrderBy] = usePersistedState(`${storageKey}:orderBy`, defaultOrderByValue);
530
- const [orderDir, setOrderDir] = usePersistedState(`${storageKey}:orderDir`, "asc");
531
- const [localFilters, setLocalFilters] = usePersistedState(`${storageKey}:filters`, {});
532
- const [sharedFilters, setSharedFilters] = usePersistedState(`${sharedFiltersKey ?? storageKey}:sharedFilters`, {});
533
- const sharedKeys = useMemo(() => new Set(facets.filter((f) => f.shared).map((f) => f.key)), [facets]);
534
- const filters = useMemo(() => {
535
- if (sharedKeys.size === 0) return localFilters;
536
- const merged = {};
537
- for (const [key, values] of Object.entries(localFilters)) if (!sharedKeys.has(key)) merged[key] = values;
538
- for (const key of sharedKeys) {
539
- const values = sharedFilters[key];
540
- if (values?.length) merged[key] = values;
541
- }
542
- return merged;
543
- }, [
544
- localFilters,
545
- sharedFilters,
546
- sharedKeys
547
- ]);
548
- const pinnedCount = actionCount ?? pinnedKeys.filter((key) => actions.some((action) => action.key === key)).length;
549
- const effectiveShowActions = showActions || alwaysShowActions;
550
- const actionsWidth = effectiveShowActions ? actionsColumnWidth(pinnedCount) : 0;
551
- const isVisible = useCallback((key) => {
552
- const col = columns.find((c) => c.key === key);
553
- return Boolean(col?.alwaysVisible) || !hiddenKeys.includes(key);
554
- }, [columns, hiddenKeys]);
555
- const visibleColumns = useMemo(() => columns.filter((c) => !c.inline && (c.alwaysVisible || !hiddenKeys.includes(c.key))), [columns, hiddenKeys]);
556
- const columnClasses = useMemo(() => visibleColumns.map(columnResponsiveClass), [visibleColumns]);
557
- const toggleColumn = useCallback((key) => setHiddenKeys((prev) => prev.includes(key) ? prev.filter((k) => k !== key) : [...prev, key]), [setHiddenKeys]);
558
- const setFacetValues = useCallback((key, values) => {
559
- const update = (prev) => {
560
- const next = { ...prev };
561
- if (values.length) next[key] = values;
562
- else delete next[key];
563
- return next;
564
- };
565
- if (sharedKeys.has(key)) setSharedFilters(update);
566
- else setLocalFilters(update);
567
- }, [
568
- setLocalFilters,
569
- setSharedFilters,
570
- sharedKeys
571
- ]);
572
- const clearFilters = useCallback(() => {
573
- setLocalFilters({});
574
- if (sharedKeys.size > 0) setSharedFilters((prev) => {
575
- const next = { ...prev };
576
- for (const key of sharedKeys) delete next[key];
577
- return next;
578
- });
579
- }, [
580
- setLocalFilters,
581
- setSharedFilters,
582
- sharedKeys
583
- ]);
584
- const isPinned = useCallback((key) => pinnedKeys.includes(key), [pinnedKeys]);
585
- const togglePinned = useCallback((key) => setPinnedKeys((prev) => prev.includes(key) ? prev.filter((k) => k !== key) : [...prev, key]), [setPinnedKeys]);
586
- const toggleColumnHeaders = useCallback(() => setShowColumnHeaders((prev) => !prev), [setShowColumnHeaders]);
587
- const toggleShowActions = useCallback(() => {
588
- if (effectiveShowActions) {
589
- setShowActions(false);
590
- setAlwaysShowActions(false);
591
- } else setShowActions(true);
592
- }, [
593
- effectiveShowActions,
594
- setShowActions,
595
- setAlwaysShowActions
596
- ]);
597
- const toggleAlwaysShowActions = useCallback(() => {
598
- const next = !alwaysShowActions;
599
- setAlwaysShowActions(next);
600
- if (next) setShowActions(true);
601
- }, [
602
- alwaysShowActions,
603
- setAlwaysShowActions,
604
- setShowActions
605
- ]);
606
- const toggleOrderDir = useCallback(() => setOrderDir((d) => d === "asc" ? "desc" : "asc"), [setOrderDir]);
607
- const applyOrder = useCallback((rows) => {
608
- const opt = effectiveOrderBys.find((o) => o.value === orderBy);
609
- if (!opt) return rows;
610
- const sign = orderDir === "asc" ? 1 : -1;
611
- return [...rows].sort((a, b) => opt.compare(a, b) * sign);
612
- }, [
613
- effectiveOrderBys,
614
- orderBy,
615
- orderDir
616
- ]);
617
- const sameKeys = (a, b) => a.length === b.length && a.every((k) => b.includes(k));
618
- const isDisplayDefault = groupBy === defaultGroupByValue && orderBy === defaultOrderByValue && orderDir === "asc" && showColumnHeaders === defaultShowColumnHeaders && showActions === defaultShowActions && alwaysShowActions === false && sameKeys(hiddenKeys, defaultHiddenKeys) && sameKeys(pinnedKeys, defaultPinnedKeys);
619
- const resetDisplay = useCallback(() => {
620
- setGroupBy(defaultGroupByValue);
621
- setOrderBy(defaultOrderByValue);
622
- setOrderDir("asc");
623
- setShowColumnHeaders(defaultShowColumnHeaders);
624
- setShowActions(defaultShowActions);
625
- setAlwaysShowActions(false);
626
- setHiddenKeys(defaultHiddenKeys);
627
- setPinnedKeys(defaultPinnedKeys);
628
- }, [
629
- setGroupBy,
630
- setOrderBy,
631
- setOrderDir,
632
- defaultOrderByValue,
633
- setShowColumnHeaders,
634
- setShowActions,
635
- setAlwaysShowActions,
636
- setHiddenKeys,
637
- setPinnedKeys,
638
- defaultGroupByValue,
639
- defaultHiddenKeys,
640
- defaultPinnedKeys,
641
- defaultShowColumnHeaders,
642
- defaultShowActions
643
- ]);
644
- return {
645
- columns,
646
- visibleColumns,
647
- columnClasses,
648
- isVisible,
649
- pinnedCount,
650
- actionsWidth,
651
- toggleColumn,
652
- groupBys,
653
- groupBy,
654
- setGroupBy,
655
- orderBys: effectiveOrderBys,
656
- orderBy,
657
- setOrderBy,
658
- orderDir,
659
- toggleOrderDir,
660
- applyOrder,
661
- facets,
662
- filters,
663
- setFacetValues,
664
- clearFilters,
665
- activeFilterCount: useMemo(() => Object.values(filters).filter((v) => v && v.length > 0).length, [filters]),
666
- applyFilters: useCallback((rows) => rows.filter((row) => facets.every((f) => {
667
- const selected = filters[f.key];
668
- return !selected || selected.length === 0 ? true : f.matches(row, selected);
669
- })), [facets, filters]),
670
- actions,
671
- isPinned,
672
- togglePinned,
673
- showColumnHeaders,
674
- toggleColumnHeaders,
675
- showActions: effectiveShowActions,
676
- toggleShowActions,
677
- alwaysShowActions,
678
- toggleAlwaysShowActions,
679
- isDisplayDefault,
680
- resetDisplay
681
- };
682
- }
683
- //#endregion
684
- //#region src/list/textEntry.ts
685
- /** Guards list-page shortcuts from firing inside inputs, terminals, editors, and dialogs. */
686
- function isTextEntryContext(target) {
687
- const el = target;
688
- if (!el) return false;
689
- if (el.tagName === "INPUT" || el.tagName === "TEXTAREA" || el.isContentEditable) return true;
690
- return Boolean(el.closest?.(".xterm, .monaco-editor, .cm-editor, [role=\"dialog\"]"));
691
- }
692
- //#endregion
693
- //#region src/list/ListViewControls.tsx
694
- /** Shared chrome for the toolbar control buttons (Filter, Display, Search) so
695
- * they read as a consistent button cluster — matched by ListSearchControl. */
696
- var listControlButtonClasses = "relative flex h-7 w-7 items-center justify-center rounded-md border border-(--theme-border) text-(--theme-muted-text-color) hover:bg-(--theme-muted-panel-bg) hover:text-(--theme-app) transition-colors";
697
- var FLYOUT = "min-w-44 rounded-lg border border-(--theme-border) bg-(--theme-app-bg) py-1 shadow-lg";
698
- /** Toggle pill shared by the Display menu's column + pinned-action pickers. */
699
- function pillClass(on) {
700
- return cx("whitespace-nowrap rounded-full border px-2.5 py-1 text-[12px] transition-colors", on ? "border-transparent bg-(--theme-muted-panel-bg) text-(--theme-app)" : "border-(--theme-border) text-(--theme-muted-text-color) hover:bg-(--theme-muted-panel-bg) hover:text-(--theme-app)");
701
- }
702
- var SECTION_LABEL = "mb-2 text-[11px] font-medium uppercase tracking-wide text-(--theme-muted-text-color)";
703
- /** Portals into .ds-root so the panel escapes the toolbar's overflow clipping. */
704
- function AnchoredPopover({ icon, label, active, shortcut, panelClassName, children }) {
705
- const btnRef = useRef(null);
706
- const panelRef = useRef(null);
707
- const [pos, setPos] = useState(null);
708
- const close = useCallback(() => setPos(null), []);
709
- const open = useCallback(() => {
710
- const r = btnRef.current?.getBoundingClientRect();
711
- if (r) setPos({
712
- right: Math.max(8, Math.round(window.innerWidth - r.right)),
713
- top: Math.round(r.bottom) + 4
714
- });
715
- }, []);
716
- useEffect(() => {
717
- if (!pos) return;
718
- const onKey = (e) => {
719
- if (e.key === "Escape") close();
720
- };
721
- const onScroll = (e) => {
722
- if (e.target instanceof Node && panelRef.current?.contains(e.target)) return;
723
- close();
584
+ const onScroll = (e) => {
585
+ if (e.target instanceof Node && panelRef.current?.contains(e.target)) return;
586
+ close();
724
587
  };
725
588
  window.addEventListener("keydown", onKey);
726
589
  window.addEventListener("scroll", onScroll, true);
@@ -743,7 +606,7 @@ function AnchoredPopover({ icon, label, active, shortcut, panelClassName, childr
743
606
  window.addEventListener("keydown", onKey);
744
607
  return () => window.removeEventListener("keydown", onKey);
745
608
  }, [shortcut, open]);
746
- return /* @__PURE__ */ jsxs(Fragment, { children: [/* @__PURE__ */ jsxs("button", {
609
+ return /* @__PURE__ */ jsxs(Fragment$1, { children: [/* @__PURE__ */ jsxs("button", {
747
610
  ref: btnRef,
748
611
  type: "button",
749
612
  onClick: () => pos ? close() : open(),
@@ -915,14 +778,16 @@ function useCloseOnOutsideClick(open, close) {
915
778
  function GroupingDropdown({ view }) {
916
779
  const t = useStrings().list;
917
780
  const [open, setOpen] = useState(false);
781
+ const ref = useCloseOnOutsideClick(open, useCallback(() => setOpen(false), []));
782
+ const current = view.groupBys.find((g) => g.value === view.groupBy);
918
783
  return /* @__PURE__ */ jsxs("div", {
919
- ref: useCloseOnOutsideClick(open, useCallback(() => setOpen(false), [])),
784
+ ref,
920
785
  className: "relative",
921
786
  children: [/* @__PURE__ */ jsxs("button", {
922
787
  type: "button",
923
788
  onClick: () => setOpen((o) => !o),
924
789
  className: "flex items-center gap-1.5 rounded-md border border-(--theme-border) px-2 py-1 text-[12px] text-(--theme-app) hover:bg-(--theme-muted-panel-bg)",
925
- children: [view.groupBys.find((g) => g.value === view.groupBy)?.label ?? t.none, /* @__PURE__ */ jsx(ChevronDownIcon, { className: "h-2.5 w-2.5 opacity-60" })]
790
+ children: [current?.label ?? t.none, /* @__PURE__ */ jsx(ChevronDownIcon, { className: "h-2.5 w-2.5 opacity-60" })]
926
791
  }), open && /* @__PURE__ */ jsx("div", {
927
792
  className: cx("absolute right-0 top-full z-20 mt-1", FLYOUT),
928
793
  children: view.groupBys.map((g) => /* @__PURE__ */ jsxs("button", {
@@ -940,14 +805,16 @@ function GroupingDropdown({ view }) {
940
805
  function OrderingDropdown({ view }) {
941
806
  const t = useStrings().list;
942
807
  const [open, setOpen] = useState(false);
808
+ const ref = useCloseOnOutsideClick(open, useCallback(() => setOpen(false), []));
809
+ const current = view.orderBys.find((o) => o.value === view.orderBy);
943
810
  return /* @__PURE__ */ jsxs("div", {
944
- ref: useCloseOnOutsideClick(open, useCallback(() => setOpen(false), [])),
811
+ ref,
945
812
  className: "relative",
946
813
  children: [/* @__PURE__ */ jsxs("button", {
947
814
  type: "button",
948
815
  onClick: () => setOpen((o) => !o),
949
816
  className: "flex items-center gap-1.5 rounded-md border border-(--theme-border) px-2 py-1 text-[12px] text-(--theme-app) hover:bg-(--theme-muted-panel-bg)",
950
- children: [view.orderBys.find((o) => o.value === view.orderBy)?.label ?? t.none, /* @__PURE__ */ jsx(ChevronDownIcon, { className: "h-2.5 w-2.5 opacity-60" })]
817
+ children: [current?.label ?? t.none, /* @__PURE__ */ jsx(ChevronDownIcon, { className: "h-2.5 w-2.5 opacity-60" })]
951
818
  }), open && /* @__PURE__ */ jsx("div", {
952
819
  className: cx("absolute right-0 top-full z-20 mt-1", FLYOUT),
953
820
  children: view.orderBys.map((o) => /* @__PURE__ */ jsxs("button", {
@@ -986,7 +853,7 @@ function FilterMenuBody({ view }) {
986
853
  const scheduleClose = () => {
987
854
  closeTimer.current = setTimeout(() => setOpenKey(null), 160);
988
855
  };
989
- return /* @__PURE__ */ jsxs(Fragment, { children: [/* @__PURE__ */ jsxs("div", {
856
+ return /* @__PURE__ */ jsxs(Fragment$1, { children: [/* @__PURE__ */ jsxs("div", {
990
857
  className: "flex items-center justify-between px-3 py-1",
991
858
  children: [/* @__PURE__ */ jsx("span", {
992
859
  className: "text-[11px] font-medium uppercase tracking-wide text-(--theme-muted-text-color)",
@@ -1049,6 +916,59 @@ function FilterFacetRow({ view, facet, open, onEnter, onLeave }) {
1049
916
  });
1050
917
  }
1051
918
  //#endregion
919
+ //#region src/list/ListPager.tsx
920
+ /** Page sizes offered by the pager's per-page select; first entry is the default. */
921
+ var LIST_PAGE_SIZES = [
922
+ 50,
923
+ 100,
924
+ 200
925
+ ];
926
+ /** Footer pager bar for paginated new-nav lists: "{start}–{end} of {total}" with prev/next. Renders nothing for a single page. */
927
+ function ListPager({ page, pageSize, total, onPageChange, pageSizes = LIST_PAGE_SIZES, onPageSizeChange, hasNext }) {
928
+ const t = useStrings().list;
929
+ const pageCount = Math.max(1, Math.ceil(total / pageSize));
930
+ const start = page * pageSize + 1;
931
+ const end = Math.min(total, (page + 1) * pageSize);
932
+ const smallest = Math.min(...pageSizes);
933
+ const showSizeSelect = !!onPageSizeChange && (total > smallest || pageSize > smallest);
934
+ if (pageCount <= 1 && !showSizeSelect) return null;
935
+ return /* @__PURE__ */ jsxs("div", {
936
+ className: "flex items-center justify-between px-2.5 h-10 shrink-0 border-t theme-border",
937
+ children: [/* @__PURE__ */ jsxs("div", {
938
+ className: "flex items-center gap-3 text-xs text-(--theme-muted-text-color)",
939
+ children: [/* @__PURE__ */ jsx("span", { children: t.pager(start, end, total) }), showSizeSelect && /* @__PURE__ */ jsxs("label", {
940
+ className: "flex items-center gap-1",
941
+ children: [t.perPage, /* @__PURE__ */ jsx("select", {
942
+ value: pageSize,
943
+ onChange: (e) => onPageSizeChange(Number(e.target.value)),
944
+ className: "theme-input rounded px-1.5 py-0.5 text-xs",
945
+ children: pageSizes.map((size) => /* @__PURE__ */ jsx("option", {
946
+ value: size,
947
+ children: size
948
+ }, size))
949
+ })]
950
+ })]
951
+ }), /* @__PURE__ */ jsxs("div", {
952
+ className: "flex items-center gap-1",
953
+ children: [/* @__PURE__ */ jsx("button", {
954
+ type: "button",
955
+ "aria-label": t.paginationPrevious,
956
+ disabled: page === 0,
957
+ onClick: () => onPageChange(page - 1),
958
+ className: cx(listControlButtonClasses, "disabled:opacity-40 disabled:pointer-events-none"),
959
+ children: /* @__PURE__ */ jsx(ChevronLeftIcon, { className: "w-3.5 h-3.5" })
960
+ }), /* @__PURE__ */ jsx("button", {
961
+ type: "button",
962
+ "aria-label": t.paginationNext,
963
+ disabled: hasNext === void 0 ? page >= pageCount - 1 : !hasNext,
964
+ onClick: () => onPageChange(page + 1),
965
+ className: cx(listControlButtonClasses, "disabled:opacity-40 disabled:pointer-events-none"),
966
+ children: /* @__PURE__ */ jsx(ChevronRightIcon, { className: "w-3.5 h-3.5" })
967
+ })]
968
+ })]
969
+ });
970
+ }
971
+ //#endregion
1052
972
  //#region src/list/listSearch.tsx
1053
973
  var NO_TERMS = [];
1054
974
  /** Pass `enabled: false` to suspend the global ⌘F/`/` hijack (e.g. when search isn't shown and browser Find should stay active). */
@@ -1178,123 +1098,321 @@ function ListCount({ total, matches, filterActive, noun, nounPlural }) {
1178
1098
  });
1179
1099
  }
1180
1100
  //#endregion
1181
- //#region src/list/ListPager.tsx
1182
- /** Page sizes offered by the pager's per-page select; first entry is the default. */
1183
- var LIST_PAGE_SIZES = [
1184
- 50,
1185
- 100,
1186
- 200
1187
- ];
1188
- /** Footer pager bar for paginated new-nav lists: "{start}–{end} of {total}" with prev/next. Renders nothing for a single page. */
1189
- function ListPager({ page, pageSize, total, onPageChange, pageSizes = LIST_PAGE_SIZES, onPageSizeChange, hasNext }) {
1190
- const t = useStrings().list;
1191
- const pageCount = Math.max(1, Math.ceil(total / pageSize));
1192
- const start = page * pageSize + 1;
1193
- const end = Math.min(total, (page + 1) * pageSize);
1194
- const smallest = Math.min(...pageSizes);
1195
- const showSizeSelect = !!onPageSizeChange && (total > smallest || pageSize > smallest);
1196
- if (pageCount <= 1 && !showSizeSelect) return null;
1197
- return /* @__PURE__ */ jsxs("div", {
1198
- className: "flex items-center justify-between px-2.5 h-10 shrink-0 border-t theme-border",
1199
- children: [/* @__PURE__ */ jsxs("div", {
1200
- className: "flex items-center gap-3 text-xs text-(--theme-muted-text-color)",
1201
- children: [/* @__PURE__ */ jsx("span", { children: t.pager(start, end, total) }), showSizeSelect && /* @__PURE__ */ jsxs("label", {
1202
- className: "flex items-center gap-1",
1203
- children: [t.perPage, /* @__PURE__ */ jsx("select", {
1204
- value: pageSize,
1205
- onChange: (e) => onPageSizeChange(Number(e.target.value)),
1206
- className: "theme-input rounded px-1.5 py-0.5 text-xs",
1207
- children: pageSizes.map((size) => /* @__PURE__ */ jsx("option", {
1208
- value: size,
1209
- children: size
1210
- }, size))
1211
- })]
1212
- })]
1213
- }), /* @__PURE__ */ jsxs("div", {
1214
- className: "flex items-center gap-1",
1215
- children: [/* @__PURE__ */ jsx("button", {
1216
- type: "button",
1217
- "aria-label": t.paginationPrevious,
1218
- disabled: page === 0,
1219
- onClick: () => onPageChange(page - 1),
1220
- className: cx(listControlButtonClasses, "disabled:opacity-40 disabled:pointer-events-none"),
1221
- children: /* @__PURE__ */ jsx(ChevronLeftIcon, { className: "w-3.5 h-3.5" })
1222
- }), /* @__PURE__ */ jsx("button", {
1223
- type: "button",
1224
- "aria-label": t.paginationNext,
1225
- disabled: hasNext === void 0 ? page >= pageCount - 1 : !hasNext,
1226
- onClick: () => onPageChange(page + 1),
1227
- className: cx(listControlButtonClasses, "disabled:opacity-40 disabled:pointer-events-none"),
1228
- children: /* @__PURE__ */ jsx(ChevronRightIcon, { className: "w-3.5 h-3.5" })
1229
- })]
1230
- })]
1231
- });
1101
+ //#region src/list/listView.tsx
1102
+ var PRIORITY_SHOW_CLASS = {
1103
+ low: "hidden @[52rem]:table-cell",
1104
+ medium: "hidden @[36rem]:table-cell"
1105
+ };
1106
+ function columnResponsiveClass(col) {
1107
+ return col.priority ? PRIORITY_SHOW_CLASS[col.priority] : "";
1232
1108
  }
1233
- //#endregion
1234
- //#region src/list/HoverCard.tsx
1235
- function useHoverCard() {
1236
- const triggerRef = useRef(null);
1237
- const [coords, setCoords] = useState(null);
1238
- const openTimer = useRef(void 0);
1239
- const closeTimer = useRef(void 0);
1240
- useEffect(() => () => {
1241
- clearTimeout(openTimer.current);
1242
- clearTimeout(closeTimer.current);
1243
- }, []);
1244
- const scheduleOpen = () => {
1245
- clearTimeout(closeTimer.current);
1246
- openTimer.current = setTimeout(() => {
1247
- const rect = triggerRef.current?.getBoundingClientRect();
1248
- if (rect) setCoords({
1249
- x: rect.left,
1250
- y: rect.bottom
1251
- });
1252
- }, 350);
1253
- };
1254
- const scheduleClose = () => {
1255
- clearTimeout(openTimer.current);
1256
- closeTimer.current = setTimeout(() => setCoords(null), 150);
1257
- };
1258
- const keepOpen = () => clearTimeout(closeTimer.current);
1109
+ var DEFAULT_ORDER = "__default";
1110
+ var FAVORITE_ORDER = "__favorite";
1111
+ /** Persisted grouping + column-visibility + field-filter state for a list page,
1112
+ * driving the shared Display/Filter menus. */
1113
+ function useListView({ storageKey, sharedFiltersKey, columns, groupBys = [], defaultGroupBy, orderBys = [], defaultOrderBy, facets = [], actions = [], actionCount, defaultShowColumnHeaders = false, defaultShowActions = true, isFavorite, isOn, createdAt }) {
1114
+ const t = useStrings().list;
1115
+ const tiebreak = orderBys[0]?.compare;
1116
+ const effectiveOrderBys = useMemo(() => {
1117
+ if (!isFavorite) return orderBys;
1118
+ const favoriteRank = (row) => isFavorite(row) ? 0 : 1;
1119
+ const onRank = (row) => isOn?.(row) ? 0 : 1;
1120
+ const createdMs = (row) => {
1121
+ const v = createdAt?.(row);
1122
+ return v === null || v === void 0 || Number.isNaN(v) ? 0 : v;
1123
+ };
1124
+ const newestFirst = (a, b) => createdMs(b) - createdMs(a);
1125
+ return [...[{
1126
+ value: DEFAULT_ORDER,
1127
+ label: t.orderDefault,
1128
+ compare: (a, b) => onRank(a) - onRank(b) || favoriteRank(a) - favoriteRank(b) || newestFirst(a, b) || (tiebreak?.(a, b) ?? 0)
1129
+ }, {
1130
+ value: FAVORITE_ORDER,
1131
+ label: t.orderFavorites,
1132
+ compare: (a, b) => favoriteRank(a) - favoriteRank(b) || (tiebreak?.(a, b) ?? 0)
1133
+ }], ...orderBys];
1134
+ }, [
1135
+ orderBys,
1136
+ isFavorite,
1137
+ isOn,
1138
+ createdAt,
1139
+ tiebreak,
1140
+ t
1141
+ ]);
1142
+ const defaultGroupByValue = defaultGroupBy ?? groupBys[0]?.value ?? "";
1143
+ const defaultOrderByValue = isFavorite ? DEFAULT_ORDER : defaultOrderBy ?? orderBys[0]?.value ?? "";
1144
+ const defaultHiddenKeys = useMemo(() => columns.filter((c) => c.defaultHidden && !c.alwaysVisible).map((c) => c.key), [columns]);
1145
+ const defaultPinnedKeys = useMemo(() => actions.filter((a) => a.defaultPinned).map((a) => a.key), [actions]);
1146
+ const [hiddenKeys, setHiddenKeys] = usePersistedState(`${storageKey}:hiddenColumns`, defaultHiddenKeys);
1147
+ const [pinnedKeys, setPinnedKeys] = usePersistedState(`${storageKey}:pinnedActions`, defaultPinnedKeys);
1148
+ const [groupBy, setGroupBy] = usePersistedState(`${storageKey}:groupBy`, defaultGroupByValue);
1149
+ const [showColumnHeaders, setShowColumnHeaders] = usePersistedState(`${storageKey}:showColumnHeaders`, defaultShowColumnHeaders);
1150
+ const [showActions, setShowActions] = usePersistedState(`${storageKey}:showActions`, defaultShowActions);
1151
+ const [alwaysShowActions, setAlwaysShowActions] = usePersistedState(`${storageKey}:alwaysShowActions`, false);
1152
+ const [orderBy, setOrderBy] = usePersistedState(`${storageKey}:orderBy`, defaultOrderByValue);
1153
+ const [orderDir, setOrderDir] = usePersistedState(`${storageKey}:orderDir`, "asc");
1154
+ const [localFilters, setLocalFilters] = usePersistedState(`${storageKey}:filters`, {});
1155
+ const [sharedFilters, setSharedFilters] = usePersistedState(`${sharedFiltersKey ?? storageKey}:sharedFilters`, {});
1156
+ const sharedKeys = useMemo(() => new Set(facets.filter((f) => f.shared).map((f) => f.key)), [facets]);
1157
+ const filters = useMemo(() => {
1158
+ if (sharedKeys.size === 0) return localFilters;
1159
+ const merged = {};
1160
+ for (const [key, values] of Object.entries(localFilters)) if (!sharedKeys.has(key)) merged[key] = values;
1161
+ for (const key of sharedKeys) {
1162
+ const values = sharedFilters[key];
1163
+ if (values?.length) merged[key] = values;
1164
+ }
1165
+ return merged;
1166
+ }, [
1167
+ localFilters,
1168
+ sharedFilters,
1169
+ sharedKeys
1170
+ ]);
1171
+ const pinnedCount = actionCount ?? pinnedKeys.filter((key) => actions.some((action) => action.key === key)).length;
1172
+ const effectiveShowActions = showActions || alwaysShowActions;
1173
+ const actionsWidth = effectiveShowActions ? actionsColumnWidth(pinnedCount) : 0;
1174
+ const isVisible = useCallback((key) => {
1175
+ const col = columns.find((c) => c.key === key);
1176
+ return Boolean(col?.alwaysVisible) || !hiddenKeys.includes(key);
1177
+ }, [columns, hiddenKeys]);
1178
+ const visibleColumns = useMemo(() => columns.filter((c) => !c.inline && (c.alwaysVisible || !hiddenKeys.includes(c.key))), [columns, hiddenKeys]);
1179
+ const columnClasses = useMemo(() => visibleColumns.map(columnResponsiveClass), [visibleColumns]);
1180
+ const toggleColumn = useCallback((key) => setHiddenKeys((prev) => prev.includes(key) ? prev.filter((k) => k !== key) : [...prev, key]), [setHiddenKeys]);
1181
+ const setFacetValues = useCallback((key, values) => {
1182
+ const update = (prev) => {
1183
+ const next = { ...prev };
1184
+ if (values.length) next[key] = values;
1185
+ else delete next[key];
1186
+ return next;
1187
+ };
1188
+ if (sharedKeys.has(key)) setSharedFilters(update);
1189
+ else setLocalFilters(update);
1190
+ }, [
1191
+ setLocalFilters,
1192
+ setSharedFilters,
1193
+ sharedKeys
1194
+ ]);
1195
+ const clearFilters = useCallback(() => {
1196
+ setLocalFilters({});
1197
+ if (sharedKeys.size > 0) setSharedFilters((prev) => {
1198
+ const next = { ...prev };
1199
+ for (const key of sharedKeys) delete next[key];
1200
+ return next;
1201
+ });
1202
+ }, [
1203
+ setLocalFilters,
1204
+ setSharedFilters,
1205
+ sharedKeys
1206
+ ]);
1207
+ const isPinned = useCallback((key) => pinnedKeys.includes(key), [pinnedKeys]);
1208
+ const togglePinned = useCallback((key) => setPinnedKeys((prev) => prev.includes(key) ? prev.filter((k) => k !== key) : [...prev, key]), [setPinnedKeys]);
1209
+ const toggleColumnHeaders = useCallback(() => setShowColumnHeaders((prev) => !prev), [setShowColumnHeaders]);
1210
+ const toggleShowActions = useCallback(() => {
1211
+ if (effectiveShowActions) {
1212
+ setShowActions(false);
1213
+ setAlwaysShowActions(false);
1214
+ } else setShowActions(true);
1215
+ }, [
1216
+ effectiveShowActions,
1217
+ setShowActions,
1218
+ setAlwaysShowActions
1219
+ ]);
1220
+ const toggleAlwaysShowActions = useCallback(() => {
1221
+ const next = !alwaysShowActions;
1222
+ setAlwaysShowActions(next);
1223
+ if (next) setShowActions(true);
1224
+ }, [
1225
+ alwaysShowActions,
1226
+ setAlwaysShowActions,
1227
+ setShowActions
1228
+ ]);
1229
+ const toggleOrderDir = useCallback(() => setOrderDir((d) => d === "asc" ? "desc" : "asc"), [setOrderDir]);
1230
+ const applyOrder = useCallback((rows) => {
1231
+ const opt = effectiveOrderBys.find((o) => o.value === orderBy);
1232
+ if (!opt) return rows;
1233
+ const sign = orderDir === "asc" ? 1 : -1;
1234
+ return [...rows].sort((a, b) => opt.compare(a, b) * sign);
1235
+ }, [
1236
+ effectiveOrderBys,
1237
+ orderBy,
1238
+ orderDir
1239
+ ]);
1240
+ const sameKeys = (a, b) => a.length === b.length && a.every((k) => b.includes(k));
1241
+ const isDisplayDefault = groupBy === defaultGroupByValue && orderBy === defaultOrderByValue && orderDir === "asc" && showColumnHeaders === defaultShowColumnHeaders && showActions === defaultShowActions && alwaysShowActions === false && sameKeys(hiddenKeys, defaultHiddenKeys) && sameKeys(pinnedKeys, defaultPinnedKeys);
1242
+ const resetDisplay = useCallback(() => {
1243
+ setGroupBy(defaultGroupByValue);
1244
+ setOrderBy(defaultOrderByValue);
1245
+ setOrderDir("asc");
1246
+ setShowColumnHeaders(defaultShowColumnHeaders);
1247
+ setShowActions(defaultShowActions);
1248
+ setAlwaysShowActions(false);
1249
+ setHiddenKeys(defaultHiddenKeys);
1250
+ setPinnedKeys(defaultPinnedKeys);
1251
+ }, [
1252
+ setGroupBy,
1253
+ setOrderBy,
1254
+ setOrderDir,
1255
+ defaultOrderByValue,
1256
+ setShowColumnHeaders,
1257
+ setShowActions,
1258
+ setAlwaysShowActions,
1259
+ setHiddenKeys,
1260
+ setPinnedKeys,
1261
+ defaultGroupByValue,
1262
+ defaultHiddenKeys,
1263
+ defaultPinnedKeys,
1264
+ defaultShowColumnHeaders,
1265
+ defaultShowActions
1266
+ ]);
1259
1267
  return {
1260
- triggerRef,
1261
- coords,
1262
- scheduleOpen,
1263
- scheduleClose,
1264
- keepOpen
1268
+ columns,
1269
+ visibleColumns,
1270
+ columnClasses,
1271
+ isVisible,
1272
+ pinnedCount,
1273
+ actionsWidth,
1274
+ toggleColumn,
1275
+ groupBys,
1276
+ groupBy,
1277
+ setGroupBy,
1278
+ orderBys: effectiveOrderBys,
1279
+ orderBy,
1280
+ setOrderBy,
1281
+ orderDir,
1282
+ toggleOrderDir,
1283
+ applyOrder,
1284
+ facets,
1285
+ filters,
1286
+ setFacetValues,
1287
+ clearFilters,
1288
+ activeFilterCount: useMemo(() => Object.values(filters).filter((v) => v && v.length > 0).length, [filters]),
1289
+ applyFilters: useCallback((rows) => rows.filter((row) => facets.every((f) => {
1290
+ const selected = filters[f.key];
1291
+ return !selected || selected.length === 0 ? true : f.matches(row, selected);
1292
+ })), [facets, filters]),
1293
+ actions,
1294
+ isPinned,
1295
+ togglePinned,
1296
+ showColumnHeaders,
1297
+ toggleColumnHeaders,
1298
+ showActions: effectiveShowActions,
1299
+ toggleShowActions,
1300
+ alwaysShowActions,
1301
+ toggleAlwaysShowActions,
1302
+ isDisplayDefault,
1303
+ resetDisplay
1265
1304
  };
1266
1305
  }
1267
- function HoverCardSurface({ x, y, widthClassName, padded = true, relayoutKey, onKeepOpen, onLeave, children }) {
1268
- const ref = useRef(null);
1269
- const [pos, setPos] = useState(null);
1270
- useLayoutEffect(() => {
1271
- if (!ref.current) return;
1272
- const { width, height } = ref.current.getBoundingClientRect();
1273
- const pad = 8;
1274
- setPos({
1275
- left: Math.max(pad, Math.min(x, window.innerWidth - width - pad)),
1276
- top: y + 8 + height + pad > window.innerHeight ? Math.max(pad, y - 8 - height) : y + 8
1277
- });
1278
- }, [
1306
+ //#endregion
1307
+ //#region src/list/UserHoverCard.tsx
1308
+ /** Opens `card` after a short hover or on focus of `children`. */
1309
+ function HoverCardTrigger({ className, children, card }) {
1310
+ const { triggerRef, coords, scheduleOpen, scheduleClose, keepOpen } = useHoverCard();
1311
+ return /* @__PURE__ */ jsxs("span", {
1312
+ ref: triggerRef,
1313
+ role: "none",
1314
+ className,
1315
+ onMouseEnter: scheduleOpen,
1316
+ onMouseLeave: scheduleClose,
1317
+ onFocus: scheduleOpen,
1318
+ onBlur: scheduleClose,
1319
+ children: [children, coords && card({
1320
+ x: coords.x,
1321
+ y: coords.y,
1322
+ onKeepOpen: keepOpen,
1323
+ onLeave: scheduleClose
1324
+ })]
1325
+ });
1326
+ }
1327
+ function UserHoverCard({ x, y, onKeepOpen, onLeave, username, name, avatarSrc, badge, href, linkComponent, loading = false, relayoutKey, children }) {
1328
+ const strings = useStrings();
1329
+ const SlotLink = useLink();
1330
+ const Link = linkComponent ?? SlotLink;
1331
+ const displayName = name || username;
1332
+ const header = /* @__PURE__ */ jsxs(Fragment$1, { children: [/* @__PURE__ */ jsx(Avatar, {
1333
+ src: avatarSrc,
1334
+ name: displayName,
1335
+ size: "lg",
1336
+ className: "shrink-0"
1337
+ }), /* @__PURE__ */ jsxs("div", {
1338
+ className: "min-w-0",
1339
+ children: [/* @__PURE__ */ jsxs("div", {
1340
+ className: "flex items-center gap-1.5",
1341
+ children: [/* @__PURE__ */ jsx("span", {
1342
+ className: "truncate text-sm font-semibold text-(--theme-app)",
1343
+ children: displayName
1344
+ }), badge && /* @__PURE__ */ jsx("span", {
1345
+ className: "shrink-0 rounded-full bg-(--theme-muted-panel-bg) px-1.5 py-0.5 text-[10px] font-medium leading-none text-(--theme-muted-text-color)",
1346
+ children: badge
1347
+ })]
1348
+ }), /* @__PURE__ */ jsx("div", {
1349
+ className: "truncate text-xs text-(--theme-muted-text-color)",
1350
+ children: username
1351
+ })]
1352
+ })] });
1353
+ return /* @__PURE__ */ jsxs(HoverCardSurface, {
1279
1354
  x,
1280
1355
  y,
1281
- relayoutKey
1282
- ]);
1283
- return createPortal(/* @__PURE__ */ jsx("div", {
1284
- ref,
1285
- role: "none",
1286
- onMouseEnter: onKeepOpen,
1287
- onMouseLeave: onLeave,
1288
- onFocus: onKeepOpen,
1289
- onBlur: onLeave,
1290
- className: cx("fixed z-[9999] overflow-hidden rounded-xl border border-(--theme-border) bg-(--theme-panel-bg) shadow-xl backdrop-blur-xl", padded && "p-3", widthClassName),
1291
- style: {
1292
- left: pos?.left ?? x,
1293
- top: pos?.top ?? y + 8,
1294
- visibility: pos ? "visible" : "hidden"
1295
- },
1356
+ widthClassName: "w-64",
1357
+ relayoutKey,
1358
+ onKeepOpen,
1359
+ onLeave,
1360
+ children: [href ? /* @__PURE__ */ jsx(Link, {
1361
+ to: href,
1362
+ className: "flex items-center gap-3 transition-opacity hover:opacity-80",
1363
+ children: header
1364
+ }) : /* @__PURE__ */ jsx("div", {
1365
+ className: "flex items-center gap-3",
1366
+ children: header
1367
+ }), loading ? /* @__PURE__ */ jsxs("div", {
1368
+ role: "status",
1369
+ "aria-label": strings.loading,
1370
+ className: "mt-3 space-y-2 border-t border-(--theme-border) pt-3",
1371
+ children: [
1372
+ /* @__PURE__ */ jsx("div", {
1373
+ "aria-hidden": "true",
1374
+ className: "h-3 w-24 animate-pulse rounded theme-muted-panel"
1375
+ }),
1376
+ /* @__PURE__ */ jsx("div", {
1377
+ "aria-hidden": "true",
1378
+ className: "h-3 w-36 animate-pulse rounded theme-muted-panel"
1379
+ }),
1380
+ /* @__PURE__ */ jsx("span", {
1381
+ className: "sr-only",
1382
+ children: strings.loading
1383
+ })
1384
+ ]
1385
+ }) : children ? /* @__PURE__ */ jsx("div", {
1386
+ className: "mt-3 space-y-2 border-t border-(--theme-border) pt-3 text-[13px]",
1387
+ children
1388
+ }) : null]
1389
+ });
1390
+ }
1391
+ var rowClasses = "flex gap-2 text-(--theme-muted-text-color)";
1392
+ /** One detail line of a hover card: a leading icon and its content. With
1393
+ * `onClick` the line is a button. */
1394
+ function HoverCardRow({ icon, children, title, align = "center", truncate = false, onClick }) {
1395
+ const content = /* @__PURE__ */ jsxs(Fragment$1, { children: [/* @__PURE__ */ jsx("span", {
1396
+ "aria-hidden": "true",
1397
+ className: cx("flex shrink-0 items-center [&>svg]:h-3.5 [&>svg]:w-3.5", align === "start" && "mt-0.5"),
1398
+ children: icon
1399
+ }), /* @__PURE__ */ jsx("span", {
1400
+ className: cx("min-w-0", truncate && "truncate"),
1296
1401
  children
1297
- }), document.querySelector(".ds-root") ?? document.body);
1402
+ })] });
1403
+ const alignClass = align === "start" ? "items-start" : "items-center";
1404
+ if (onClick) return /* @__PURE__ */ jsx("button", {
1405
+ type: "button",
1406
+ title,
1407
+ onClick,
1408
+ className: cx(rowClasses, alignClass, "-mx-1 max-w-full rounded px-1 py-0.5 text-left transition-colors hover:bg-(--theme-muted-panel-bg) hover:text-(--theme-app)"),
1409
+ children: content
1410
+ });
1411
+ return /* @__PURE__ */ jsx("div", {
1412
+ title,
1413
+ className: cx(rowClasses, alignClass),
1414
+ children: content
1415
+ });
1298
1416
  }
1299
1417
  //#endregion
1300
- export { ActionToolbar as A, ListSkeleton as C, actionsColumnWidth as D, RowSelectCheckbox as E, stickyTabsClasses as M, stickyTabsUnderHeaderClasses as N, listTableFixedProps as O, stickyToolbarClasses as P, ListError as S, NameCell as T, ListRow as _, ListCount as a, GroupRow as b, ListDisplayMenu as c, isTextEntryContext as d, DEFAULT_ORDER as f, ListPage as g, ListColumns as h, ListPager as i, ToolbarButton as j, listTableProps as k, ListFilterMenu as l, useListView as m, useHoverCard as n, ListSearchControl as o, FAVORITE_ORDER as p, LIST_PAGE_SIZES as r, useListSearch as s, HoverCardSurface as t, listControlButtonClasses as u, ListRowActionsProvider as v, NAME_MIN_WIDTH_PX as w, ListActionsHeader as x, useListNavigate as y };
1418
+ export { listTableProps as A, ListError as C, RowSelectCheckbox as D, NameCell as E, stickyTabsClasses as F, stickyTabsUnderHeaderClasses as I, stickyToolbarClasses as L, useHoverCard as M, ActionToolbar as N, actionsColumnWidth as O, ToolbarButton as P, ListActionsHeader as S, NAME_MIN_WIDTH_PX as T, ListPage as _, FAVORITE_ORDER as a, useListNavigate as b, ListSearchControl as c, ListPager as d, ListDisplayMenu as f, ListColumns as g, isTextEntryContext as h, DEFAULT_ORDER as i, HoverCardSurface as j, listTableFixedProps as k, useListSearch as l, listControlButtonClasses as m, HoverCardTrigger as n, useListView as o, ListFilterMenu as p, UserHoverCard as r, ListCount as s, HoverCardRow as t, LIST_PAGE_SIZES as u, ListRow as v, ListSkeleton as w, GroupRow as x, ListRowActionsProvider as y };