@flanksource/clicky-ui 0.2.20 → 0.3.1
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.
- package/dist/components/Combobox.cjs +5 -2
- package/dist/components/Combobox.cjs.map +1 -1
- package/dist/components/Combobox.d.ts.map +1 -1
- package/dist/components/Combobox.js +5 -2
- package/dist/components/Combobox.js.map +1 -1
- package/dist/components/FilterBar.cjs +280 -253
- package/dist/components/FilterBar.cjs.map +1 -1
- package/dist/components/FilterBar.d.ts.map +1 -1
- package/dist/components/FilterBar.js +280 -253
- package/dist/components/FilterBar.js.map +1 -1
- package/dist/components/JsonSchemaForm.cjs +3 -1
- package/dist/components/JsonSchemaForm.cjs.map +1 -1
- package/dist/components/JsonSchemaForm.d.ts.map +1 -1
- package/dist/components/JsonSchemaForm.js +4 -2
- package/dist/components/JsonSchemaForm.js.map +1 -1
- package/dist/components/MultiSelect.cjs +29 -32
- package/dist/components/MultiSelect.cjs.map +1 -1
- package/dist/components/MultiSelect.d.ts.map +1 -1
- package/dist/components/MultiSelect.js +30 -33
- package/dist/components/MultiSelect.js.map +1 -1
- package/dist/components/TimeRange.cjs +29 -37
- package/dist/components/TimeRange.cjs.map +1 -1
- package/dist/components/TimeRange.d.ts.map +1 -1
- package/dist/components/TimeRange.js +30 -38
- package/dist/components/TimeRange.js.map +1 -1
- package/dist/components/TreePickerField.cjs +6 -3
- package/dist/components/TreePickerField.cjs.map +1 -1
- package/dist/components/TreePickerField.d.ts.map +1 -1
- package/dist/components/TreePickerField.js +6 -3
- package/dist/components/TreePickerField.js.map +1 -1
- package/dist/components/icon-menu-picker.cjs +9 -3
- package/dist/components/icon-menu-picker.cjs.map +1 -1
- package/dist/components/icon-menu-picker.d.ts.map +1 -1
- package/dist/components/icon-menu-picker.js +9 -3
- package/dist/components/icon-menu-picker.js.map +1 -1
- package/dist/components/json-schema-form-fields.cjs +80 -2
- package/dist/components/json-schema-form-fields.cjs.map +1 -1
- package/dist/components/json-schema-form-fields.d.ts +15 -0
- package/dist/components/json-schema-form-fields.d.ts.map +1 -1
- package/dist/components/json-schema-form-fields.js +81 -3
- package/dist/components/json-schema-form-fields.js.map +1 -1
- package/dist/components/json-schema-form-refs.cjs +60 -0
- package/dist/components/json-schema-form-refs.cjs.map +1 -0
- package/dist/components/json-schema-form-refs.d.ts +3 -0
- package/dist/components/json-schema-form-refs.d.ts.map +1 -0
- package/dist/components/json-schema-form-refs.js +60 -0
- package/dist/components/json-schema-form-refs.js.map +1 -0
- package/dist/components/json-schema-form-render.cjs +14 -2
- package/dist/components/json-schema-form-render.cjs.map +1 -1
- package/dist/components/json-schema-form-render.d.ts.map +1 -1
- package/dist/components/json-schema-form-render.js +15 -3
- package/dist/components/json-schema-form-render.js.map +1 -1
- package/dist/components/json-schema-form-resolve.cjs +5 -0
- package/dist/components/json-schema-form-resolve.cjs.map +1 -1
- package/dist/components/json-schema-form-resolve.d.ts.map +1 -1
- package/dist/components/json-schema-form-resolve.js +5 -0
- package/dist/components/json-schema-form-resolve.js.map +1 -1
- package/dist/components/json-schema-form-template-menu.cjs +83 -0
- package/dist/components/json-schema-form-template-menu.cjs.map +1 -0
- package/dist/components/json-schema-form-template-menu.d.ts +15 -0
- package/dist/components/json-schema-form-template-menu.d.ts.map +1 -0
- package/dist/components/json-schema-form-template-menu.js +83 -0
- package/dist/components/json-schema-form-template-menu.js.map +1 -0
- package/dist/components/json-schema-form-template.cjs +18 -0
- package/dist/components/json-schema-form-template.cjs.map +1 -0
- package/dist/components/json-schema-form-template.d.ts +13 -0
- package/dist/components/json-schema-form-template.d.ts.map +1 -0
- package/dist/components/json-schema-form-template.js +18 -0
- package/dist/components/json-schema-form-template.js.map +1 -0
- package/dist/components/json-schema-form-types.d.ts +5 -1
- package/dist/components/json-schema-form-types.d.ts.map +1 -1
- package/dist/components.cjs +4 -0
- package/dist/components.cjs.map +1 -1
- package/dist/components.d.ts +3 -0
- package/dist/components.d.ts.map +1 -1
- package/dist/components.js +4 -0
- package/dist/components.js.map +1 -1
- package/dist/data/Clicky.cjs +6 -9
- package/dist/data/Clicky.cjs.map +1 -1
- package/dist/data/Clicky.d.ts.map +1 -1
- package/dist/data/Clicky.js +6 -9
- package/dist/data/Clicky.js.map +1 -1
- package/dist/data/DataTable.cjs +23 -17
- package/dist/data/DataTable.cjs.map +1 -1
- package/dist/data/DataTable.d.ts +7 -1
- package/dist/data/DataTable.d.ts.map +1 -1
- package/dist/data/DataTable.js +24 -18
- package/dist/data/DataTable.js.map +1 -1
- package/dist/data/Gauge.cjs +37 -4
- package/dist/data/Gauge.cjs.map +1 -1
- package/dist/data/Gauge.d.ts +6 -1
- package/dist/data/Gauge.d.ts.map +1 -1
- package/dist/data/Gauge.js +37 -4
- package/dist/data/Gauge.js.map +1 -1
- package/dist/data/TimeseriesCoreBars.cjs +127 -29
- package/dist/data/TimeseriesCoreBars.cjs.map +1 -1
- package/dist/data/TimeseriesCoreBars.d.ts +11 -1
- package/dist/data/TimeseriesCoreBars.d.ts.map +1 -1
- package/dist/data/TimeseriesCoreBars.js +128 -30
- package/dist/data/TimeseriesCoreBars.js.map +1 -1
- package/dist/data/TimeseriesGauge.cjs +105 -47
- package/dist/data/TimeseriesGauge.cjs.map +1 -1
- package/dist/data/TimeseriesGauge.d.ts +6 -1
- package/dist/data/TimeseriesGauge.d.ts.map +1 -1
- package/dist/data/TimeseriesGauge.js +105 -47
- package/dist/data/TimeseriesGauge.js.map +1 -1
- package/dist/data/WorkloadCard.cjs +371 -0
- package/dist/data/WorkloadCard.cjs.map +1 -0
- package/dist/data/WorkloadCard.d.ts +24 -0
- package/dist/data/WorkloadCard.d.ts.map +1 -0
- package/dist/data/WorkloadCard.js +371 -0
- package/dist/data/WorkloadCard.js.map +1 -0
- package/dist/data/WorkloadCard.model.cjs +51 -0
- package/dist/data/WorkloadCard.model.cjs.map +1 -0
- package/dist/data/WorkloadCard.model.d.ts +53 -0
- package/dist/data/WorkloadCard.model.d.ts.map +1 -0
- package/dist/data/WorkloadCard.model.js +51 -0
- package/dist/data/WorkloadCard.model.js.map +1 -0
- package/dist/data/ai/ChatFab.cjs +3 -1
- package/dist/data/ai/ChatFab.cjs.map +1 -1
- package/dist/data/ai/ChatFab.d.ts.map +1 -1
- package/dist/data/ai/ChatFab.js +3 -1
- package/dist/data/ai/ChatFab.js.map +1 -1
- package/dist/data/ai/ChatWindow.cjs +25 -7
- package/dist/data/ai/ChatWindow.cjs.map +1 -1
- package/dist/data/ai/ChatWindow.d.ts +11 -3
- package/dist/data/ai/ChatWindow.d.ts.map +1 -1
- package/dist/data/ai/ChatWindow.js +26 -8
- package/dist/data/ai/ChatWindow.js.map +1 -1
- package/dist/data/ai/chat-window-context.cjs +2 -1
- package/dist/data/ai/chat-window-context.cjs.map +1 -1
- package/dist/data/ai/chat-window-context.d.ts +1 -1
- package/dist/data/ai/chat-window-context.d.ts.map +1 -1
- package/dist/data/ai/chat-window-context.js +2 -1
- package/dist/data/ai/chat-window-context.js.map +1 -1
- package/dist/data/ai/context.cjs.map +1 -1
- package/dist/data/ai/context.d.ts +3 -0
- package/dist/data/ai/context.d.ts.map +1 -1
- package/dist/data/ai/context.js.map +1 -1
- package/dist/data/chat/Chat.cjs +13 -2
- package/dist/data/chat/Chat.cjs.map +1 -1
- package/dist/data/chat/Chat.d.ts +4 -2
- package/dist/data/chat/Chat.d.ts.map +1 -1
- package/dist/data/chat/Chat.js +14 -3
- package/dist/data/chat/Chat.js.map +1 -1
- package/dist/data/chat/Conversation.cjs +47 -2
- package/dist/data/chat/Conversation.cjs.map +1 -1
- package/dist/data/chat/Conversation.d.ts +8 -2
- package/dist/data/chat/Conversation.d.ts.map +1 -1
- package/dist/data/chat/Conversation.js +47 -2
- package/dist/data/chat/Conversation.js.map +1 -1
- package/dist/data/chat/Message.cjs +13 -4
- package/dist/data/chat/Message.cjs.map +1 -1
- package/dist/data/chat/Message.d.ts +4 -2
- package/dist/data/chat/Message.d.ts.map +1 -1
- package/dist/data/chat/Message.js +13 -4
- package/dist/data/chat/Message.js.map +1 -1
- package/dist/data/chat/ToolCall.cjs +9 -4
- package/dist/data/chat/ToolCall.cjs.map +1 -1
- package/dist/data/chat/ToolCall.d.ts +3 -2
- package/dist/data/chat/ToolCall.d.ts.map +1 -1
- package/dist/data/chat/ToolCall.js +9 -4
- package/dist/data/chat/ToolCall.js.map +1 -1
- package/dist/data/chat/index.d.ts +1 -1
- package/dist/data/chat/index.d.ts.map +1 -1
- package/dist/data/chat/types.cjs.map +1 -1
- package/dist/data/chat/types.d.ts +7 -0
- package/dist/data/chat/types.d.ts.map +1 -1
- package/dist/data/chat/types.js.map +1 -1
- package/dist/data/version-info.cjs +3 -3
- package/dist/data/version-info.js +3 -3
- package/dist/data.cjs +7 -0
- package/dist/data.cjs.map +1 -1
- package/dist/data.d.ts +5 -3
- package/dist/data.d.ts.map +1 -1
- package/dist/data.js +8 -1
- package/dist/data.js.map +1 -1
- package/dist/hooks/use-sort.cjs +19 -10
- package/dist/hooks/use-sort.cjs.map +1 -1
- package/dist/hooks/use-sort.d.ts +3 -0
- package/dist/hooks/use-sort.d.ts.map +1 -1
- package/dist/hooks/use-sort.js +19 -10
- package/dist/hooks/use-sort.js.map +1 -1
- package/dist/index.cjs +11 -0
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +11 -0
- package/dist/index.js.map +1 -1
- package/dist/layout/AppShell.cjs +6 -10
- package/dist/layout/AppShell.cjs.map +1 -1
- package/dist/layout/AppShell.d.ts +2 -0
- package/dist/layout/AppShell.d.ts.map +1 -1
- package/dist/layout/AppShell.js +6 -10
- package/dist/layout/AppShell.js.map +1 -1
- package/dist/overlay/DropdownMenu.cjs +50 -38
- package/dist/overlay/DropdownMenu.cjs.map +1 -1
- package/dist/overlay/DropdownMenu.d.ts +5 -1
- package/dist/overlay/DropdownMenu.d.ts.map +1 -1
- package/dist/overlay/DropdownMenu.js +50 -38
- package/dist/overlay/DropdownMenu.js.map +1 -1
- package/dist/overlay/HoverCard.cjs +7 -2
- package/dist/overlay/HoverCard.cjs.map +1 -1
- package/dist/overlay/HoverCard.d.ts.map +1 -1
- package/dist/overlay/HoverCard.js +7 -2
- package/dist/overlay/HoverCard.js.map +1 -1
- package/dist/overlay/Modal.cjs +20 -17
- package/dist/overlay/Modal.cjs.map +1 -1
- package/dist/overlay/Modal.d.ts.map +1 -1
- package/dist/overlay/Modal.js +21 -18
- package/dist/overlay/Modal.js.map +1 -1
- package/dist/overlay/Toast.cjs +9 -1
- package/dist/overlay/Toast.cjs.map +1 -1
- package/dist/overlay/Toast.d.ts.map +1 -1
- package/dist/overlay/Toast.js +9 -1
- package/dist/overlay/Toast.js.map +1 -1
- package/dist/overlay/modalStack.cjs +53 -1
- package/dist/overlay/modalStack.cjs.map +1 -1
- package/dist/overlay/modalStack.d.ts +12 -0
- package/dist/overlay/modalStack.d.ts.map +1 -1
- package/dist/overlay/modalStack.js +54 -2
- package/dist/overlay/modalStack.js.map +1 -1
- package/dist/overlay/zIndex.cjs +20 -0
- package/dist/overlay/zIndex.cjs.map +1 -0
- package/dist/overlay/zIndex.d.ts +39 -0
- package/dist/overlay/zIndex.d.ts.map +1 -0
- package/dist/overlay/zIndex.js +20 -0
- package/dist/overlay/zIndex.js.map +1 -0
- package/dist/rpc/AcceptPicker.cjs +28 -26
- package/dist/rpc/AcceptPicker.cjs.map +1 -1
- package/dist/rpc/AcceptPicker.d.ts.map +1 -1
- package/dist/rpc/AcceptPicker.js +29 -27
- package/dist/rpc/AcceptPicker.js.map +1 -1
- package/dist/styles.css +1 -1
- package/package.json +1 -1
|
@@ -1,8 +1,11 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
3
3
|
const react = require("react");
|
|
4
|
+
const zIndex = require("./zIndex.cjs");
|
|
4
5
|
const stack = [];
|
|
5
6
|
const listeners = /* @__PURE__ */ new Set();
|
|
7
|
+
const escapeStack = [];
|
|
8
|
+
let escapeDocument = null;
|
|
6
9
|
function emit() {
|
|
7
10
|
for (const listener of listeners) listener();
|
|
8
11
|
}
|
|
@@ -15,6 +18,30 @@ function subscribe(listener) {
|
|
|
15
18
|
function getSnapshot() {
|
|
16
19
|
return stack.join("\0");
|
|
17
20
|
}
|
|
21
|
+
function onEscapeKeyDown(event) {
|
|
22
|
+
if (event.defaultPrevented || event.key !== "Escape" || event.isComposing || event.keyCode === 229) {
|
|
23
|
+
return;
|
|
24
|
+
}
|
|
25
|
+
const top = escapeStack[escapeStack.length - 1];
|
|
26
|
+
if (!top) return;
|
|
27
|
+
event.preventDefault();
|
|
28
|
+
event.stopPropagation();
|
|
29
|
+
event.stopImmediatePropagation();
|
|
30
|
+
top.onEscape();
|
|
31
|
+
}
|
|
32
|
+
function ensureEscapeListener() {
|
|
33
|
+
if (escapeDocument || typeof document === "undefined") return;
|
|
34
|
+
escapeDocument = document;
|
|
35
|
+
escapeDocument.addEventListener("keydown", onEscapeKeyDown);
|
|
36
|
+
}
|
|
37
|
+
function removeEscapeLayer(id) {
|
|
38
|
+
const index = escapeStack.findIndex((entry) => entry.id === id);
|
|
39
|
+
if (index !== -1) escapeStack.splice(index, 1);
|
|
40
|
+
if (escapeStack.length === 0 && escapeDocument) {
|
|
41
|
+
escapeDocument.removeEventListener("keydown", onEscapeKeyDown);
|
|
42
|
+
escapeDocument = null;
|
|
43
|
+
}
|
|
44
|
+
}
|
|
18
45
|
function useModalStack(open) {
|
|
19
46
|
const id = react.useId();
|
|
20
47
|
react.useSyncExternalStore(subscribe, getSnapshot, getSnapshot);
|
|
@@ -29,7 +56,32 @@ function useModalStack(open) {
|
|
|
29
56
|
};
|
|
30
57
|
}, [open, id]);
|
|
31
58
|
const depth = stack.indexOf(id);
|
|
32
|
-
return {
|
|
59
|
+
return {
|
|
60
|
+
isTop: depth !== -1 && depth === stack.length - 1,
|
|
61
|
+
depth: depth === -1 ? 0 : depth
|
|
62
|
+
};
|
|
63
|
+
}
|
|
64
|
+
function useEscapeLayer(open, onEscape, enabled = true) {
|
|
65
|
+
const id = react.useId();
|
|
66
|
+
const onEscapeRef = react.useRef(onEscape);
|
|
67
|
+
onEscapeRef.current = onEscape;
|
|
68
|
+
react.useEffect(() => {
|
|
69
|
+
if (!open || !enabled) return;
|
|
70
|
+
ensureEscapeListener();
|
|
71
|
+
escapeStack.push({
|
|
72
|
+
id,
|
|
73
|
+
onEscape: () => onEscapeRef.current()
|
|
74
|
+
});
|
|
75
|
+
return () => removeEscapeLayer(id);
|
|
76
|
+
}, [enabled, id, open]);
|
|
77
|
+
}
|
|
78
|
+
function useFloatingZIndex() {
|
|
79
|
+
react.useSyncExternalStore(subscribe, getSnapshot, getSnapshot);
|
|
80
|
+
if (stack.length === 0) return zIndex.zIndex.popover;
|
|
81
|
+
const topModalZ = zIndex.zIndex.modal + (stack.length - 1) * zIndex.zIndex.modalStep;
|
|
82
|
+
return topModalZ + zIndex.zIndex.popoverOverModalOffset;
|
|
33
83
|
}
|
|
84
|
+
exports.useEscapeLayer = useEscapeLayer;
|
|
85
|
+
exports.useFloatingZIndex = useFloatingZIndex;
|
|
34
86
|
exports.useModalStack = useModalStack;
|
|
35
87
|
//# sourceMappingURL=modalStack.cjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"modalStack.cjs","sources":["../../src/overlay/modalStack.ts"],"sourcesContent":["import { useEffect, useId, useSyncExternalStore } from \"react\";\n\n// A process-wide stack of the currently open modals, topmost last. Modals mount\n// independently (no shared provider), so the stack lives at module scope and is\n// shared through useSyncExternalStore. It lets nested modals cooperate: only the\n// topmost reacts to Escape, and each renders above the one it opened over.\nconst stack: string[] = [];\nconst listeners = new Set<() => void>();\n\nfunction emit() {\n for (const listener of listeners) listener();\n}\n\nfunction subscribe(listener: () => void) {\n listeners.add(listener);\n return () => {\n listeners.delete(listener);\n };\n}\n\n// The snapshot is the stack identity; it only changes when an entry is pushed or\n// popped, so subscribers re-render exactly when their position could have moved.\nfunction getSnapshot() {\n return stack.join(\"
|
|
1
|
+
{"version":3,"file":"modalStack.cjs","sources":["../../src/overlay/modalStack.ts"],"sourcesContent":["import { useEffect, useId, useRef, useSyncExternalStore } from \"react\";\nimport { zIndex } from \"./zIndex\";\n\n// A process-wide stack of the currently open modals, topmost last. Modals mount\n// independently (no shared provider), so the stack lives at module scope and is\n// shared through useSyncExternalStore. It lets nested modals cooperate: only the\n// topmost reacts to Escape, and each renders above the one it opened over.\nconst stack: string[] = [];\nconst listeners = new Set<() => void>();\nconst escapeStack: Array<{ id: string; onEscape: () => void }> = [];\nlet escapeDocument: Document | null = null;\n\nfunction emit() {\n for (const listener of listeners) listener();\n}\n\nfunction subscribe(listener: () => void) {\n listeners.add(listener);\n return () => {\n listeners.delete(listener);\n };\n}\n\n// The snapshot is the stack identity; it only changes when an entry is pushed or\n// popped, so subscribers re-render exactly when their position could have moved.\nfunction getSnapshot() {\n return stack.join(\"\\u0000\");\n}\n\nfunction onEscapeKeyDown(event: KeyboardEvent) {\n if (\n event.defaultPrevented ||\n event.key !== \"Escape\" ||\n event.isComposing ||\n (event as KeyboardEvent & { keyCode?: number }).keyCode === 229\n ) {\n return;\n }\n\n const top = escapeStack[escapeStack.length - 1];\n if (!top) return;\n\n event.preventDefault();\n event.stopPropagation();\n event.stopImmediatePropagation();\n top.onEscape();\n}\n\nfunction ensureEscapeListener() {\n if (escapeDocument || typeof document === \"undefined\") return;\n escapeDocument = document;\n escapeDocument.addEventListener(\"keydown\", onEscapeKeyDown);\n}\n\nfunction removeEscapeLayer(id: string) {\n const index = escapeStack.findIndex((entry) => entry.id === id);\n if (index !== -1) escapeStack.splice(index, 1);\n\n if (escapeStack.length === 0 && escapeDocument) {\n escapeDocument.removeEventListener(\"keydown\", onEscapeKeyDown);\n escapeDocument = null;\n }\n}\n\nexport type ModalStackPosition = {\n /** Whether this modal is the topmost open one and should own global affordances. */\n isTop: boolean;\n /** Zero-based depth in the stack; drives the stacking order of nested modals. */\n depth: number;\n};\n\n/**\n * Registers a modal in the global stack while `open`, returning its live\n * position. Used so a nested modal sits above its opener and only the topmost\n * modal closes on Escape.\n */\nexport function useModalStack(open: boolean): ModalStackPosition {\n const id = useId();\n useSyncExternalStore(subscribe, getSnapshot, getSnapshot);\n\n useEffect(() => {\n if (!open) return;\n stack.push(id);\n emit();\n return () => {\n const index = stack.indexOf(id);\n if (index !== -1) stack.splice(index, 1);\n emit();\n };\n }, [open, id]);\n\n const depth = stack.indexOf(id);\n return {\n isTop: depth !== -1 && depth === stack.length - 1,\n depth: depth === -1 ? 0 : depth,\n };\n}\n\n/**\n * Registers an Escape-closeable overlay while `open`. The topmost registered\n * layer owns Escape, so a keypress dismisses one dialog/menu layer at a time.\n */\nexport function useEscapeLayer(open: boolean, onEscape: () => void, enabled = true) {\n const id = useId();\n const onEscapeRef = useRef(onEscape);\n onEscapeRef.current = onEscape;\n\n useEffect(() => {\n if (!open || !enabled) return;\n\n ensureEscapeListener();\n escapeStack.push({\n id,\n onEscape: () => onEscapeRef.current(),\n });\n\n return () => removeEscapeLayer(id);\n }, [enabled, id, open]);\n}\n\n/**\n * z-index a floating layer (dropdown / combobox / tooltip / popover) should use\n * so it renders above any open modal — and below the next nested modal — or at\n * the popover floor when no modal is open. Subscribes to the modal stack so the\n * value tracks modals opening and closing.\n */\nexport function useFloatingZIndex(): number {\n useSyncExternalStore(subscribe, getSnapshot, getSnapshot);\n if (stack.length === 0) return zIndex.popover;\n const topModalZ = zIndex.modal + (stack.length - 1) * zIndex.modalStep;\n return topModalZ + zIndex.popoverOverModalOffset;\n}\n"],"names":["useId","useSyncExternalStore","useEffect","useRef","zIndex"],"mappings":";;;;AAOA,MAAM,QAAkB,CAAA;AACxB,MAAM,gCAAgB,IAAA;AACtB,MAAM,cAA2D,CAAA;AACjE,IAAI,iBAAkC;AAEtC,SAAS,OAAO;AACd,aAAW,YAAY,UAAW,UAAA;AACpC;AAEA,SAAS,UAAU,UAAsB;AACvC,YAAU,IAAI,QAAQ;AACtB,SAAO,MAAM;AACX,cAAU,OAAO,QAAQ;AAAA,EAC3B;AACF;AAIA,SAAS,cAAc;AACrB,SAAO,MAAM,KAAK,IAAQ;AAC5B;AAEA,SAAS,gBAAgB,OAAsB;AAC7C,MACE,MAAM,oBACN,MAAM,QAAQ,YACd,MAAM,eACL,MAA+C,YAAY,KAC5D;AACA;AAAA,EACF;AAEA,QAAM,MAAM,YAAY,YAAY,SAAS,CAAC;AAC9C,MAAI,CAAC,IAAK;AAEV,QAAM,eAAA;AACN,QAAM,gBAAA;AACN,QAAM,yBAAA;AACN,MAAI,SAAA;AACN;AAEA,SAAS,uBAAuB;AAC9B,MAAI,kBAAkB,OAAO,aAAa,YAAa;AACvD,mBAAiB;AACjB,iBAAe,iBAAiB,WAAW,eAAe;AAC5D;AAEA,SAAS,kBAAkB,IAAY;AACrC,QAAM,QAAQ,YAAY,UAAU,CAAC,UAAU,MAAM,OAAO,EAAE;AAC9D,MAAI,UAAU,GAAI,aAAY,OAAO,OAAO,CAAC;AAE7C,MAAI,YAAY,WAAW,KAAK,gBAAgB;AAC9C,mBAAe,oBAAoB,WAAW,eAAe;AAC7D,qBAAiB;AAAA,EACnB;AACF;AAcO,SAAS,cAAc,MAAmC;AAC/D,QAAM,KAAKA,MAAAA,MAAA;AACXC,6BAAqB,WAAW,aAAa,WAAW;AAExDC,QAAAA,UAAU,MAAM;AACd,QAAI,CAAC,KAAM;AACX,UAAM,KAAK,EAAE;AACb,SAAA;AACA,WAAO,MAAM;AACX,YAAM,QAAQ,MAAM,QAAQ,EAAE;AAC9B,UAAI,UAAU,GAAI,OAAM,OAAO,OAAO,CAAC;AACvC,WAAA;AAAA,IACF;AAAA,EACF,GAAG,CAAC,MAAM,EAAE,CAAC;AAEb,QAAM,QAAQ,MAAM,QAAQ,EAAE;AAC9B,SAAO;AAAA,IACL,OAAO,UAAU,MAAM,UAAU,MAAM,SAAS;AAAA,IAChD,OAAO,UAAU,KAAK,IAAI;AAAA,EAAA;AAE9B;AAMO,SAAS,eAAe,MAAe,UAAsB,UAAU,MAAM;AAClF,QAAM,KAAKF,MAAAA,MAAA;AACX,QAAM,cAAcG,MAAAA,OAAO,QAAQ;AACnC,cAAY,UAAU;AAEtBD,QAAAA,UAAU,MAAM;AACd,QAAI,CAAC,QAAQ,CAAC,QAAS;AAEvB,yBAAA;AACA,gBAAY,KAAK;AAAA,MACf;AAAA,MACA,UAAU,MAAM,YAAY,QAAA;AAAA,IAAQ,CACrC;AAED,WAAO,MAAM,kBAAkB,EAAE;AAAA,EACnC,GAAG,CAAC,SAAS,IAAI,IAAI,CAAC;AACxB;AAQO,SAAS,oBAA4B;AAC1CD,6BAAqB,WAAW,aAAa,WAAW;AACxD,MAAI,MAAM,WAAW,EAAG,QAAOG,OAAAA,OAAO;AACtC,QAAM,YAAYA,OAAAA,OAAO,SAAS,MAAM,SAAS,KAAKA,OAAAA,OAAO;AAC7D,SAAO,YAAYA,OAAAA,OAAO;AAC5B;;;;"}
|
|
@@ -10,4 +10,16 @@ export type ModalStackPosition = {
|
|
|
10
10
|
* modal closes on Escape.
|
|
11
11
|
*/
|
|
12
12
|
export declare function useModalStack(open: boolean): ModalStackPosition;
|
|
13
|
+
/**
|
|
14
|
+
* Registers an Escape-closeable overlay while `open`. The topmost registered
|
|
15
|
+
* layer owns Escape, so a keypress dismisses one dialog/menu layer at a time.
|
|
16
|
+
*/
|
|
17
|
+
export declare function useEscapeLayer(open: boolean, onEscape: () => void, enabled?: boolean): void;
|
|
18
|
+
/**
|
|
19
|
+
* z-index a floating layer (dropdown / combobox / tooltip / popover) should use
|
|
20
|
+
* so it renders above any open modal — and below the next nested modal — or at
|
|
21
|
+
* the popover floor when no modal is open. Subscribes to the modal stack so the
|
|
22
|
+
* value tracks modals opening and closing.
|
|
23
|
+
*/
|
|
24
|
+
export declare function useFloatingZIndex(): number;
|
|
13
25
|
//# sourceMappingURL=modalStack.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"modalStack.d.ts","sourceRoot":"","sources":["../../src/overlay/modalStack.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"modalStack.d.ts","sourceRoot":"","sources":["../../src/overlay/modalStack.ts"],"names":[],"mappings":"AAgEA,MAAM,MAAM,kBAAkB,GAAG;IAC/B,oFAAoF;IACpF,KAAK,EAAE,OAAO,CAAC;IACf,iFAAiF;IACjF,KAAK,EAAE,MAAM,CAAC;CACf,CAAC;AAEF;;;;GAIG;AACH,wBAAgB,aAAa,CAAC,IAAI,EAAE,OAAO,GAAG,kBAAkB,CAoB/D;AAED;;;GAGG;AACH,wBAAgB,cAAc,CAAC,IAAI,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,IAAI,EAAE,OAAO,UAAO,QAgBjF;AAED;;;;;GAKG;AACH,wBAAgB,iBAAiB,IAAI,MAAM,CAK1C"}
|
|
@@ -1,6 +1,9 @@
|
|
|
1
|
-
import { useId, useSyncExternalStore, useEffect } from "react";
|
|
1
|
+
import { useId, useSyncExternalStore, useEffect, useRef } from "react";
|
|
2
|
+
import { zIndex } from "./zIndex.js";
|
|
2
3
|
const stack = [];
|
|
3
4
|
const listeners = /* @__PURE__ */ new Set();
|
|
5
|
+
const escapeStack = [];
|
|
6
|
+
let escapeDocument = null;
|
|
4
7
|
function emit() {
|
|
5
8
|
for (const listener of listeners) listener();
|
|
6
9
|
}
|
|
@@ -13,6 +16,30 @@ function subscribe(listener) {
|
|
|
13
16
|
function getSnapshot() {
|
|
14
17
|
return stack.join("\0");
|
|
15
18
|
}
|
|
19
|
+
function onEscapeKeyDown(event) {
|
|
20
|
+
if (event.defaultPrevented || event.key !== "Escape" || event.isComposing || event.keyCode === 229) {
|
|
21
|
+
return;
|
|
22
|
+
}
|
|
23
|
+
const top = escapeStack[escapeStack.length - 1];
|
|
24
|
+
if (!top) return;
|
|
25
|
+
event.preventDefault();
|
|
26
|
+
event.stopPropagation();
|
|
27
|
+
event.stopImmediatePropagation();
|
|
28
|
+
top.onEscape();
|
|
29
|
+
}
|
|
30
|
+
function ensureEscapeListener() {
|
|
31
|
+
if (escapeDocument || typeof document === "undefined") return;
|
|
32
|
+
escapeDocument = document;
|
|
33
|
+
escapeDocument.addEventListener("keydown", onEscapeKeyDown);
|
|
34
|
+
}
|
|
35
|
+
function removeEscapeLayer(id) {
|
|
36
|
+
const index = escapeStack.findIndex((entry) => entry.id === id);
|
|
37
|
+
if (index !== -1) escapeStack.splice(index, 1);
|
|
38
|
+
if (escapeStack.length === 0 && escapeDocument) {
|
|
39
|
+
escapeDocument.removeEventListener("keydown", onEscapeKeyDown);
|
|
40
|
+
escapeDocument = null;
|
|
41
|
+
}
|
|
42
|
+
}
|
|
16
43
|
function useModalStack(open) {
|
|
17
44
|
const id = useId();
|
|
18
45
|
useSyncExternalStore(subscribe, getSnapshot, getSnapshot);
|
|
@@ -27,9 +54,34 @@ function useModalStack(open) {
|
|
|
27
54
|
};
|
|
28
55
|
}, [open, id]);
|
|
29
56
|
const depth = stack.indexOf(id);
|
|
30
|
-
return {
|
|
57
|
+
return {
|
|
58
|
+
isTop: depth !== -1 && depth === stack.length - 1,
|
|
59
|
+
depth: depth === -1 ? 0 : depth
|
|
60
|
+
};
|
|
61
|
+
}
|
|
62
|
+
function useEscapeLayer(open, onEscape, enabled = true) {
|
|
63
|
+
const id = useId();
|
|
64
|
+
const onEscapeRef = useRef(onEscape);
|
|
65
|
+
onEscapeRef.current = onEscape;
|
|
66
|
+
useEffect(() => {
|
|
67
|
+
if (!open || !enabled) return;
|
|
68
|
+
ensureEscapeListener();
|
|
69
|
+
escapeStack.push({
|
|
70
|
+
id,
|
|
71
|
+
onEscape: () => onEscapeRef.current()
|
|
72
|
+
});
|
|
73
|
+
return () => removeEscapeLayer(id);
|
|
74
|
+
}, [enabled, id, open]);
|
|
75
|
+
}
|
|
76
|
+
function useFloatingZIndex() {
|
|
77
|
+
useSyncExternalStore(subscribe, getSnapshot, getSnapshot);
|
|
78
|
+
if (stack.length === 0) return zIndex.popover;
|
|
79
|
+
const topModalZ = zIndex.modal + (stack.length - 1) * zIndex.modalStep;
|
|
80
|
+
return topModalZ + zIndex.popoverOverModalOffset;
|
|
31
81
|
}
|
|
32
82
|
export {
|
|
83
|
+
useEscapeLayer,
|
|
84
|
+
useFloatingZIndex,
|
|
33
85
|
useModalStack
|
|
34
86
|
};
|
|
35
87
|
//# sourceMappingURL=modalStack.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"modalStack.js","sources":["../../src/overlay/modalStack.ts"],"sourcesContent":["import { useEffect, useId, useSyncExternalStore } from \"react\";\n\n// A process-wide stack of the currently open modals, topmost last. Modals mount\n// independently (no shared provider), so the stack lives at module scope and is\n// shared through useSyncExternalStore. It lets nested modals cooperate: only the\n// topmost reacts to Escape, and each renders above the one it opened over.\nconst stack: string[] = [];\nconst listeners = new Set<() => void>();\n\nfunction emit() {\n for (const listener of listeners) listener();\n}\n\nfunction subscribe(listener: () => void) {\n listeners.add(listener);\n return () => {\n listeners.delete(listener);\n };\n}\n\n// The snapshot is the stack identity; it only changes when an entry is pushed or\n// popped, so subscribers re-render exactly when their position could have moved.\nfunction getSnapshot() {\n return stack.join(\"
|
|
1
|
+
{"version":3,"file":"modalStack.js","sources":["../../src/overlay/modalStack.ts"],"sourcesContent":["import { useEffect, useId, useRef, useSyncExternalStore } from \"react\";\nimport { zIndex } from \"./zIndex\";\n\n// A process-wide stack of the currently open modals, topmost last. Modals mount\n// independently (no shared provider), so the stack lives at module scope and is\n// shared through useSyncExternalStore. It lets nested modals cooperate: only the\n// topmost reacts to Escape, and each renders above the one it opened over.\nconst stack: string[] = [];\nconst listeners = new Set<() => void>();\nconst escapeStack: Array<{ id: string; onEscape: () => void }> = [];\nlet escapeDocument: Document | null = null;\n\nfunction emit() {\n for (const listener of listeners) listener();\n}\n\nfunction subscribe(listener: () => void) {\n listeners.add(listener);\n return () => {\n listeners.delete(listener);\n };\n}\n\n// The snapshot is the stack identity; it only changes when an entry is pushed or\n// popped, so subscribers re-render exactly when their position could have moved.\nfunction getSnapshot() {\n return stack.join(\"\\u0000\");\n}\n\nfunction onEscapeKeyDown(event: KeyboardEvent) {\n if (\n event.defaultPrevented ||\n event.key !== \"Escape\" ||\n event.isComposing ||\n (event as KeyboardEvent & { keyCode?: number }).keyCode === 229\n ) {\n return;\n }\n\n const top = escapeStack[escapeStack.length - 1];\n if (!top) return;\n\n event.preventDefault();\n event.stopPropagation();\n event.stopImmediatePropagation();\n top.onEscape();\n}\n\nfunction ensureEscapeListener() {\n if (escapeDocument || typeof document === \"undefined\") return;\n escapeDocument = document;\n escapeDocument.addEventListener(\"keydown\", onEscapeKeyDown);\n}\n\nfunction removeEscapeLayer(id: string) {\n const index = escapeStack.findIndex((entry) => entry.id === id);\n if (index !== -1) escapeStack.splice(index, 1);\n\n if (escapeStack.length === 0 && escapeDocument) {\n escapeDocument.removeEventListener(\"keydown\", onEscapeKeyDown);\n escapeDocument = null;\n }\n}\n\nexport type ModalStackPosition = {\n /** Whether this modal is the topmost open one and should own global affordances. */\n isTop: boolean;\n /** Zero-based depth in the stack; drives the stacking order of nested modals. */\n depth: number;\n};\n\n/**\n * Registers a modal in the global stack while `open`, returning its live\n * position. Used so a nested modal sits above its opener and only the topmost\n * modal closes on Escape.\n */\nexport function useModalStack(open: boolean): ModalStackPosition {\n const id = useId();\n useSyncExternalStore(subscribe, getSnapshot, getSnapshot);\n\n useEffect(() => {\n if (!open) return;\n stack.push(id);\n emit();\n return () => {\n const index = stack.indexOf(id);\n if (index !== -1) stack.splice(index, 1);\n emit();\n };\n }, [open, id]);\n\n const depth = stack.indexOf(id);\n return {\n isTop: depth !== -1 && depth === stack.length - 1,\n depth: depth === -1 ? 0 : depth,\n };\n}\n\n/**\n * Registers an Escape-closeable overlay while `open`. The topmost registered\n * layer owns Escape, so a keypress dismisses one dialog/menu layer at a time.\n */\nexport function useEscapeLayer(open: boolean, onEscape: () => void, enabled = true) {\n const id = useId();\n const onEscapeRef = useRef(onEscape);\n onEscapeRef.current = onEscape;\n\n useEffect(() => {\n if (!open || !enabled) return;\n\n ensureEscapeListener();\n escapeStack.push({\n id,\n onEscape: () => onEscapeRef.current(),\n });\n\n return () => removeEscapeLayer(id);\n }, [enabled, id, open]);\n}\n\n/**\n * z-index a floating layer (dropdown / combobox / tooltip / popover) should use\n * so it renders above any open modal — and below the next nested modal — or at\n * the popover floor when no modal is open. Subscribes to the modal stack so the\n * value tracks modals opening and closing.\n */\nexport function useFloatingZIndex(): number {\n useSyncExternalStore(subscribe, getSnapshot, getSnapshot);\n if (stack.length === 0) return zIndex.popover;\n const topModalZ = zIndex.modal + (stack.length - 1) * zIndex.modalStep;\n return topModalZ + zIndex.popoverOverModalOffset;\n}\n"],"names":[],"mappings":";;AAOA,MAAM,QAAkB,CAAA;AACxB,MAAM,gCAAgB,IAAA;AACtB,MAAM,cAA2D,CAAA;AACjE,IAAI,iBAAkC;AAEtC,SAAS,OAAO;AACd,aAAW,YAAY,UAAW,UAAA;AACpC;AAEA,SAAS,UAAU,UAAsB;AACvC,YAAU,IAAI,QAAQ;AACtB,SAAO,MAAM;AACX,cAAU,OAAO,QAAQ;AAAA,EAC3B;AACF;AAIA,SAAS,cAAc;AACrB,SAAO,MAAM,KAAK,IAAQ;AAC5B;AAEA,SAAS,gBAAgB,OAAsB;AAC7C,MACE,MAAM,oBACN,MAAM,QAAQ,YACd,MAAM,eACL,MAA+C,YAAY,KAC5D;AACA;AAAA,EACF;AAEA,QAAM,MAAM,YAAY,YAAY,SAAS,CAAC;AAC9C,MAAI,CAAC,IAAK;AAEV,QAAM,eAAA;AACN,QAAM,gBAAA;AACN,QAAM,yBAAA;AACN,MAAI,SAAA;AACN;AAEA,SAAS,uBAAuB;AAC9B,MAAI,kBAAkB,OAAO,aAAa,YAAa;AACvD,mBAAiB;AACjB,iBAAe,iBAAiB,WAAW,eAAe;AAC5D;AAEA,SAAS,kBAAkB,IAAY;AACrC,QAAM,QAAQ,YAAY,UAAU,CAAC,UAAU,MAAM,OAAO,EAAE;AAC9D,MAAI,UAAU,GAAI,aAAY,OAAO,OAAO,CAAC;AAE7C,MAAI,YAAY,WAAW,KAAK,gBAAgB;AAC9C,mBAAe,oBAAoB,WAAW,eAAe;AAC7D,qBAAiB;AAAA,EACnB;AACF;AAcO,SAAS,cAAc,MAAmC;AAC/D,QAAM,KAAK,MAAA;AACX,uBAAqB,WAAW,aAAa,WAAW;AAExD,YAAU,MAAM;AACd,QAAI,CAAC,KAAM;AACX,UAAM,KAAK,EAAE;AACb,SAAA;AACA,WAAO,MAAM;AACX,YAAM,QAAQ,MAAM,QAAQ,EAAE;AAC9B,UAAI,UAAU,GAAI,OAAM,OAAO,OAAO,CAAC;AACvC,WAAA;AAAA,IACF;AAAA,EACF,GAAG,CAAC,MAAM,EAAE,CAAC;AAEb,QAAM,QAAQ,MAAM,QAAQ,EAAE;AAC9B,SAAO;AAAA,IACL,OAAO,UAAU,MAAM,UAAU,MAAM,SAAS;AAAA,IAChD,OAAO,UAAU,KAAK,IAAI;AAAA,EAAA;AAE9B;AAMO,SAAS,eAAe,MAAe,UAAsB,UAAU,MAAM;AAClF,QAAM,KAAK,MAAA;AACX,QAAM,cAAc,OAAO,QAAQ;AACnC,cAAY,UAAU;AAEtB,YAAU,MAAM;AACd,QAAI,CAAC,QAAQ,CAAC,QAAS;AAEvB,yBAAA;AACA,gBAAY,KAAK;AAAA,MACf;AAAA,MACA,UAAU,MAAM,YAAY,QAAA;AAAA,IAAQ,CACrC;AAED,WAAO,MAAM,kBAAkB,EAAE;AAAA,EACnC,GAAG,CAAC,SAAS,IAAI,IAAI,CAAC;AACxB;AAQO,SAAS,oBAA4B;AAC1C,uBAAqB,WAAW,aAAa,WAAW;AACxD,MAAI,MAAM,WAAW,EAAG,QAAO,OAAO;AACtC,QAAM,YAAY,OAAO,SAAS,MAAM,SAAS,KAAK,OAAO;AAC7D,SAAO,YAAY,OAAO;AAC5B;"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
3
|
+
const zIndex = {
|
|
4
|
+
/** Persistent chat launcher. */
|
|
5
|
+
chatFab: 60,
|
|
6
|
+
/** Floating chat windows; `ChatWindowManager` increments from this base. */
|
|
7
|
+
chatWindow: 61,
|
|
8
|
+
/** Floating transient content when NO modal is open (above app chrome). */
|
|
9
|
+
popover: 9e3,
|
|
10
|
+
/** Modal/dialog at depth 0; nested modals add `modalStep` per level. */
|
|
11
|
+
modal: 1e4,
|
|
12
|
+
/** Per-level step between stacked modals. */
|
|
13
|
+
modalStep: 10,
|
|
14
|
+
/** How far above the top modal floating content sits (below the next nest). */
|
|
15
|
+
popoverOverModalOffset: 5,
|
|
16
|
+
/** Toasts / notifications — always the topmost layer. */
|
|
17
|
+
toast: 1e5
|
|
18
|
+
};
|
|
19
|
+
exports.zIndex = zIndex;
|
|
20
|
+
//# sourceMappingURL=zIndex.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"zIndex.cjs","sources":["../../src/overlay/zIndex.ts"],"sourcesContent":["/**\n * Centralized z-index scale for clicky-ui overlays — the single source of truth\n * so stacking conflicts (e.g. a dropdown opened inside a modal rendering behind\n * it) cannot recur.\n *\n * These are applied as inline `style={{ zIndex }}`, never as arbitrary `z-[N]`\n * Tailwind classes: a consumer's Tailwind build only generates the arbitrary\n * classes it can scan from clicky-ui's published dist, so a freshly chosen\n * `z-[N]` may silently emit no rule. Inline styles are immune to that.\n *\n * Floating, transient content (dropdown / combobox / menu / tooltip / popover)\n * must clear whatever modal is open, so its z-index is computed relative to the\n * active modal via `useFloatingZIndex` (see ./modalStack) rather than taken from\n * a constant here.\n *\n * Layers NOT listed here are intentionally local: they live inside their own\n * stacking context and never participate in the global ordering —\n * `Timeline` (`z-[1]`), `RangeSlider` thumbs (20/30), and `Modal`'s\n * `ConfirmClosePrompt` (`z-10`, relative to the modal panel).\n */\nexport const zIndex = {\n /** In-flow raised affordances (sticky bits). */\n raised: 30,\n /** Persistent chat launcher. */\n chatFab: 60,\n /** Floating chat windows; `ChatWindowManager` increments from this base. */\n chatWindow: 61,\n /** Floating transient content when NO modal is open (above app chrome). */\n popover: 9000,\n /** Modal/dialog at depth 0; nested modals add `modalStep` per level. */\n modal: 10000,\n /** Per-level step between stacked modals. */\n modalStep: 10,\n /** How far above the top modal floating content sits (below the next nest). */\n popoverOverModalOffset: 5,\n /** Toasts / notifications — always the topmost layer. */\n toast: 100000,\n} as const;\n"],"names":[],"mappings":";;AAoBO,MAAM,SAAS;AAAA;AAAA,EAIpB,SAAS;AAAA;AAAA,EAET,YAAY;AAAA;AAAA,EAEZ,SAAS;AAAA;AAAA,EAET,OAAO;AAAA;AAAA,EAEP,WAAW;AAAA;AAAA,EAEX,wBAAwB;AAAA;AAAA,EAExB,OAAO;AACT;;"}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Centralized z-index scale for clicky-ui overlays — the single source of truth
|
|
3
|
+
* so stacking conflicts (e.g. a dropdown opened inside a modal rendering behind
|
|
4
|
+
* it) cannot recur.
|
|
5
|
+
*
|
|
6
|
+
* These are applied as inline `style={{ zIndex }}`, never as arbitrary `z-[N]`
|
|
7
|
+
* Tailwind classes: a consumer's Tailwind build only generates the arbitrary
|
|
8
|
+
* classes it can scan from clicky-ui's published dist, so a freshly chosen
|
|
9
|
+
* `z-[N]` may silently emit no rule. Inline styles are immune to that.
|
|
10
|
+
*
|
|
11
|
+
* Floating, transient content (dropdown / combobox / menu / tooltip / popover)
|
|
12
|
+
* must clear whatever modal is open, so its z-index is computed relative to the
|
|
13
|
+
* active modal via `useFloatingZIndex` (see ./modalStack) rather than taken from
|
|
14
|
+
* a constant here.
|
|
15
|
+
*
|
|
16
|
+
* Layers NOT listed here are intentionally local: they live inside their own
|
|
17
|
+
* stacking context and never participate in the global ordering —
|
|
18
|
+
* `Timeline` (`z-[1]`), `RangeSlider` thumbs (20/30), and `Modal`'s
|
|
19
|
+
* `ConfirmClosePrompt` (`z-10`, relative to the modal panel).
|
|
20
|
+
*/
|
|
21
|
+
export declare const zIndex: {
|
|
22
|
+
/** In-flow raised affordances (sticky bits). */
|
|
23
|
+
readonly raised: 30;
|
|
24
|
+
/** Persistent chat launcher. */
|
|
25
|
+
readonly chatFab: 60;
|
|
26
|
+
/** Floating chat windows; `ChatWindowManager` increments from this base. */
|
|
27
|
+
readonly chatWindow: 61;
|
|
28
|
+
/** Floating transient content when NO modal is open (above app chrome). */
|
|
29
|
+
readonly popover: 9000;
|
|
30
|
+
/** Modal/dialog at depth 0; nested modals add `modalStep` per level. */
|
|
31
|
+
readonly modal: 10000;
|
|
32
|
+
/** Per-level step between stacked modals. */
|
|
33
|
+
readonly modalStep: 10;
|
|
34
|
+
/** How far above the top modal floating content sits (below the next nest). */
|
|
35
|
+
readonly popoverOverModalOffset: 5;
|
|
36
|
+
/** Toasts / notifications — always the topmost layer. */
|
|
37
|
+
readonly toast: 100000;
|
|
38
|
+
};
|
|
39
|
+
//# sourceMappingURL=zIndex.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"zIndex.d.ts","sourceRoot":"","sources":["../../src/overlay/zIndex.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AACH,eAAO,MAAM,MAAM;IACjB,gDAAgD;;IAEhD,gCAAgC;;IAEhC,4EAA4E;;IAE5E,2EAA2E;;IAE3E,wEAAwE;;IAExE,6CAA6C;;IAE7C,+EAA+E;;IAE/E,yDAAyD;;CAEjD,CAAC"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
const zIndex = {
|
|
2
|
+
/** Persistent chat launcher. */
|
|
3
|
+
chatFab: 60,
|
|
4
|
+
/** Floating chat windows; `ChatWindowManager` increments from this base. */
|
|
5
|
+
chatWindow: 61,
|
|
6
|
+
/** Floating transient content when NO modal is open (above app chrome). */
|
|
7
|
+
popover: 9e3,
|
|
8
|
+
/** Modal/dialog at depth 0; nested modals add `modalStep` per level. */
|
|
9
|
+
modal: 1e4,
|
|
10
|
+
/** Per-level step between stacked modals. */
|
|
11
|
+
modalStep: 10,
|
|
12
|
+
/** How far above the top modal floating content sits (below the next nest). */
|
|
13
|
+
popoverOverModalOffset: 5,
|
|
14
|
+
/** Toasts / notifications — always the topmost layer. */
|
|
15
|
+
toast: 1e5
|
|
16
|
+
};
|
|
17
|
+
export {
|
|
18
|
+
zIndex
|
|
19
|
+
};
|
|
20
|
+
//# sourceMappingURL=zIndex.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"zIndex.js","sources":["../../src/overlay/zIndex.ts"],"sourcesContent":["/**\n * Centralized z-index scale for clicky-ui overlays — the single source of truth\n * so stacking conflicts (e.g. a dropdown opened inside a modal rendering behind\n * it) cannot recur.\n *\n * These are applied as inline `style={{ zIndex }}`, never as arbitrary `z-[N]`\n * Tailwind classes: a consumer's Tailwind build only generates the arbitrary\n * classes it can scan from clicky-ui's published dist, so a freshly chosen\n * `z-[N]` may silently emit no rule. Inline styles are immune to that.\n *\n * Floating, transient content (dropdown / combobox / menu / tooltip / popover)\n * must clear whatever modal is open, so its z-index is computed relative to the\n * active modal via `useFloatingZIndex` (see ./modalStack) rather than taken from\n * a constant here.\n *\n * Layers NOT listed here are intentionally local: they live inside their own\n * stacking context and never participate in the global ordering —\n * `Timeline` (`z-[1]`), `RangeSlider` thumbs (20/30), and `Modal`'s\n * `ConfirmClosePrompt` (`z-10`, relative to the modal panel).\n */\nexport const zIndex = {\n /** In-flow raised affordances (sticky bits). */\n raised: 30,\n /** Persistent chat launcher. */\n chatFab: 60,\n /** Floating chat windows; `ChatWindowManager` increments from this base. */\n chatWindow: 61,\n /** Floating transient content when NO modal is open (above app chrome). */\n popover: 9000,\n /** Modal/dialog at depth 0; nested modals add `modalStep` per level. */\n modal: 10000,\n /** Per-level step between stacked modals. */\n modalStep: 10,\n /** How far above the top modal floating content sits (below the next nest). */\n popoverOverModalOffset: 5,\n /** Toasts / notifications — always the topmost layer. */\n toast: 100000,\n} as const;\n"],"names":[],"mappings":"AAoBO,MAAM,SAAS;AAAA;AAAA,EAIpB,SAAS;AAAA;AAAA,EAET,YAAY;AAAA;AAAA,EAEZ,SAAS;AAAA;AAAA,EAET,OAAO;AAAA;AAAA,EAEP,WAAW;AAAA;AAAA,EAEX,wBAAwB;AAAA;AAAA,EAExB,OAAO;AACT;"}
|
|
@@ -2,9 +2,11 @@
|
|
|
2
2
|
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
3
3
|
const jsxRuntime = require("react/jsx-runtime");
|
|
4
4
|
const react = require("react");
|
|
5
|
+
const react$1 = require("@floating-ui/react");
|
|
5
6
|
const button = require("../components/button.cjs");
|
|
6
7
|
const Icon = require("../data/Icon.cjs");
|
|
7
8
|
const utils = require("../lib/utils.cjs");
|
|
9
|
+
const modalStack = require("../overlay/modalStack.cjs");
|
|
8
10
|
const acceptOptions = require("./accept-options.cjs");
|
|
9
11
|
const UiEllipsis = require("../icons/components/UiEllipsis.cjs");
|
|
10
12
|
const UiCheck = require("../icons/components/UiCheck.cjs");
|
|
@@ -23,52 +25,52 @@ function AcceptPicker({
|
|
|
23
25
|
className
|
|
24
26
|
}) {
|
|
25
27
|
var _a;
|
|
26
|
-
const rootRef = react.useRef(null);
|
|
27
28
|
const [open, setOpen] = react.useState(false);
|
|
28
29
|
const pad = size === "sm" ? "px-2 py-0.5" : "px-2.5 py-1";
|
|
29
30
|
const activeLabel = ((_a = options.find((opt) => opt.value === value)) == null ? void 0 : _a.label) ?? value;
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
return /* @__PURE__ */ jsxRuntime.jsxs("div", { ref: rootRef, className: utils.cn("relative flex", className), children: [
|
|
31
|
+
const floatingZ = modalStack.useFloatingZIndex();
|
|
32
|
+
const { refs, floatingStyles, context } = react$1.useFloating({
|
|
33
|
+
open,
|
|
34
|
+
onOpenChange: setOpen,
|
|
35
|
+
placement: "bottom-end",
|
|
36
|
+
whileElementsMounted: react$1.autoUpdate,
|
|
37
|
+
middleware: [react$1.offset(6), react$1.flip({ padding: 8 }), react$1.shift({ padding: 8 })]
|
|
38
|
+
});
|
|
39
|
+
const { getReferenceProps, getFloatingProps } = react$1.useInteractions([
|
|
40
|
+
react$1.useClick(context),
|
|
41
|
+
react$1.useDismiss(context, { escapeKey: false }),
|
|
42
|
+
react$1.useRole(context, { role: "menu" })
|
|
43
|
+
]);
|
|
44
|
+
modalStack.useEscapeLayer(open, () => {
|
|
45
|
+
setOpen(false);
|
|
46
|
+
if (refs.domReference.current instanceof HTMLElement) refs.domReference.current.focus();
|
|
47
|
+
});
|
|
48
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: utils.cn("flex", className), children: [
|
|
49
49
|
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
50
50
|
button.Button,
|
|
51
51
|
{
|
|
52
|
+
ref: refs.setReference,
|
|
52
53
|
type: "button",
|
|
53
54
|
variant: "outline",
|
|
54
55
|
size: "sm",
|
|
55
56
|
"aria-label": "Open format menu",
|
|
56
|
-
"aria-haspopup": "menu",
|
|
57
|
-
"aria-expanded": open,
|
|
58
57
|
className: utils.cn("h-auto gap-1.5", pad),
|
|
59
|
-
|
|
58
|
+
...getReferenceProps(),
|
|
60
59
|
children: [
|
|
61
60
|
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-xs font-medium", children: activeLabel }),
|
|
62
61
|
/* @__PURE__ */ jsxRuntime.jsx(Icon.Icon, { icon: UiEllipsis.UiEllipsis, className: "text-muted-foreground" })
|
|
63
62
|
]
|
|
64
63
|
}
|
|
65
64
|
),
|
|
66
|
-
open && /* @__PURE__ */ jsxRuntime.jsxs(
|
|
65
|
+
open && /* @__PURE__ */ jsxRuntime.jsx(react$1.FloatingPortal, { children: /* @__PURE__ */ jsxRuntime.jsx(react$1.FloatingFocusManager, { context, modal: false, children: /* @__PURE__ */ jsxRuntime.jsxs(
|
|
67
66
|
"div",
|
|
68
67
|
{
|
|
68
|
+
ref: refs.setFloating,
|
|
69
69
|
role: "menu",
|
|
70
70
|
"aria-label": "Format and preview options",
|
|
71
|
-
|
|
71
|
+
style: { ...floatingStyles, zIndex: floatingZ },
|
|
72
|
+
className: "min-w-[12rem] rounded-md border border-border bg-popover p-1 text-popover-foreground shadow-lg shadow-black/5",
|
|
73
|
+
...getFloatingProps(),
|
|
72
74
|
children: [
|
|
73
75
|
/* @__PURE__ */ jsxRuntime.jsx(MenuSectionLabel, { children: "Format" }),
|
|
74
76
|
options.map((opt) => /* @__PURE__ */ jsxRuntime.jsx(
|
|
@@ -101,7 +103,7 @@ function AcceptPicker({
|
|
|
101
103
|
] })
|
|
102
104
|
]
|
|
103
105
|
}
|
|
104
|
-
)
|
|
106
|
+
) }) })
|
|
105
107
|
] });
|
|
106
108
|
}
|
|
107
109
|
function MenuSectionLabel({ children }) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"AcceptPicker.cjs","sources":["../../src/rpc/AcceptPicker.tsx"],"sourcesContent":["import {
|
|
1
|
+
{"version":3,"file":"AcceptPicker.cjs","sources":["../../src/rpc/AcceptPicker.tsx"],"sourcesContent":["import { useState, type Ref } from \"react\";\nimport {\n autoUpdate,\n flip,\n FloatingFocusManager,\n FloatingPortal,\n offset,\n shift,\n useClick,\n useDismiss,\n useFloating,\n useInteractions,\n useRole,\n} from \"@floating-ui/react\";\nimport { Button } from \"../components/button\";\nimport { Icon } from \"../data/Icon\";\nimport { UiEllipsis, UiCheck } from \"../icons\";\nimport { cn } from \"../lib/utils\";\nimport { useEscapeLayer, useFloatingZIndex } from \"../overlay/modalStack\";\nimport {\n ACCEPT_OPTIONS,\n type AcceptOption,\n type OperationPreviewMode,\n} from \"./accept-options\";\n\nexport type AcceptPickerProps = {\n value: string;\n onChange: (value: string) => void;\n size?: \"sm\" | \"md\";\n options?: readonly AcceptOption[];\n previewMode?: OperationPreviewMode;\n onPreviewModeChange?: (mode: OperationPreviewMode) => void;\n className?: string;\n};\n\nconst PREVIEW_OPTIONS: Array<{ value: OperationPreviewMode; label: string }> = [\n { value: \"curl\", label: \"Show cURL preview\" },\n { value: \"cli\", label: \"Show CLI preview\" },\n { value: \"hidden\", label: \"Hide preview\" },\n];\n\nexport function AcceptPicker({\n value,\n onChange,\n size = \"md\",\n options = ACCEPT_OPTIONS,\n previewMode = \"hidden\",\n onPreviewModeChange,\n className,\n}: AcceptPickerProps) {\n const [open, setOpen] = useState(false);\n const pad = size === \"sm\" ? \"px-2 py-0.5\" : \"px-2.5 py-1\";\n const activeLabel = options.find((opt) => opt.value === value)?.label ?? value;\n\n // Portaled (floating-ui) so the menu escapes `overflow` clipping from\n // scroll-container ancestors, matching Combobox/DropdownMenu.\n const floatingZ = useFloatingZIndex();\n const { refs, floatingStyles, context } = useFloating({\n open,\n onOpenChange: setOpen,\n placement: \"bottom-end\",\n whileElementsMounted: autoUpdate,\n middleware: [offset(6), flip({ padding: 8 }), shift({ padding: 8 })],\n });\n const { getReferenceProps, getFloatingProps } = useInteractions([\n useClick(context),\n useDismiss(context, { escapeKey: false }),\n useRole(context, { role: \"menu\" }),\n ]);\n useEscapeLayer(open, () => {\n setOpen(false);\n if (refs.domReference.current instanceof HTMLElement) refs.domReference.current.focus();\n });\n\n return (\n <div className={cn(\"flex\", className)}>\n <Button\n ref={refs.setReference as Ref<HTMLButtonElement>}\n type=\"button\"\n variant=\"outline\"\n size=\"sm\"\n aria-label=\"Open format menu\"\n className={cn(\"h-auto gap-1.5\", pad)}\n {...getReferenceProps()}\n >\n <span className=\"text-xs font-medium\">{activeLabel}</span>\n <Icon icon={UiEllipsis} className=\"text-muted-foreground\" />\n </Button>\n {open && (\n <FloatingPortal>\n <FloatingFocusManager context={context} modal={false}>\n <div\n ref={refs.setFloating}\n role=\"menu\"\n aria-label=\"Format and preview options\"\n style={{ ...floatingStyles, zIndex: floatingZ }}\n className=\"min-w-[12rem] rounded-md border border-border bg-popover p-1 text-popover-foreground shadow-lg shadow-black/5\"\n {...getFloatingProps()}\n >\n <MenuSectionLabel>Format</MenuSectionLabel>\n {options.map((opt) => (\n <MenuRadioItem\n key={opt.value}\n label={opt.label}\n active={opt.value === value}\n onSelect={() => {\n onChange(opt.value);\n setOpen(false);\n }}\n />\n ))}\n {onPreviewModeChange && (\n <>\n <div role=\"separator\" className=\"my-1 h-px bg-border\" />\n <MenuSectionLabel>Preview</MenuSectionLabel>\n {PREVIEW_OPTIONS.map((option) => (\n <MenuRadioItem\n key={option.value}\n label={option.label}\n active={option.value === previewMode}\n onSelect={() => {\n onPreviewModeChange(option.value);\n setOpen(false);\n }}\n />\n ))}\n </>\n )}\n </div>\n </FloatingFocusManager>\n </FloatingPortal>\n )}\n </div>\n );\n}\n\nfunction MenuSectionLabel({ children }: { children: string }) {\n return (\n <div className=\"px-2 py-1 text-[10px] font-semibold uppercase tracking-wider text-muted-foreground\">\n {children}\n </div>\n );\n}\n\nfunction MenuRadioItem({\n label,\n active,\n onSelect,\n}: {\n label: string;\n active: boolean;\n onSelect: () => void;\n}) {\n return (\n <button\n type=\"button\"\n role=\"menuitemradio\"\n aria-checked={active}\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 && \"font-medium\",\n )}\n onClick={onSelect}\n >\n <span className=\"min-w-0 flex-1\">{label}</span>\n {active ? <Icon icon={UiCheck} className=\"shrink-0\" /> : null}\n </button>\n );\n}\n"],"names":["ACCEPT_OPTIONS","useState","useFloatingZIndex","useFloating","autoUpdate","offset","flip","shift","useInteractions","useClick","useDismiss","useRole","useEscapeLayer","cn","jsxs","Button","jsx","Icon","UiEllipsis","FloatingPortal","FloatingFocusManager","Fragment","UiCheck"],"mappings":";;;;;;;;;;;;AAmCA,MAAM,kBAAyE;AAAA,EAC7E,EAAE,OAAO,QAAQ,OAAO,oBAAA;AAAA,EACxB,EAAE,OAAO,OAAO,OAAO,mBAAA;AAAA,EACvB,EAAE,OAAO,UAAU,OAAO,eAAA;AAC5B;AAEO,SAAS,aAAa;AAAA,EAC3B;AAAA,EACA;AAAA,EACA,OAAO;AAAA,EACP,UAAUA,cAAAA;AAAAA,EACV,cAAc;AAAA,EACd;AAAA,EACA;AACF,GAAsB;;AACpB,QAAM,CAAC,MAAM,OAAO,IAAIC,MAAAA,SAAS,KAAK;AACtC,QAAM,MAAM,SAAS,OAAO,gBAAgB;AAC5C,QAAM,gBAAc,aAAQ,KAAK,CAAC,QAAQ,IAAI,UAAU,KAAK,MAAzC,mBAA4C,UAAS;AAIzE,QAAM,YAAYC,WAAAA,kBAAA;AAClB,QAAM,EAAE,MAAM,gBAAgB,QAAA,IAAYC,QAAAA,YAAY;AAAA,IACpD;AAAA,IACA,cAAc;AAAA,IACd,WAAW;AAAA,IACX,sBAAsBC,QAAAA;AAAAA,IACtB,YAAY,CAACC,QAAAA,OAAO,CAAC,GAAGC,QAAAA,KAAK,EAAE,SAAS,EAAA,CAAG,GAAGC,QAAAA,MAAM,EAAE,SAAS,EAAA,CAAG,CAAC;AAAA,EAAA,CACpE;AACD,QAAM,EAAE,mBAAmB,iBAAA,IAAqBC,wBAAgB;AAAA,IAC9DC,QAAAA,SAAS,OAAO;AAAA,IAChBC,QAAAA,WAAW,SAAS,EAAE,WAAW,OAAO;AAAA,IACxCC,QAAAA,QAAQ,SAAS,EAAE,MAAM,QAAQ;AAAA,EAAA,CAClC;AACDC,aAAAA,eAAe,MAAM,MAAM;AACzB,YAAQ,KAAK;AACb,QAAI,KAAK,aAAa,mBAAmB,YAAa,MAAK,aAAa,QAAQ,MAAA;AAAA,EAClF,CAAC;AAED,yCACG,OAAA,EAAI,WAAWC,MAAAA,GAAG,QAAQ,SAAS,GAClC,UAAA;AAAA,IAAAC,2BAAAA;AAAAA,MAACC,OAAAA;AAAAA,MAAA;AAAA,QACC,KAAK,KAAK;AAAA,QACV,MAAK;AAAA,QACL,SAAQ;AAAA,QACR,MAAK;AAAA,QACL,cAAW;AAAA,QACX,WAAWF,MAAAA,GAAG,kBAAkB,GAAG;AAAA,QAClC,GAAG,kBAAA;AAAA,QAEJ,UAAA;AAAA,UAAAG,2BAAAA,IAAC,QAAA,EAAK,WAAU,uBAAuB,UAAA,aAAY;AAAA,UACnDA,2BAAAA,IAACC,KAAAA,MAAA,EAAK,MAAMC,WAAAA,YAAY,WAAU,wBAAA,CAAwB;AAAA,QAAA;AAAA,MAAA;AAAA,IAAA;AAAA,IAE3D,QACCF,2BAAAA,IAACG,wBAAA,EACC,yCAACC,8BAAA,EAAqB,SAAkB,OAAO,OAC7C,UAAAN,2BAAAA;AAAAA,MAAC;AAAA,MAAA;AAAA,QACC,KAAK,KAAK;AAAA,QACV,MAAK;AAAA,QACL,cAAW;AAAA,QACX,OAAO,EAAE,GAAG,gBAAgB,QAAQ,UAAA;AAAA,QACpC,WAAU;AAAA,QACT,GAAG,iBAAA;AAAA,QAER,UAAA;AAAA,UAAAE,2BAAAA,IAAC,oBAAiB,UAAA,SAAA,CAAM;AAAA,UACvB,QAAQ,IAAI,CAAC,QACZA,2BAAAA;AAAAA,YAAC;AAAA,YAAA;AAAA,cAEC,OAAO,IAAI;AAAA,cACX,QAAQ,IAAI,UAAU;AAAA,cACtB,UAAU,MAAM;AACd,yBAAS,IAAI,KAAK;AAClB,wBAAQ,KAAK;AAAA,cACf;AAAA,YAAA;AAAA,YANK,IAAI;AAAA,UAAA,CAQZ;AAAA,UACA,uBACCF,2BAAAA,KAAAO,qBAAA,EACE,UAAA;AAAA,YAAAL,2BAAAA,IAAC,OAAA,EAAI,MAAK,aAAY,WAAU,uBAAsB;AAAA,YACtDA,2BAAAA,IAAC,oBAAiB,UAAA,UAAA,CAAO;AAAA,YACxB,gBAAgB,IAAI,CAAC,WACpBA,2BAAAA;AAAAA,cAAC;AAAA,cAAA;AAAA,gBAEC,OAAO,OAAO;AAAA,gBACd,QAAQ,OAAO,UAAU;AAAA,gBACzB,UAAU,MAAM;AACd,sCAAoB,OAAO,KAAK;AAChC,0BAAQ,KAAK;AAAA,gBACf;AAAA,cAAA;AAAA,cANK,OAAO;AAAA,YAAA,CAQf;AAAA,UAAA,EAAA,CACH;AAAA,QAAA;AAAA,MAAA;AAAA,IAAA,GAGF,EAAA,CACF;AAAA,EAAA,GAEJ;AAEJ;AAEA,SAAS,iBAAiB,EAAE,YAAkC;AAC5D,SACEA,2BAAAA,IAAC,OAAA,EAAI,WAAU,sFACZ,SAAA,CACH;AAEJ;AAEA,SAAS,cAAc;AAAA,EACrB;AAAA,EACA;AAAA,EACA;AACF,GAIG;AACD,SACEF,2BAAAA;AAAAA,IAAC;AAAA,IAAA;AAAA,MACC,MAAK;AAAA,MACL,MAAK;AAAA,MACL,gBAAc;AAAA,MACd,WAAWD,MAAAA;AAAAA,QACT;AAAA,QACA;AAAA,QACA,UAAU;AAAA,MAAA;AAAA,MAEZ,SAAS;AAAA,MAET,UAAA;AAAA,QAAAG,2BAAAA,IAAC,QAAA,EAAK,WAAU,kBAAkB,UAAA,OAAM;AAAA,QACvC,SAASA,2BAAAA,IAACC,KAAAA,MAAA,EAAK,MAAMK,QAAAA,SAAS,WAAU,YAAW,IAAK;AAAA,MAAA;AAAA,IAAA;AAAA,EAAA;AAG/D;;"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"AcceptPicker.d.ts","sourceRoot":"","sources":["../../src/rpc/AcceptPicker.tsx"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"AcceptPicker.d.ts","sourceRoot":"","sources":["../../src/rpc/AcceptPicker.tsx"],"names":[],"mappings":"AAmBA,OAAO,EAEL,KAAK,YAAY,EACjB,KAAK,oBAAoB,EAC1B,MAAM,kBAAkB,CAAC;AAE1B,MAAM,MAAM,iBAAiB,GAAG;IAC9B,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IAClC,IAAI,CAAC,EAAE,IAAI,GAAG,IAAI,CAAC;IACnB,OAAO,CAAC,EAAE,SAAS,YAAY,EAAE,CAAC;IAClC,WAAW,CAAC,EAAE,oBAAoB,CAAC;IACnC,mBAAmB,CAAC,EAAE,CAAC,IAAI,EAAE,oBAAoB,KAAK,IAAI,CAAC;IAC3D,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB,CAAC;AAQF,wBAAgB,YAAY,CAAC,EAC3B,KAAK,EACL,QAAQ,EACR,IAAW,EACX,OAAwB,EACxB,WAAsB,EACtB,mBAAmB,EACnB,SAAS,GACV,EAAE,iBAAiB,2CAqFnB"}
|
package/dist/rpc/AcceptPicker.js
CHANGED
|
@@ -1,8 +1,10 @@
|
|
|
1
1
|
import { jsxs, jsx, Fragment } from "react/jsx-runtime";
|
|
2
|
-
import {
|
|
2
|
+
import { useState } from "react";
|
|
3
|
+
import { useFloating, autoUpdate, offset, flip, shift, useInteractions, useClick, useDismiss, useRole, FloatingPortal, FloatingFocusManager } from "@floating-ui/react";
|
|
3
4
|
import { Button } from "../components/button.js";
|
|
4
5
|
import { Icon } from "../data/Icon.js";
|
|
5
6
|
import { cn } from "../lib/utils.js";
|
|
7
|
+
import { useFloatingZIndex, useEscapeLayer } from "../overlay/modalStack.js";
|
|
6
8
|
import { ACCEPT_OPTIONS } from "./accept-options.js";
|
|
7
9
|
import { UiEllipsis } from "../icons/components/UiEllipsis.js";
|
|
8
10
|
import { UiCheck } from "../icons/components/UiCheck.js";
|
|
@@ -21,52 +23,52 @@ function AcceptPicker({
|
|
|
21
23
|
className
|
|
22
24
|
}) {
|
|
23
25
|
var _a;
|
|
24
|
-
const rootRef = useRef(null);
|
|
25
26
|
const [open, setOpen] = useState(false);
|
|
26
27
|
const pad = size === "sm" ? "px-2 py-0.5" : "px-2.5 py-1";
|
|
27
28
|
const activeLabel = ((_a = options.find((opt) => opt.value === value)) == null ? void 0 : _a.label) ?? value;
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
return /* @__PURE__ */ jsxs("div", { ref: rootRef, className: cn("relative flex", className), children: [
|
|
29
|
+
const floatingZ = useFloatingZIndex();
|
|
30
|
+
const { refs, floatingStyles, context } = useFloating({
|
|
31
|
+
open,
|
|
32
|
+
onOpenChange: setOpen,
|
|
33
|
+
placement: "bottom-end",
|
|
34
|
+
whileElementsMounted: autoUpdate,
|
|
35
|
+
middleware: [offset(6), flip({ padding: 8 }), shift({ padding: 8 })]
|
|
36
|
+
});
|
|
37
|
+
const { getReferenceProps, getFloatingProps } = useInteractions([
|
|
38
|
+
useClick(context),
|
|
39
|
+
useDismiss(context, { escapeKey: false }),
|
|
40
|
+
useRole(context, { role: "menu" })
|
|
41
|
+
]);
|
|
42
|
+
useEscapeLayer(open, () => {
|
|
43
|
+
setOpen(false);
|
|
44
|
+
if (refs.domReference.current instanceof HTMLElement) refs.domReference.current.focus();
|
|
45
|
+
});
|
|
46
|
+
return /* @__PURE__ */ jsxs("div", { className: cn("flex", className), children: [
|
|
47
47
|
/* @__PURE__ */ jsxs(
|
|
48
48
|
Button,
|
|
49
49
|
{
|
|
50
|
+
ref: refs.setReference,
|
|
50
51
|
type: "button",
|
|
51
52
|
variant: "outline",
|
|
52
53
|
size: "sm",
|
|
53
54
|
"aria-label": "Open format menu",
|
|
54
|
-
"aria-haspopup": "menu",
|
|
55
|
-
"aria-expanded": open,
|
|
56
55
|
className: cn("h-auto gap-1.5", pad),
|
|
57
|
-
|
|
56
|
+
...getReferenceProps(),
|
|
58
57
|
children: [
|
|
59
58
|
/* @__PURE__ */ jsx("span", { className: "text-xs font-medium", children: activeLabel }),
|
|
60
59
|
/* @__PURE__ */ jsx(Icon, { icon: UiEllipsis, className: "text-muted-foreground" })
|
|
61
60
|
]
|
|
62
61
|
}
|
|
63
62
|
),
|
|
64
|
-
open && /* @__PURE__ */ jsxs(
|
|
63
|
+
open && /* @__PURE__ */ jsx(FloatingPortal, { children: /* @__PURE__ */ jsx(FloatingFocusManager, { context, modal: false, children: /* @__PURE__ */ jsxs(
|
|
65
64
|
"div",
|
|
66
65
|
{
|
|
66
|
+
ref: refs.setFloating,
|
|
67
67
|
role: "menu",
|
|
68
68
|
"aria-label": "Format and preview options",
|
|
69
|
-
|
|
69
|
+
style: { ...floatingStyles, zIndex: floatingZ },
|
|
70
|
+
className: "min-w-[12rem] rounded-md border border-border bg-popover p-1 text-popover-foreground shadow-lg shadow-black/5",
|
|
71
|
+
...getFloatingProps(),
|
|
70
72
|
children: [
|
|
71
73
|
/* @__PURE__ */ jsx(MenuSectionLabel, { children: "Format" }),
|
|
72
74
|
options.map((opt) => /* @__PURE__ */ jsx(
|
|
@@ -99,7 +101,7 @@ function AcceptPicker({
|
|
|
99
101
|
] })
|
|
100
102
|
]
|
|
101
103
|
}
|
|
102
|
-
)
|
|
104
|
+
) }) })
|
|
103
105
|
] });
|
|
104
106
|
}
|
|
105
107
|
function MenuSectionLabel({ children }) {
|