@evinvest/uikit 0.26.0 → 0.29.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/README.md +148 -17
- package/dist/components/account-menu.js +70 -0
- package/dist/components/account-menu.js.map +1 -0
- package/dist/components/alert-dialog.js +4 -3
- package/dist/components/alert-dialog.js.map +1 -1
- package/dist/components/app-shell.js +11 -0
- package/dist/components/app-shell.js.map +1 -1
- package/dist/components/auth-wall.js +42 -0
- package/dist/components/auth-wall.js.map +1 -0
- package/dist/components/checkbox.js +2 -0
- package/dist/components/checkbox.js.map +1 -1
- package/dist/components/command.js +180 -25
- package/dist/components/command.js.map +1 -1
- package/dist/components/context-menu.js +8 -8
- package/dist/components/context-menu.js.map +1 -1
- package/dist/components/dialog.js +4 -3
- package/dist/components/dialog.js.map +1 -1
- package/dist/components/drawer.js +9 -5
- package/dist/components/drawer.js.map +1 -1
- package/dist/components/dropdown-menu.js +13 -10
- package/dist/components/dropdown-menu.js.map +1 -1
- package/dist/components/field.js +3 -8
- package/dist/components/field.js.map +1 -1
- package/dist/components/info-tip.js +2 -2
- package/dist/components/info-tip.js.map +1 -1
- package/dist/components/input.js +2 -0
- package/dist/components/input.js.map +1 -1
- package/dist/components/menubar.js +18 -5
- package/dist/components/menubar.js.map +1 -1
- package/dist/components/native-select.js +2 -0
- package/dist/components/native-select.js.map +1 -1
- package/dist/components/navigation-menu.js +2 -2
- package/dist/components/navigation-menu.js.map +1 -1
- package/dist/components/popover.js +2 -2
- package/dist/components/popover.js.map +1 -1
- package/dist/components/select.js +4 -2
- package/dist/components/select.js.map +1 -1
- package/dist/components/sheet.js +4 -3
- package/dist/components/sheet.js.map +1 -1
- package/dist/components/sonner.js +1 -0
- package/dist/components/sonner.js.map +1 -1
- package/dist/components/switch.js +2 -0
- package/dist/components/switch.js.map +1 -1
- package/dist/components/table.js +24 -7
- package/dist/components/table.js.map +1 -1
- package/dist/components/textarea.js +2 -0
- package/dist/components/textarea.js.map +1 -1
- package/dist/components/toggle-group.js +1 -1
- package/dist/components/toggle-group.js.map +1 -1
- package/dist/components/top-bar.js +21 -0
- package/dist/components/top-bar.js.map +1 -0
- package/dist/generated/command.js +2 -2
- package/dist/generated/command.js.map +1 -1
- package/dist/generated/context-menu.js +1 -1
- package/dist/generated/context-menu.js.map +1 -1
- package/dist/generated/dropdown-menu.js +1 -1
- package/dist/generated/dropdown-menu.js.map +1 -1
- package/dist/generated/menubar.js +1 -1
- package/dist/generated/menubar.js.map +1 -1
- package/dist/generated/table.js +20 -3
- package/dist/generated/table.js.map +1 -1
- package/dist/generated/toggle.js +2 -2
- package/dist/generated/toggle.js.map +1 -1
- package/dist/index.d.ts +179 -76
- package/dist/index.js +6 -4
- package/dist/primitives/dismissable-layer.js +80 -15
- package/dist/primitives/dismissable-layer.js.map +1 -1
- package/dist/primitives/labelable.js +24 -0
- package/dist/primitives/labelable.js.map +1 -0
- package/dist/primitives/use-roving-focus.js +13 -7
- package/dist/primitives/use-roving-focus.js.map +1 -1
- package/package.json +1 -1
- package/styles/ev.css +4 -2
- package/styles/theme.css +7 -0
- package/styles/tokens.css +15 -3
- package/dist/components/chart.js +0 -151
- package/dist/components/chart.js.map +0 -1
- package/dist/components/resizable.js +0 -193
- package/dist/components/resizable.js.map +0 -1
- package/dist/generated/chart.js +0 -9
- package/dist/generated/chart.js.map +0 -1
- package/dist/generated/resizable.js +0 -11
- package/dist/generated/resizable.js.map +0 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/primitives/dismissable-layer.tsx"],"sourcesContent":["\"use client\";\n\nimport * as React from \"react\";\n\ntype LayerRef = React.RefObject<HTMLDivElement | null>;\n\n// The open layers, oldest first. An overlay opened inside another (a Select in\n// a Dialog, a Popover in a Drawer) is portaled out of its parent's subtree, so\n// \"outside the parent\" would include it: the stack is what tells a nested\n// layer from the rest of the page.\nconst stack: LayerRef[] = [];\n\nfunction isInsideHigherLayer(own: LayerRef, target: Node): boolean {\n const index = stack.indexOf(own);\n // Not on the stack (a listener outliving its cleanup): nothing is above it.\n if (index < 0) return false;\n return stack.slice(index + 1).some((layer) => layer.current?.contains(target) ?? false);\n}\n\n/** Why a layer is being dismissed: the event itself, for a caller that treats keys and pointers apart. */\nexport type DismissEvent = PointerEvent | KeyboardEvent;\n\n/**\n * Calls `onDismiss` on Escape or on a pointer-down outside the layer — the\n * dep-light core of every overlay's \"click away to close\". Pass refs to any\n * nodes that should NOT count as outside (e.g. the trigger), via `exclude`.\n *\n * Layers stack, in the order they opened: Escape dismisses only the topmost\n * layer on this stack, and a pointer-down inside a layer opened above this one\n * is not outside it — so a Select's list inside a Dialog closes the list, not\n * the Dialog. The stack knows only the overlays built on this hook: a\n * `Drawer` or `CommandDialog` (Escape in their own React `onKeyDown`) is not\n * on it, and a menu that also closes on Escape in its React `onKeyDown` lets\n * the key bubble through React's tree to what holds it. Moving those onto the\n * stack is a follow-up.\n *\n * Mirrors the dismiss behaviour Rust expresses with a full-screen backdrop.\n */\nexport function useDismissableLayer(opts: {\n enabled: boolean;\n onDismiss: (event: DismissEvent) => void;\n exclude?: Array<React.RefObject<Element | null>>;\n}): React.RefObject<HTMLDivElement | null> {\n const { enabled, onDismiss, exclude } = opts;\n const ref = React.useRef<HTMLDivElement | null>(null);\n const onDismissRef = React.useRef(onDismiss);\n // Callers pass `exclude` inline, a new array each render: read through a ref,\n // or the effect would re-run and move this layer to the top of the stack.\n const excludeRef = React.useRef(exclude);\n React.useEffect(() => {\n onDismissRef.current = onDismiss;\n excludeRef.current = exclude;\n });\n\n React.useEffect(() => {\n if (!enabled) return;\n stack.push(ref);\n\n function onPointerDown(event: PointerEvent) {\n const target = event.target as Node | null;\n if (!target) return;\n if (ref.current && ref.current.contains(target)) return;\n for (const r of excludeRef.current ?? []) {\n if (r.current && r.current.contains(target)) return;\n }\n if (isInsideHigherLayer(ref, target)) return;\n onDismissRef.current(event);\n }\n\n function onKeyDown(event: KeyboardEvent) {\n if (event.key === \"Escape\" && stack[stack.length - 1] === ref) onDismissRef.current(event);\n }\n\n document.addEventListener(\"pointerdown\", onPointerDown, true);\n document.addEventListener(\"keydown\", onKeyDown);\n return () => {\n const index = stack.indexOf(ref);\n if (index >= 0) stack.splice(index, 1);\n document.removeEventListener(\"pointerdown\", onPointerDown, true);\n document.removeEventListener(\"keydown\", onKeyDown);\n };\n }, [enabled]);\n\n return ref;\n}\n"],"mappings":";AAEA,YAAY,WAAW;AAQvB,MAAM,QAAoB,CAAC;AAE3B,SAAS,oBAAoB,KAAe,QAAuB;AACjE,QAAM,QAAQ,MAAM,QAAQ,GAAG;AAE/B,MAAI,QAAQ,EAAG,QAAO;AACtB,SAAO,MAAM,MAAM,QAAQ,CAAC,EAAE,KAAK,CAAC,UAAU,MAAM,SAAS,SAAS,MAAM,KAAK,KAAK;AACxF;AAqBO,SAAS,oBAAoB,MAIO;AACzC,QAAM,EAAE,SAAS,WAAW,QAAQ,IAAI;AACxC,QAAM,MAAM,MAAM,OAA8B,IAAI;AACpD,QAAM,eAAe,MAAM,OAAO,SAAS;AAG3C,QAAM,aAAa,MAAM,OAAO,OAAO;AACvC,QAAM,UAAU,MAAM;AACpB,iBAAa,UAAU;AACvB,eAAW,UAAU;AAAA,EACvB,CAAC;AAED,QAAM,UAAU,MAAM;AACpB,QAAI,CAAC,QAAS;AACd,UAAM,KAAK,GAAG;AAEd,aAAS,cAAc,OAAqB;AAC1C,YAAM,SAAS,MAAM;AACrB,UAAI,CAAC,OAAQ;AACb,UAAI,IAAI,WAAW,IAAI,QAAQ,SAAS,MAAM,EAAG;AACjD,iBAAW,KAAK,WAAW,WAAW,CAAC,GAAG;AACxC,YAAI,EAAE,WAAW,EAAE,QAAQ,SAAS,MAAM,EAAG;AAAA,MAC/C;AACA,UAAI,oBAAoB,KAAK,MAAM,EAAG;AACtC,mBAAa,QAAQ,KAAK;AAAA,IAC5B;AAEA,aAAS,UAAU,OAAsB;AACvC,UAAI,MAAM,QAAQ,YAAY,MAAM,MAAM,SAAS,CAAC,MAAM,IAAK,cAAa,QAAQ,KAAK;AAAA,IAC3F;AAEA,aAAS,iBAAiB,eAAe,eAAe,IAAI;AAC5D,aAAS,iBAAiB,WAAW,SAAS;AAC9C,WAAO,MAAM;AACX,YAAM,QAAQ,MAAM,QAAQ,GAAG;AAC/B,UAAI,SAAS,EAAG,OAAM,OAAO,OAAO,CAAC;AACrC,eAAS,oBAAoB,eAAe,eAAe,IAAI;AAC/D,eAAS,oBAAoB,WAAW,SAAS;AAAA,IACnD;AAAA,EACF,GAAG,CAAC,OAAO,CAAC;AAEZ,SAAO;AACT;","names":[]}
|
|
1
|
+
{"version":3,"sources":["../../src/primitives/dismissable-layer.tsx"],"sourcesContent":["\"use client\";\n\nimport * as React from \"react\";\n\ntype LayerRef = React.RefObject<HTMLDivElement | null>;\n\ninterface LayerInfo {\n /** The layer this one was rendered inside, from context — not the one below it on the stack. */\n parent: LayerRef | null;\n modal: boolean;\n}\n\ninterface LayerStore {\n // The open layers, bottom first. An overlay opened inside another (a Select\n // in a Dialog, a Popover in a Drawer) is portaled out of its parent's\n // subtree, so \"outside the parent\" would include it: the stack is what tells\n // a nested layer from the rest of the page.\n stack: LayerRef[];\n info: WeakMap<LayerRef, LayerInfo>;\n // The stack as it stood when an event started its trip. By the time the\n // document hears an Escape, a React `onKeyDown` on the way (a Select's, a\n // consumer's) may already have closed the top layer and — a discrete update\n // commits synchronously — popped it, so the layer below would find itself\n // on top and close on the same key; a pointer-down can close an upper modal\n // the same way and lift its barrier mid-flight. Taken in the window's\n // capture phase, which runs before any DOM listener, React's root included.\n seen: WeakMap<Event, LayerRef[]>;\n snapshot: (event: Event) => void;\n}\n\n// One stack per page, not per module copy: a micro-frontend that bundles its\n// own uikit must see the host's layers, and the host its. Versioned, so a copy\n// with a different store shape keeps to itself instead of misreading this one.\nconst STORE_KEY = Symbol.for(\"@evinvest/uikit/dismissable-layers@1\");\n\nfunction isStore(value: unknown): value is LayerStore {\n return typeof value === \"object\" && value !== null && \"stack\" in value && Array.isArray(value.stack);\n}\n\nfunction sharedStore(): LayerStore {\n const existing: unknown = Reflect.get(globalThis, STORE_KEY);\n if (isStore(existing)) return existing;\n const store: LayerStore = {\n stack: [],\n info: new WeakMap(),\n seen: new WeakMap(),\n snapshot: (event) => {\n if (!store.seen.has(event)) store.seen.set(event, store.stack.slice());\n },\n };\n Reflect.set(globalThis, STORE_KEY, store);\n return store;\n}\n\nconst store = sharedStore();\n\n/**\n * Elements carrying this attribute are outside every layer without being a\n * click away from any: a press there dismisses nothing (the toaster).\n */\nexport const LAYER_IGNORE_ATTR = \"data-dismissable-layer-ignore\";\n\nfunction layersAt(event: Event): LayerRef[] {\n // An event dispatched where the window never sees it falls back to the live stack.\n return store.seen.get(event) ?? store.stack;\n}\n\nfunction isPointerOutside(own: LayerRef, event: PointerEvent): boolean {\n const target = event.target;\n if (!(target instanceof Node)) return false;\n const el = target instanceof Element ? target : target.parentElement;\n if (el?.closest(`[${LAYER_IGNORE_ATTR}]`)) return false;\n const layers = layersAt(event);\n const index = layers.indexOf(own);\n // Not on the stack (a listener outliving its cleanup): nothing is above it.\n if (index < 0) return true;\n const above = layers.slice(index + 1);\n // A modal above is a barrier: whatever the press landed on — its scrim, its\n // panel, a toast over it — the modal answers for it, not the layers below.\n if (above.some((layer) => store.info.get(layer)?.modal === true)) return false;\n return !above.some((layer) => layer.current?.contains(target) ?? false);\n}\n\nfunction ownsEscape(own: LayerRef, event: KeyboardEvent): boolean {\n const layers = layersAt(event);\n return layers[layers.length - 1] === own;\n}\n\nfunction isDescendant(layer: LayerRef, ancestor: LayerRef): boolean {\n for (let p = store.info.get(layer)?.parent ?? null; p; p = store.info.get(p)?.parent ?? null) {\n if (p === ancestor) return true;\n }\n return false;\n}\n\nfunction push(layer: LayerRef) {\n const { stack } = store;\n if (stack.length === 0) {\n window.addEventListener(\"keydown\", store.snapshot, true);\n window.addEventListener(\"pointerdown\", store.snapshot, true);\n }\n // Children's effects run before their parent's, so a layer opened in the\n // same commit as one nested in it (`defaultOpen` on both, a shared `open`)\n // arrives second: it goes below its first descendant, not on top.\n const firstChild = stack.findIndex((other) => isDescendant(other, layer));\n if (firstChild < 0) stack.push(layer);\n else stack.splice(firstChild, 0, layer);\n}\n\nfunction pop(layer: LayerRef) {\n const { stack } = store;\n const index = stack.indexOf(layer);\n if (index >= 0) stack.splice(index, 1);\n if (stack.length === 0) {\n window.removeEventListener(\"keydown\", store.snapshot, true);\n window.removeEventListener(\"pointerdown\", store.snapshot, true);\n }\n}\n\nconst ParentLayerContext = React.createContext<LayerRef | null>(null);\n\n/**\n * Marks `children` as rendered inside `layer` (the ref `useDismissableLayer`\n * returned), so a layer among them always stacks above it — even when both\n * open in the same commit. Wrap the overlay's content in it.\n */\nexport function DismissableLayerScope({ layer, children }: { layer: LayerRef; children?: React.ReactNode }) {\n return <ParentLayerContext.Provider value={layer}>{children}</ParentLayerContext.Provider>;\n}\n\n/** Why a layer is being dismissed: the event itself, for a caller that treats keys and pointers apart. */\nexport type DismissEvent = PointerEvent | KeyboardEvent;\n\n/**\n * Calls `onDismiss` on Escape or on a pointer-down outside the layer — the\n * dep-light core of every overlay's \"click away to close\". Pass refs to any\n * nodes that should NOT count as outside (e.g. the trigger), via `exclude`.\n *\n * Layers stack: a layer rendered inside another's `DismissableLayerScope`\n * sits above it, the rest in the order they opened. Escape dismisses only the\n * topmost layer, and a pointer-down inside a layer above this one is not\n * outside it — so a Select's list inside a Dialog closes the list, not the\n * Dialog. The Escape goes to the layer that was on top when the key was\n * pressed, even if a handler on its way closed that layer first.\n *\n * `modal: true` makes the layer a barrier: while it is open, the layers below\n * ignore every pointer-down — a press on its scrim closes it alone. Elements\n * marked with `LAYER_IGNORE_ATTR` (the toaster) are outside no layer.\n *\n * `pointerOutside: false` keeps the layer on the stack (it takes Escape, and\n * the layers below see a pointer-down inside it as inside) but leaves outside\n * clicks to the caller — for an overlay whose own scrim is what \"outside\"\n * means (Drawer, CommandDialog).\n *\n * The stack is shared through `globalThis`, so every copy of this module on\n * the page sees one stack; parent links need one React context, so they hold\n * within a copy only.\n *\n * Mirrors the dismiss behaviour Rust expresses with a full-screen backdrop.\n */\nexport function useDismissableLayer(opts: {\n enabled: boolean;\n onDismiss: (event: DismissEvent) => void;\n exclude?: Array<React.RefObject<Element | null>>;\n /** Dismiss on a pointer-down outside the layer. Default `true`. */\n pointerOutside?: boolean;\n /** Bar the layers below from pointer-downs while open. Default `false`. */\n modal?: boolean;\n}): React.RefObject<HTMLDivElement | null> {\n const { enabled, onDismiss, exclude, pointerOutside = true, modal = false } = opts;\n const parent = React.useContext(ParentLayerContext);\n const ref = React.useRef<HTMLDivElement | null>(null);\n const onDismissRef = React.useRef(onDismiss);\n // Callers pass `exclude` inline, a new array each render: read through a ref,\n // or the effect would re-run and move this layer to the top of the stack.\n const excludeRef = React.useRef(exclude);\n React.useEffect(() => {\n onDismissRef.current = onDismiss;\n excludeRef.current = exclude;\n });\n\n React.useEffect(() => {\n if (!enabled) return;\n store.info.set(ref, { parent, modal });\n push(ref);\n\n function onPointerDown(event: PointerEvent) {\n const target = event.target;\n if (!(target instanceof Node)) return;\n if (ref.current && ref.current.contains(target)) return;\n for (const r of excludeRef.current ?? []) {\n if (r.current && r.current.contains(target)) return;\n }\n if (isPointerOutside(ref, event)) onDismissRef.current(event);\n }\n\n function onKeyDown(event: KeyboardEvent) {\n if (event.key === \"Escape\" && ownsEscape(ref, event)) onDismissRef.current(event);\n }\n\n if (pointerOutside) document.addEventListener(\"pointerdown\", onPointerDown, true);\n document.addEventListener(\"keydown\", onKeyDown);\n return () => {\n pop(ref);\n document.removeEventListener(\"pointerdown\", onPointerDown, true);\n document.removeEventListener(\"keydown\", onKeyDown);\n };\n }, [enabled, pointerOutside, modal, parent]);\n\n return ref;\n}\n"],"mappings":"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","names":["store"]}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
const LABELABLE = /* @__PURE__ */ Symbol.for("@evinvest/uikit/labelable@1");
|
|
2
|
+
const LAZY = /* @__PURE__ */ Symbol.for("react.lazy");
|
|
3
|
+
function markLabelable(component) {
|
|
4
|
+
Object.defineProperty(component, LABELABLE, { value: true });
|
|
5
|
+
}
|
|
6
|
+
function isLabelable(type) {
|
|
7
|
+
const resolved = unwrapLazy(type);
|
|
8
|
+
return (typeof resolved === "function" || typeof resolved === "object" && resolved !== null) && Reflect.get(resolved, LABELABLE) === true;
|
|
9
|
+
}
|
|
10
|
+
function unwrapLazy(type) {
|
|
11
|
+
if (typeof type !== "object" || type === null || Reflect.get(type, "$$typeof") !== LAZY) return type;
|
|
12
|
+
const init = Reflect.get(type, "_init");
|
|
13
|
+
if (typeof init !== "function") return void 0;
|
|
14
|
+
try {
|
|
15
|
+
return Reflect.apply(init, void 0, [Reflect.get(type, "_payload")]);
|
|
16
|
+
} catch {
|
|
17
|
+
return void 0;
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
export {
|
|
21
|
+
isLabelable,
|
|
22
|
+
markLabelable
|
|
23
|
+
};
|
|
24
|
+
//# sourceMappingURL=labelable.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/primitives/labelable.ts"],"sourcesContent":["// How `FieldLabel` tells a kit control from any other component without\n// importing it: each control marks itself in its own module. Recognising them\n// by identity meant `field.tsx` imported every control, so a page with one\n// `Field` and an `Input` still shipped the whole `Select` (floating, portal,\n// focus scope, listbox — ~4 KB gz).\n//\n// `Symbol.for`, not `Symbol`: two copies of the kit in one app (a hoisting\n// accident) still read each other's marks.\nconst LABELABLE = Symbol.for(\"@evinvest/uikit/labelable@1\");\nconst LAZY = Symbol.for(\"react.lazy\");\n\n/** Marks a component that renders one labelable element and takes its `Field`'s id. */\nexport function markLabelable(component: object): void {\n Object.defineProperty(component, LABELABLE, { value: true });\n}\n\n/** Whether an element `type` is a component marked with `markLabelable`. */\nexport function isLabelable(type: unknown): boolean {\n const resolved = unwrapLazy(type);\n return (\n (typeof resolved === \"function\" || (typeof resolved === \"object\" && resolved !== null)) &&\n Reflect.get(resolved, LABELABLE) === true\n );\n}\n\n// An element a Server Component rendered reaches the client with a lazy type:\n// the Flight client wraps every client reference in a `React.lazy`-shaped\n// object, so the control's own function (and its mark) sits behind it. The\n// mark cannot travel through the reference instead — the server holds only the\n// module id, never the module. So resolve the lazy the way the reconciler\n// does, by calling its `_init` on its `_payload`: once the module has loaded\n// that returns the export synchronously. Until then it throws (a thenable while\n// pending, the error if loading failed); that is answered \"not a control\",\n// the pre-mark behaviour, and the reconciler meets the same throw itself when\n// it renders the element.\nfunction unwrapLazy(type: unknown): unknown {\n if (typeof type !== \"object\" || type === null || Reflect.get(type, \"$$typeof\") !== LAZY) return type;\n const init: unknown = Reflect.get(type, \"_init\");\n if (typeof init !== \"function\") return undefined;\n try {\n return Reflect.apply(init, undefined, [Reflect.get(type, \"_payload\")]);\n } catch {\n return undefined;\n }\n}\n"],"mappings":"AAQA,MAAM,YAAY,uBAAO,IAAI,6BAA6B;AAC1D,MAAM,OAAO,uBAAO,IAAI,YAAY;AAG7B,SAAS,cAAc,WAAyB;AACrD,SAAO,eAAe,WAAW,WAAW,EAAE,OAAO,KAAK,CAAC;AAC7D;AAGO,SAAS,YAAY,MAAwB;AAClD,QAAM,WAAW,WAAW,IAAI;AAChC,UACG,OAAO,aAAa,cAAe,OAAO,aAAa,YAAY,aAAa,SACjF,QAAQ,IAAI,UAAU,SAAS,MAAM;AAEzC;AAYA,SAAS,WAAW,MAAwB;AAC1C,MAAI,OAAO,SAAS,YAAY,SAAS,QAAQ,QAAQ,IAAI,MAAM,UAAU,MAAM,KAAM,QAAO;AAChG,QAAM,OAAgB,QAAQ,IAAI,MAAM,OAAO;AAC/C,MAAI,OAAO,SAAS,WAAY,QAAO;AACvC,MAAI;AACF,WAAO,QAAQ,MAAM,MAAM,QAAW,CAAC,QAAQ,IAAI,MAAM,UAAU,CAAC,CAAC;AAAA,EACvE,QAAQ;AACN,WAAO;AAAA,EACT;AACF;","names":[]}
|
|
@@ -3,12 +3,17 @@ import * as React from "react";
|
|
|
3
3
|
function useRovingFocus(opts) {
|
|
4
4
|
const { count, orientation = "vertical", loop = true, initial = 0 } = opts;
|
|
5
5
|
const [activeIndex, setActiveIndex] = React.useState(initial);
|
|
6
|
-
const
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
6
|
+
const resolveCount = () => typeof count === "function" ? count() : count;
|
|
7
|
+
const next = (dir) => {
|
|
8
|
+
const total = resolveCount();
|
|
9
|
+
if (total <= 0) return;
|
|
10
|
+
setActiveIndex((i) => {
|
|
11
|
+
let n = Math.min(Math.max(i, 0), total - 1) + dir;
|
|
12
|
+
if (n < 0) n = loop ? total - 1 : 0;
|
|
13
|
+
else if (n >= total) n = loop ? 0 : total - 1;
|
|
14
|
+
return n;
|
|
15
|
+
});
|
|
16
|
+
};
|
|
12
17
|
const onKeyDown = (event) => {
|
|
13
18
|
const horiz = orientation === "horizontal" || orientation === "both";
|
|
14
19
|
const vert = orientation === "vertical" || orientation === "both";
|
|
@@ -29,7 +34,8 @@ function useRovingFocus(opts) {
|
|
|
29
34
|
setActiveIndex(0);
|
|
30
35
|
} else if (event.key === "End") {
|
|
31
36
|
event.preventDefault();
|
|
32
|
-
|
|
37
|
+
const total = resolveCount();
|
|
38
|
+
if (total > 0) setActiveIndex(total - 1);
|
|
33
39
|
}
|
|
34
40
|
};
|
|
35
41
|
return { activeIndex, setActiveIndex, onKeyDown };
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/primitives/use-roving-focus.ts"],"sourcesContent":["\"use client\";\n\nimport * as React from \"react\";\n\n/**\n * Arrow-key roving focus over a set of items — the dep-light core of menus,\n * tabs, radio-groups and toolbars (replacing `@radix-ui/react-roving-focus`).\n * Returns an `onKeyDown` to spread on the container and the active index; items\n * should set `tabIndex={index === activeIndex ? 0 : -1}`.\n *\n * Mirrors the keyboard navigation Rust drives with a focused-index signal.\n */\nexport function useRovingFocus(opts: {\n count: number;\n orientation?: \"horizontal\" | \"vertical\" | \"both\";\n loop?: boolean;\n initial?: number;\n}): {\n activeIndex: number;\n setActiveIndex: (i: number) => void;\n onKeyDown: (event: React.KeyboardEvent) => void;\n} {\n const { count, orientation = \"vertical\", loop = true, initial = 0 } = opts;\n const [activeIndex, setActiveIndex] = React.useState(initial);\n\n const next = (dir: 1 | -1)
|
|
1
|
+
{"version":3,"sources":["../../src/primitives/use-roving-focus.ts"],"sourcesContent":["\"use client\";\n\nimport * as React from \"react\";\n\n/**\n * Arrow-key roving focus over a set of items — the dep-light core of menus,\n * tabs, radio-groups and toolbars (replacing `@radix-ui/react-roving-focus`).\n * Returns an `onKeyDown` to spread on the container and the active index; items\n * should set `tabIndex={index === activeIndex ? 0 : -1}`.\n *\n * `count` may be a getter: containers whose items are only known from the DOM\n * (menus with conditionally rendered or disabled items, inline sub-menus) pass\n * one so the bound is read at keydown time — never during render, which keeps\n * the hook safe under SSR.\n *\n * Mirrors the keyboard navigation Rust drives with a focused-index signal.\n */\nexport function useRovingFocus(opts: {\n count: number | (() => number);\n orientation?: \"horizontal\" | \"vertical\" | \"both\";\n loop?: boolean;\n initial?: number;\n}): {\n activeIndex: number;\n setActiveIndex: (i: number) => void;\n onKeyDown: (event: React.KeyboardEvent) => void;\n} {\n const { count, orientation = \"vertical\", loop = true, initial = 0 } = opts;\n const [activeIndex, setActiveIndex] = React.useState(initial);\n\n const resolveCount = () => (typeof count === \"function\" ? count() : count);\n\n const next = (dir: 1 | -1) => {\n const total = resolveCount();\n if (total <= 0) return;\n setActiveIndex((i) => {\n // Clamp first: the item set may have shrunk since the index was set.\n let n = Math.min(Math.max(i, 0), total - 1) + dir;\n if (n < 0) n = loop ? total - 1 : 0;\n else if (n >= total) n = loop ? 0 : total - 1;\n return n;\n });\n };\n\n const onKeyDown = (event: React.KeyboardEvent) => {\n const horiz = orientation === \"horizontal\" || orientation === \"both\";\n const vert = orientation === \"vertical\" || orientation === \"both\";\n if (vert && event.key === \"ArrowDown\") {\n event.preventDefault();\n next(1);\n } else if (vert && event.key === \"ArrowUp\") {\n event.preventDefault();\n next(-1);\n } else if (horiz && event.key === \"ArrowRight\") {\n event.preventDefault();\n next(1);\n } else if (horiz && event.key === \"ArrowLeft\") {\n event.preventDefault();\n next(-1);\n } else if (event.key === \"Home\") {\n event.preventDefault();\n setActiveIndex(0);\n } else if (event.key === \"End\") {\n event.preventDefault();\n const total = resolveCount();\n if (total > 0) setActiveIndex(total - 1);\n }\n };\n\n return { activeIndex, setActiveIndex, onKeyDown };\n}\n"],"mappings":";AAEA,YAAY,WAAW;AAehB,SAAS,eAAe,MAS7B;AACA,QAAM,EAAE,OAAO,cAAc,YAAY,OAAO,MAAM,UAAU,EAAE,IAAI;AACtE,QAAM,CAAC,aAAa,cAAc,IAAI,MAAM,SAAS,OAAO;AAE5D,QAAM,eAAe,MAAO,OAAO,UAAU,aAAa,MAAM,IAAI;AAEpE,QAAM,OAAO,CAAC,QAAgB;AAC5B,UAAM,QAAQ,aAAa;AAC3B,QAAI,SAAS,EAAG;AAChB,mBAAe,CAAC,MAAM;AAEpB,UAAI,IAAI,KAAK,IAAI,KAAK,IAAI,GAAG,CAAC,GAAG,QAAQ,CAAC,IAAI;AAC9C,UAAI,IAAI,EAAG,KAAI,OAAO,QAAQ,IAAI;AAAA,eACzB,KAAK,MAAO,KAAI,OAAO,IAAI,QAAQ;AAC5C,aAAO;AAAA,IACT,CAAC;AAAA,EACH;AAEA,QAAM,YAAY,CAAC,UAA+B;AAChD,UAAM,QAAQ,gBAAgB,gBAAgB,gBAAgB;AAC9D,UAAM,OAAO,gBAAgB,cAAc,gBAAgB;AAC3D,QAAI,QAAQ,MAAM,QAAQ,aAAa;AACrC,YAAM,eAAe;AACrB,WAAK,CAAC;AAAA,IACR,WAAW,QAAQ,MAAM,QAAQ,WAAW;AAC1C,YAAM,eAAe;AACrB,WAAK,EAAE;AAAA,IACT,WAAW,SAAS,MAAM,QAAQ,cAAc;AAC9C,YAAM,eAAe;AACrB,WAAK,CAAC;AAAA,IACR,WAAW,SAAS,MAAM,QAAQ,aAAa;AAC7C,YAAM,eAAe;AACrB,WAAK,EAAE;AAAA,IACT,WAAW,MAAM,QAAQ,QAAQ;AAC/B,YAAM,eAAe;AACrB,qBAAe,CAAC;AAAA,IAClB,WAAW,MAAM,QAAQ,OAAO;AAC9B,YAAM,eAAe;AACrB,YAAM,QAAQ,aAAa;AAC3B,UAAI,QAAQ,EAAG,gBAAe,QAAQ,CAAC;AAAA,IACzC;AAAA,EACF;AAEA,SAAO,EAAE,aAAa,gBAAgB,UAAU;AAClD;","names":[]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@evinvest/uikit",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.29.1",
|
|
4
4
|
"description": "Dep-light React UI kit: shadcn-semantics components with zero @radix-ui / cva, mirroring the ev_lib::uikit Rust feature. Ships the shared design tokens.",
|
|
5
5
|
"license": "BlueOak-1.0.0",
|
|
6
6
|
"publishConfig": {
|
package/styles/ev.css
CHANGED
|
@@ -60,8 +60,10 @@
|
|
|
60
60
|
--accent-warn: #f2c94c;
|
|
61
61
|
--on-accent-warn: #070d18;
|
|
62
62
|
/* lifted off the brand red #da251d, which failed AA on a card. This one value
|
|
63
|
-
*
|
|
64
|
-
*
|
|
63
|
+
* is the fill and the text on a bare surface; on its own 10 % tint (a
|
|
64
|
+
* destructive menu row) the text is the derived --accent-error-ink, which
|
|
65
|
+
* EV leaves to the contract: #ec8379, 4.83:1 on that tint over popover. The
|
|
66
|
+
* vivid brand red is a gitops constant, not a UI token. */
|
|
65
67
|
--accent-error: #ef5b52;
|
|
66
68
|
--on-accent-error: #070d18;
|
|
67
69
|
|
package/styles/theme.css
CHANGED
|
@@ -538,6 +538,7 @@
|
|
|
538
538
|
--color-on-accent-warn: var(--on-accent-warn);
|
|
539
539
|
--color-accent-error: var(--accent-error);
|
|
540
540
|
--color-on-accent-error: var(--on-accent-error);
|
|
541
|
+
--color-accent-error-ink: var(--accent-error-ink);
|
|
541
542
|
|
|
542
543
|
/* charts — distinguishable hues carrying no significance */
|
|
543
544
|
--color-chart-1: var(--chart-1);
|
|
@@ -565,6 +566,12 @@
|
|
|
565
566
|
* side — ink over white needs ~47% to clear it, dark lands near 4:1. */
|
|
566
567
|
--input: color-mix(in srgb, var(--ink) 48%, transparent);
|
|
567
568
|
--ring: var(--primary-ink);
|
|
569
|
+
/* the error role as text on its own 10 % tint — a destructive menu row
|
|
570
|
+
* (lib#166). The fill alone read 3.76:1 there on EV and 2.48:1 on a dark
|
|
571
|
+
* brand; 30 % of the ink pulls it toward whichever polarity the text needs.
|
|
572
|
+
* Derived rather than required so a brand file that predates it still
|
|
573
|
+
* renders; one that misses the floor pins its own (docs/spec/accents.md). */
|
|
574
|
+
--accent-error-ink: color-mix(in srgb, var(--accent-error) 70%, var(--ink));
|
|
568
575
|
}
|
|
569
576
|
|
|
570
577
|
/* Geometry. A `[data-brand]` scope is a theme root of its own, so it restarts
|
package/styles/tokens.css
CHANGED
|
@@ -21,6 +21,8 @@
|
|
|
21
21
|
* accent-trace · accent-debug · accent-info · accent-warn · accent-error
|
|
22
22
|
* primary-ink — the primary role as ink on a surface, where the
|
|
23
23
|
* fill and the readable value are different colours
|
|
24
|
+
* accent-error-ink — the error role as text on its own tint;
|
|
25
|
+
* derived from accent-error and ink, a palette may pin it
|
|
24
26
|
* SCALARS radius · control-* · display-scale · page-* · shell-* · shadows · fonts
|
|
25
27
|
* MOTION ev-ease-* · ev-dur-* · ev-rise · ev-stagger(-section)
|
|
26
28
|
* CHARTS chart-1 … chart-5
|
|
@@ -37,7 +39,8 @@
|
|
|
37
39
|
*
|
|
38
40
|
* Accents are ordered by significance, not by meaning; see docs/spec/accents.md.
|
|
39
41
|
* Their values are read outside CSS (gitops mirrors them into Discord embed
|
|
40
|
-
* bars), so they stay plain hex — no color-mix.
|
|
42
|
+
* bars), so they stay plain hex — no color-mix. `accent-error-ink` is not an
|
|
43
|
+
* accent but a reading of one, so it lives with the derived tokens.
|
|
41
44
|
*/
|
|
42
45
|
|
|
43
46
|
/*
|
|
@@ -579,6 +582,7 @@
|
|
|
579
582
|
--color-on-accent-warn: var(--on-accent-warn);
|
|
580
583
|
--color-accent-error: var(--accent-error);
|
|
581
584
|
--color-on-accent-error: var(--on-accent-error);
|
|
585
|
+
--color-accent-error-ink: var(--accent-error-ink);
|
|
582
586
|
|
|
583
587
|
/* charts — distinguishable hues carrying no significance */
|
|
584
588
|
--color-chart-1: var(--chart-1);
|
|
@@ -606,6 +610,12 @@
|
|
|
606
610
|
* side — ink over white needs ~47% to clear it, dark lands near 4:1. */
|
|
607
611
|
--input: color-mix(in srgb, var(--ink) 48%, transparent);
|
|
608
612
|
--ring: var(--primary-ink);
|
|
613
|
+
/* the error role as text on its own 10 % tint — a destructive menu row
|
|
614
|
+
* (lib#166). The fill alone read 3.76:1 there on EV and 2.48:1 on a dark
|
|
615
|
+
* brand; 30 % of the ink pulls it toward whichever polarity the text needs.
|
|
616
|
+
* Derived rather than required so a brand file that predates it still
|
|
617
|
+
* renders; one that misses the floor pins its own (docs/spec/accents.md). */
|
|
618
|
+
--accent-error-ink: color-mix(in srgb, var(--accent-error) 70%, var(--ink));
|
|
609
619
|
}
|
|
610
620
|
|
|
611
621
|
/* Geometry. A `[data-brand]` scope is a theme root of its own, so it restarts
|
|
@@ -754,8 +764,10 @@
|
|
|
754
764
|
--accent-warn: #f2c94c;
|
|
755
765
|
--on-accent-warn: #070d18;
|
|
756
766
|
/* lifted off the brand red #da251d, which failed AA on a card. This one value
|
|
757
|
-
*
|
|
758
|
-
*
|
|
767
|
+
* is the fill and the text on a bare surface; on its own 10 % tint (a
|
|
768
|
+
* destructive menu row) the text is the derived --accent-error-ink, which
|
|
769
|
+
* EV leaves to the contract: #ec8379, 4.83:1 on that tint over popover. The
|
|
770
|
+
* vivid brand red is a gitops constant, not a UI token. */
|
|
759
771
|
--accent-error: #ef5b52;
|
|
760
772
|
--on-accent-error: #070d18;
|
|
761
773
|
|
package/dist/components/chart.js
DELETED
|
@@ -1,151 +0,0 @@
|
|
|
1
|
-
"use client";
|
|
2
|
-
import { Fragment, jsx, jsxs } from "react/jsx-runtime";
|
|
3
|
-
import * as React from "react";
|
|
4
|
-
import { cn } from "../lib/cn.js";
|
|
5
|
-
import { CHART_CONTAINER, CHART_LEGEND, CHART_TOOLTIP } from "../generated/chart.js";
|
|
6
|
-
const ChartContext = React.createContext(null);
|
|
7
|
-
function useChart() {
|
|
8
|
-
const context = React.useContext(ChartContext);
|
|
9
|
-
if (!context) {
|
|
10
|
-
throw new Error("useChart must be used within a <ChartContainer />");
|
|
11
|
-
}
|
|
12
|
-
return context;
|
|
13
|
-
}
|
|
14
|
-
function ChartContainer({
|
|
15
|
-
id,
|
|
16
|
-
className,
|
|
17
|
-
children,
|
|
18
|
-
config,
|
|
19
|
-
...props
|
|
20
|
-
}) {
|
|
21
|
-
const uniqueId = React.useId();
|
|
22
|
-
const chartId = `chart-${id || uniqueId.replace(/:/g, "")}`;
|
|
23
|
-
return /* @__PURE__ */ jsx(ChartContext.Provider, { value: { config }, children: /* @__PURE__ */ jsxs(
|
|
24
|
-
"div",
|
|
25
|
-
{
|
|
26
|
-
"data-slot": "chart",
|
|
27
|
-
"data-chart": chartId,
|
|
28
|
-
className: cn(CHART_CONTAINER, className),
|
|
29
|
-
...props,
|
|
30
|
-
children: [
|
|
31
|
-
/* @__PURE__ */ jsx(ChartStyle, { id: chartId, config }),
|
|
32
|
-
children
|
|
33
|
-
]
|
|
34
|
-
}
|
|
35
|
-
) });
|
|
36
|
-
}
|
|
37
|
-
const ChartStyle = ({ id, config }) => {
|
|
38
|
-
const colorConfig = Object.entries(config).filter(([, c]) => c.color);
|
|
39
|
-
if (!colorConfig.length) {
|
|
40
|
-
return null;
|
|
41
|
-
}
|
|
42
|
-
return /* @__PURE__ */ jsx(
|
|
43
|
-
"style",
|
|
44
|
-
{
|
|
45
|
-
dangerouslySetInnerHTML: {
|
|
46
|
-
__html: `[data-chart=${id}] {
|
|
47
|
-
${colorConfig.map(([key, itemConfig]) => ` --color-${key}: ${itemConfig.color};`).join("\n")}
|
|
48
|
-
}`
|
|
49
|
-
}
|
|
50
|
-
}
|
|
51
|
-
);
|
|
52
|
-
};
|
|
53
|
-
const ChartTooltip = ({ children }) => /* @__PURE__ */ jsx(Fragment, { children });
|
|
54
|
-
function ChartTooltipContent({
|
|
55
|
-
className,
|
|
56
|
-
items = [],
|
|
57
|
-
label,
|
|
58
|
-
hideLabel = false,
|
|
59
|
-
hideIndicator = false,
|
|
60
|
-
labelClassName
|
|
61
|
-
}) {
|
|
62
|
-
useChart();
|
|
63
|
-
if (!items.length) {
|
|
64
|
-
return null;
|
|
65
|
-
}
|
|
66
|
-
return /* @__PURE__ */ jsxs(
|
|
67
|
-
"div",
|
|
68
|
-
{
|
|
69
|
-
"data-slot": "chart-tooltip",
|
|
70
|
-
className: cn(CHART_TOOLTIP, className),
|
|
71
|
-
children: [
|
|
72
|
-
!hideLabel && label ? /* @__PURE__ */ jsx("div", { className: cn("font-medium", labelClassName), children: label }) : null,
|
|
73
|
-
/* @__PURE__ */ jsx("div", { className: "grid gap-1.5", children: items.map((item, index) => /* @__PURE__ */ jsxs(
|
|
74
|
-
"div",
|
|
75
|
-
{
|
|
76
|
-
className: cn(
|
|
77
|
-
"[&>svg]:text-ink-soft flex w-full flex-wrap items-stretch gap-2 [&>svg]:h-2.5 [&>svg]:w-2.5 items-center"
|
|
78
|
-
),
|
|
79
|
-
children: [
|
|
80
|
-
!hideIndicator && /* @__PURE__ */ jsx(
|
|
81
|
-
"div",
|
|
82
|
-
{
|
|
83
|
-
className: "shrink-0 rounded-[2px] h-2.5 w-2.5",
|
|
84
|
-
style: {
|
|
85
|
-
backgroundColor: item.color,
|
|
86
|
-
borderColor: item.color
|
|
87
|
-
}
|
|
88
|
-
}
|
|
89
|
-
),
|
|
90
|
-
/* @__PURE__ */ jsxs("div", { className: "flex flex-1 justify-between leading-none items-center", children: [
|
|
91
|
-
/* @__PURE__ */ jsx("span", { className: "text-ink-soft", children: item.label }),
|
|
92
|
-
item.value !== void 0 && /* @__PURE__ */ jsx("span", { className: "text-ink font-mono font-medium tabular-nums", children: item.value })
|
|
93
|
-
] })
|
|
94
|
-
]
|
|
95
|
-
},
|
|
96
|
-
index
|
|
97
|
-
)) })
|
|
98
|
-
]
|
|
99
|
-
}
|
|
100
|
-
);
|
|
101
|
-
}
|
|
102
|
-
const ChartLegend = ({ children }) => /* @__PURE__ */ jsx(Fragment, { children });
|
|
103
|
-
function ChartLegendContent({
|
|
104
|
-
className,
|
|
105
|
-
hideIcon = false,
|
|
106
|
-
items
|
|
107
|
-
}) {
|
|
108
|
-
const { config } = useChart();
|
|
109
|
-
const rows = items ?? Object.entries(config).map(([key, c]) => ({
|
|
110
|
-
label: c.label ?? key,
|
|
111
|
-
...c.color ? { color: c.color } : {}
|
|
112
|
-
}));
|
|
113
|
-
if (!rows.length) {
|
|
114
|
-
return null;
|
|
115
|
-
}
|
|
116
|
-
return /* @__PURE__ */ jsx(
|
|
117
|
-
"div",
|
|
118
|
-
{
|
|
119
|
-
"data-slot": "chart-legend",
|
|
120
|
-
className: cn(CHART_LEGEND, className),
|
|
121
|
-
children: rows.map((item, index) => /* @__PURE__ */ jsxs(
|
|
122
|
-
"div",
|
|
123
|
-
{
|
|
124
|
-
className: cn(
|
|
125
|
-
"[&>svg]:text-ink-soft flex items-center gap-1.5 [&>svg]:h-3 [&>svg]:w-3"
|
|
126
|
-
),
|
|
127
|
-
children: [
|
|
128
|
-
!hideIcon && /* @__PURE__ */ jsx(
|
|
129
|
-
"div",
|
|
130
|
-
{
|
|
131
|
-
className: "h-2 w-2 shrink-0 rounded-[2px]",
|
|
132
|
-
style: { backgroundColor: item.color }
|
|
133
|
-
}
|
|
134
|
-
),
|
|
135
|
-
item.label
|
|
136
|
-
]
|
|
137
|
-
},
|
|
138
|
-
index
|
|
139
|
-
))
|
|
140
|
-
}
|
|
141
|
-
);
|
|
142
|
-
}
|
|
143
|
-
export {
|
|
144
|
-
ChartContainer,
|
|
145
|
-
ChartLegend,
|
|
146
|
-
ChartLegendContent,
|
|
147
|
-
ChartStyle,
|
|
148
|
-
ChartTooltip,
|
|
149
|
-
ChartTooltipContent
|
|
150
|
-
};
|
|
151
|
-
//# sourceMappingURL=chart.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/components/chart.tsx"],"sourcesContent":["\"use client\";\n\n// Dep-light chart primitives: the shadcn/recharts wrapper minus recharts.\n//\n// Upstream shadcn `chart` is theming + presentational tooltip/legend wrappers\n// around recharts, which does the actual plotting. We keep the wrappers and\n// drop recharts: `ChartContainer` is a themed SVG host that emits per-key\n// `--color-<key>` custom properties from its `config`, and consumers draw their\n// own <svg>/series inside it. `ChartTooltipContent` and `ChartLegendContent`\n// are purely presentational and take explicit `items` instead of a recharts\n// payload. `ChartTooltip`/`ChartLegend` are passthrough wrappers. `dark:*`\n// selectors are dropped; the recharts-specific `[&_.recharts-*]` selectors are\n// dropped from the container base.\n\nimport * as React from \"react\";\nimport { cn } from \"../lib/cn\";\nimport { CHART_CONTAINER, CHART_LEGEND, CHART_TOOLTIP } from \"../generated/chart\";\n\nexport type ChartConfig = {\n [k in string]: {\n label?: React.ReactNode;\n color?: string;\n };\n};\n\ntype ChartContextProps = {\n config: ChartConfig;\n};\n\nconst ChartContext = React.createContext<ChartContextProps | null>(null);\n\nfunction useChart() {\n const context = React.useContext(ChartContext);\n\n if (!context) {\n throw new Error(\"useChart must be used within a <ChartContainer />\");\n }\n\n return context;\n}\n\nfunction ChartContainer({\n id,\n className,\n children,\n config,\n ...props\n}: React.ComponentProps<\"div\"> & {\n config: ChartConfig;\n}) {\n const uniqueId = React.useId();\n const chartId = `chart-${id || uniqueId.replace(/:/g, \"\")}`;\n\n return (\n <ChartContext.Provider value={{ config }}>\n <div\n data-slot=\"chart\"\n data-chart={chartId}\n className={cn(CHART_CONTAINER, className)}\n {...props}\n >\n <ChartStyle id={chartId} config={config} />\n {children}\n </div>\n </ChartContext.Provider>\n );\n}\n\nconst ChartStyle = ({ id, config }: { id: string; config: ChartConfig }) => {\n const colorConfig = Object.entries(config).filter(([, c]) => c.color);\n\n if (!colorConfig.length) {\n return null;\n }\n\n return (\n <style\n dangerouslySetInnerHTML={{\n __html: `[data-chart=${id}] {\n${colorConfig\n .map(([key, itemConfig]) => ` --color-${key}: ${itemConfig.color};`)\n .join(\"\\n\")}\n}`,\n }}\n />\n );\n};\n\n// One rendered tooltip/legend row. Replaces the recharts payload.\nexport type ChartItem = {\n label?: React.ReactNode;\n value?: React.ReactNode;\n color?: string;\n};\n\nconst ChartTooltip = ({ children }: { children?: React.ReactNode }) => (\n <>{children}</>\n);\n\nfunction ChartTooltipContent({\n className,\n items = [],\n label,\n hideLabel = false,\n hideIndicator = false,\n labelClassName,\n}: React.ComponentProps<\"div\"> & {\n items?: ChartItem[];\n label?: React.ReactNode;\n hideLabel?: boolean;\n hideIndicator?: boolean;\n labelClassName?: string;\n}) {\n useChart();\n\n if (!items.length) {\n return null;\n }\n\n return (\n <div\n data-slot=\"chart-tooltip\"\n className={cn(CHART_TOOLTIP, className)}\n >\n {!hideLabel && label ? (\n <div className={cn(\"font-medium\", labelClassName)}>{label}</div>\n ) : null}\n <div className=\"grid gap-1.5\">\n {items.map((item, index) => (\n <div\n key={index}\n className={cn(\n \"[&>svg]:text-ink-soft flex w-full flex-wrap items-stretch gap-2 [&>svg]:h-2.5 [&>svg]:w-2.5 items-center\",\n )}\n >\n {!hideIndicator && (\n <div\n className=\"shrink-0 rounded-[2px] h-2.5 w-2.5\"\n style={\n {\n backgroundColor: item.color,\n borderColor: item.color,\n } as React.CSSProperties\n }\n />\n )}\n <div className=\"flex flex-1 justify-between leading-none items-center\">\n <span className=\"text-ink-soft\">{item.label}</span>\n {item.value !== undefined && (\n <span className=\"text-ink font-mono font-medium tabular-nums\">\n {item.value}\n </span>\n )}\n </div>\n </div>\n ))}\n </div>\n </div>\n );\n}\n\nconst ChartLegend = ({ children }: { children?: React.ReactNode }) => (\n <>{children}</>\n);\n\nfunction ChartLegendContent({\n className,\n hideIcon = false,\n items,\n}: React.ComponentProps<\"div\"> & {\n hideIcon?: boolean;\n items?: ChartItem[];\n}) {\n const { config } = useChart();\n\n const rows: ChartItem[] =\n items ??\n Object.entries(config).map(([key, c]) => ({\n label: c.label ?? key,\n ...(c.color ? { color: c.color } : {}),\n }));\n\n if (!rows.length) {\n return null;\n }\n\n return (\n <div\n data-slot=\"chart-legend\"\n className={cn(CHART_LEGEND, className)}\n >\n {rows.map((item, index) => (\n <div\n key={index}\n className={cn(\n \"[&>svg]:text-ink-soft flex items-center gap-1.5 [&>svg]:h-3 [&>svg]:w-3\",\n )}\n >\n {!hideIcon && (\n <div\n className=\"h-2 w-2 shrink-0 rounded-[2px]\"\n style={{ backgroundColor: item.color }}\n />\n )}\n {item.label}\n </div>\n ))}\n </div>\n );\n}\n\nexport {\n ChartContainer,\n ChartTooltip,\n ChartTooltipContent,\n ChartLegend,\n ChartLegendContent,\n ChartStyle,\n};\n"],"mappings":"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","names":[]}
|
|
@@ -1,193 +0,0 @@
|
|
|
1
|
-
"use client";
|
|
2
|
-
import { jsx, jsxs } from "react/jsx-runtime";
|
|
3
|
-
import * as React from "react";
|
|
4
|
-
import { cn } from "../lib/cn.js";
|
|
5
|
-
import {
|
|
6
|
-
RESIZABLE_GROUP,
|
|
7
|
-
RESIZABLE_HANDLE,
|
|
8
|
-
RESIZABLE_HANDLE_GRIP,
|
|
9
|
-
RESIZABLE_PANEL
|
|
10
|
-
} from "../generated/resizable.js";
|
|
11
|
-
const ResizableContext = React.createContext(null);
|
|
12
|
-
function useResizable() {
|
|
13
|
-
const ctx = React.useContext(ResizableContext);
|
|
14
|
-
if (!ctx)
|
|
15
|
-
throw new Error("Resizable parts must be used within a ResizablePanelGroup");
|
|
16
|
-
return ctx;
|
|
17
|
-
}
|
|
18
|
-
function redistribute(sizes, index, delta) {
|
|
19
|
-
const before = sizes[index];
|
|
20
|
-
const after = sizes[index + 1];
|
|
21
|
-
if (before === void 0 || after === void 0) return sizes;
|
|
22
|
-
const moved = Math.max(-before, Math.min(after, delta));
|
|
23
|
-
const next = sizes.slice();
|
|
24
|
-
next[index] = before + moved;
|
|
25
|
-
next[index + 1] = after - moved;
|
|
26
|
-
return next;
|
|
27
|
-
}
|
|
28
|
-
function ResizablePanelGroup({
|
|
29
|
-
className,
|
|
30
|
-
direction = "horizontal",
|
|
31
|
-
keyboardStep = 10,
|
|
32
|
-
onLayout,
|
|
33
|
-
children,
|
|
34
|
-
...props
|
|
35
|
-
}) {
|
|
36
|
-
const [sizes, setSizes] = React.useState([]);
|
|
37
|
-
const groupRef = React.useRef(null);
|
|
38
|
-
const register = React.useCallback((index, defaultSize) => {
|
|
39
|
-
setSizes((prev) => {
|
|
40
|
-
if (prev[index] !== void 0) return prev;
|
|
41
|
-
const next = prev.slice();
|
|
42
|
-
while (next.length <= index) next.push(0);
|
|
43
|
-
next[index] = defaultSize;
|
|
44
|
-
return next;
|
|
45
|
-
});
|
|
46
|
-
}, []);
|
|
47
|
-
React.useEffect(() => {
|
|
48
|
-
if (sizes.length) onLayout?.(sizes);
|
|
49
|
-
}, [sizes, onLayout]);
|
|
50
|
-
const value = React.useMemo(
|
|
51
|
-
() => ({ sizes, setSizes, register, direction, keyboardStep, groupRef }),
|
|
52
|
-
[sizes, register, direction, keyboardStep]
|
|
53
|
-
);
|
|
54
|
-
return /* @__PURE__ */ jsx(ResizableContext.Provider, { value, children: /* @__PURE__ */ jsx(
|
|
55
|
-
"div",
|
|
56
|
-
{
|
|
57
|
-
ref: groupRef,
|
|
58
|
-
"data-slot": "resizable-panel-group",
|
|
59
|
-
"data-panel-group-direction": direction,
|
|
60
|
-
className: cn(RESIZABLE_GROUP, className),
|
|
61
|
-
...props,
|
|
62
|
-
children
|
|
63
|
-
}
|
|
64
|
-
) });
|
|
65
|
-
}
|
|
66
|
-
function ResizablePanel({
|
|
67
|
-
className,
|
|
68
|
-
index,
|
|
69
|
-
defaultSize = 50,
|
|
70
|
-
style,
|
|
71
|
-
children,
|
|
72
|
-
...props
|
|
73
|
-
}) {
|
|
74
|
-
const { sizes, register } = useResizable();
|
|
75
|
-
React.useEffect(() => {
|
|
76
|
-
register(index, defaultSize);
|
|
77
|
-
}, [register, index, defaultSize]);
|
|
78
|
-
const basis = sizes[index] ?? defaultSize;
|
|
79
|
-
return /* @__PURE__ */ jsx(
|
|
80
|
-
"div",
|
|
81
|
-
{
|
|
82
|
-
"data-slot": "resizable-panel",
|
|
83
|
-
className: cn(RESIZABLE_PANEL, className),
|
|
84
|
-
style: { flex: `${basis} 1 0%`, ...style },
|
|
85
|
-
...props,
|
|
86
|
-
children
|
|
87
|
-
}
|
|
88
|
-
);
|
|
89
|
-
}
|
|
90
|
-
function ResizableHandle({
|
|
91
|
-
className,
|
|
92
|
-
index,
|
|
93
|
-
withHandle,
|
|
94
|
-
children,
|
|
95
|
-
...props
|
|
96
|
-
}) {
|
|
97
|
-
const { setSizes, direction, keyboardStep, groupRef } = useResizable();
|
|
98
|
-
const draggingRef = React.useRef(false);
|
|
99
|
-
const resize = React.useCallback(
|
|
100
|
-
(delta) => setSizes((prev) => redistribute(prev, index, delta)),
|
|
101
|
-
[setSizes, index]
|
|
102
|
-
);
|
|
103
|
-
const onPointerMove = React.useCallback(
|
|
104
|
-
(event) => {
|
|
105
|
-
if (!draggingRef.current) return;
|
|
106
|
-
const rect = groupRef.current?.getBoundingClientRect();
|
|
107
|
-
if (!rect) return;
|
|
108
|
-
const span = direction === "vertical" ? rect.height : rect.width;
|
|
109
|
-
if (span <= 0) return;
|
|
110
|
-
const px = direction === "vertical" ? event.movementY : event.movementX;
|
|
111
|
-
resize(px / span * 100);
|
|
112
|
-
},
|
|
113
|
-
[direction, resize, groupRef]
|
|
114
|
-
);
|
|
115
|
-
const onPointerUp = React.useCallback(() => {
|
|
116
|
-
draggingRef.current = false;
|
|
117
|
-
window.removeEventListener("pointermove", onPointerMove);
|
|
118
|
-
window.removeEventListener("pointerup", onPointerUp);
|
|
119
|
-
}, [onPointerMove]);
|
|
120
|
-
const onPointerDown = (event) => {
|
|
121
|
-
event.preventDefault();
|
|
122
|
-
draggingRef.current = true;
|
|
123
|
-
window.addEventListener("pointermove", onPointerMove);
|
|
124
|
-
window.addEventListener("pointerup", onPointerUp);
|
|
125
|
-
};
|
|
126
|
-
React.useEffect(() => () => onPointerUp(), [onPointerUp]);
|
|
127
|
-
const onKeyDown = (event) => {
|
|
128
|
-
let delta;
|
|
129
|
-
switch (event.key) {
|
|
130
|
-
case "ArrowLeft":
|
|
131
|
-
case "ArrowUp":
|
|
132
|
-
delta = -keyboardStep;
|
|
133
|
-
break;
|
|
134
|
-
case "ArrowRight":
|
|
135
|
-
case "ArrowDown":
|
|
136
|
-
delta = keyboardStep;
|
|
137
|
-
break;
|
|
138
|
-
default:
|
|
139
|
-
return;
|
|
140
|
-
}
|
|
141
|
-
if (direction === "horizontal" && (event.key === "ArrowUp" || event.key === "ArrowDown") || direction === "vertical" && (event.key === "ArrowLeft" || event.key === "ArrowRight"))
|
|
142
|
-
return;
|
|
143
|
-
event.preventDefault();
|
|
144
|
-
resize(delta);
|
|
145
|
-
};
|
|
146
|
-
return /* @__PURE__ */ jsxs(
|
|
147
|
-
"div",
|
|
148
|
-
{
|
|
149
|
-
"data-slot": "resizable-handle",
|
|
150
|
-
"data-panel-group-direction": direction,
|
|
151
|
-
role: "separator",
|
|
152
|
-
"aria-orientation": direction === "horizontal" ? "vertical" : "horizontal",
|
|
153
|
-
tabIndex: 0,
|
|
154
|
-
className: cn(RESIZABLE_HANDLE, className),
|
|
155
|
-
onPointerDown,
|
|
156
|
-
onKeyDown,
|
|
157
|
-
...props,
|
|
158
|
-
children: [
|
|
159
|
-
withHandle && /* @__PURE__ */ jsx("div", { className: RESIZABLE_HANDLE_GRIP, children: /* @__PURE__ */ jsxs(
|
|
160
|
-
"svg",
|
|
161
|
-
{
|
|
162
|
-
className: "size-2.5",
|
|
163
|
-
xmlns: "http://www.w3.org/2000/svg",
|
|
164
|
-
width: "15",
|
|
165
|
-
height: "15",
|
|
166
|
-
viewBox: "0 0 24 24",
|
|
167
|
-
fill: "none",
|
|
168
|
-
stroke: "currentColor",
|
|
169
|
-
strokeWidth: "2",
|
|
170
|
-
strokeLinecap: "round",
|
|
171
|
-
strokeLinejoin: "round",
|
|
172
|
-
"aria-hidden": "true",
|
|
173
|
-
children: [
|
|
174
|
-
/* @__PURE__ */ jsx("circle", { cx: "9", cy: "12", r: "1" }),
|
|
175
|
-
/* @__PURE__ */ jsx("circle", { cx: "9", cy: "5", r: "1" }),
|
|
176
|
-
/* @__PURE__ */ jsx("circle", { cx: "9", cy: "19", r: "1" }),
|
|
177
|
-
/* @__PURE__ */ jsx("circle", { cx: "15", cy: "12", r: "1" }),
|
|
178
|
-
/* @__PURE__ */ jsx("circle", { cx: "15", cy: "5", r: "1" }),
|
|
179
|
-
/* @__PURE__ */ jsx("circle", { cx: "15", cy: "19", r: "1" })
|
|
180
|
-
]
|
|
181
|
-
}
|
|
182
|
-
) }),
|
|
183
|
-
children
|
|
184
|
-
]
|
|
185
|
-
}
|
|
186
|
-
);
|
|
187
|
-
}
|
|
188
|
-
export {
|
|
189
|
-
ResizableHandle,
|
|
190
|
-
ResizablePanel,
|
|
191
|
-
ResizablePanelGroup
|
|
192
|
-
};
|
|
193
|
-
//# sourceMappingURL=resizable.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/components/resizable.tsx"],"sourcesContent":["\"use client\";\n\nimport * as React from \"react\";\nimport { cn } from \"../lib/cn\";\nimport {\n RESIZABLE_GROUP,\n RESIZABLE_HANDLE,\n RESIZABLE_HANDLE_GRIP,\n RESIZABLE_PANEL,\n} from \"../generated/resizable\";\n\nexport type ResizableDirection = \"horizontal\" | \"vertical\";\n\ninterface ResizableContextValue {\n sizes: number[];\n setSizes: React.Dispatch<React.SetStateAction<number[]>>;\n register: (index: number, defaultSize: number) => void;\n direction: ResizableDirection;\n keyboardStep: number;\n groupRef: React.RefObject<HTMLDivElement | null>;\n}\n\nconst ResizableContext = React.createContext<ResizableContextValue | null>(null);\n\nfunction useResizable(): ResizableContextValue {\n const ctx = React.useContext(ResizableContext);\n if (!ctx)\n throw new Error(\"Resizable parts must be used within a ResizablePanelGroup\");\n return ctx;\n}\n\n/** Grows the panel before `index` by `delta` %, shrinking the one after it. */\nfunction redistribute(sizes: number[], index: number, delta: number): number[] {\n const before = sizes[index];\n const after = sizes[index + 1];\n if (before === undefined || after === undefined) return sizes;\n const moved = Math.max(-before, Math.min(after, delta));\n const next = sizes.slice();\n next[index] = before + moved;\n next[index + 1] = after - moved;\n return next;\n}\n\nexport interface ResizablePanelGroupProps\n extends React.ComponentProps<\"div\"> {\n direction?: ResizableDirection;\n keyboardStep?: number;\n onLayout?: (sizes: number[]) => void;\n}\n\nexport function ResizablePanelGroup({\n className,\n direction = \"horizontal\",\n keyboardStep = 10,\n onLayout,\n children,\n ...props\n}: ResizablePanelGroupProps) {\n const [sizes, setSizes] = React.useState<number[]>([]);\n const groupRef = React.useRef<HTMLDivElement>(null);\n\n const register = React.useCallback((index: number, defaultSize: number) => {\n setSizes((prev) => {\n if (prev[index] !== undefined) return prev;\n const next = prev.slice();\n while (next.length <= index) next.push(0);\n next[index] = defaultSize;\n return next;\n });\n }, []);\n\n React.useEffect(() => {\n if (sizes.length) onLayout?.(sizes);\n }, [sizes, onLayout]);\n\n const value = React.useMemo<ResizableContextValue>(\n () => ({ sizes, setSizes, register, direction, keyboardStep, groupRef }),\n [sizes, register, direction, keyboardStep],\n );\n\n return (\n <ResizableContext.Provider value={value}>\n <div\n ref={groupRef}\n data-slot=\"resizable-panel-group\"\n data-panel-group-direction={direction}\n className={cn(RESIZABLE_GROUP, className)}\n {...props}\n >\n {children}\n </div>\n </ResizableContext.Provider>\n );\n}\n\nexport interface ResizablePanelProps extends React.ComponentProps<\"div\"> {\n index: number;\n defaultSize?: number;\n}\n\nexport function ResizablePanel({\n className,\n index,\n defaultSize = 50,\n style,\n children,\n ...props\n}: ResizablePanelProps) {\n const { sizes, register } = useResizable();\n React.useEffect(() => {\n register(index, defaultSize);\n }, [register, index, defaultSize]);\n const basis = sizes[index] ?? defaultSize;\n return (\n <div\n data-slot=\"resizable-panel\"\n className={cn(RESIZABLE_PANEL, className)}\n style={{ flex: `${basis} 1 0%`, ...style }}\n {...props}\n >\n {children}\n </div>\n );\n}\n\nexport interface ResizableHandleProps extends React.ComponentProps<\"div\"> {\n index: number;\n withHandle?: boolean;\n}\n\nexport function ResizableHandle({\n className,\n index,\n withHandle,\n children,\n ...props\n}: ResizableHandleProps) {\n const { setSizes, direction, keyboardStep, groupRef } = useResizable();\n const draggingRef = React.useRef(false);\n\n const resize = React.useCallback(\n (delta: number) => setSizes((prev) => redistribute(prev, index, delta)),\n [setSizes, index],\n );\n\n const onPointerMove = React.useCallback(\n (event: PointerEvent) => {\n if (!draggingRef.current) return;\n const rect = groupRef.current?.getBoundingClientRect();\n if (!rect) return;\n const span = direction === \"vertical\" ? rect.height : rect.width;\n if (span <= 0) return;\n const px = direction === \"vertical\" ? event.movementY : event.movementX;\n resize((px / span) * 100);\n },\n [direction, resize, groupRef],\n );\n\n const onPointerUp = React.useCallback(() => {\n draggingRef.current = false;\n window.removeEventListener(\"pointermove\", onPointerMove);\n window.removeEventListener(\"pointerup\", onPointerUp);\n }, [onPointerMove]);\n\n const onPointerDown = (event: React.PointerEvent) => {\n event.preventDefault();\n draggingRef.current = true;\n window.addEventListener(\"pointermove\", onPointerMove);\n window.addEventListener(\"pointerup\", onPointerUp);\n };\n\n React.useEffect(() => () => onPointerUp(), [onPointerUp]);\n\n const onKeyDown = (event: React.KeyboardEvent) => {\n let delta: number;\n switch (event.key) {\n case \"ArrowLeft\":\n case \"ArrowUp\":\n delta = -keyboardStep;\n break;\n case \"ArrowRight\":\n case \"ArrowDown\":\n delta = keyboardStep;\n break;\n default:\n return;\n }\n if (\n (direction === \"horizontal\" &&\n (event.key === \"ArrowUp\" || event.key === \"ArrowDown\")) ||\n (direction === \"vertical\" &&\n (event.key === \"ArrowLeft\" || event.key === \"ArrowRight\"))\n )\n return;\n event.preventDefault();\n resize(delta);\n };\n\n return (\n <div\n data-slot=\"resizable-handle\"\n data-panel-group-direction={direction}\n role=\"separator\"\n aria-orientation={direction === \"horizontal\" ? \"vertical\" : \"horizontal\"}\n tabIndex={0}\n className={cn(RESIZABLE_HANDLE, className)}\n onPointerDown={onPointerDown}\n onKeyDown={onKeyDown}\n {...props}\n >\n {withHandle && (\n <div className={RESIZABLE_HANDLE_GRIP}>\n <svg\n className=\"size-2.5\"\n xmlns=\"http://www.w3.org/2000/svg\"\n width=\"15\"\n height=\"15\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n aria-hidden=\"true\"\n >\n <circle cx=\"9\" cy=\"12\" r=\"1\" />\n <circle cx=\"9\" cy=\"5\" r=\"1\" />\n <circle cx=\"9\" cy=\"19\" r=\"1\" />\n <circle cx=\"15\" cy=\"12\" r=\"1\" />\n <circle cx=\"15\" cy=\"5\" r=\"1\" />\n <circle cx=\"15\" cy=\"19\" r=\"1\" />\n </svg>\n </div>\n )}\n {children}\n </div>\n );\n}\n"],"mappings":"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","names":[]}
|
package/dist/generated/chart.js
DELETED
|
@@ -1,9 +0,0 @@
|
|
|
1
|
-
const CHART_CONTAINER = "flex aspect-video justify-center text-xs [&_.recharts-layer]:outline-hidden [&_.recharts-surface]:outline-hidden [&_svg]:outline-hidden";
|
|
2
|
-
const CHART_TOOLTIP = "border-border/50 bg-background grid min-w-[8rem] items-start gap-1.5 rounded-lg border px-2.5 py-1.5 text-xs shadow-xl";
|
|
3
|
-
const CHART_LEGEND = "flex items-center justify-center gap-4";
|
|
4
|
-
export {
|
|
5
|
-
CHART_CONTAINER,
|
|
6
|
-
CHART_LEGEND,
|
|
7
|
-
CHART_TOOLTIP
|
|
8
|
-
};
|
|
9
|
-
//# sourceMappingURL=chart.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/generated/chart.ts"],"sourcesContent":["// AUTO-GENERATED by `nix run .#gen` — do not edit.\n\nexport const CHART_CONTAINER = \"flex aspect-video justify-center text-xs [&_.recharts-layer]:outline-hidden [&_.recharts-surface]:outline-hidden [&_svg]:outline-hidden\";\n\nexport const CHART_TOOLTIP = \"border-border/50 bg-background grid min-w-[8rem] items-start gap-1.5 rounded-lg border px-2.5 py-1.5 text-xs shadow-xl\";\n\nexport const CHART_LEGEND = \"flex items-center justify-center gap-4\";\n"],"mappings":"AAEO,MAAM,kBAAkB;AAExB,MAAM,gBAAgB;AAEtB,MAAM,eAAe;","names":[]}
|
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
const RESIZABLE_GROUP = "flex h-full w-full data-[panel-group-direction=vertical]:flex-col";
|
|
2
|
-
const RESIZABLE_PANEL = "relative";
|
|
3
|
-
const RESIZABLE_HANDLE = "bg-border focus-visible:ring-ring relative flex w-px items-center justify-center after:absolute after:inset-y-0 after:left-1/2 after:w-1 after:-translate-x-1/2 focus-visible:ring-1 focus-visible:ring-offset-1 focus-visible:outline-hidden data-[panel-group-direction=vertical]:h-px data-[panel-group-direction=vertical]:w-full data-[panel-group-direction=vertical]:after:left-0 data-[panel-group-direction=vertical]:after:h-1 data-[panel-group-direction=vertical]:after:w-full data-[panel-group-direction=vertical]:after:translate-x-0 data-[panel-group-direction=vertical]:after:-translate-y-1/2 [&[data-panel-group-direction=vertical]>div]:rotate-90";
|
|
4
|
-
const RESIZABLE_HANDLE_GRIP = "bg-border z-10 flex h-4 w-3 items-center justify-center rounded-xs border border-border";
|
|
5
|
-
export {
|
|
6
|
-
RESIZABLE_GROUP,
|
|
7
|
-
RESIZABLE_HANDLE,
|
|
8
|
-
RESIZABLE_HANDLE_GRIP,
|
|
9
|
-
RESIZABLE_PANEL
|
|
10
|
-
};
|
|
11
|
-
//# sourceMappingURL=resizable.js.map
|