@flanksource/clicky-ui 0.2.12 → 0.2.13

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 (168) hide show
  1. package/dist/components/Combobox.cjs +47 -33
  2. package/dist/components/Combobox.cjs.map +1 -1
  3. package/dist/components/Combobox.d.ts +12 -0
  4. package/dist/components/Combobox.d.ts.map +1 -1
  5. package/dist/components/Combobox.js +48 -34
  6. package/dist/components/Combobox.js.map +1 -1
  7. package/dist/components/IconButton.cjs +26 -0
  8. package/dist/components/IconButton.cjs.map +1 -0
  9. package/dist/components/IconButton.d.ts +25 -0
  10. package/dist/components/IconButton.d.ts.map +1 -0
  11. package/dist/components/IconButton.js +26 -0
  12. package/dist/components/IconButton.js.map +1 -0
  13. package/dist/components/SecretKeySelector.cjs +151 -0
  14. package/dist/components/SecretKeySelector.cjs.map +1 -0
  15. package/dist/components/SecretKeySelector.d.ts +47 -0
  16. package/dist/components/SecretKeySelector.d.ts.map +1 -0
  17. package/dist/components/SecretKeySelector.js +151 -0
  18. package/dist/components/SecretKeySelector.js.map +1 -0
  19. package/dist/components/WorkloadPicker.cjs +144 -0
  20. package/dist/components/WorkloadPicker.cjs.map +1 -0
  21. package/dist/components/WorkloadPicker.d.ts +52 -0
  22. package/dist/components/WorkloadPicker.d.ts.map +1 -0
  23. package/dist/components/WorkloadPicker.js +144 -0
  24. package/dist/components/WorkloadPicker.js.map +1 -0
  25. package/dist/components/icon-menu-picker.cjs +83 -112
  26. package/dist/components/icon-menu-picker.cjs.map +1 -1
  27. package/dist/components/icon-menu-picker.d.ts.map +1 -1
  28. package/dist/components/icon-menu-picker.js +85 -114
  29. package/dist/components/icon-menu-picker.js.map +1 -1
  30. package/dist/components.cjs +10 -0
  31. package/dist/components.cjs.map +1 -1
  32. package/dist/components.d.ts +3 -0
  33. package/dist/components.d.ts.map +1 -1
  34. package/dist/components.js +11 -1
  35. package/dist/components.js.map +1 -1
  36. package/dist/data/Clicky.cjs +1 -1
  37. package/dist/data/Clicky.cjs.map +1 -1
  38. package/dist/data/Clicky.js +1 -1
  39. package/dist/data/Clicky.js.map +1 -1
  40. package/dist/data/Version.cjs +42 -0
  41. package/dist/data/Version.cjs.map +1 -0
  42. package/dist/data/Version.d.ts +36 -0
  43. package/dist/data/Version.d.ts.map +1 -0
  44. package/dist/data/Version.js +42 -0
  45. package/dist/data/Version.js.map +1 -0
  46. package/dist/data/test-runner/TestDetailPanel.cjs +165 -0
  47. package/dist/data/test-runner/TestDetailPanel.cjs.map +1 -0
  48. package/dist/data/test-runner/TestDetailPanel.d.ts +7 -0
  49. package/dist/data/test-runner/TestDetailPanel.d.ts.map +1 -0
  50. package/dist/data/test-runner/TestDetailPanel.js +165 -0
  51. package/dist/data/test-runner/TestDetailPanel.js.map +1 -0
  52. package/dist/data/test-runner/TestFailureDetail.cjs +78 -0
  53. package/dist/data/test-runner/TestFailureDetail.cjs.map +1 -0
  54. package/dist/data/test-runner/TestFailureDetail.d.ts +14 -0
  55. package/dist/data/test-runner/TestFailureDetail.d.ts.map +1 -0
  56. package/dist/data/test-runner/TestFailureDetail.js +78 -0
  57. package/dist/data/test-runner/TestFailureDetail.js.map +1 -0
  58. package/dist/data/test-runner/TestFilterBar.cjs +108 -0
  59. package/dist/data/test-runner/TestFilterBar.cjs.map +1 -0
  60. package/dist/data/test-runner/TestFilterBar.d.ts +15 -0
  61. package/dist/data/test-runner/TestFilterBar.d.ts.map +1 -0
  62. package/dist/data/test-runner/TestFilterBar.js +108 -0
  63. package/dist/data/test-runner/TestFilterBar.js.map +1 -0
  64. package/dist/data/test-runner/TestRunSummary.cjs +81 -0
  65. package/dist/data/test-runner/TestRunSummary.cjs.map +1 -0
  66. package/dist/data/test-runner/TestRunSummary.d.ts +19 -0
  67. package/dist/data/test-runner/TestRunSummary.d.ts.map +1 -0
  68. package/dist/data/test-runner/TestRunSummary.js +81 -0
  69. package/dist/data/test-runner/TestRunSummary.js.map +1 -0
  70. package/dist/data/test-runner/TestRunner.cjs +143 -0
  71. package/dist/data/test-runner/TestRunner.cjs.map +1 -0
  72. package/dist/data/test-runner/TestRunner.d.ts +42 -0
  73. package/dist/data/test-runner/TestRunner.d.ts.map +1 -0
  74. package/dist/data/test-runner/TestRunner.fixtures.d.ts +26 -0
  75. package/dist/data/test-runner/TestRunner.fixtures.d.ts.map +1 -0
  76. package/dist/data/test-runner/TestRunner.js +143 -0
  77. package/dist/data/test-runner/TestRunner.js.map +1 -0
  78. package/dist/data/test-runner/TestTree.cjs +42 -0
  79. package/dist/data/test-runner/TestTree.cjs.map +1 -0
  80. package/dist/data/test-runner/TestTree.d.ts +9 -0
  81. package/dist/data/test-runner/TestTree.d.ts.map +1 -0
  82. package/dist/data/test-runner/TestTree.js +42 -0
  83. package/dist/data/test-runner/TestTree.js.map +1 -0
  84. package/dist/data/test-runner/TestTreeNode.cjs +99 -0
  85. package/dist/data/test-runner/TestTreeNode.cjs.map +1 -0
  86. package/dist/data/test-runner/TestTreeNode.d.ts +12 -0
  87. package/dist/data/test-runner/TestTreeNode.d.ts.map +1 -0
  88. package/dist/data/test-runner/TestTreeNode.js +99 -0
  89. package/dist/data/test-runner/TestTreeNode.js.map +1 -0
  90. package/dist/data/test-runner/adapter.cjs +57 -0
  91. package/dist/data/test-runner/adapter.cjs.map +1 -0
  92. package/dist/data/test-runner/adapter.d.ts +60 -0
  93. package/dist/data/test-runner/adapter.d.ts.map +1 -0
  94. package/dist/data/test-runner/adapter.js +57 -0
  95. package/dist/data/test-runner/adapter.js.map +1 -0
  96. package/dist/data/test-runner/context.cjs +15 -0
  97. package/dist/data/test-runner/context.cjs.map +1 -0
  98. package/dist/data/test-runner/context.d.ts +40 -0
  99. package/dist/data/test-runner/context.d.ts.map +1 -0
  100. package/dist/data/test-runner/context.js +15 -0
  101. package/dist/data/test-runner/context.js.map +1 -0
  102. package/dist/data/test-runner/filterState.cjs +47 -0
  103. package/dist/data/test-runner/filterState.cjs.map +1 -0
  104. package/dist/data/test-runner/filterState.d.ts +14 -0
  105. package/dist/data/test-runner/filterState.d.ts.map +1 -0
  106. package/dist/data/test-runner/filterState.js +47 -0
  107. package/dist/data/test-runner/filterState.js.map +1 -0
  108. package/dist/data/test-runner/frameworkIcon.cjs +27 -0
  109. package/dist/data/test-runner/frameworkIcon.cjs.map +1 -0
  110. package/dist/data/test-runner/frameworkIcon.d.ts +3 -0
  111. package/dist/data/test-runner/frameworkIcon.d.ts.map +1 -0
  112. package/dist/data/test-runner/frameworkIcon.js +27 -0
  113. package/dist/data/test-runner/frameworkIcon.js.map +1 -0
  114. package/dist/data/test-runner/index.d.ts +14 -0
  115. package/dist/data/test-runner/index.d.ts.map +1 -0
  116. package/dist/data/test-runner/status.cjs +234 -0
  117. package/dist/data/test-runner/status.cjs.map +1 -0
  118. package/dist/data/test-runner/status.d.ts +52 -0
  119. package/dist/data/test-runner/status.d.ts.map +1 -0
  120. package/dist/data/test-runner/status.js +234 -0
  121. package/dist/data/test-runner/status.js.map +1 -0
  122. package/dist/data/test-runner/types.d.ts +148 -0
  123. package/dist/data/test-runner/types.d.ts.map +1 -0
  124. package/dist/data/version-info.cjs +26 -0
  125. package/dist/data/version-info.cjs.map +1 -0
  126. package/dist/data/version-info.d.ts +11 -0
  127. package/dist/data/version-info.d.ts.map +1 -0
  128. package/dist/data/version-info.js +26 -0
  129. package/dist/data/version-info.js.map +1 -0
  130. package/dist/data.cjs +49 -0
  131. package/dist/data.cjs.map +1 -1
  132. package/dist/data.d.ts +3 -0
  133. package/dist/data.d.ts.map +1 -1
  134. package/dist/data.js +50 -1
  135. package/dist/data.js.map +1 -1
  136. package/dist/index.cjs +59 -0
  137. package/dist/index.cjs.map +1 -1
  138. package/dist/index.js +60 -1
  139. package/dist/index.js.map +1 -1
  140. package/dist/overlay/DropdownMenu.cjs +57 -30
  141. package/dist/overlay/DropdownMenu.cjs.map +1 -1
  142. package/dist/overlay/DropdownMenu.d.ts.map +1 -1
  143. package/dist/overlay/DropdownMenu.js +57 -30
  144. package/dist/overlay/DropdownMenu.js.map +1 -1
  145. package/dist/overlay/Modal.cjs +62 -6
  146. package/dist/overlay/Modal.cjs.map +1 -1
  147. package/dist/overlay/Modal.d.ts +19 -1
  148. package/dist/overlay/Modal.d.ts.map +1 -1
  149. package/dist/overlay/Modal.js +62 -6
  150. package/dist/overlay/Modal.js.map +1 -1
  151. package/dist/rpc/CommandForm.cjs +2 -2
  152. package/dist/rpc/CommandForm.cjs.map +1 -1
  153. package/dist/rpc/CommandForm.d.ts.map +1 -1
  154. package/dist/rpc/CommandForm.js +3 -3
  155. package/dist/rpc/CommandForm.js.map +1 -1
  156. package/dist/rpc/formMetadata.cjs +5 -4
  157. package/dist/rpc/formMetadata.cjs.map +1 -1
  158. package/dist/rpc/formMetadata.d.ts.map +1 -1
  159. package/dist/rpc/formMetadata.js +6 -5
  160. package/dist/rpc/formMetadata.js.map +1 -1
  161. package/dist/rpc/types.cjs +4 -0
  162. package/dist/rpc/types.cjs.map +1 -1
  163. package/dist/rpc/types.d.ts +10 -0
  164. package/dist/rpc/types.d.ts.map +1 -1
  165. package/dist/rpc/types.js +5 -1
  166. package/dist/rpc/types.js.map +1 -1
  167. package/dist/styles.css +1 -1
  168. package/package.json +3 -1
