@evinvest/uikit 0.18.0 → 0.20.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +210 -13
- package/dist/chunk-3IPB4QQJ.js +306 -0
- package/dist/chunk-3IPB4QQJ.js.map +1 -0
- package/dist/components/accordion.js +136 -0
- package/dist/components/accordion.js.map +1 -0
- package/dist/components/alert-dialog.js +175 -0
- package/dist/components/alert-dialog.js.map +1 -0
- package/dist/components/alert.js +49 -0
- package/dist/components/alert.js.map +1 -0
- package/dist/components/avatar.js +54 -0
- package/dist/components/avatar.js.map +1 -0
- package/dist/components/badge.js +25 -0
- package/dist/components/badge.js.map +1 -0
- package/dist/components/band.js +75 -0
- package/dist/components/band.js.map +1 -0
- package/dist/components/breadcrumb.js +132 -0
- package/dist/components/breadcrumb.js.map +1 -0
- package/dist/components/button-group.js +61 -0
- package/dist/components/button-group.js.map +1 -0
- package/dist/components/button.js +55 -0
- package/dist/components/button.js.map +1 -0
- package/dist/components/calendar.js +226 -0
- package/dist/components/calendar.js.map +1 -0
- package/dist/components/card.js +98 -0
- package/dist/components/card.js.map +1 -0
- package/dist/components/carousel.js +262 -0
- package/dist/components/carousel.js.map +1 -0
- package/dist/components/chart.js +151 -0
- package/dist/components/chart.js.map +1 -0
- package/dist/components/checkbox.js +68 -0
- package/dist/components/checkbox.js.map +1 -0
- package/dist/components/collapsible.js +60 -0
- package/dist/components/collapsible.js.map +1 -0
- package/dist/components/command.js +274 -0
- package/dist/components/command.js.map +1 -0
- package/dist/components/container.js +18 -0
- package/dist/components/container.js.map +1 -0
- package/dist/components/context-menu.js +337 -0
- package/dist/components/context-menu.js.map +1 -0
- package/dist/components/date-time-picker.js +301 -0
- package/dist/components/date-time-picker.js.map +1 -0
- package/dist/components/dialog.js +207 -0
- package/dist/components/dialog.js.map +1 -0
- package/dist/components/drawer.js +351 -0
- package/dist/components/drawer.js.map +1 -0
- package/dist/components/dropdown-menu.js +356 -0
- package/dist/components/dropdown-menu.js.map +1 -0
- package/dist/components/empty.js +91 -0
- package/dist/components/empty.js.map +1 -0
- package/dist/components/field-context.js +30 -0
- package/dist/components/field-context.js.map +1 -0
- package/dist/components/field.js +216 -0
- package/dist/components/field.js.map +1 -0
- package/dist/components/footer.js +89 -0
- package/dist/components/footer.js.map +1 -0
- package/dist/components/form.js +101 -0
- package/dist/components/form.js.map +1 -0
- package/dist/components/hover-card.js +90 -0
- package/dist/components/hover-card.js.map +1 -0
- package/dist/components/info-tip.js +161 -0
- package/dist/components/info-tip.js.map +1 -0
- package/dist/components/input-group.js +124 -0
- package/dist/components/input-group.js.map +1 -0
- package/dist/components/input-otp.js +120 -0
- package/dist/components/input-otp.js.map +1 -0
- package/dist/components/input.js +26 -0
- package/dist/components/input.js.map +1 -0
- package/dist/components/item.js +167 -0
- package/dist/components/item.js.map +1 -0
- package/dist/components/kbd.js +29 -0
- package/dist/components/kbd.js.map +1 -0
- package/dist/components/label.js +11 -0
- package/dist/components/label.js.map +1 -0
- package/dist/components/logo.js +41 -0
- package/dist/components/logo.js.map +1 -0
- package/dist/components/menubar.js +330 -0
- package/dist/components/menubar.js.map +1 -0
- package/dist/components/native-select.js +62 -0
- package/dist/components/native-select.js.map +1 -0
- package/dist/components/navigation-menu.js +204 -0
- package/dist/components/navigation-menu.js.map +1 -0
- package/dist/components/pagination.js +138 -0
- package/dist/components/pagination.js.map +1 -0
- package/dist/components/popover.js +104 -0
- package/dist/components/popover.js.map +1 -0
- package/dist/components/progress.js +30 -0
- package/dist/components/progress.js.map +1 -0
- package/dist/components/radio-group.js +113 -0
- package/dist/components/radio-group.js.map +1 -0
- package/dist/components/resizable.js +193 -0
- package/dist/components/resizable.js.map +1 -0
- package/dist/components/scroll-area.js +40 -0
- package/dist/components/scroll-area.js.map +1 -0
- package/dist/components/section-descriptor.js +88 -0
- package/dist/components/section-descriptor.js.map +1 -0
- package/dist/components/select-chevron.js +25 -0
- package/dist/components/select-chevron.js.map +1 -0
- package/dist/components/select.js +288 -0
- package/dist/components/select.js.map +1 -0
- package/dist/components/separator.js +31 -0
- package/dist/components/separator.js.map +1 -0
- package/dist/components/sheet.js +200 -0
- package/dist/components/sheet.js.map +1 -0
- package/dist/components/sidebar.js +326 -0
- package/dist/components/sidebar.js.map +1 -0
- package/dist/components/skeleton.js +18 -0
- package/dist/components/skeleton.js.map +1 -0
- package/dist/components/slider.js +138 -0
- package/dist/components/slider.js.map +1 -0
- package/dist/components/sonner.js +319 -0
- package/dist/components/sonner.js.map +1 -0
- package/dist/components/spinner.js +23 -0
- package/dist/components/spinner.js.map +1 -0
- package/dist/components/status-screen.js +145 -0
- package/dist/components/status-screen.js.map +1 -0
- package/dist/components/switch.js +54 -0
- package/dist/components/switch.js.map +1 -0
- package/dist/components/table.js +124 -0
- package/dist/components/table.js.map +1 -0
- package/dist/components/tabs.js +133 -0
- package/dist/components/tabs.js.map +1 -0
- package/dist/components/terminal.js +206 -0
- package/dist/components/terminal.js.map +1 -0
- package/dist/components/textarea.js +22 -0
- package/dist/components/textarea.js.map +1 -0
- package/dist/components/toggle-group.js +105 -0
- package/dist/components/toggle-group.js.map +1 -0
- package/dist/components/toggle.js +53 -0
- package/dist/components/toggle.js.map +1 -0
- package/dist/components/tooltip.js +102 -0
- package/dist/components/tooltip.js.map +1 -0
- package/dist/generated/accent.js +27 -0
- package/dist/generated/accent.js.map +1 -0
- package/dist/generated/accordion.js +13 -0
- package/dist/generated/accordion.js.map +1 -0
- package/dist/generated/alert-dialog.js +15 -0
- package/dist/generated/alert-dialog.js.map +1 -0
- package/dist/generated/alert.js +16 -0
- package/dist/generated/alert.js.map +1 -0
- package/dist/generated/avatar.js +9 -0
- package/dist/generated/avatar.js.map +1 -0
- package/dist/generated/badge.js +13 -0
- package/dist/generated/badge.js.map +1 -0
- package/dist/generated/band.js +39 -0
- package/dist/generated/band.js.map +1 -0
- package/dist/generated/breadcrumb.js +15 -0
- package/dist/generated/breadcrumb.js.map +1 -0
- package/dist/generated/button-group.js +14 -0
- package/dist/generated/button-group.js.map +1 -0
- package/dist/generated/button.js +30 -0
- package/dist/generated/button.js.map +1 -0
- package/dist/generated/calendar.js +29 -0
- package/dist/generated/calendar.js.map +1 -0
- package/dist/generated/card.js +17 -0
- package/dist/generated/card.js.map +1 -0
- package/dist/generated/carousel.js +31 -0
- package/dist/generated/carousel.js.map +1 -0
- package/dist/generated/chart.js +9 -0
- package/dist/generated/chart.js.map +1 -0
- package/dist/generated/checkbox.js +7 -0
- package/dist/generated/checkbox.js.map +1 -0
- package/dist/generated/command.js +27 -0
- package/dist/generated/command.js.map +1 -0
- package/dist/generated/container.js +5 -0
- package/dist/generated/container.js.map +1 -0
- package/dist/generated/context-menu.js +19 -0
- package/dist/generated/context-menu.js.map +1 -0
- package/dist/generated/date-time-picker.js +15 -0
- package/dist/generated/date-time-picker.js.map +1 -0
- package/dist/generated/dialog.js +17 -0
- package/dist/generated/dialog.js.map +1 -0
- package/dist/generated/drawer.js +26 -0
- package/dist/generated/drawer.js.map +1 -0
- package/dist/generated/dropdown-menu.js +21 -0
- package/dist/generated/dropdown-menu.js.map +1 -0
- package/dist/generated/empty.js +20 -0
- package/dist/generated/empty.js.map +1 -0
- package/dist/generated/field.js +33 -0
- package/dist/generated/field.js.map +1 -0
- package/dist/generated/focus.js +5 -0
- package/dist/generated/focus.js.map +1 -0
- package/dist/generated/form.js +11 -0
- package/dist/generated/form.js.map +1 -0
- package/dist/generated/hover-card.js +5 -0
- package/dist/generated/hover-card.js.map +1 -0
- package/dist/generated/input-group.js +29 -0
- package/dist/generated/input-group.js.map +1 -0
- package/dist/generated/input-otp.js +15 -0
- package/dist/generated/input-otp.js.map +1 -0
- package/dist/generated/input.js +11 -0
- package/dist/generated/input.js.map +1 -0
- package/dist/generated/item.js +40 -0
- package/dist/generated/item.js.map +1 -0
- package/dist/generated/kbd.js +7 -0
- package/dist/generated/kbd.js.map +1 -0
- package/dist/generated/label.js +5 -0
- package/dist/generated/label.js.map +1 -0
- package/dist/generated/menubar.js +27 -0
- package/dist/generated/menubar.js.map +1 -0
- package/dist/generated/navigation-menu.js +19 -0
- package/dist/generated/navigation-menu.js.map +1 -0
- package/dist/generated/popover.js +5 -0
- package/dist/generated/popover.js.map +1 -0
- package/dist/generated/progress.js +7 -0
- package/dist/generated/progress.js.map +1 -0
- package/dist/generated/radio-group.js +7 -0
- package/dist/generated/radio-group.js.map +1 -0
- package/dist/generated/resizable.js +11 -0
- package/dist/generated/resizable.js.map +1 -0
- package/dist/generated/scroll-area.js +14 -0
- package/dist/generated/scroll-area.js.map +1 -0
- package/dist/generated/select.js +15 -0
- package/dist/generated/select.js.map +1 -0
- package/dist/generated/separator.js +10 -0
- package/dist/generated/separator.js.map +1 -0
- package/dist/generated/sheet.js +25 -0
- package/dist/generated/sheet.js.map +1 -0
- package/dist/generated/sidebar.js +41 -0
- package/dist/generated/sidebar.js.map +1 -0
- package/dist/generated/skeleton.js +5 -0
- package/dist/generated/skeleton.js.map +1 -0
- package/dist/generated/slider.js +11 -0
- package/dist/generated/slider.js.map +1 -0
- package/dist/generated/sonner.js +30 -0
- package/dist/generated/sonner.js.map +1 -0
- package/dist/generated/switch.js +7 -0
- package/dist/generated/switch.js.map +1 -0
- package/dist/generated/table.js +21 -0
- package/dist/generated/table.js.map +1 -0
- package/dist/generated/tabs.js +11 -0
- package/dist/generated/tabs.js.map +1 -0
- package/dist/generated/terminal.js +70 -0
- package/dist/generated/terminal.js.map +1 -0
- package/dist/generated/textarea.js +11 -0
- package/dist/generated/textarea.js.map +1 -0
- package/dist/generated/toggle.js +18 -0
- package/dist/generated/toggle.js.map +1 -0
- package/dist/generated/tooltip.js +5 -0
- package/dist/generated/tooltip.js.map +1 -0
- package/dist/index.d.ts +141 -34
- package/dist/index.js +73 -8623
- package/dist/lib/cn.js +12 -0
- package/dist/lib/cn.js.map +1 -0
- package/dist/lib/focus.js +5 -0
- package/dist/lib/focus.js.map +1 -0
- package/dist/palette-cli.js +41 -0
- package/dist/palette-cli.js.map +1 -0
- package/dist/palette.d.ts +80 -0
- package/dist/palette.js +25 -0
- package/dist/palette.js.map +1 -0
- package/dist/primitives/dismissable-layer.js +35 -0
- package/dist/primitives/dismissable-layer.js.map +1 -0
- package/dist/primitives/focus-scope.js +58 -0
- package/dist/primitives/focus-scope.js.map +1 -0
- package/dist/primitives/merge-refs.js +13 -0
- package/dist/primitives/merge-refs.js.map +1 -0
- package/dist/primitives/portal.js +19 -0
- package/dist/primitives/portal.js.map +1 -0
- package/dist/primitives/presence.js +45 -0
- package/dist/primitives/presence.js.map +1 -0
- package/dist/primitives/slot.js +39 -0
- package/dist/primitives/slot.js.map +1 -0
- package/dist/primitives/use-controllable-state.js +24 -0
- package/dist/primitives/use-controllable-state.js.map +1 -0
- package/dist/primitives/use-floating.js +128 -0
- package/dist/primitives/use-floating.js.map +1 -0
- package/dist/primitives/use-hover-intent.js +50 -0
- package/dist/primitives/use-hover-intent.js.map +1 -0
- package/dist/primitives/use-roving-focus.js +40 -0
- package/dist/primitives/use-roving-focus.js.map +1 -0
- package/dist/primitives/walk-elements.js +13 -0
- package/dist/primitives/walk-elements.js.map +1 -0
- package/package.json +15 -5
- package/styles/ev.css +73 -0
- package/styles/theme.css +470 -0
- package/styles/tokens.css +129 -90
- package/dist/index.js.map +0 -1
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/primitives/use-floating.ts"],"sourcesContent":["\"use client\";\n\nimport * as React from \"react\";\n\nexport type Side = \"top\" | \"right\" | \"bottom\" | \"left\";\nexport type Align = \"start\" | \"center\" | \"end\";\n\nexport interface FloatingResult {\n floatingRef: React.RefObject<HTMLElement | null>;\n style: React.CSSProperties;\n side: Side;\n align: Align;\n}\n\n// The element sits at its containing block's origin and is moved with the\n// `translate` property, never with `top`/`left`: an absolute box's\n// shrink-to-fit width is \"containing block minus `left`\", so a `w-fit` surface\n// pushed past the viewport's right edge (horizontal scroll, a nested scroller)\n// would collapse to one word per line. `translate` composes with `transform`,\n// so the enter animations (which animate `transform`) are unaffected. The\n// offset never goes through React: `place()` / `sync()` write it straight to\n// the element, so this style prop stays one frozen object.\nconst ABSOLUTE: React.CSSProperties = Object.freeze({ position: \"absolute\", top: 0, left: 0 });\n\nconst POSITIONED = new Set([\"relative\", \"absolute\", \"fixed\", \"sticky\"]);\n\n/**\n * Converts a viewport-relative point into the coordinate space of the\n * floating element's containing block, i.e. the numbers `position: absolute`\n * expects. floating-ui's `strategy: \"absolute\"` does the same walk.\n */\nfunction toContainingBlock(\n floating: HTMLElement,\n x: number,\n y: number,\n): { x: number; y: number; root: boolean } {\n const parent = floating.offsetParent;\n const doc = floating.ownerDocument;\n const root = parent === doc.body || parent === doc.documentElement || parent === null;\n // `offsetParent` reports `body` even when nothing is positioned; only a\n // positioned body/html really forms a containing block.\n const positioned =\n parent instanceof HTMLElement &&\n (!root || POSITIONED.has(doc.defaultView?.getComputedStyle(parent).position ?? \"\"));\n if (!positioned) {\n const win = doc.defaultView;\n return { x: x + (win?.scrollX ?? 0), y: y + (win?.scrollY ?? 0), root: true };\n }\n const p = parent.getBoundingClientRect();\n return {\n x: x - p.left - parent.clientLeft + parent.scrollLeft,\n y: y - p.top - parent.clientTop + parent.scrollTop,\n root: false,\n };\n}\n\ninterface Size2D {\n width: number;\n height: number;\n}\n\n// The layout box, not `getBoundingClientRect()`: the latter reports the box\n// mid-animation (`zoom-in-95` scales it to 0.95 on the first frame), which\n// placed a top-side popover 5 % of its height too low, over the anchor.\nfunction layoutSize(el: HTMLElement): Size2D {\n return { width: el.offsetWidth, height: el.offsetHeight };\n}\n\nfunction viewport(): { vw: number; vh: number } {\n // `clientWidth` excludes the scrollbar, which the floating element cannot\n // sit under anyway; jsdom reports 0 there, hence the fallback.\n const el = document.documentElement;\n return {\n vw: el.clientWidth || window.innerWidth,\n vh: el.clientHeight || window.innerHeight,\n };\n}\n\n/**\n * Positions a floating element against an anchor with `position: absolute` in\n * the coordinate space of its containing block (the `Portal` puts it in\n * `document.body`, so normally document coordinates) — the dep-light stand-in\n * for `@radix-ui/react-popper` / floating-ui. Supports a preferred\n * `side`/`align`, an `offset`, and a single collision flip onto the opposite\n * side when the preferred side overflows the viewport.\n *\n * Two update modes:\n * - `place()` — full pass (flip + clamp into the viewport) on open, on window\n * `resize`, and whenever the anchor or the floating element changes size.\n * - `sync()` — re-derives the coordinates from the anchor with the side and\n * the clamp shift already chosen; runs on every `scroll` (captured on\n * `window`, so nested scroll containers count too).\n *\n * Because the element is absolutely positioned in the document, a document\n * scroll moves it natively with the page — `sync()` then computes the same\n * numbers and is a no-op — so the overlay never lags behind the compositor.\n * Only a nested scroll container changes the coordinates, and there a frame\n * of lag is acceptable. The side is never revisited on scroll: no jumping.\n * A page that scrolls `body` instead of the document (`html { overflow:\n * hidden } body { overflow: auto }`) is such a nested scroller: correct, but\n * with the frame of lag the `fixed` strategy had.\n *\n * Rust's overlays use CSS-only placement (`data-side`) and do not measure; see\n * the README \"Limitations\".\n */\nexport function useFloating(opts: {\n anchorRef: React.RefObject<Element | null>;\n open: boolean;\n side?: Side;\n align?: Align;\n offset?: number;\n}): FloatingResult {\n const { anchorRef, open, side = \"bottom\", align = \"center\", offset = 4 } = opts;\n const floatingRef = React.useRef<HTMLElement | null>(null);\n const [placedSide, setPlacedSide] = React.useState<Side>(side);\n // The last full placement: the side that won the flip and how far the\n // viewport clamp pushed the element off its ideal spot. `sync()` reuses both\n // instead of measuring against the viewport again.\n const placement = React.useRef<{ side: Side; shiftX: number; shiftY: number }>({\n side,\n shiftX: 0,\n shiftY: 0,\n });\n\n React.useLayoutEffect(() => {\n if (!open) return;\n\n function ideal(a: DOMRect, f: Size2D, placed: Side): { top: number; left: number } {\n let top = 0;\n let left = 0;\n const vertical = placed === \"top\" || placed === \"bottom\";\n\n if (placed === \"bottom\") top = a.bottom + offset;\n else if (placed === \"top\") top = a.top - offset - f.height;\n else if (placed === \"right\") left = a.right + offset;\n else left = a.left - offset - f.width;\n\n if (vertical) {\n if (align === \"start\") left = a.left;\n else if (align === \"end\") left = a.right - f.width;\n else left = a.left + a.width / 2 - f.width / 2;\n } else {\n if (align === \"start\") top = a.top;\n else if (align === \"end\") top = a.bottom - f.height;\n else top = a.top + a.height / 2 - f.height / 2;\n }\n return { top, left };\n }\n\n // `contain` keeps the box inside the initial containing block: a box past\n // the document's edge grows the page (a scrollbar shows for as long as the\n // overlay is open). `place()` already clamps against the viewport;\n // `sync()` follows a nested scroller's anchor and only needs this bound.\n function write(floating: HTMLElement, f: Size2D, top: number, left: number, contain: boolean) {\n const p = toContainingBlock(floating, left, top);\n let { x, y } = p;\n if (contain && p.root) {\n const icbWidth = floating.ownerDocument.documentElement.clientWidth || window.innerWidth;\n x = Math.max(0, Math.min(x, icbWidth - f.width));\n y = Math.max(0, y);\n }\n floating.style.translate = `${Math.round(x)}px ${Math.round(y)}px`;\n }\n\n function place() {\n const anchor = anchorRef.current;\n const floating = floatingRef.current;\n if (!anchor || !floating) return;\n\n const a = anchor.getBoundingClientRect();\n const f = layoutSize(floating);\n const { vw, vh } = viewport();\n\n let placed: Side = side;\n if (side === \"bottom\" && a.bottom + offset + f.height > vh && a.top - offset - f.height > 0)\n placed = \"top\";\n else if (side === \"top\" && a.top - offset - f.height < 0 && a.bottom + offset + f.height < vh)\n placed = \"bottom\";\n else if (side === \"right\" && a.right + offset + f.width > vw && a.left - offset - f.width > 0)\n placed = \"left\";\n else if (side === \"left\" && a.left - offset - f.width < 0 && a.right + offset + f.width < vw)\n placed = \"right\";\n\n const { top, left } = ideal(a, f, placed);\n const clampedLeft = Math.max(offset, Math.min(left, vw - f.width - offset));\n const clampedTop = Math.max(offset, Math.min(top, vh - f.height - offset));\n\n placement.current = {\n side: placed,\n shiftX: clampedLeft - left,\n shiftY: clampedTop - top,\n };\n write(floating, f, clampedTop, clampedLeft, false);\n // Only a real change may re-render: this runs on every resize tick.\n setPlacedSide(prev => (prev === placed ? prev : placed));\n }\n\n function sync() {\n const anchor = anchorRef.current;\n const floating = floatingRef.current;\n if (!anchor || !floating) return;\n\n const a = anchor.getBoundingClientRect();\n const f = layoutSize(floating);\n const { side: placed, shiftX, shiftY } = placement.current;\n const { top, left } = ideal(a, f, placed);\n write(floating, f, top + shiftY, left + shiftX, true);\n }\n\n place();\n // No rAF: `scroll` already fires at most once per frame, and a synchronous\n // DOM write from the handler lands in that same frame — rAF would cost one.\n window.addEventListener(\"scroll\", sync, true);\n window.addEventListener(\"resize\", place);\n\n let observer: ResizeObserver | undefined;\n if (typeof ResizeObserver !== \"undefined\") {\n observer = new ResizeObserver(place);\n if (anchorRef.current) observer.observe(anchorRef.current);\n if (floatingRef.current) observer.observe(floatingRef.current);\n }\n\n return () => {\n window.removeEventListener(\"scroll\", sync, true);\n window.removeEventListener(\"resize\", place);\n observer?.disconnect();\n };\n }, [open, side, align, offset, anchorRef]);\n\n return { floatingRef, style: ABSOLUTE, side: placedSide, align };\n}\n"],"mappings":"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","names":[]}
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import * as React from "react";
|
|
3
|
+
function useHoverIntent(opts) {
|
|
4
|
+
const { onOpen, onClose, openDelay = 500, closeDelay = 0 } = opts;
|
|
5
|
+
const openRef = React.useRef(onOpen);
|
|
6
|
+
const closeRef = React.useRef(onClose);
|
|
7
|
+
React.useEffect(() => {
|
|
8
|
+
openRef.current = onOpen;
|
|
9
|
+
closeRef.current = onClose;
|
|
10
|
+
});
|
|
11
|
+
const timer = React.useRef(null);
|
|
12
|
+
const clear = React.useCallback(() => {
|
|
13
|
+
if (timer.current != null) {
|
|
14
|
+
clearTimeout(timer.current);
|
|
15
|
+
timer.current = null;
|
|
16
|
+
}
|
|
17
|
+
}, []);
|
|
18
|
+
React.useEffect(() => clear, [clear]);
|
|
19
|
+
const onPointerEnter = React.useCallback(
|
|
20
|
+
(event) => {
|
|
21
|
+
if (event.pointerType !== "mouse") return;
|
|
22
|
+
clear();
|
|
23
|
+
timer.current = setTimeout(() => {
|
|
24
|
+
timer.current = null;
|
|
25
|
+
openRef.current();
|
|
26
|
+
}, openDelay);
|
|
27
|
+
},
|
|
28
|
+
[clear, openDelay]
|
|
29
|
+
);
|
|
30
|
+
const onPointerLeave = React.useCallback(
|
|
31
|
+
(event) => {
|
|
32
|
+
if (event.pointerType !== "mouse") return;
|
|
33
|
+
clear();
|
|
34
|
+
if (closeDelay > 0) {
|
|
35
|
+
timer.current = setTimeout(() => {
|
|
36
|
+
timer.current = null;
|
|
37
|
+
closeRef.current();
|
|
38
|
+
}, closeDelay);
|
|
39
|
+
} else {
|
|
40
|
+
closeRef.current();
|
|
41
|
+
}
|
|
42
|
+
},
|
|
43
|
+
[clear, closeDelay]
|
|
44
|
+
);
|
|
45
|
+
return { onPointerEnter, onPointerLeave };
|
|
46
|
+
}
|
|
47
|
+
export {
|
|
48
|
+
useHoverIntent
|
|
49
|
+
};
|
|
50
|
+
//# sourceMappingURL=use-hover-intent.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/primitives/use-hover-intent.ts"],"sourcesContent":["\"use client\";\n\nimport * as React from \"react\";\n\nexport interface HoverIntentHandlers {\n onPointerEnter: (event: React.PointerEvent) => void;\n onPointerLeave: (event: React.PointerEvent) => void;\n}\n\n/**\n * Mouse-only hover-with-intent for the {@link InfoTip} toggletip: opens after the\n * cursor dwells `openDelay`ms over the trigger, closes after `closeDelay`ms once\n * it leaves. Touch and pen pointers are ignored — they have no hover, so a\n * coarse-pointer device never fires this and the toggletip's click/tap path takes\n * over. This timer is the one piece of behaviour with no Rust counterpart: the\n * Dioxus kit has no host timers (the same reason it has no Portal or floating\n * engine — see the README \"Limitations\"), so its trigger opens on hover instantly.\n */\nexport function useHoverIntent(opts: {\n onOpen: () => void;\n onClose: () => void;\n openDelay?: number;\n closeDelay?: number;\n}): HoverIntentHandlers {\n const { onOpen, onClose, openDelay = 500, closeDelay = 0 } = opts;\n\n const openRef = React.useRef(onOpen);\n const closeRef = React.useRef(onClose);\n React.useEffect(() => {\n openRef.current = onOpen;\n closeRef.current = onClose;\n });\n\n const timer = React.useRef<ReturnType<typeof setTimeout> | null>(null);\n const clear = React.useCallback(() => {\n if (timer.current != null) {\n clearTimeout(timer.current);\n timer.current = null;\n }\n }, []);\n React.useEffect(() => clear, [clear]);\n\n const onPointerEnter = React.useCallback(\n (event: React.PointerEvent) => {\n if (event.pointerType !== \"mouse\") return;\n clear();\n timer.current = setTimeout(() => {\n timer.current = null;\n openRef.current();\n }, openDelay);\n },\n [clear, openDelay],\n );\n\n const onPointerLeave = React.useCallback(\n (event: React.PointerEvent) => {\n if (event.pointerType !== \"mouse\") return;\n clear();\n if (closeDelay > 0) {\n timer.current = setTimeout(() => {\n timer.current = null;\n closeRef.current();\n }, closeDelay);\n } else {\n closeRef.current();\n }\n },\n [clear, closeDelay],\n );\n\n return { onPointerEnter, onPointerLeave };\n}\n"],"mappings":";AAEA,YAAY,WAAW;AAgBhB,SAAS,eAAe,MAKP;AACtB,QAAM,EAAE,QAAQ,SAAS,YAAY,KAAK,aAAa,EAAE,IAAI;AAE7D,QAAM,UAAU,MAAM,OAAO,MAAM;AACnC,QAAM,WAAW,MAAM,OAAO,OAAO;AACrC,QAAM,UAAU,MAAM;AACpB,YAAQ,UAAU;AAClB,aAAS,UAAU;AAAA,EACrB,CAAC;AAED,QAAM,QAAQ,MAAM,OAA6C,IAAI;AACrE,QAAM,QAAQ,MAAM,YAAY,MAAM;AACpC,QAAI,MAAM,WAAW,MAAM;AACzB,mBAAa,MAAM,OAAO;AAC1B,YAAM,UAAU;AAAA,IAClB;AAAA,EACF,GAAG,CAAC,CAAC;AACL,QAAM,UAAU,MAAM,OAAO,CAAC,KAAK,CAAC;AAEpC,QAAM,iBAAiB,MAAM;AAAA,IAC3B,CAAC,UAA8B;AAC7B,UAAI,MAAM,gBAAgB,QAAS;AACnC,YAAM;AACN,YAAM,UAAU,WAAW,MAAM;AAC/B,cAAM,UAAU;AAChB,gBAAQ,QAAQ;AAAA,MAClB,GAAG,SAAS;AAAA,IACd;AAAA,IACA,CAAC,OAAO,SAAS;AAAA,EACnB;AAEA,QAAM,iBAAiB,MAAM;AAAA,IAC3B,CAAC,UAA8B;AAC7B,UAAI,MAAM,gBAAgB,QAAS;AACnC,YAAM;AACN,UAAI,aAAa,GAAG;AAClB,cAAM,UAAU,WAAW,MAAM;AAC/B,gBAAM,UAAU;AAChB,mBAAS,QAAQ;AAAA,QACnB,GAAG,UAAU;AAAA,MACf,OAAO;AACL,iBAAS,QAAQ;AAAA,MACnB;AAAA,IACF;AAAA,IACA,CAAC,OAAO,UAAU;AAAA,EACpB;AAEA,SAAO,EAAE,gBAAgB,eAAe;AAC1C;","names":[]}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import * as React from "react";
|
|
3
|
+
function useRovingFocus(opts) {
|
|
4
|
+
const { count, orientation = "vertical", loop = true, initial = 0 } = opts;
|
|
5
|
+
const [activeIndex, setActiveIndex] = React.useState(initial);
|
|
6
|
+
const next = (dir) => setActiveIndex((i) => {
|
|
7
|
+
let n = i + dir;
|
|
8
|
+
if (n < 0) n = loop ? count - 1 : 0;
|
|
9
|
+
else if (n >= count) n = loop ? 0 : count - 1;
|
|
10
|
+
return n;
|
|
11
|
+
});
|
|
12
|
+
const onKeyDown = (event) => {
|
|
13
|
+
const horiz = orientation === "horizontal" || orientation === "both";
|
|
14
|
+
const vert = orientation === "vertical" || orientation === "both";
|
|
15
|
+
if (vert && event.key === "ArrowDown") {
|
|
16
|
+
event.preventDefault();
|
|
17
|
+
next(1);
|
|
18
|
+
} else if (vert && event.key === "ArrowUp") {
|
|
19
|
+
event.preventDefault();
|
|
20
|
+
next(-1);
|
|
21
|
+
} else if (horiz && event.key === "ArrowRight") {
|
|
22
|
+
event.preventDefault();
|
|
23
|
+
next(1);
|
|
24
|
+
} else if (horiz && event.key === "ArrowLeft") {
|
|
25
|
+
event.preventDefault();
|
|
26
|
+
next(-1);
|
|
27
|
+
} else if (event.key === "Home") {
|
|
28
|
+
event.preventDefault();
|
|
29
|
+
setActiveIndex(0);
|
|
30
|
+
} else if (event.key === "End") {
|
|
31
|
+
event.preventDefault();
|
|
32
|
+
setActiveIndex(count - 1);
|
|
33
|
+
}
|
|
34
|
+
};
|
|
35
|
+
return { activeIndex, setActiveIndex, onKeyDown };
|
|
36
|
+
}
|
|
37
|
+
export {
|
|
38
|
+
useRovingFocus
|
|
39
|
+
};
|
|
40
|
+
//# sourceMappingURL=use-roving-focus.js.map
|
|
@@ -0,0 +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) =>\n setActiveIndex((i) => {\n let n = i + dir;\n if (n < 0) n = loop ? count - 1 : 0;\n else if (n >= count) n = loop ? 0 : count - 1;\n return 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 setActiveIndex(count - 1);\n }\n };\n\n return { activeIndex, setActiveIndex, onKeyDown };\n}\n"],"mappings":";AAEA,YAAY,WAAW;AAUhB,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,OAAO,CAAC,QACZ,eAAe,CAAC,MAAM;AACpB,QAAI,IAAI,IAAI;AACZ,QAAI,IAAI,EAAG,KAAI,OAAO,QAAQ,IAAI;AAAA,aACzB,KAAK,MAAO,KAAI,OAAO,IAAI,QAAQ;AAC5C,WAAO;AAAA,EACT,CAAC;AAEH,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,qBAAe,QAAQ,CAAC;AAAA,IAC1B;AAAA,EACF;AAEA,SAAO,EAAE,aAAa,gBAAgB,UAAU;AAClD;","names":[]}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import * as React from "react";
|
|
2
|
+
function walkElements(node, visit) {
|
|
3
|
+
if (Array.isArray(node)) {
|
|
4
|
+
for (const child of node) walkElements(child, visit);
|
|
5
|
+
return;
|
|
6
|
+
}
|
|
7
|
+
if (!React.isValidElement(node)) return;
|
|
8
|
+
if (node.type === React.Fragment || visit(node)) walkElements(node.props.children, visit);
|
|
9
|
+
}
|
|
10
|
+
export {
|
|
11
|
+
walkElements
|
|
12
|
+
};
|
|
13
|
+
//# sourceMappingURL=walk-elements.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/primitives/walk-elements.ts"],"sourcesContent":["import * as React from \"react\";\n\nexport type ElementWithChildren = React.ReactElement<{ children?: unknown }>;\n\n/**\n * Visits the elements of a children tree, looking through arrays and\n * fragments; `visit` returns whether to descend into that element's children.\n *\n * Only elements, arrays and fragments are walked. `children` is whatever the\n * caller passed — a render function, or a plain object an i18n component\n * interpolates (`{ count }` under Trans) — and `React.Children` throws on an\n * object, so anything else is skipped rather than handed to it.\n */\nexport function walkElements(node: unknown, visit: (element: ElementWithChildren) => boolean): void {\n if (Array.isArray(node)) {\n for (const child of node) walkElements(child, visit);\n return;\n }\n if (!React.isValidElement<{ children?: unknown }>(node)) return;\n if (node.type === React.Fragment || visit(node)) walkElements(node.props.children, visit);\n}\n"],"mappings":"AAAA,YAAY,WAAW;AAahB,SAAS,aAAa,MAAe,OAAwD;AAClG,MAAI,MAAM,QAAQ,IAAI,GAAG;AACvB,eAAW,SAAS,KAAM,cAAa,OAAO,KAAK;AACnD;AAAA,EACF;AACA,MAAI,CAAC,MAAM,eAAuC,IAAI,EAAG;AACzD,MAAI,KAAK,SAAS,MAAM,YAAY,MAAM,IAAI,EAAG,cAAa,KAAK,MAAM,UAAU,KAAK;AAC1F;","names":[]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@evinvest/uikit",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.20.0",
|
|
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": {
|
|
@@ -17,10 +17,19 @@
|
|
|
17
17
|
"types": "./dist/index.d.ts",
|
|
18
18
|
"import": "./dist/index.js"
|
|
19
19
|
},
|
|
20
|
-
"./
|
|
20
|
+
"./palette": {
|
|
21
|
+
"types": "./dist/palette.d.ts",
|
|
22
|
+
"import": "./dist/palette.js"
|
|
23
|
+
},
|
|
24
|
+
"./styles/tokens.css": "./styles/tokens.css",
|
|
25
|
+
"./styles/theme.css": "./styles/theme.css",
|
|
26
|
+
"./styles/ev.css": "./styles/ev.css"
|
|
21
27
|
},
|
|
22
28
|
"types": "./dist/index.d.ts",
|
|
23
29
|
"main": "./dist/index.js",
|
|
30
|
+
"bin": {
|
|
31
|
+
"evinvest-palette": "./dist/palette-cli.js"
|
|
32
|
+
},
|
|
24
33
|
"files": [
|
|
25
34
|
"dist",
|
|
26
35
|
"styles"
|
|
@@ -32,10 +41,10 @@
|
|
|
32
41
|
"node": ">=20"
|
|
33
42
|
},
|
|
34
43
|
"scripts": {
|
|
35
|
-
"build": "tsup",
|
|
36
|
-
"test": "vitest run",
|
|
44
|
+
"build": "rm -rf dist && tsup && node scripts/emit-barrel.mjs && node scripts/fully-specify.mjs dist",
|
|
45
|
+
"test": "vitest run --project dom && NODE_OPTIONS=--conditions=react-server vitest run --project rsc",
|
|
37
46
|
"typecheck": "tsc --noEmit",
|
|
38
|
-
"prepare": "tsup",
|
|
47
|
+
"prepare": "rm -rf dist && tsup && node scripts/emit-barrel.mjs && node scripts/fully-specify.mjs dist",
|
|
39
48
|
"prepublishOnly": "node scripts/verify-pack.mjs"
|
|
40
49
|
},
|
|
41
50
|
"peerDependencies": {
|
|
@@ -55,6 +64,7 @@
|
|
|
55
64
|
"jsdom": "^25.0.1",
|
|
56
65
|
"react": "^19.2.1",
|
|
57
66
|
"react-dom": "^19.2.1",
|
|
67
|
+
"react-server-dom-webpack": "^19.2.7",
|
|
58
68
|
"tsup": "^8.3.5",
|
|
59
69
|
"typescript": "^5.7.2",
|
|
60
70
|
"vitest": "^2.1.8"
|
package/styles/ev.css
ADDED
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
/* AUTO-GENERATED by `nix run .#gen` from the repo-root ev.css — do not edit. */
|
|
2
|
+
/* ═══ PALETTE: EV ════════════════════════════════════════════════
|
|
3
|
+
*
|
|
4
|
+
* Zero specificity: EV is the default a brand scope overrides, whatever order
|
|
5
|
+
* the two sheets are imported in.
|
|
6
|
+
*
|
|
7
|
+
* Surface ladder — dark UI reads as unfinished when every plane is the same
|
|
8
|
+
* value, so the steps below are deliberate and measured; keep them apart if you
|
|
9
|
+
* retune. background #070d18 → secondary #0d1526 (1.07:1) → card #16233c (1.24:1
|
|
10
|
+
* vs background) → popover #1d2c49 (1.13:1 vs card) → muted #26375c. Elevation
|
|
11
|
+
* rides the same ladder via --shadow-card / -elevated / -overlay. Card is also
|
|
12
|
+
* pinned from above by a second floor: --primary has to clear 3:1 against it
|
|
13
|
+
* (3.39:1 today), so lifting card one step breaks the tokens test.
|
|
14
|
+
*/
|
|
15
|
+
:where(:root, [data-brand="ev"]) {
|
|
16
|
+
/* the polarity, for what the platform draws itself (a native <select>'s
|
|
17
|
+
* popup); a custom property so nothing but the kit's opt-ins reads it */
|
|
18
|
+
--scheme: dark;
|
|
19
|
+
|
|
20
|
+
/* ── surfaces ────────────────────────────────────────────────── */
|
|
21
|
+
--background: #070d18;
|
|
22
|
+
--card: #16233c;
|
|
23
|
+
--popover: #1d2c49;
|
|
24
|
+
--muted: #26375c;
|
|
25
|
+
|
|
26
|
+
/* ── ink ─────────────────────────────────────────────────────── */
|
|
27
|
+
--ink: #e6e1d3;
|
|
28
|
+
|
|
29
|
+
/* ── roles ───────────────────────────────────────────────────── */
|
|
30
|
+
--brand: #001e4e;
|
|
31
|
+
/* teal, not the brand navy: navy filled a Button/Switch at ~1.1:1 against
|
|
32
|
+
* these surfaces, i.e. an invisible control, and consumers hardcoded teal to
|
|
33
|
+
* get around it. The brand navy still lives in --brand.
|
|
34
|
+
*
|
|
35
|
+
* A fill and an ink are different jobs, so the primary role carries two
|
|
36
|
+
* values (docs/spec/accents.md). --primary-ink is the teal that reads on the
|
|
37
|
+
* surfaces: 5.85:1 on background, 4.72:1 on card. --primary is the same hue
|
|
38
|
+
* and chroma one step down in lightness — OKLCH L 0.550 C 0.094 H 183°
|
|
39
|
+
* against the ink's L 0.630 C 0.101 H 183° — so the CTA carries white:
|
|
40
|
+
* --on-primary reads on it at 4.63:1, and the fill clears the 3:1 non-text
|
|
41
|
+
* floor against background (4.20:1), secondary (3.94:1), card (3.39:1) and
|
|
42
|
+
* popover (3.01:1), so a checked Switch on a Card still reads as one. Muted
|
|
43
|
+
* is the one surface under the floor (2.54:1); the controls that fill there
|
|
44
|
+
* carry an on-primary mark, see the spec. Darkening the single value instead
|
|
45
|
+
* would have dropped every teal label below AA. */
|
|
46
|
+
--primary: #128377;
|
|
47
|
+
--on-primary: #ffffff;
|
|
48
|
+
--primary-ink: #2a9d8f;
|
|
49
|
+
--secondary: #0d1526;
|
|
50
|
+
--on-secondary: var(--ink);
|
|
51
|
+
/* valence, not significance: a success reads as good while staying quiet */
|
|
52
|
+
--positive: #2e9e5b;
|
|
53
|
+
--on-positive: #070d18;
|
|
54
|
+
--accent-trace: #6b7fa0;
|
|
55
|
+
--on-accent-trace: #070d18;
|
|
56
|
+
--accent-debug: #2a9d8f;
|
|
57
|
+
--on-accent-debug: #070d18;
|
|
58
|
+
--accent-info: #4a90d9;
|
|
59
|
+
--on-accent-info: #070d18;
|
|
60
|
+
--accent-warn: #f2c94c;
|
|
61
|
+
--on-accent-warn: #070d18;
|
|
62
|
+
/* lifted off the brand red #da251d, which failed AA on a card. This one value
|
|
63
|
+
* carries both the fill and the text; the vivid brand red is a gitops
|
|
64
|
+
* constant, not a UI token. */
|
|
65
|
+
--accent-error: #ef5b52;
|
|
66
|
+
--on-accent-error: #070d18;
|
|
67
|
+
|
|
68
|
+
--chart-1: #2a9d8f;
|
|
69
|
+
--chart-2: #2e9e5b;
|
|
70
|
+
--chart-3: #f2c94c;
|
|
71
|
+
--chart-4: #e58aae;
|
|
72
|
+
--chart-5: #4a90d9;
|
|
73
|
+
}
|