@cueplusplus/ui 0.1.0 → 0.3.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/CHANGELOG.md +705 -0
- package/dist/brand/_chassis.d.ts +54 -0
- package/dist/brand/_chassis.js +81 -0
- package/dist/brand/_geometry.js +41 -0
- package/dist/brand/cue-logotype.d.ts +29 -0
- package/dist/brand/cue-logotype.js +60 -0
- package/dist/brand/cue-mark.d.ts +30 -0
- package/dist/brand/cue-mark.js +61 -0
- package/dist/brand/index.d.ts +5 -0
- package/dist/brand/plussie.d.ts +67 -0
- package/dist/brand/plussie.js +125 -0
- package/dist/chat/agent-pile.js +1 -1
- package/dist/chat/ask-box.js +2 -2
- package/dist/chat/delegation-card.js +1 -1
- package/dist/chat/message.js +2 -2
- package/dist/chrome/_edge-scroller.d.ts +45 -0
- package/dist/chrome/_edge-scroller.js +149 -0
- package/dist/chrome/_glyphs.js +19 -1
- package/dist/chrome/_tabs-scroll.d.ts +13 -8
- package/dist/chrome/_tabs-scroll.js +13 -8
- package/dist/chrome/app-bar.d.ts +103 -0
- package/dist/chrome/app-bar.js +175 -0
- package/dist/chrome/app-shell.d.ts +125 -0
- package/dist/chrome/app-shell.js +167 -0
- package/dist/chrome/footer.d.ts +75 -0
- package/dist/chrome/footer.js +68 -0
- package/dist/chrome/index.d.ts +5 -1
- package/dist/chrome/index.js +4 -1
- package/dist/chrome/navigation-menu.js +1 -1
- package/dist/chrome/page-shell.d.ts +1 -1
- package/dist/chrome/page-shell.js +15 -5
- package/dist/chrome/segmented-control.d.ts +19 -0
- package/dist/chrome/segmented-control.js +40 -21
- package/dist/chrome/tabs.js +21 -65
- package/dist/chrome/toolbar.d.ts +22 -0
- package/dist/chrome/toolbar.js +26 -5
- package/dist/configurator/_overrides.js +22 -8
- package/dist/configurator/configurator.js +1 -1
- package/dist/configurator/panel-sections.js +10 -4
- package/dist/dmx/channel-matrix.js +1 -1
- package/dist/forms/otp-field.js +1 -1
- package/dist/index.d.ts +18 -9
- package/dist/index.js +16 -10
- package/dist/instruments/data-table.js +1 -1
- package/dist/instruments/index.d.ts +2 -2
- package/dist/instruments/index.js +2 -2
- package/dist/instruments/table.d.ts +14 -1
- package/dist/instruments/table.js +20 -1
- package/dist/layout/carousel.js +1 -1
- package/dist/layout/container.d.ts +1 -1
- package/dist/layout/container.js +6 -3
- package/dist/layout/index.d.ts +3 -3
- package/dist/layout/index.js +3 -3
- package/dist/layout/pagination.js +1 -1
- package/dist/layout/sidebar.d.ts +23 -3
- package/dist/layout/sidebar.js +18 -7
- package/dist/midi/spectrum-visualizer.js +1 -1
- package/dist/midi/timeline-ruler.js +1 -1
- package/dist/overlays/command-palette.js +1 -1
- package/dist/overlays/dialog.js +1 -1
- package/dist/overlays/dropdown-menu.js +2 -2
- package/dist/overlays/hover-card.js +1 -1
- package/dist/overlays/index.js +1 -1
- package/dist/overlays/popover.js +1 -1
- package/dist/overlays/sheet.js +1 -1
- package/dist/overlays/toast.js +1 -1
- package/dist/primitives/chip.d.ts +1 -1
- package/dist/primitives/index.d.ts +1 -1
- package/dist/primitives/index.js +1 -1
- package/dist/primitives/status-dot.d.ts +7 -0
- package/dist/primitives/status-dot.js +8 -1
- package/dist/styles.css +58 -2
- package/dist/system/density.d.ts +4 -1
- package/dist/system/density.js +12 -4
- package/dist/system/index.d.ts +4 -4
- package/dist/system/portal.d.ts +5 -5
- package/dist/system/portal.js +30 -11
- package/dist/system/prepaint.d.ts +34 -9
- package/dist/system/prepaint.js +48 -25
- package/dist/system/theme-provider.d.ts +48 -11
- package/dist/system/theme-provider.js +109 -35
- package/dist/system/use-density.d.ts +3 -3
- package/dist/system/use-density.js +16 -6
- package/dist/system/use-theme.d.ts +4 -2
- package/dist/system/use-theme.js +4 -2
- package/dist/theming/_presets.js +133 -5
- package/dist/theming/create-theme.d.ts +2 -2
- package/dist/theming/create-theme.js +37 -19
- package/dist/theming/serialize.d.ts +1 -1
- package/dist/theming/serialize.js +25 -1
- package/manifest/components/accordion.json +154 -0
- package/manifest/components/agent-pile.json +116 -0
- package/manifest/components/alert-dialog.json +190 -0
- package/manifest/components/app-bar.json +244 -0
- package/manifest/components/app-shell.json +291 -0
- package/manifest/components/app-window-frame.json +102 -0
- package/manifest/components/ask-box.json +209 -0
- package/manifest/components/autocomplete.json +197 -0
- package/manifest/components/avatar-group.json +72 -0
- package/manifest/components/avatar.json +95 -0
- package/manifest/components/breadcrumb.json +74 -0
- package/manifest/components/button-group.json +74 -0
- package/manifest/components/button.json +125 -0
- package/manifest/components/calendar.json +65 -0
- package/manifest/components/card.json +140 -0
- package/manifest/components/carousel.json +200 -0
- package/manifest/components/channel-matrix.json +173 -0
- package/manifest/components/chart-container.json +111 -0
- package/manifest/components/chart-ramp.json +72 -0
- package/manifest/components/chart-swatch.json +65 -0
- package/manifest/components/chart-tooltip-content.json +114 -0
- package/manifest/components/checkbox-group.json +68 -0
- package/manifest/components/checkbox.json +93 -0
- package/manifest/components/chip.json +132 -0
- package/manifest/components/collapsible.json +120 -0
- package/manifest/components/color-area.json +59 -0
- package/manifest/components/color-field.json +79 -0
- package/manifest/components/color-picker.json +175 -0
- package/manifest/components/color-slider.json +75 -0
- package/manifest/components/color-swatch.json +68 -0
- package/manifest/components/colors-section.json +66 -0
- package/manifest/components/combobox.json +198 -0
- package/manifest/components/command-palette.json +177 -0
- package/manifest/components/composer.json +176 -0
- package/manifest/components/container.json +60 -0
- package/manifest/components/context-menu.json +121 -0
- package/manifest/components/copy-button.json +93 -0
- package/manifest/components/cue-logotype.json +96 -0
- package/manifest/components/cue-mark.json +97 -0
- package/manifest/components/cue-portal-frame.json +55 -0
- package/manifest/components/data-table-pagination.json +83 -0
- package/manifest/components/data-table-toolbar.json +104 -0
- package/manifest/components/date-field.json +80 -0
- package/manifest/components/date-picker.json +191 -0
- package/manifest/components/date-range-picker.json +191 -0
- package/manifest/components/delegation-card.json +144 -0
- package/manifest/components/density.json +58 -0
- package/manifest/components/description-list.json +84 -0
- package/manifest/components/dialog.json +198 -0
- package/manifest/components/disclosure.json +109 -0
- package/manifest/components/dmx-bar.json +94 -0
- package/manifest/components/dmx-strip.json +101 -0
- package/manifest/components/drawer.json +179 -0
- package/manifest/components/dropdown-menu.json +229 -0
- package/manifest/components/empty-state.json +90 -0
- package/manifest/components/env-var-input.json +150 -0
- package/manifest/components/export-dialog.json +84 -0
- package/manifest/components/eyebrow.json +56 -0
- package/manifest/components/field-description.json +63 -0
- package/manifest/components/field-error.json +77 -0
- package/manifest/components/field-label.json +63 -0
- package/manifest/components/field.json +79 -0
- package/manifest/components/file-upload.json +159 -0
- package/manifest/components/flow-background.json +50 -0
- package/manifest/components/flow-controls.json +50 -0
- package/manifest/components/footer.json +112 -0
- package/manifest/components/grid.json +81 -0
- package/manifest/components/group-bar.json +102 -0
- package/manifest/components/hover-card.json +151 -0
- package/manifest/components/icon-button.json +88 -0
- package/manifest/components/info-tip.json +98 -0
- package/manifest/components/input-group.json +91 -0
- package/manifest/components/input.json +89 -0
- package/manifest/components/item.json +129 -0
- package/manifest/components/kbd.json +52 -0
- package/manifest/components/link.json +81 -0
- package/manifest/components/log-viewer.json +139 -0
- package/manifest/components/menubar.json +157 -0
- package/manifest/components/message-list.json +100 -0
- package/manifest/components/message.json +116 -0
- package/manifest/components/meter.json +114 -0
- package/manifest/components/multi-select.json +190 -0
- package/manifest/components/musical-time-input.json +113 -0
- package/manifest/components/navigation-menu.json +226 -0
- package/manifest/components/node-card.json +109 -0
- package/manifest/components/node-handle.json +69 -0
- package/manifest/components/number-field.json +107 -0
- package/manifest/components/otp-field.json +128 -0
- package/manifest/components/page-shell.json +96 -0
- package/manifest/components/pagination.json +92 -0
- package/manifest/components/panel-header.json +77 -0
- package/manifest/components/panel.json +71 -0
- package/manifest/components/password-input.json +119 -0
- package/manifest/components/piano-keyboard.json +120 -0
- package/manifest/components/plussie.json +111 -0
- package/manifest/components/popover.json +193 -0
- package/manifest/components/preset-section.json +73 -0
- package/manifest/components/progress.json +95 -0
- package/manifest/components/radio-group.json +73 -0
- package/manifest/components/radio.json +80 -0
- package/manifest/components/rating.json +141 -0
- package/manifest/components/resizable.json +88 -0
- package/manifest/components/row.json +109 -0
- package/manifest/components/scroll-area.json +91 -0
- package/manifest/components/scrollable-tabs-list.json +83 -0
- package/manifest/components/scrub-input.json +200 -0
- package/manifest/components/seam-cell.json +75 -0
- package/manifest/components/seam-grid.json +75 -0
- package/manifest/components/seam-list.json +56 -0
- package/manifest/components/search-input.json +134 -0
- package/manifest/components/section-header.json +112 -0
- package/manifest/components/segmented-control.json +138 -0
- package/manifest/components/select.json +194 -0
- package/manifest/components/separator.json +53 -0
- package/manifest/components/shape-section.json +66 -0
- package/manifest/components/sheet.json +186 -0
- package/manifest/components/sidebar.json +198 -0
- package/manifest/components/signal-edge.json +56 -0
- package/manifest/components/skeleton.json +46 -0
- package/manifest/components/slider.json +89 -0
- package/manifest/components/sparkline.json +76 -0
- package/manifest/components/spectrum-visualizer.json +115 -0
- package/manifest/components/spinner.json +61 -0
- package/manifest/components/stack.json +96 -0
- package/manifest/components/stat.json +87 -0
- package/manifest/components/status-bar.json +58 -0
- package/manifest/components/status-dot.json +78 -0
- package/manifest/components/stepper.json +89 -0
- package/manifest/components/switch.json +87 -0
- package/manifest/components/table-scroll-region.json +69 -0
- package/manifest/components/table.json +155 -0
- package/manifest/components/tabs.json +145 -0
- package/manifest/components/tags-input.json +190 -0
- package/manifest/components/terminal-frame.json +119 -0
- package/manifest/components/textarea.json +76 -0
- package/manifest/components/theme-configurator.json +124 -0
- package/manifest/components/theme-provider.json +134 -0
- package/manifest/components/threshold-rail.json +160 -0
- package/manifest/components/time-field.json +80 -0
- package/manifest/components/timeline-ruler.json +139 -0
- package/manifest/components/timeline.json +115 -0
- package/manifest/components/title-bar.json +82 -0
- package/manifest/components/toast.json +130 -0
- package/manifest/components/toggle-group.json +106 -0
- package/manifest/components/toggle.json +109 -0
- package/manifest/components/token-editor.json +90 -0
- package/manifest/components/toolbar.json +163 -0
- package/manifest/components/tooltip.json +164 -0
- package/manifest/components/tree-visibility-toggle.json +84 -0
- package/manifest/components/tree.json +140 -0
- package/manifest/components/two-step-button.json +113 -0
- package/manifest/components/universe-grid.json +127 -0
- package/manifest/components/usage-chart.json +124 -0
- package/manifest/manifest.json +2142 -0
- package/manifest/tokens.json +138 -0
- package/package.json +13 -5
package/dist/layout/sidebar.d.ts
CHANGED
|
@@ -7,7 +7,27 @@ interface SidebarContextValue {
|
|
|
7
7
|
}
|
|
8
8
|
/** Read the collapse state of the nearest {@link SidebarRoot}. */
|
|
9
9
|
declare function useSidebar(): SidebarContextValue;
|
|
10
|
+
/**
|
|
11
|
+
* Which landmark a navigation column announces as.
|
|
12
|
+
*
|
|
13
|
+
* `"navigation"` renders `<nav>`, `"complementary"` renders `<aside>`. Two
|
|
14
|
+
* values rather than a free `role`, because those are the only two a column of
|
|
15
|
+
* destinations can honestly be — and naming the landmark keeps the element and
|
|
16
|
+
* the role from ever disagreeing.
|
|
17
|
+
*/
|
|
18
|
+
type SidebarLandmark = "navigation" | "complementary";
|
|
10
19
|
interface SidebarRootProps extends React.ComponentPropsWithoutRef<"aside"> {
|
|
20
|
+
/**
|
|
21
|
+
* Which landmark the column is. Defaults to `"navigation"`, rendering
|
|
22
|
+
* `<nav>`; `"complementary"` renders `<aside>` instead.
|
|
23
|
+
*
|
|
24
|
+
* A column of `Sidebar.Item`s is a list of destinations, one of which carries
|
|
25
|
+
* `aria-current="page"` — that is primary navigation, and announcing it as
|
|
26
|
+
* complementary tells a screen-reader user the site's main map is an aside.
|
|
27
|
+
* `"complementary"` is there for the column that genuinely is one: a filter
|
|
28
|
+
* rail, an inspector, a related-links strip.
|
|
29
|
+
*/
|
|
30
|
+
landmark?: SidebarLandmark;
|
|
11
31
|
/** Collapsed state when controlled. Pass with `onCollapsedChange`. */
|
|
12
32
|
collapsed?: boolean;
|
|
13
33
|
/** Initial collapsed state when uncontrolled. Defaults to `false`. */
|
|
@@ -46,8 +66,8 @@ interface SidebarRailProps extends Omit<React.ComponentPropsWithoutRef<"button">
|
|
|
46
66
|
expandLabel?: string;
|
|
47
67
|
}
|
|
48
68
|
/**
|
|
49
|
-
* The console's navigation column: sections of items,
|
|
50
|
-
* the whole thing to icons.
|
|
69
|
+
* The console's navigation column: sections of items, a scroller of its own,
|
|
70
|
+
* and a rail that collapses the whole thing to icons.
|
|
51
71
|
*
|
|
52
72
|
* @example
|
|
53
73
|
* <Sidebar.Root defaultCollapsed aria-label="Main">
|
|
@@ -64,4 +84,4 @@ declare const Sidebar: {
|
|
|
64
84
|
Rail: React.ForwardRefExoticComponent<SidebarRailProps & React.RefAttributes<HTMLButtonElement>>;
|
|
65
85
|
};
|
|
66
86
|
//#endregion
|
|
67
|
-
export { Sidebar, SidebarItemProps, SidebarRailProps, SidebarRootProps, SidebarSectionProps, useSidebar };
|
|
87
|
+
export { Sidebar, SidebarItemProps, SidebarLandmark, SidebarRailProps, SidebarRootProps, SidebarSectionProps, useSidebar };
|
package/dist/layout/sidebar.js
CHANGED
|
@@ -19,9 +19,14 @@ const SidebarContext = React.createContext({
|
|
|
19
19
|
function useSidebar() {
|
|
20
20
|
return React.useContext(SidebarContext);
|
|
21
21
|
}
|
|
22
|
+
/** The element each landmark is spelled with. */
|
|
23
|
+
const LANDMARK_ELEMENTS = {
|
|
24
|
+
navigation: "nav",
|
|
25
|
+
complementary: "aside"
|
|
26
|
+
};
|
|
22
27
|
/**
|
|
23
|
-
* The console's navigation column: sections of items,
|
|
24
|
-
* the whole thing to icons.
|
|
28
|
+
* The console's navigation column: sections of items, a scroller of its own,
|
|
29
|
+
* and a rail that collapses the whole thing to icons.
|
|
25
30
|
*
|
|
26
31
|
* @example
|
|
27
32
|
* <Sidebar.Root defaultCollapsed aria-label="Main">
|
|
@@ -32,7 +37,8 @@ function useSidebar() {
|
|
|
32
37
|
* </Sidebar.Root>
|
|
33
38
|
*/
|
|
34
39
|
const Sidebar = {
|
|
35
|
-
Root: React.forwardRef(function SidebarRoot({ className, collapsed: collapsedProp, defaultCollapsed = false, onCollapsedChange, width = "14rem", collapsedWidth = "3rem", style, ...elementProps }, ref) {
|
|
40
|
+
Root: React.forwardRef(function SidebarRoot({ className, landmark = "navigation", collapsed: collapsedProp, defaultCollapsed = false, onCollapsedChange, width = "14rem", collapsedWidth = "3rem", style, children, ...elementProps }, ref) {
|
|
41
|
+
const Element = LANDMARK_ELEMENTS[landmark];
|
|
36
42
|
const [uncontrolled, setUncontrolled] = React.useState(defaultCollapsed);
|
|
37
43
|
const collapsed = collapsedProp ?? uncontrolled;
|
|
38
44
|
const toggle = React.useCallback(() => {
|
|
@@ -50,16 +56,21 @@ const Sidebar = {
|
|
|
50
56
|
}), [collapsed, toggle]);
|
|
51
57
|
return /* @__PURE__ */ jsx(SidebarContext.Provider, {
|
|
52
58
|
value: context,
|
|
53
|
-
children: /* @__PURE__ */ jsx(
|
|
59
|
+
children: /* @__PURE__ */ jsx(Element, {
|
|
54
60
|
ref,
|
|
55
61
|
"data-slot": "sidebar",
|
|
56
62
|
"data-collapsed": collapsed ? "" : void 0,
|
|
57
|
-
className: cn("group/sidebar relative flex h-full shrink-0 flex-col
|
|
63
|
+
className: cn("group/sidebar relative flex h-full min-h-0 shrink-0 flex-col border-r border-border bg-surface-1 transition-[width] duration-150 ease-out motion-reduce:transition-none", className),
|
|
58
64
|
style: {
|
|
59
65
|
width: collapsed ? collapsedWidth : width,
|
|
60
66
|
...style
|
|
61
67
|
},
|
|
62
|
-
...elementProps
|
|
68
|
+
...elementProps,
|
|
69
|
+
children: /* @__PURE__ */ jsx("div", {
|
|
70
|
+
"data-slot": "sidebar-scroller",
|
|
71
|
+
className: "flex min-h-0 flex-1 flex-col gap-(--cue-space-4) overflow-y-auto py-(--cue-space-4)",
|
|
72
|
+
children
|
|
73
|
+
})
|
|
63
74
|
})
|
|
64
75
|
});
|
|
65
76
|
}),
|
|
@@ -88,7 +99,7 @@ const Sidebar = {
|
|
|
88
99
|
"data-slot": "sidebar-item",
|
|
89
100
|
"data-active": active ? "" : void 0,
|
|
90
101
|
"aria-current": active ? "page" : void 0,
|
|
91
|
-
className: cn("flex h-control-md w-full cursor-pointer items-center gap-(--cue-space-3) rounded-(--radius-control) border-0 bg-transparent px-(--cue-space-3) text-left font-mono text-(length:--cue-text-ui) text-fg-muted no-underline transition-colors duration-150 outline-none select-none hover:bg-surface-2 hover:text-fg focus-visible:outline-2 focus-visible:outline-solid focus-visible:-outline-offset-1 focus-visible:outline-accent data-[active]:bg-accent-soft data-[active]:text-accent disabled:pointer-events-none disabled:opacity-40", className),
|
|
102
|
+
className: cn("relative flex h-control-md w-full cursor-pointer items-center gap-(--cue-space-3) rounded-(--radius-control) border-0 bg-transparent px-(--cue-space-3) text-left font-mono text-(length:--cue-text-ui) text-fg-muted no-underline transition-colors duration-150 outline-none select-none hover:bg-surface-2 hover:text-fg focus-visible:outline-2 focus-visible:outline-solid focus-visible:-outline-offset-1 focus-visible:outline-accent data-[active]:bg-accent-soft data-[active]:text-accent disabled:pointer-events-none disabled:opacity-40", className),
|
|
92
103
|
children: /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
93
104
|
Icon === void 0 ? null : /* @__PURE__ */ jsx(Icon, {
|
|
94
105
|
"aria-hidden": "true",
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
import { cn } from "../lib/cn.js";
|
|
3
3
|
import { useIsomorphicLayoutEffect } from "../system/use-isomorphic-layout-effect.js";
|
|
4
|
-
import { toRem } from "../instruments/_rem.js";
|
|
5
4
|
import { useComposedRefs } from "../lib/compose.js";
|
|
5
|
+
import { toRem } from "../instruments/_rem.js";
|
|
6
6
|
import { resolveToken } from "../charts/_token.js";
|
|
7
7
|
import { RAMPS } from "../charts/ramps.js";
|
|
8
8
|
import * as React from "react";
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
import { cn } from "../lib/cn.js";
|
|
3
|
-
import { toRem } from "../instruments/_rem.js";
|
|
4
3
|
import { useComposedRefs } from "../lib/compose.js";
|
|
4
|
+
import { toRem } from "../instruments/_rem.js";
|
|
5
5
|
import { DEFAULT_TIME_SIGNATURE, barBeats, beatsToMusical, formatMusicalTime } from "./_time.js";
|
|
6
6
|
import { rulerTicks } from "./_ruler.js";
|
|
7
7
|
import * as React from "react";
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
import { cn } from "../lib/cn.js";
|
|
3
|
+
import { SearchGlyph } from "./_glyphs.js";
|
|
3
4
|
import { useCuePortalProps } from "../system/portal.js";
|
|
4
5
|
import { overlayModalTransitionClasses, overlaySurfaceClasses, scrimClasses } from "./_surface.js";
|
|
5
6
|
import { useDebouncedValue } from "./_debounce.js";
|
|
6
|
-
import { SearchGlyph } from "./_glyphs.js";
|
|
7
7
|
import * as React from "react";
|
|
8
8
|
import { Fragment, jsx, jsxs } from "react/jsx-runtime";
|
|
9
9
|
import { Combobox } from "@base-ui/react/combobox";
|
package/dist/overlays/dialog.js
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
import { cn } from "../lib/cn.js";
|
|
3
3
|
import { cva } from "../lib/cva.js";
|
|
4
|
+
import { CrossGlyph } from "./_glyphs.js";
|
|
4
5
|
import { useCuePortalProps } from "../system/portal.js";
|
|
5
6
|
import { overlayDescriptionClasses, overlayFooterClasses, overlayModalTransitionClasses, overlaySurfaceClasses, overlayTitleClasses, scrimClasses } from "./_surface.js";
|
|
6
7
|
import { IconButton } from "../primitives/icon-button.js";
|
|
7
|
-
import { CrossGlyph } from "./_glyphs.js";
|
|
8
8
|
import * as React from "react";
|
|
9
9
|
import { jsx, jsxs } from "react/jsx-runtime";
|
|
10
10
|
import { Dialog } from "@base-ui/react/dialog";
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
import { cn } from "../lib/cn.js";
|
|
3
|
+
import { useComposedRefs } from "../lib/compose.js";
|
|
4
|
+
import { TickGlyph } from "./_glyphs.js";
|
|
3
5
|
import { useCuePortalProps } from "../system/portal.js";
|
|
4
6
|
import { menuItemClasses, menuLabelClasses, menuPopupClasses, menuSeparatorClasses, overlayPopupTransitionClasses, overlayPositionerClasses, overlaySurfaceClasses } from "./_surface.js";
|
|
5
|
-
import { TickGlyph } from "./_glyphs.js";
|
|
6
|
-
import { useComposedRefs } from "../lib/compose.js";
|
|
7
7
|
import { useCloseOnWheel } from "./_wheel.js";
|
|
8
8
|
import * as React from "react";
|
|
9
9
|
import { jsx, jsxs } from "react/jsx-runtime";
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
import { cn } from "../lib/cn.js";
|
|
3
|
+
import { useComposedRefs } from "../lib/compose.js";
|
|
3
4
|
import { useCuePortalProps } from "../system/portal.js";
|
|
4
5
|
import { overlayPopupTransitionClasses, overlayPositionerClasses, overlaySurfaceClasses } from "./_surface.js";
|
|
5
|
-
import { useComposedRefs } from "../lib/compose.js";
|
|
6
6
|
import { useCloseOnWheel } from "./_wheel.js";
|
|
7
7
|
import * as React from "react";
|
|
8
8
|
import { jsx } from "react/jsx-runtime";
|
package/dist/overlays/index.js
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import { OVERLAY_SIDE_OFFSET, menuItemClasses, menuLabelClasses, menuPopupClasses, menuSeparatorClasses, overlayDescriptionClasses, overlayFooterClasses, overlayModalTransitionClasses, overlayPopupTransitionClasses, overlayPositionerClasses, overlaySurfaceClasses, overlayTextClasses, overlayTitleClasses, scrimClasses } from "./_surface.js";
|
|
2
|
+
import { Drawer } from "./drawer.js";
|
|
2
3
|
import { AlertDialog } from "./alert-dialog.js";
|
|
3
4
|
import { CommandPalette } from "./command-palette.js";
|
|
4
5
|
import { DropdownMenu } from "./dropdown-menu.js";
|
|
5
6
|
import { ContextMenu } from "./context-menu.js";
|
|
6
7
|
import { Dialog } from "./dialog.js";
|
|
7
|
-
import { Drawer } from "./drawer.js";
|
|
8
8
|
import { HoverCard } from "./hover-card.js";
|
|
9
9
|
import { Tooltip } from "./tooltip.js";
|
|
10
10
|
import { InfoTip } from "./info-tip.js";
|
package/dist/overlays/popover.js
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
import { cn } from "../lib/cn.js";
|
|
3
|
+
import { useComposedRefs } from "../lib/compose.js";
|
|
3
4
|
import { useCuePortalProps } from "../system/portal.js";
|
|
4
5
|
import { overlayDescriptionClasses, overlayPopupTransitionClasses, overlayPositionerClasses, overlaySurfaceClasses, overlayTitleClasses } from "./_surface.js";
|
|
5
|
-
import { useComposedRefs } from "../lib/compose.js";
|
|
6
6
|
import { useCloseOnWheel } from "./_wheel.js";
|
|
7
7
|
import * as React from "react";
|
|
8
8
|
import { jsx } from "react/jsx-runtime";
|
package/dist/overlays/sheet.js
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
import { cn } from "../lib/cn.js";
|
|
3
3
|
import { cva } from "../lib/cva.js";
|
|
4
|
+
import { CrossGlyph } from "./_glyphs.js";
|
|
4
5
|
import { useCuePortalProps } from "../system/portal.js";
|
|
5
6
|
import { overlayDescriptionClasses, overlayFooterClasses, overlaySurfaceClasses, overlayTitleClasses, scrimClasses } from "./_surface.js";
|
|
6
7
|
import { IconButton } from "../primitives/icon-button.js";
|
|
7
|
-
import { CrossGlyph } from "./_glyphs.js";
|
|
8
8
|
import * as React from "react";
|
|
9
9
|
import { jsx, jsxs } from "react/jsx-runtime";
|
|
10
10
|
import { Dialog } from "@base-ui/react/dialog";
|
package/dist/overlays/toast.js
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
import { cn } from "../lib/cn.js";
|
|
3
|
+
import { CrossGlyph } from "./_glyphs.js";
|
|
3
4
|
import { useCuePortalProps } from "../system/portal.js";
|
|
4
5
|
import { overlaySurfaceClasses } from "./_surface.js";
|
|
5
|
-
import { CrossGlyph } from "./_glyphs.js";
|
|
6
6
|
import * as React from "react";
|
|
7
7
|
import { jsx, jsxs } from "react/jsx-runtime";
|
|
8
8
|
import { Toast } from "@base-ui/react/toast";
|
|
@@ -15,7 +15,7 @@ import * as React from "react";
|
|
|
15
15
|
* <span className={chipVariants({ tone: "danger", variant: "outline" })}>fault</span>
|
|
16
16
|
*/
|
|
17
17
|
declare const chipVariants: (props?: ({
|
|
18
|
-
tone?: "
|
|
18
|
+
tone?: "info" | "warn" | "danger" | "accent" | "ok" | "busy" | "neutral" | null | undefined;
|
|
19
19
|
variant?: "outline" | "tinted" | null | undefined;
|
|
20
20
|
interactive?: boolean | null | undefined;
|
|
21
21
|
} & ClassProp) | undefined) => string;
|
|
@@ -1,10 +1,10 @@
|
|
|
1
|
+
import { Separator, SeparatorProps } from "./separator.js";
|
|
1
2
|
import { Button, ButtonProps, buttonVariants } from "./button.js";
|
|
2
3
|
import { StatusDot, StatusDotProps, StatusTone } from "./status-dot.js";
|
|
3
4
|
import { Avatar, AvatarGroup, AvatarGroupProps, AvatarProps, AvatarSize } from "./avatar.js";
|
|
4
5
|
import { Chip, ChipProps, chipVariants } from "./chip.js";
|
|
5
6
|
import { IconButton, IconButtonProps } from "./icon-button.js";
|
|
6
7
|
import { Kbd, KbdProps } from "./kbd.js";
|
|
7
|
-
import { Separator, SeparatorProps } from "./separator.js";
|
|
8
8
|
import { Skeleton, SkeletonProps } from "./skeleton.js";
|
|
9
9
|
import { Spinner, SpinnerProps } from "./spinner.js";
|
|
10
10
|
export { Avatar, AvatarGroup, type AvatarGroupProps, type AvatarProps, type AvatarSize, Button, type ButtonProps, Chip, type ChipProps, IconButton, type IconButtonProps, Kbd, type KbdProps, Separator, type SeparatorProps, Skeleton, type SkeletonProps, Spinner, type SpinnerProps, StatusDot, type StatusDotProps, type StatusTone, buttonVariants, chipVariants };
|
package/dist/primitives/index.js
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import { Button, buttonVariants } from "./button.js";
|
|
2
2
|
import { Chip, chipVariants } from "./chip.js";
|
|
3
3
|
import { Spinner } from "./spinner.js";
|
|
4
|
+
import { Separator } from "./separator.js";
|
|
4
5
|
import { IconButton } from "./icon-button.js";
|
|
5
6
|
import { StatusDot } from "./status-dot.js";
|
|
6
7
|
import { Avatar, AvatarGroup } from "./avatar.js";
|
|
7
8
|
import { Kbd } from "./kbd.js";
|
|
8
|
-
import { Separator } from "./separator.js";
|
|
9
9
|
import { Skeleton } from "./skeleton.js";
|
|
10
10
|
export { Avatar, AvatarGroup, Button, Chip, IconButton, Kbd, Separator, Skeleton, Spinner, StatusDot, buttonVariants, chipVariants };
|
|
@@ -32,6 +32,13 @@ interface StatusDotProps extends Omit<React.ComponentPropsWithoutRef<"span">, "c
|
|
|
32
32
|
* component always emits an `sr-only` label inside a `role="status"` wrapper,
|
|
33
33
|
* so the state is announced as well as shown (WCAG 1.4.1).
|
|
34
34
|
*
|
|
35
|
+
* The wrapper is `relative` for that label's sake and no other reason.
|
|
36
|
+
* `.sr-only` is `position: absolute`; without a positioned ancestor its
|
|
37
|
+
* containing block is the initial one, so its scrollable overflow lands on
|
|
38
|
+
* `<html>` rather than on whatever scroller it is nested in. One dot is
|
|
39
|
+
* harmless and a table of two thousand rows is a document several thousand
|
|
40
|
+
* pixels taller than anything visible on it.
|
|
41
|
+
*
|
|
35
42
|
* Static markup — no `"use client"`.
|
|
36
43
|
*
|
|
37
44
|
* @example
|
|
@@ -20,6 +20,13 @@ const toRem = (px) => `${px / 16}rem`;
|
|
|
20
20
|
* component always emits an `sr-only` label inside a `role="status"` wrapper,
|
|
21
21
|
* so the state is announced as well as shown (WCAG 1.4.1).
|
|
22
22
|
*
|
|
23
|
+
* The wrapper is `relative` for that label's sake and no other reason.
|
|
24
|
+
* `.sr-only` is `position: absolute`; without a positioned ancestor its
|
|
25
|
+
* containing block is the initial one, so its scrollable overflow lands on
|
|
26
|
+
* `<html>` rather than on whatever scroller it is nested in. One dot is
|
|
27
|
+
* harmless and a table of two thousand rows is a document several thousand
|
|
28
|
+
* pixels taller than anything visible on it.
|
|
29
|
+
*
|
|
23
30
|
* Static markup — no `"use client"`.
|
|
24
31
|
*
|
|
25
32
|
* @example
|
|
@@ -31,7 +38,7 @@ const StatusDot = React.forwardRef(function StatusDot({ className, tone, pulse =
|
|
|
31
38
|
return /* @__PURE__ */ jsxs("span", {
|
|
32
39
|
ref,
|
|
33
40
|
role: "status",
|
|
34
|
-
className: cn("inline-flex shrink-0 items-center justify-center", className),
|
|
41
|
+
className: cn("relative inline-flex shrink-0 items-center justify-center", className),
|
|
35
42
|
...elementProps,
|
|
36
43
|
children: [/* @__PURE__ */ jsx("span", {
|
|
37
44
|
"aria-hidden": "true",
|
package/dist/styles.css
CHANGED
|
@@ -14,6 +14,62 @@
|
|
|
14
14
|
|
|
15
15
|
@source "./";
|
|
16
16
|
|
|
17
|
-
|
|
17
|
+
/* One variant per rung of the density ladder, each named after the rung it
|
|
18
|
+
* matches — so `density-large:` means the level a consumer writes as
|
|
19
|
+
* `density="large"`, and cannot drift from it.
|
|
20
|
+
*
|
|
21
|
+
* `density-ultra:` is gone with the five-rung rename of 2026-08-19: with an
|
|
22
|
+
* `ultra-large` rung in the ladder, "ultra" no longer names one level. Its
|
|
23
|
+
* replacement is `density-ultra-compact:`. `density-large:` survives the rename
|
|
24
|
+
* as a name and changes meaning with it — it matched the ladder's top rung
|
|
25
|
+
* before, and the ladder now has two rungs above that one. */
|
|
26
|
+
@custom-variant density-ultra-compact (&:where([data-density="ultra-compact"], [data-density="ultra-compact"] *));
|
|
27
|
+
@custom-variant density-compact (&:where([data-density="compact"], [data-density="compact"] *));
|
|
28
|
+
@custom-variant density-normal (&:where([data-density="normal"], [data-density="normal"] *));
|
|
18
29
|
@custom-variant density-large (&:where([data-density="large"], [data-density="large"] *));
|
|
19
|
-
@custom-variant
|
|
30
|
+
@custom-variant density-ultra-large (&:where([data-density="ultra-large"], [data-density="ultra-large"] *));
|
|
31
|
+
@custom-variant mode-light {
|
|
32
|
+
&:where([data-mode="light"], [data-mode="light"] *) {
|
|
33
|
+
@slot;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
@media (prefers-color-scheme: light) {
|
|
37
|
+
&:where([data-mode="system"], [data-mode="system"] *) {
|
|
38
|
+
@slot;
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
/* The one keyframe this library's core needs, and the reason it cannot be a
|
|
44
|
+
* utility: `<Plussie idle />` blinks, and Tailwind has no `animate-*` for a
|
|
45
|
+
* two-frame squash about an SVG group's own centre.
|
|
46
|
+
*
|
|
47
|
+
* Same shape as the pulse in `flow.css`: a bespoke class, the keyframes beside
|
|
48
|
+
* it, and a `prefers-reduced-motion` block that switches it off. `fill-box`
|
|
49
|
+
* puts the transform origin at the eye's own centre rather than the SVG's
|
|
50
|
+
* corner, which is what makes the eye shut across its middle instead of sliding
|
|
51
|
+
* up. The class does nothing unless the prop asks for it — every other Plussie
|
|
52
|
+
* on the page is still. */
|
|
53
|
+
@keyframes cue-plussie-blink {
|
|
54
|
+
0%,
|
|
55
|
+
93%,
|
|
56
|
+
100% {
|
|
57
|
+
transform: scaleY(1);
|
|
58
|
+
}
|
|
59
|
+
95.5%,
|
|
60
|
+
96.5% {
|
|
61
|
+
transform: scaleY(0.05);
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
.cue-plussie-idle {
|
|
66
|
+
transform-box: fill-box;
|
|
67
|
+
transform-origin: center;
|
|
68
|
+
animation: cue-plussie-blink 5.2s ease-in-out infinite;
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
@media (prefers-reduced-motion: reduce) {
|
|
72
|
+
.cue-plussie-idle {
|
|
73
|
+
animation: none;
|
|
74
|
+
}
|
|
75
|
+
}
|
package/dist/system/density.d.ts
CHANGED
|
@@ -2,7 +2,10 @@ import * as React from "react";
|
|
|
2
2
|
import { Density } from "@cueplusplus/tokens";
|
|
3
3
|
//#region src/system/density.d.ts
|
|
4
4
|
interface DensityProps {
|
|
5
|
-
/**
|
|
5
|
+
/**
|
|
6
|
+
* Level to apply to this subtree: `ultra-compact`, `compact`, `normal`,
|
|
7
|
+
* `large` or `ultra-large`.
|
|
8
|
+
*/
|
|
6
9
|
density: Density;
|
|
7
10
|
/** Subtree that should render at `density`. */
|
|
8
11
|
children: React.ReactNode;
|
package/dist/system/density.js
CHANGED
|
@@ -2,13 +2,21 @@
|
|
|
2
2
|
import * as React from "react";
|
|
3
3
|
import { jsx } from "react/jsx-runtime";
|
|
4
4
|
//#region src/system/density.tsx
|
|
5
|
-
/**
|
|
6
|
-
|
|
7
|
-
|
|
5
|
+
/**
|
|
6
|
+
* Density level every unstamped subtree falls back to.
|
|
7
|
+
*
|
|
8
|
+
* `compact`, which is the second rung and not the middle one. This is console
|
|
9
|
+
* software: the ladder is symmetric about `normal` for the sake of its names,
|
|
10
|
+
* but the level a screen gets when nobody chose is the dense one.
|
|
11
|
+
*/
|
|
12
|
+
const DEFAULT_DENSITY = "compact";
|
|
13
|
+
/** The five levels, as a runtime array for validating persisted input. */
|
|
8
14
|
const DENSITY_LEVELS = [
|
|
9
15
|
"ultra-compact",
|
|
16
|
+
"compact",
|
|
10
17
|
"normal",
|
|
11
|
-
"large"
|
|
18
|
+
"large",
|
|
19
|
+
"ultra-large"
|
|
12
20
|
];
|
|
13
21
|
/**
|
|
14
22
|
* Nearest ambient density. `null` means "nothing has stamped a level yet", which
|
package/dist/system/index.d.ts
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import { ResolvedMode, ThemeContextValue, ThemeProvider, ThemeProviderProps } from "./theme-provider.js";
|
|
1
|
+
import { FontFamilies, ResolvedMode, ThemeContextValue, ThemeProvider, ThemeProviderProps } from "./theme-provider.js";
|
|
2
2
|
import { Density, DensityProps } from "./density.js";
|
|
3
3
|
import { CuePortalFrame, CuePortalFrameProps, useCuePortalProps } from "./portal.js";
|
|
4
|
-
import { DEFAULT_STORAGE_KEY, PersistedPreferences, prepaintScript } from "./prepaint.js";
|
|
4
|
+
import { DEFAULT_STORAGE_KEY, PersistedPreferences, PrepaintDefaults, PrepaintOptions, prepaintScript } from "./prepaint.js";
|
|
5
5
|
import { ControlSize, useControlHeight, useDensity } from "./use-density.js";
|
|
6
6
|
import { useTheme } from "./use-theme.js";
|
|
7
|
-
import { Density as DensityLevel, Mode, ThemeName } from "@cueplusplus/tokens";
|
|
8
|
-
export { type ControlSize, CuePortalFrame, type CuePortalFrameProps, DEFAULT_STORAGE_KEY, Density, type DensityLevel, type DensityProps, type Mode, type PersistedPreferences, type ResolvedMode, type ThemeContextValue, type ThemeName, ThemeProvider, type ThemeProviderProps, prepaintScript, useControlHeight, useCuePortalProps, useDensity, useTheme };
|
|
7
|
+
import { Density as DensityLevel, FontName, Mode, ThemeName } from "@cueplusplus/tokens";
|
|
8
|
+
export { type ControlSize, CuePortalFrame, type CuePortalFrameProps, DEFAULT_STORAGE_KEY, Density, type DensityLevel, type DensityProps, type FontFamilies, type FontName, type Mode, type PersistedPreferences, type PrepaintDefaults, type PrepaintOptions, type ResolvedMode, type ThemeContextValue, type ThemeName, ThemeProvider, type ThemeProviderProps, prepaintScript, useControlHeight, useCuePortalProps, useDensity, useTheme };
|
package/dist/system/portal.d.ts
CHANGED
|
@@ -2,11 +2,11 @@ import * as React from "react";
|
|
|
2
2
|
//#region src/system/portal.d.ts
|
|
3
3
|
/**
|
|
4
4
|
* Props to spread onto a Base UI `Portal` part so the portal root inherits the
|
|
5
|
-
* caller's theme, density and mode.
|
|
5
|
+
* caller's theme, density, font pairing and mode.
|
|
6
6
|
*
|
|
7
7
|
* Returns a `container` element appended to `document.body` and stamped with
|
|
8
|
-
* `data-theme` / `data-density` / `data-
|
|
9
|
-
* from the nearest provider and density island. The container is
|
|
8
|
+
* `data-theme` / `data-density` / `data-font` / `data-mode` (plus
|
|
9
|
+
* `--cue-font-scale`) copied from the nearest provider and density island. The container is
|
|
10
10
|
* `display: contents`, so it changes no layout and creates no containing block —
|
|
11
11
|
* fixed-position overlay content behaves exactly as if it were a direct child of
|
|
12
12
|
* `<body>`.
|
|
@@ -38,8 +38,8 @@ interface CuePortalFrameProps {
|
|
|
38
38
|
* chosen (a third-party overlay, or content already portaled by something else).
|
|
39
39
|
*
|
|
40
40
|
* Wraps `children` in a `display: contents` element carrying the same
|
|
41
|
-
* `data-theme` / `data-density` / `data-
|
|
42
|
-
* {@link useCuePortalProps}. Prefer the hook — a stamped container costs one
|
|
41
|
+
* `data-theme` / `data-density` / `data-font` / `data-mode` stamp and
|
|
42
|
+
* `--cue-font-scale` as {@link useCuePortalProps}. Prefer the hook — a stamped container costs one
|
|
43
43
|
* element per overlay instead of one per render tree — and reach for this only
|
|
44
44
|
* when the container prop is not available.
|
|
45
45
|
*
|
package/dist/system/portal.js
CHANGED
|
@@ -1,14 +1,17 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
import { useIsomorphicLayoutEffect } from "./use-isomorphic-layout-effect.js";
|
|
3
3
|
import { DensityContext } from "./density.js";
|
|
4
|
-
import { FontScaleContext, ThemeContext } from "./theme-provider.js";
|
|
4
|
+
import { FontFamiliesContext, FontScaleContext, ThemeContext } from "./theme-provider.js";
|
|
5
5
|
import * as React from "react";
|
|
6
6
|
import { jsx } from "react/jsx-runtime";
|
|
7
|
+
import { DEFAULT_FONT } from "@cueplusplus/tokens";
|
|
7
8
|
//#region src/system/portal.tsx
|
|
8
9
|
const DEFAULT_THEME = "cue";
|
|
9
|
-
const
|
|
10
|
+
const DEFAULT_MODE = "dark";
|
|
10
11
|
/** Custom property the density text ladder multiplies by; see `FontScaleContext`. */
|
|
11
12
|
const FONT_SCALE_PROPERTY = "--cue-font-scale";
|
|
13
|
+
const FONT_SANS_PROPERTY = "--cue-font-sans";
|
|
14
|
+
const FONT_MONO_PROPERTY = "--cue-font-mono";
|
|
12
15
|
/**
|
|
13
16
|
* Read the stamp from React context — never from the DOM. A portal is mounted
|
|
14
17
|
* outside its owner's DOM subtree, so `getComputedStyle`-style discovery would
|
|
@@ -21,20 +24,23 @@ function usePortalStamp() {
|
|
|
21
24
|
const theme = React.useContext(ThemeContext);
|
|
22
25
|
const island = React.useContext(DensityContext);
|
|
23
26
|
const fontScale = React.useContext(FontScaleContext);
|
|
27
|
+
const fontFamilies = React.useContext(FontFamiliesContext);
|
|
24
28
|
return {
|
|
25
29
|
theme: theme?.theme ?? DEFAULT_THEME,
|
|
26
|
-
density: island ?? theme?.density ?? "
|
|
27
|
-
mode: theme?.
|
|
28
|
-
|
|
30
|
+
density: island ?? theme?.density ?? "compact",
|
|
31
|
+
mode: theme?.mode ?? DEFAULT_MODE,
|
|
32
|
+
font: theme?.font ?? DEFAULT_FONT,
|
|
33
|
+
fontScale,
|
|
34
|
+
fontFamilies
|
|
29
35
|
};
|
|
30
36
|
}
|
|
31
37
|
/**
|
|
32
38
|
* Props to spread onto a Base UI `Portal` part so the portal root inherits the
|
|
33
|
-
* caller's theme, density and mode.
|
|
39
|
+
* caller's theme, density, font pairing and mode.
|
|
34
40
|
*
|
|
35
41
|
* Returns a `container` element appended to `document.body` and stamped with
|
|
36
|
-
* `data-theme` / `data-density` / `data-
|
|
37
|
-
* from the nearest provider and density island. The container is
|
|
42
|
+
* `data-theme` / `data-density` / `data-font` / `data-mode` (plus
|
|
43
|
+
* `--cue-font-scale`) copied from the nearest provider and density island. The container is
|
|
38
44
|
* `display: contents`, so it changes no layout and creates no containing block —
|
|
39
45
|
* fixed-position overlay content behaves exactly as if it were a direct child of
|
|
40
46
|
* `<body>`.
|
|
@@ -75,8 +81,11 @@ function useCuePortalProps() {
|
|
|
75
81
|
container,
|
|
76
82
|
stamp.theme,
|
|
77
83
|
stamp.density,
|
|
84
|
+
stamp.font,
|
|
78
85
|
stamp.mode,
|
|
79
|
-
stamp.fontScale
|
|
86
|
+
stamp.fontScale,
|
|
87
|
+
stamp.fontFamilies?.sans,
|
|
88
|
+
stamp.fontFamilies?.mono
|
|
80
89
|
]);
|
|
81
90
|
return React.useMemo(() => container === null ? {} : { container }, [container]);
|
|
82
91
|
}
|
|
@@ -84,17 +93,24 @@ function useCuePortalProps() {
|
|
|
84
93
|
function applyStamp(element, stamp) {
|
|
85
94
|
element.setAttribute("data-theme", stamp.theme);
|
|
86
95
|
element.setAttribute("data-density", stamp.density);
|
|
96
|
+
element.setAttribute("data-font", stamp.font);
|
|
87
97
|
element.setAttribute("data-mode", stamp.mode);
|
|
88
98
|
if (stamp.fontScale === null) element.style.removeProperty(FONT_SCALE_PROPERTY);
|
|
89
99
|
else element.style.setProperty(FONT_SCALE_PROPERTY, String(stamp.fontScale));
|
|
100
|
+
setOptionalProperty(element, FONT_SANS_PROPERTY, stamp.fontFamilies?.sans);
|
|
101
|
+
setOptionalProperty(element, FONT_MONO_PROPERTY, stamp.fontFamilies?.mono);
|
|
102
|
+
}
|
|
103
|
+
function setOptionalProperty(element, property, value) {
|
|
104
|
+
if (value === void 0) element.style.removeProperty(property);
|
|
105
|
+
else element.style.setProperty(property, value);
|
|
90
106
|
}
|
|
91
107
|
/**
|
|
92
108
|
* Inline version of the portal contract, for portals whose container cannot be
|
|
93
109
|
* chosen (a third-party overlay, or content already portaled by something else).
|
|
94
110
|
*
|
|
95
111
|
* Wraps `children` in a `display: contents` element carrying the same
|
|
96
|
-
* `data-theme` / `data-density` / `data-
|
|
97
|
-
* {@link useCuePortalProps}. Prefer the hook — a stamped container costs one
|
|
112
|
+
* `data-theme` / `data-density` / `data-font` / `data-mode` stamp and
|
|
113
|
+
* `--cue-font-scale` as {@link useCuePortalProps}. Prefer the hook — a stamped container costs one
|
|
98
114
|
* element per overlay instead of one per render tree — and reach for this only
|
|
99
115
|
* when the container prop is not available.
|
|
100
116
|
*
|
|
@@ -106,12 +122,15 @@ function CuePortalFrame({ children, className, style }) {
|
|
|
106
122
|
const frameStyle = {
|
|
107
123
|
display: "contents",
|
|
108
124
|
...stamp.fontScale === null ? null : { [FONT_SCALE_PROPERTY]: stamp.fontScale },
|
|
125
|
+
...stamp.fontFamilies?.sans === void 0 ? null : { [FONT_SANS_PROPERTY]: stamp.fontFamilies.sans },
|
|
126
|
+
...stamp.fontFamilies?.mono === void 0 ? null : { [FONT_MONO_PROPERTY]: stamp.fontFamilies.mono },
|
|
109
127
|
...style
|
|
110
128
|
};
|
|
111
129
|
return /* @__PURE__ */ jsx("div", {
|
|
112
130
|
"data-cue-portal": "",
|
|
113
131
|
"data-theme": stamp.theme,
|
|
114
132
|
"data-density": stamp.density,
|
|
133
|
+
"data-font": stamp.font,
|
|
115
134
|
"data-mode": stamp.mode,
|
|
116
135
|
className,
|
|
117
136
|
style: frameStyle,
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { ThemeName } from "@cueplusplus/tokens";
|
|
1
|
+
import { Density, FontName, Mode, ThemeName } from "@cueplusplus/tokens";
|
|
2
2
|
//#region src/system/prepaint.d.ts
|
|
3
3
|
/** localStorage key the ThemeProvider and the pre-paint script share by default. */
|
|
4
4
|
declare const DEFAULT_STORAGE_KEY = "cue-ui";
|
|
@@ -10,17 +10,36 @@ interface PersistedPreferences {
|
|
|
10
10
|
density?: string;
|
|
11
11
|
/** Last mode the user picked, including the literal `"system"`. */
|
|
12
12
|
mode?: string;
|
|
13
|
+
/** Last font pairing the user picked. */
|
|
14
|
+
font?: string;
|
|
15
|
+
}
|
|
16
|
+
/** Complete server-authoritative fallback stamped when storage is absent or ignored. */
|
|
17
|
+
interface PrepaintDefaults {
|
|
18
|
+
theme: ThemeName;
|
|
19
|
+
density: Density;
|
|
20
|
+
mode: Mode;
|
|
21
|
+
/** Initial document-wide font pairing. Defaults to the token package's system pairing. */
|
|
22
|
+
font?: FontName;
|
|
23
|
+
}
|
|
24
|
+
/** Options form for apps whose server projection, not localStorage, owns first paint. */
|
|
25
|
+
interface PrepaintOptions {
|
|
26
|
+
/** localStorage key shared with ThemeProvider. */
|
|
27
|
+
storageKey?: string;
|
|
28
|
+
/** Complete validated fallback triple. */
|
|
29
|
+
defaults: PrepaintDefaults;
|
|
30
|
+
/** Whether valid stored axes may override `defaults`. Defaults to `true`. */
|
|
31
|
+
readStoredPreferences?: boolean;
|
|
13
32
|
}
|
|
14
33
|
/**
|
|
15
34
|
* Build the blocking inline script that stamps `data-theme`, `data-density`,
|
|
16
|
-
* `data-mode` and `color-scheme` on `<html>` from localStorage
|
|
17
|
-
* paint.
|
|
35
|
+
* `data-font`, `data-mode` and `color-scheme` on `<html>` from localStorage
|
|
36
|
+
* before the first paint.
|
|
18
37
|
*
|
|
19
38
|
* Render it as `<script dangerouslySetInnerHTML={{ __html: prepaintScript() }} />`
|
|
20
39
|
* in `<head>`, above everything else. The output never contains `</script>` and
|
|
21
40
|
* never throws: private-mode localStorage failures degrade to the dark-first
|
|
22
|
-
* defaults (`cue` / `
|
|
23
|
-
* `@cueplusplus/tokens/theme.css` already paints.
|
|
41
|
+
* defaults (`cue` / `compact` / `system` / `dark`), which are also what bare
|
|
42
|
+
* `:root` in `@cueplusplus/tokens/theme.css` already paints.
|
|
24
43
|
*
|
|
25
44
|
* @param storageKey - localStorage key to read. Must match the `storageKey`
|
|
26
45
|
* passed to `<ThemeProvider>`. Defaults to {@link DEFAULT_STORAGE_KEY}.
|
|
@@ -28,11 +47,17 @@ interface PersistedPreferences {
|
|
|
28
47
|
* Must match the `theme` passed to `<ThemeProvider>`, or the first paint
|
|
29
48
|
* dresses `<html>` in one preset while the app renders in another. Defaults to
|
|
30
49
|
* `"cue"`.
|
|
50
|
+
* @param defaultDensity - Density level to stamp for a visitor with nothing
|
|
51
|
+
* persisted yet. Same rule as `defaultTheme`: it must match the `density`
|
|
52
|
+
* passed to `<ThemeProvider>` or the first frame is drawn at one rung and
|
|
53
|
+
* every frame after it at another. Defaults to `"compact"`, the library's own
|
|
54
|
+
* fallback, which is what an app that passes no `density` renders at.
|
|
31
55
|
* @returns One line of JavaScript, safe to inline verbatim.
|
|
32
56
|
* @example
|
|
33
|
-
* // An app whose provider is <ThemeProvider theme="terminal">:
|
|
34
|
-
* prepaintScript(DEFAULT_STORAGE_KEY, "terminal");
|
|
57
|
+
* // An app whose provider is <ThemeProvider theme="terminal" density="normal">:
|
|
58
|
+
* prepaintScript(DEFAULT_STORAGE_KEY, "terminal", "normal");
|
|
35
59
|
*/
|
|
36
|
-
declare function prepaintScript(storageKey?: string, defaultTheme?: ThemeName): string;
|
|
60
|
+
declare function prepaintScript(storageKey?: string, defaultTheme?: ThemeName, defaultDensity?: Density, defaultFont?: FontName): string;
|
|
61
|
+
declare function prepaintScript(options: PrepaintOptions): string;
|
|
37
62
|
//#endregion
|
|
38
|
-
export { DEFAULT_STORAGE_KEY, PersistedPreferences, prepaintScript };
|
|
63
|
+
export { DEFAULT_STORAGE_KEY, PersistedPreferences, PrepaintDefaults, PrepaintOptions, prepaintScript };
|