@@ -1,8 +1,10 @@
1
- import { jsxs, jsx, Fragment } from "react/jsx-runtime";
2
- import { forwardRef, useRef, useState, useImperativeHandle, useMemo, useCallback, useEffect } from "react";
1
+ import { jsxs, jsx } from "react/jsx-runtime";
2
+ import { forwardRef, useState, useRef, useMemo } from "react";
3
+ import { useFloating, autoUpdate, offset, flip, shift, useClick, useDismiss, useRole, useListNavigation, useTypeahead, useInteractions, useMergeRefs, FloatingPortal, FloatingFocusManager } from "@floating-ui/react";
3
4
  import { cn } from "../lib/utils.js";
4
5
  import { Icon } from "../data/Icon.js";
5
6
  import { Button } from "./button.js";
7
+ import { IconButton } from "./IconButton.js";
6
8
  import { UiChevronDown } from "../icons/components/UiChevronDown.js";
7
9
  import { UiCheck } from "../icons/components/UiCheck.js";
8
10
  function IconMenuPickerInner({
@@ -16,137 +18,104 @@ function IconMenuPickerInner({
16
18
  className,
17
19
  triggerClassName,
18
20
  menuClassName
19
- }, ref) {
20
- const rootRef = useRef(null);
21
- const triggerRef = useRef(null);
22
- const itemRefs = useRef([]);
21
+ }, forwardedRef) {
23
22
  const [open, setOpen] = useState(false);
24
- useImperativeHandle(ref, () => rootRef.current);
25
- const activeIndex = useMemo(
26
- () => Math.max(
27
- 0,
28
- options.findIndex((option) => option.value === value)
29
- ),
23
+ const [activeIndex, setActiveIndex] = useState(null);
24
+ const listRef = useRef([]);
25
+ const labelsRef = useRef(options.map((o) => o.label));
26
+ labelsRef.current = options.map((o) => o.label);
27
+ const selectedIndex = useMemo(
28
+ () => options.findIndex((option) => option.value === value),
30
29
  [options, value]
31
30
  );
32
- const close = useCallback((returnFocus) => {
33
- var _a;
31
+ const { refs, floatingStyles, context } = useFloating({
32
+ open,
33
+ onOpenChange: setOpen,
34
+ placement: "bottom-start",
35
+ whileElementsMounted: autoUpdate,
36
+ // offset(6) reproduces the previous 0.375rem gap; flip opens the menu
37
+ // upward when the trigger is near the bottom edge; shift slides it back
38
+ // on-screen at the left/right edges. The 8px padding keeps a gutter.
39
+ middleware: [offset(6), flip({ padding: 8 }), shift({ padding: 8 })]
40
+ });
41
+ const click = useClick(context);
42
+ const dismiss = useDismiss(context);
43
+ const role = useRole(context, { role: "menu" });
44
+ const listNav = useListNavigation(context, {
45
+ listRef,
46
+ activeIndex,
47
+ selectedIndex,
48
+ onNavigate: setActiveIndex,
49
+ loop: true
50
+ });
51
+ const typeahead = useTypeahead(context, {
52
+ listRef: labelsRef,
53
+ activeIndex,
54
+ onMatch: setActiveIndex
55
+ });
56
+ const { getReferenceProps, getFloatingProps, getItemProps } = useInteractions([
57
+ click,
58
+ dismiss,
59
+ role,
60
+ listNav,
61
+ typeahead
62
+ ]);
63
+ const referenceRef = useMergeRefs([refs.setReference, forwardedRef]);
64
+ const select = (next) => {
65
+ onChange(next);
34
66
  setOpen(false);
35
- if (returnFocus) (_a = triggerRef.current) == null ? void 0 : _a.focus();
36
- }, []);
37
- const select = useCallback(
38
- (next) => {
39
- onChange(next);
40
- close(true);
41
- },
42
- [close, onChange]
43
- );
44
- useEffect(() => {
45
- if (!open) return;
46
- const onPointerDown = (event) => {
47
- var _a;
48
- if (event.button !== 0) return;
49
- if (!((_a = rootRef.current) == null ? void 0 : _a.contains(event.target))) {
50
- close(false);
51
- }
52
- };
53
- const onKeyDown = (event) => {
54
- if (event.key === "Escape") {
55
- event.preventDefault();
56
- close(true);
57
- }
58
- };
59
- document.addEventListener("pointerdown", onPointerDown);
60
- document.addEventListener("keydown", onKeyDown);
61
- return () => {
62
- document.removeEventListener("pointerdown", onPointerDown);
63
- document.removeEventListener("keydown", onKeyDown);
64
- };
65
- }, [close, open]);
66
- useEffect(() => {
67
- if (!open) return;
68
- const node = itemRefs.current[activeIndex];
69
- node == null ? void 0 : node.focus();
70
- }, [activeIndex, open]);
71
- const focusItem = (index) => {
72
- var _a;
73
- const wrapped = (index + options.length) % options.length;
74
- (_a = itemRefs.current[wrapped]) == null ? void 0 : _a.focus();
75
67
  };
76
- const onMenuKeyDown = (event) => {
77
- const focusedIndex = itemRefs.current.findIndex((node) => node === document.activeElement);
78
- if (event.key === "ArrowDown") {
79
- event.preventDefault();
80
- focusItem((focusedIndex < 0 ? activeIndex : focusedIndex) + 1);
81
- return;
82
- }
83
- if (event.key === "ArrowUp") {
84
- event.preventDefault();
85
- focusItem((focusedIndex < 0 ? activeIndex : focusedIndex) - 1);
86
- return;
87
- }
88
- if (event.key === "Home") {
89
- event.preventDefault();
90
- focusItem(0);
91
- return;
92
- }
93
- if (event.key === "End") {
94
- event.preventDefault();
95
- focusItem(options.length - 1);
96
- return;
97
- }
98
- if (event.key === "Tab") {
99
- close(false);
100
- }
101
- };
102
- const onTriggerKeyDown = (event) => {
103
- if (event.key === "ArrowDown" || event.key === "Enter" || event.key === " ") {
104
- event.preventDefault();
105
- setOpen(true);
106
- }
107
- };
108
- const selected = options[activeIndex];
68
+ const selected = options[selectedIndex];
109
69
  if (!selected) {
110
70
  throw new Error(`IconMenuPicker: value "${value}" not found in options for ${ariaLabel}`);
111
71
  }
112
- return /* @__PURE__ */ jsxs("div", { ref: rootRef, className: cn("relative inline-flex", showLabel && "w-full", className), children: [
113
- /* @__PURE__ */ jsxs(
72
+ const triggerTitleText = triggerTitle ?? `${ariaLabel}: ${selected.label}`;
73
+ return /* @__PURE__ */ jsxs("div", { ref: referenceRef, className: cn("relative inline-flex", showLabel && "w-full", className), children: [
74
+ showLabel ? /* @__PURE__ */ jsxs(
114
75
  Button,
115
76
  {
116
- ref: triggerRef,
117
77
  type: "button",
118
78
  variant: "ghost",
119
- size: showLabel ? "default" : "icon",
79
+ size: "default",
120
80
  "aria-label": ariaLabel,
121
81
  "aria-haspopup": "menu",
122
82
  "aria-expanded": open,
123
- title: triggerTitle ?? `${ariaLabel}: ${selected.label}`,
124
- onClick: () => setOpen((current) => !current),
125
- onKeyDown: onTriggerKeyDown,
83
+ title: triggerTitleText,
126
84
  className: cn(
127
- "text-muted-foreground hover:text-foreground",
128
- showLabel && "w-full justify-start",
85
+ "w-full justify-start text-muted-foreground hover:text-foreground",
129
86
  triggerClassName
130
87
  ),
88
+ ...getReferenceProps(),
131
89
  children: [
132
- /* @__PURE__ */ jsx(Icon, { icon: selected.icon, ...showLabel ? { className: "shrink-0 text-foreground" } : {} }),
133
- showLabel && /* @__PURE__ */ jsxs(Fragment, { children: [
134
- /* @__PURE__ */ jsx("span", { className: "min-w-0 flex-1 truncate text-left capitalize", children: `${ariaLabel}: ${selected.label}` }),
135
- /* @__PURE__ */ jsx(Icon, { icon: UiChevronDown, className: "shrink-0 text-muted-foreground" })
136
- ] })
90
+ /* @__PURE__ */ jsx(Icon, { icon: selected.icon, className: "shrink-0 text-foreground" }),
91
+ /* @__PURE__ */ jsx("span", { className: "min-w-0 flex-1 truncate text-left capitalize", children: `${ariaLabel}: ${selected.label}` }),
92
+ /* @__PURE__ */ jsx(Icon, { icon: UiChevronDown, className: "shrink-0 text-muted-foreground" })
137
93
  ]
138
94
  }
95
+ ) : /* @__PURE__ */ jsx(
96
+ IconButton,
97
+ {
98
+ icon: selected.icon,
99
+ label: ariaLabel,
100
+ title: triggerTitleText,
101
+ "aria-haspopup": "menu",
102
+ "aria-expanded": open,
103
+ className: triggerClassName,
104
+ ...getReferenceProps()
105
+ }
139
106
  ),
140
- open && /* @__PURE__ */ jsxs(
107
+ open && /* @__PURE__ */ jsx(FloatingPortal, { children: /* @__PURE__ */ jsx(FloatingFocusManager, { context, modal: false, initialFocus: selectedIndex, children: /* @__PURE__ */ jsxs(
141
108
  "div",
142
109
  {
110
+ ref: refs.setFloating,
143
111
  role: "menu",
144
112
  "aria-label": ariaLabel,
145
- onKeyDown: onMenuKeyDown,
113
+ style: floatingStyles,
146
114
  className: cn(
147
- "absolute left-0 top-[calc(100%+0.375rem)] z-50 min-w-[12rem] rounded-md border border-border bg-popover p-1 text-popover-foreground shadow-lg shadow-black/5",
115
+ "z-[9999] min-w-[12rem] rounded-md border border-border bg-popover p-1 text-popover-foreground shadow-lg shadow-black/5",
148
116
  menuClassName
149
117
  ),
118
+ ...getFloatingProps(),
150
119
  children: [
151
120
  options.map((option, index) => {
152
121
  const active = option.value === value;
@@ -154,24 +123,26 @@ function IconMenuPickerInner({
154
123
  "button",
155
124
  {
156
125
  ref: (node) => {
157
- itemRefs.current[index] = node;
126
+ listRef.current[index] = node;
158
127
  },
159
128
  type: "button",
160
129
  role: "menuitemradio",
161
130
  "aria-checked": active,
162
- tabIndex: active ? 0 : -1,
163
- onClick: () => select(option.value),
164
- onKeyDown: (event) => {
165
- if (event.key === "Enter" || event.key === " ") {
166
- event.preventDefault();
167
- select(option.value);
168
- }
169
- },
131
+ tabIndex: index === activeIndex ? 0 : -1,
170
132
  className: cn(
171
133
  "flex w-full items-center gap-2 rounded-sm px-2 py-1.5 text-left text-sm transition-colors",
172
134
  "hover:bg-accent hover:text-accent-foreground focus:bg-accent focus:text-accent-foreground focus:outline-none",
173
135
  active && "text-foreground"
174
136
  ),
137
+ ...getItemProps({
138
+ onClick: () => select(option.value),
139
+ onKeyDown: (event) => {
140
+ if (event.key === "Enter" || event.key === " ") {
141
+ event.preventDefault();
142
+ select(option.value);
143
+ }
144
+ }
145
+ }),
175
146
  children: [
176
147
  /* @__PURE__ */ jsx(Icon, { icon: option.icon, className: "shrink-0 text-muted-foreground" }),
177
148
  /* @__PURE__ */ jsx("span", { className: "min-w-0 flex-1 truncate capitalize", children: option.label }),
@@ -184,7 +155,7 @@ function IconMenuPickerInner({
184
155
  footer ? /* @__PURE__ */ jsx("div", { className: "mt-1 border-t border-border/60 px-2 py-1.5 text-[11px] text-muted-foreground", children: footer }) : null
185
156
  ]
186
157
  }
187
- )
158
+ ) }) })
188
159
  ] });
189
160
  }
190
161
  const IconMenuPicker = forwardRef(IconMenuPickerInner);
@@ -1 +1 @@
1
- {"version":3,"file":"icon-menu-picker.js","sources":["../../src/components/icon-menu-picker.tsx"],"sourcesContent":["import {\n forwardRef,\n useCallback,\n useEffect,\n useImperativeHandle,\n useMemo,\n useRef,\n useState,\n type KeyboardEvent as ReactKeyboardEvent,\n type ReactNode,\n} from \"react\";\nimport { cn } from \"../lib/utils\";\nimport { Icon, type StaticIconComponent } from \"../data/Icon\";\nimport { UiCheck, UiChevronDown } from \"../icons\";\nimport { Button } from \"./button\";\n\nexport type IconMenuOption<T extends string> = {\n value: T;\n icon: StaticIconComponent;\n label: string;\n description?: string;\n};\n\nexport type IconMenuPickerProps<T extends string> = {\n value: T;\n onChange: (next: T) => void;\n options: IconMenuOption<T>[];\n ariaLabel: string;\n triggerTitle?: string | undefined;\n footer?: ReactNode | undefined;\n showLabel?: boolean | undefined;\n className?: string | undefined;\n triggerClassName?: string | undefined;\n menuClassName?: string | undefined;\n};\n\nfunction IconMenuPickerInner<T extends string>(\n {\n value,\n onChange,\n options,\n ariaLabel,\n triggerTitle,\n footer,\n showLabel,\n className,\n triggerClassName,\n menuClassName,\n }: IconMenuPickerProps<T>,\n ref: React.Ref<HTMLDivElement>,\n) {\n const rootRef = useRef<HTMLDivElement>(null);\n const triggerRef = useRef<HTMLButtonElement>(null);\n const itemRefs = useRef<(HTMLButtonElement | null)[]>([]);\n const [open, setOpen] = useState(false);\n\n useImperativeHandle(ref, () => rootRef.current as HTMLDivElement);\n\n const activeIndex = useMemo(\n () =>\n Math.max(\n 0,\n options.findIndex((option) => option.value === value),\n ),\n [options, value],\n );\n\n const close = useCallback((returnFocus: boolean) => {\n setOpen(false);\n if (returnFocus) triggerRef.current?.focus();\n }, []);\n\n const select = useCallback(\n (next: T) => {\n onChange(next);\n close(true);\n },\n [close, onChange],\n );\n\n useEffect(() => {\n if (!open) return;\n\n const onPointerDown = (event: PointerEvent) => {\n if (event.button !== 0) return;\n if (!rootRef.current?.contains(event.target as Node)) {\n close(false);\n }\n };\n\n const onKeyDown = (event: KeyboardEvent) => {\n if (event.key === \"Escape\") {\n event.preventDefault();\n close(true);\n }\n };\n\n document.addEventListener(\"pointerdown\", onPointerDown);\n document.addEventListener(\"keydown\", onKeyDown);\n return () => {\n document.removeEventListener(\"pointerdown\", onPointerDown);\n document.removeEventListener(\"keydown\", onKeyDown);\n };\n }, [close, open]);\n\n useEffect(() => {\n if (!open) return;\n const node = itemRefs.current[activeIndex];\n node?.focus();\n }, [activeIndex, open]);\n\n const focusItem = (index: number) => {\n const wrapped = (index + options.length) % options.length;\n itemRefs.current[wrapped]?.focus();\n };\n\n const onMenuKeyDown = (event: ReactKeyboardEvent<HTMLDivElement>) => {\n const focusedIndex = itemRefs.current.findIndex((node) => node === document.activeElement);\n if (event.key === \"ArrowDown\") {\n event.preventDefault();\n focusItem((focusedIndex < 0 ? activeIndex : focusedIndex) + 1);\n return;\n }\n if (event.key === \"ArrowUp\") {\n event.preventDefault();\n focusItem((focusedIndex < 0 ? activeIndex : focusedIndex) - 1);\n return;\n }\n if (event.key === \"Home\") {\n event.preventDefault();\n focusItem(0);\n return;\n }\n if (event.key === \"End\") {\n event.preventDefault();\n focusItem(options.length - 1);\n return;\n }\n if (event.key === \"Tab\") {\n close(false);\n }\n };\n\n const onTriggerKeyDown = (event: ReactKeyboardEvent<HTMLButtonElement>) => {\n if (event.key === \"ArrowDown\" || event.key === \"Enter\" || event.key === \" \") {\n event.preventDefault();\n setOpen(true);\n }\n };\n\n const selected = options[activeIndex];\n if (!selected) {\n throw new Error(`IconMenuPicker: value \"${value}\" not found in options for ${ariaLabel}`);\n }\n\n return (\n <div ref={rootRef} className={cn(\"relative inline-flex\", showLabel && \"w-full\", className)}>\n <Button\n ref={triggerRef}\n type=\"button\"\n variant=\"ghost\"\n size={showLabel ? \"default\" : \"icon\"}\n aria-label={ariaLabel}\n aria-haspopup=\"menu\"\n aria-expanded={open}\n title={triggerTitle ?? `${ariaLabel}: ${selected.label}`}\n onClick={() => setOpen((current) => !current)}\n onKeyDown={onTriggerKeyDown}\n className={cn(\n \"text-muted-foreground hover:text-foreground\",\n showLabel && \"w-full justify-start\",\n triggerClassName,\n )}\n >\n <Icon icon={selected.icon} {...(showLabel ? { className: \"shrink-0 text-foreground\" } : {})} />\n {showLabel && (\n <>\n <span className=\"min-w-0 flex-1 truncate text-left capitalize\">\n {`${ariaLabel}: ${selected.label}`}\n </span>\n <Icon icon={UiChevronDown} className=\"shrink-0 text-muted-foreground\" />\n </>\n )}\n </Button>\n {open && (\n <div\n role=\"menu\"\n aria-label={ariaLabel}\n onKeyDown={onMenuKeyDown}\n className={cn(\n \"absolute left-0 top-[calc(100%+0.375rem)] z-50 min-w-[12rem] rounded-md border border-border bg-popover p-1 text-popover-foreground shadow-lg shadow-black/5\",\n menuClassName,\n )}\n >\n {options.map((option, index) => {\n const active = option.value === value;\n return (\n <button\n key={option.value}\n ref={(node) => {\n itemRefs.current[index] = node;\n }}\n type=\"button\"\n role=\"menuitemradio\"\n aria-checked={active}\n tabIndex={active ? 0 : -1}\n onClick={() => select(option.value)}\n onKeyDown={(event) => {\n if (event.key === \"Enter\" || event.key === \" \") {\n event.preventDefault();\n select(option.value);\n }\n }}\n className={cn(\n \"flex w-full items-center gap-2 rounded-sm px-2 py-1.5 text-left text-sm transition-colors\",\n \"hover:bg-accent hover:text-accent-foreground focus:bg-accent focus:text-accent-foreground focus:outline-none\",\n active && \"text-foreground\",\n )}\n >\n <Icon icon={option.icon} className=\"shrink-0 text-muted-foreground\" />\n <span className=\"min-w-0 flex-1 truncate capitalize\">{option.label}</span>\n {active ? (\n <Icon icon={UiCheck} className=\"shrink-0 text-foreground\" />\n ) : (\n <span className=\"inline-block size-4 shrink-0\" aria-hidden />\n )}\n </button>\n );\n })}\n {footer ? (\n <div className=\"mt-1 border-t border-border/60 px-2 py-1.5 text-[11px] text-muted-foreground\">\n {footer}\n </div>\n ) : null}\n </div>\n )}\n </div>\n );\n}\n\nexport const IconMenuPicker = forwardRef(IconMenuPickerInner) as <T extends string>(\n props: IconMenuPickerProps<T> & { ref?: React.Ref<HTMLDivElement> },\n) => JSX.Element;\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"icon-menu-picker.js","sources":["../../src/components/icon-menu-picker.tsx"],"sourcesContent":["import {\n forwardRef,\n useMemo,\n useRef,\n useState,\n type ReactNode,\n} from \"react\";\nimport {\n autoUpdate,\n flip,\n FloatingFocusManager,\n FloatingPortal,\n offset,\n shift,\n useClick,\n useDismiss,\n useFloating,\n useInteractions,\n useListNavigation,\n useMergeRefs,\n useRole,\n useTypeahead,\n} from \"@floating-ui/react\";\nimport { cn } from \"../lib/utils\";\nimport { Icon, type StaticIconComponent } from \"../data/Icon\";\nimport { UiCheck, UiChevronDown } from \"../icons\";\nimport { Button } from \"./button\";\nimport { IconButton } from \"./IconButton\";\n\nexport type IconMenuOption<T extends string> = {\n value: T;\n icon: StaticIconComponent;\n label: string;\n description?: string;\n};\n\nexport type IconMenuPickerProps<T extends string> = {\n value: T;\n onChange: (next: T) => void;\n options: IconMenuOption<T>[];\n ariaLabel: string;\n triggerTitle?: string | undefined;\n footer?: ReactNode | undefined;\n showLabel?: boolean | undefined;\n className?: string | undefined;\n triggerClassName?: string | undefined;\n menuClassName?: string | undefined;\n};\n\nfunction IconMenuPickerInner<T extends string>(\n {\n value,\n onChange,\n options,\n ariaLabel,\n triggerTitle,\n footer,\n showLabel,\n className,\n triggerClassName,\n menuClassName,\n }: IconMenuPickerProps<T>,\n forwardedRef: React.Ref<HTMLDivElement>,\n) {\n const [open, setOpen] = useState(false);\n // Index of the item highlighted by keyboard navigation. Null until the user\n // arrows/typeaheads, so a pointer-opened menu starts with the selected row\n // focused (selectedIndex below) rather than the first.\n const [activeIndex, setActiveIndex] = useState<number | null>(null);\n const listRef = useRef<(HTMLElement | null)[]>([]);\n const labelsRef = useRef<string[]>(options.map((o) => o.label));\n labelsRef.current = options.map((o) => o.label);\n\n const selectedIndex = useMemo(\n () => options.findIndex((option) => option.value === value),\n [options, value],\n );\n\n const { refs, floatingStyles, context } = useFloating<HTMLDivElement>({\n open,\n onOpenChange: setOpen,\n placement: \"bottom-start\",\n whileElementsMounted: autoUpdate,\n // offset(6) reproduces the previous 0.375rem gap; flip opens the menu\n // upward when the trigger is near the bottom edge; shift slides it back\n // on-screen at the left/right edges. The 8px padding keeps a gutter.\n middleware: [offset(6), flip({ padding: 8 }), shift({ padding: 8 })],\n });\n\n const click = useClick(context);\n const dismiss = useDismiss(context);\n const role = useRole(context, { role: \"menu\" });\n const listNav = useListNavigation(context, {\n listRef,\n activeIndex,\n selectedIndex,\n onNavigate: setActiveIndex,\n loop: true,\n });\n const typeahead = useTypeahead(context, {\n listRef: labelsRef,\n activeIndex,\n onMatch: setActiveIndex,\n });\n\n const { getReferenceProps, getFloatingProps, getItemProps } = useInteractions([\n click,\n dismiss,\n role,\n listNav,\n typeahead,\n ]);\n\n // Keep the trigger wrapper available both to floating-ui (as the positioning\n // reference) and to the consumer's forwarded ref.\n const referenceRef = useMergeRefs([refs.setReference, forwardedRef]);\n\n const select = (next: T) => {\n onChange(next);\n setOpen(false);\n };\n\n const selected = options[selectedIndex];\n if (!selected) {\n throw new Error(`IconMenuPicker: value \"${value}\" not found in options for ${ariaLabel}`);\n }\n\n const triggerTitleText = triggerTitle ?? `${ariaLabel}: ${selected.label}`;\n\n return (\n <div ref={referenceRef} className={cn(\"relative inline-flex\", showLabel && \"w-full\", className)}>\n {showLabel ? (\n <Button\n type=\"button\"\n variant=\"ghost\"\n size=\"default\"\n aria-label={ariaLabel}\n aria-haspopup=\"menu\"\n aria-expanded={open}\n title={triggerTitleText}\n className={cn(\n \"w-full justify-start text-muted-foreground hover:text-foreground\",\n triggerClassName,\n )}\n {...getReferenceProps()}\n >\n <Icon icon={selected.icon} className=\"shrink-0 text-foreground\" />\n <span className=\"min-w-0 flex-1 truncate text-left capitalize\">\n {`${ariaLabel}: ${selected.label}`}\n </span>\n <Icon icon={UiChevronDown} className=\"shrink-0 text-muted-foreground\" />\n </Button>\n ) : (\n <IconButton\n icon={selected.icon}\n label={ariaLabel}\n title={triggerTitleText}\n aria-haspopup=\"menu\"\n aria-expanded={open}\n className={triggerClassName}\n {...getReferenceProps()}\n />\n )}\n {open && (\n <FloatingPortal>\n <FloatingFocusManager context={context} modal={false} initialFocus={selectedIndex}>\n <div\n ref={refs.setFloating}\n role=\"menu\"\n aria-label={ariaLabel}\n style={floatingStyles}\n className={cn(\n \"z-[9999] min-w-[12rem] rounded-md border border-border bg-popover p-1 text-popover-foreground shadow-lg shadow-black/5\",\n menuClassName,\n )}\n {...getFloatingProps()}\n >\n {options.map((option, index) => {\n const active = option.value === value;\n return (\n <button\n key={option.value}\n ref={(node) => {\n listRef.current[index] = node;\n }}\n type=\"button\"\n role=\"menuitemradio\"\n aria-checked={active}\n tabIndex={index === activeIndex ? 0 : -1}\n className={cn(\n \"flex w-full items-center gap-2 rounded-sm px-2 py-1.5 text-left text-sm transition-colors\",\n \"hover:bg-accent hover:text-accent-foreground focus:bg-accent focus:text-accent-foreground focus:outline-none\",\n active && \"text-foreground\",\n )}\n {...getItemProps({\n onClick: () => select(option.value),\n onKeyDown: (event) => {\n if (event.key === \"Enter\" || event.key === \" \") {\n event.preventDefault();\n select(option.value);\n }\n },\n })}\n >\n <Icon icon={option.icon} className=\"shrink-0 text-muted-foreground\" />\n <span className=\"min-w-0 flex-1 truncate capitalize\">{option.label}</span>\n {active ? (\n <Icon icon={UiCheck} className=\"shrink-0 text-foreground\" />\n ) : (\n <span className=\"inline-block size-4 shrink-0\" aria-hidden />\n )}\n </button>\n );\n })}\n {footer ? (\n <div className=\"mt-1 border-t border-border/60 px-2 py-1.5 text-[11px] text-muted-foreground\">\n {footer}\n </div>\n ) : null}\n </div>\n </FloatingFocusManager>\n </FloatingPortal>\n )}\n </div>\n );\n}\n\nexport const IconMenuPicker = forwardRef(IconMenuPickerInner) as <T extends string>(\n props: IconMenuPickerProps<T> & { ref?: React.Ref<HTMLDivElement> },\n) => JSX.Element;\n"],"names":[],"mappings":"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"}
@@ -1,6 +1,7 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
3
3
  const button = require("./components/button.cjs");
4
+ const IconButton = require("./components/IconButton.cjs");
4
5
  const SplitButton = require("./components/SplitButton.cjs");
5
6
  const FormatOptionsDropdown = require("./components/FormatOptionsDropdown.cjs");
6
7
  const DateField = require("./components/DateField.cjs");
@@ -12,6 +13,8 @@ const FilterBar = require("./components/FilterBar.cjs");
12
13
  const MultiSelect = require("./components/MultiSelect.cjs");
13
14
  const select = require("./components/select.cjs");
14
15
  const Combobox = require("./components/Combobox.cjs");
16
+ const WorkloadPicker = require("./components/WorkloadPicker.cjs");
17
+ const SecretKeySelector = require("./components/SecretKeySelector.cjs");
15
18
  const themeSwitcher = require("./components/theme-switcher.cjs");
16
19
  const densitySwitcher = require("./components/density-switcher.cjs");
17
20
  const iconMenuPicker = require("./components/icon-menu-picker.cjs");
@@ -25,6 +28,7 @@ const HoverCard = require("./overlay/HoverCard.cjs");
25
28
  const Modal = require("./overlay/Modal.cjs");
26
29
  exports.Button = button.Button;
27
30
  exports.buttonVariants = button.buttonVariants;
31
+ exports.IconButton = IconButton.IconButton;
28
32
  exports.SplitButton = SplitButton.SplitButton;
29
33
  exports.CLICKY_FORMAT_OPTIONS = FormatOptionsDropdown.CLICKY_FORMAT_OPTIONS;
30
34
  exports.FormatOptionsDropdown = FormatOptionsDropdown.FormatOptionsDropdown;
@@ -37,6 +41,12 @@ exports.FilterBar = FilterBar.FilterBar;
37
41
  exports.MultiSelect = MultiSelect.MultiSelect;
38
42
  exports.Select = select.Select;
39
43
  exports.Combobox = Combobox.Combobox;
44
+ exports.WorkloadPicker = WorkloadPicker.WorkloadPicker;
45
+ exports.kindForValue = WorkloadPicker.kindForValue;
46
+ exports.loadedWorkloads = WorkloadPicker.loadedWorkloads;
47
+ exports.parseWorkloadKey = WorkloadPicker.parseWorkloadKey;
48
+ exports.workloadKey = WorkloadPicker.workloadKey;
49
+ exports.SecretKeySelector = SecretKeySelector.SecretKeySelector;
40
50
  exports.ThemeSwitcher = themeSwitcher.ThemeSwitcher;
41
51
  exports.DensitySwitcher = densitySwitcher.DensitySwitcher;
42
52
  exports.IconMenuPicker = iconMenuPicker.IconMenuPicker;
@@ -1 +1 @@
1
- {"version":3,"file":"components.cjs","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
1
+ {"version":3,"file":"components.cjs","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
@@ -1,4 +1,5 @@
1
1
  export { Button, buttonVariants, type ButtonProps } from './components/button';
2
+ export { IconButton, type IconButtonProps } from './components/IconButton';
2
3
  export { SplitButton, type SplitButtonProps } from './components/SplitButton';
3
4
  export { FormatOptionsDropdown, CLICKY_FORMAT_OPTIONS, type FormatOptionsDropdownProps, type FormatOption, } from './components/FormatOptionsDropdown';
4
5
  export { DateField, type DateFieldMode, type DateFieldProps } from './components/DateField';
@@ -10,6 +11,8 @@ export { FilterBar, type FilterBarBooleanFilter, type FilterBarEnumFilter, type
10
11
  export { MultiSelect, type MultiSelectOption, type MultiSelectProps, } from './components/MultiSelect';
11
12
  export { Select, type SelectProps, type SelectOption } from './components/select';
12
13
  export { Combobox, type ComboboxProps, type ComboboxOption, type ComboboxSingleProps, type ComboboxMultiProps, } from './components/Combobox';
14
+ export { WorkloadPicker, workloadKey, parseWorkloadKey, kindForValue, loadedWorkloads, type WorkloadPickerProps, type WorkloadKind, type WorkloadResource, type ParsedWorkloadKey, } from './components/WorkloadPicker';
15
+ export { SecretKeySelector, type SecretKeySelectorProps, type SecretKind, type SecretKeyValue, type SecretResource, type KeyPreview, } from './components/SecretKeySelector';
13
16
  export { ThemeSwitcher, type ThemeSwitcherProps } from './components/theme-switcher';
14
17
  export { DensitySwitcher, type DensitySwitcherProps } from './components/density-switcher';
15
18
  export { IconMenuPicker, type IconMenuPickerProps, type IconMenuOption, } from './components/icon-menu-picker';
@@ -1 +1 @@
1
- {"version":3,"file":"components.d.ts","sourceRoot":"","sources":["../src/components.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"components.d.ts","sourceRoot":"","sources":["../src/components.ts"],"names":[],"mappings":"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"}
@@ -1,4 +1,5 @@
1
1
  import { Button, buttonVariants } from "./components/button.js";
2
+ import { IconButton } from "./components/IconButton.js";
2
3
  import { SplitButton } from "./components/SplitButton.js";
3
4
  import { CLICKY_FORMAT_OPTIONS, FormatOptionsDropdown } from "./components/FormatOptionsDropdown.js";
4
5
  import { DateField } from "./components/DateField.js";
@@ -10,6 +11,8 @@ import { FilterBar } from "./components/FilterBar.js";
10
11
  import { MultiSelect } from "./components/MultiSelect.js";
11
12
  import { Select } from "./components/select.js";
12
13
  import { Combobox } from "./components/Combobox.js";
14
+ import { WorkloadPicker, kindForValue, loadedWorkloads, parseWorkloadKey, workloadKey } from "./components/WorkloadPicker.js";
15
+ import { SecretKeySelector } from "./components/SecretKeySelector.js";
13
16
  import { ThemeSwitcher } from "./components/theme-switcher.js";
14
17
  import { DensitySwitcher } from "./components/density-switcher.js";
15
18
  import { IconMenuPicker } from "./components/icon-menu-picker.js";
@@ -35,21 +38,28 @@ export {
35
38
  FilterBar,
36
39
  FormatOptionsDropdown,
37
40
  HoverCard,
41
+ IconButton,
38
42
  IconMenuPicker,
39
43
  JsonSchemaForm,
40
44
  Modal,
41
45
  MultiSelect,
42
46
  RangeSlider,
47
+ SecretKeySelector,
43
48
  Section,
44
49
  Select,
45
50
  SplitButton,
46
51
  SplitPane,
47
52
  ThemeSwitcher,
48
53
  TimeRange,
54
+ WorkloadPicker,
49
55
  buttonVariants,
50
56
  effectiveProperties,
51
57
  isOpenStringMap,
58
+ kindForValue,
59
+ loadedWorkloads,
52
60
  matchesIf,
53
- resolveControl
61
+ parseWorkloadKey,
62
+ resolveControl,
63
+ workloadKey
54
64
  };
55
65
  //# sourceMappingURL=components.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"components.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;"}
1
+ {"version":3,"file":"components.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;"}
@@ -1739,7 +1739,7 @@ function ClickyTable({
1739
1739
  const effectiveExternalFilters = externalFilters ?? runtime.tableExternalFilters;
1740
1740
  const effectivePagination = pagination ?? runtime.tablePagination;
1741
1741
  const effectiveMenuActions = menuActions ?? runtime.tableMenuActions;
1742
- if (columns.length === 0 || rows.length === 0) {
1742
+ if (columns.length === 0) {
1743
1743
  return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "text-sm text-muted-foreground", children: "No data" });
1744
1744
  }
1745
1745
  if (shouldRenderRowsAsCollapsedStructs(columns, rows)) {