@cueplusplus/ui 0.1.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/dist/charts/_token.js +39 -0
- package/dist/charts/container.d.ts +58 -0
- package/dist/charts/container.js +77 -0
- package/dist/charts/index.d.ts +5 -0
- package/dist/charts/index.js +5 -0
- package/dist/charts/ramps.d.ts +140 -0
- package/dist/charts/ramps.js +615 -0
- package/dist/charts/theme.d.ts +112 -0
- package/dist/charts/theme.js +165 -0
- package/dist/charts/tones.d.ts +111 -0
- package/dist/charts/tones.js +127 -0
- package/dist/chat/_glyphs.js +55 -0
- package/dist/chat/agent-color.d.ts +84 -0
- package/dist/chat/agent-color.js +101 -0
- package/dist/chat/agent-pile.d.ts +55 -0
- package/dist/chat/agent-pile.js +121 -0
- package/dist/chat/ask-box.d.ts +88 -0
- package/dist/chat/ask-box.js +341 -0
- package/dist/chat/composer.d.ts +66 -0
- package/dist/chat/composer.js +144 -0
- package/dist/chat/delegation-card.d.ts +60 -0
- package/dist/chat/delegation-card.js +129 -0
- package/dist/chat/index.d.ts +8 -0
- package/dist/chat/index.js +8 -0
- package/dist/chat/message-list.d.ts +39 -0
- package/dist/chat/message-list.js +105 -0
- package/dist/chat/message.d.ts +47 -0
- package/dist/chat/message.js +108 -0
- package/dist/chrome/_glyphs.js +101 -0
- package/dist/chrome/_tabs-scroll.d.ts +62 -0
- package/dist/chrome/_tabs-scroll.js +68 -0
- package/dist/chrome/_tree.d.ts +75 -0
- package/dist/chrome/_tree.js +49 -0
- package/dist/chrome/empty-state.d.ts +37 -0
- package/dist/chrome/empty-state.js +57 -0
- package/dist/chrome/eyebrow.d.ts +29 -0
- package/dist/chrome/eyebrow.js +36 -0
- package/dist/chrome/index.d.ts +17 -0
- package/dist/chrome/index.js +17 -0
- package/dist/chrome/navigation-menu.d.ts +80 -0
- package/dist/chrome/navigation-menu.js +121 -0
- package/dist/chrome/page-shell.d.ts +38 -0
- package/dist/chrome/page-shell.js +66 -0
- package/dist/chrome/panel.d.ts +55 -0
- package/dist/chrome/panel.js +67 -0
- package/dist/chrome/row.d.ts +82 -0
- package/dist/chrome/row.js +106 -0
- package/dist/chrome/scroll-area.d.ts +39 -0
- package/dist/chrome/scroll-area.js +70 -0
- package/dist/chrome/section-header.d.ts +42 -0
- package/dist/chrome/section-header.js +79 -0
- package/dist/chrome/segmented-control.d.ts +58 -0
- package/dist/chrome/segmented-control.js +76 -0
- package/dist/chrome/status-bar.d.ts +46 -0
- package/dist/chrome/status-bar.js +56 -0
- package/dist/chrome/tabs.d.ts +80 -0
- package/dist/chrome/tabs.js +176 -0
- package/dist/chrome/title-bar.d.ts +37 -0
- package/dist/chrome/title-bar.js +45 -0
- package/dist/chrome/toolbar.d.ts +46 -0
- package/dist/chrome/toolbar.js +62 -0
- package/dist/chrome/tree.d.ts +98 -0
- package/dist/chrome/tree.js +248 -0
- package/dist/color/_checker.js +14 -0
- package/dist/color/_convert.d.ts +52 -0
- package/dist/color/_convert.js +66 -0
- package/dist/color/_glyphs.js +28 -0
- package/dist/color/_thumb.js +15 -0
- package/dist/color/_value.js +28 -0
- package/dist/color/color-area.d.ts +27 -0
- package/dist/color/color-area.js +40 -0
- package/dist/color/color-field.d.ts +32 -0
- package/dist/color/color-field.js +43 -0
- package/dist/color/color-picker.d.ts +71 -0
- package/dist/color/color-picker.js +178 -0
- package/dist/color/color-slider.d.ts +31 -0
- package/dist/color/color-slider.js +51 -0
- package/dist/color/color-swatch.d.ts +32 -0
- package/dist/color/color-swatch.js +44 -0
- package/dist/color/index.d.ts +7 -0
- package/dist/color/index.js +7 -0
- package/dist/configurator/_export.d.ts +78 -0
- package/dist/configurator/_export.js +261 -0
- package/dist/configurator/_glyphs.js +92 -0
- package/dist/configurator/_overrides.d.ts +247 -0
- package/dist/configurator/_overrides.js +514 -0
- package/dist/configurator/configurator.d.ts +71 -0
- package/dist/configurator/configurator.js +279 -0
- package/dist/configurator/export-dialog.d.ts +30 -0
- package/dist/configurator/export-dialog.js +121 -0
- package/dist/configurator/index.d.ts +8 -0
- package/dist/configurator/index.js +8 -0
- package/dist/configurator/panel-sections.d.ts +86 -0
- package/dist/configurator/panel-sections.js +316 -0
- package/dist/configurator/token-editor.d.ts +74 -0
- package/dist/configurator/token-editor.js +149 -0
- package/dist/configurator/use-zoom.d.ts +87 -0
- package/dist/configurator/use-zoom.js +113 -0
- package/dist/date/_glyphs.js +34 -0
- package/dist/date/_segments.js +55 -0
- package/dist/date/_trigger.js +31 -0
- package/dist/date/calendar.d.ts +25 -0
- package/dist/date/calendar.js +125 -0
- package/dist/date/date-field.d.ts +34 -0
- package/dist/date/date-field.js +41 -0
- package/dist/date/date-picker.d.ts +69 -0
- package/dist/date/date-picker.js +89 -0
- package/dist/date/date-range-picker.d.ts +65 -0
- package/dist/date/date-range-picker.js +92 -0
- package/dist/date/index.d.ts +6 -0
- package/dist/date/index.js +6 -0
- package/dist/date/time-field.d.ts +29 -0
- package/dist/date/time-field.js +36 -0
- package/dist/dmx/_ramp.d.ts +77 -0
- package/dist/dmx/_ramp.js +169 -0
- package/dist/dmx/_readout.js +53 -0
- package/dist/dmx/_universe.d.ts +105 -0
- package/dist/dmx/_universe.js +112 -0
- package/dist/dmx/channel-matrix.d.ts +81 -0
- package/dist/dmx/channel-matrix.js +285 -0
- package/dist/dmx/dmx-bar.d.ts +50 -0
- package/dist/dmx/dmx-bar.js +107 -0
- package/dist/dmx/dmx-strip.d.ts +41 -0
- package/dist/dmx/dmx-strip.js +196 -0
- package/dist/dmx/index.d.ts +7 -0
- package/dist/dmx/index.js +7 -0
- package/dist/dmx/universe-grid.d.ts +61 -0
- package/dist/dmx/universe-grid.js +182 -0
- package/dist/flow/_frame.d.ts +52 -0
- package/dist/flow/_frame.js +38 -0
- package/dist/flow/controls.d.ts +41 -0
- package/dist/flow/controls.js +53 -0
- package/dist/flow/flow.css +121 -0
- package/dist/flow/handles.d.ts +40 -0
- package/dist/flow/handles.js +61 -0
- package/dist/flow/index.d.ts +7 -0
- package/dist/flow/index.js +7 -0
- package/dist/flow/node-card.d.ts +71 -0
- package/dist/flow/node-card.js +102 -0
- package/dist/flow/signal-edge.d.ts +60 -0
- package/dist/flow/signal-edge.js +108 -0
- package/dist/flow/use-flow-theme.d.ts +69 -0
- package/dist/flow/use-flow-theme.js +109 -0
- package/dist/forms/_chassis.d.ts +64 -0
- package/dist/forms/_chassis.js +59 -0
- package/dist/forms/_glyphs.js +143 -0
- package/dist/forms/_listbox.js +55 -0
- package/dist/forms/autocomplete.d.ts +61 -0
- package/dist/forms/autocomplete.js +88 -0
- package/dist/forms/button-group.d.ts +47 -0
- package/dist/forms/button-group.js +52 -0
- package/dist/forms/checkbox.d.ts +51 -0
- package/dist/forms/checkbox.js +98 -0
- package/dist/forms/combobox.d.ts +73 -0
- package/dist/forms/combobox.js +108 -0
- package/dist/forms/env-var-input.d.ts +74 -0
- package/dist/forms/env-var-input.js +116 -0
- package/dist/forms/field.d.ts +89 -0
- package/dist/forms/field.js +102 -0
- package/dist/forms/file-upload.d.ts +113 -0
- package/dist/forms/file-upload.js +232 -0
- package/dist/forms/index.d.ts +26 -0
- package/dist/forms/index.js +26 -0
- package/dist/forms/input-group.d.ts +31 -0
- package/dist/forms/input-group.js +54 -0
- package/dist/forms/input.d.ts +33 -0
- package/dist/forms/input.js +36 -0
- package/dist/forms/multi-select.d.ts +62 -0
- package/dist/forms/multi-select.js +107 -0
- package/dist/forms/number-field.d.ts +38 -0
- package/dist/forms/number-field.js +64 -0
- package/dist/forms/otp-field.d.ts +54 -0
- package/dist/forms/otp-field.js +59 -0
- package/dist/forms/password-input.d.ts +46 -0
- package/dist/forms/password-input.js +62 -0
- package/dist/forms/radio-group.d.ts +50 -0
- package/dist/forms/radio-group.js +64 -0
- package/dist/forms/rating.d.ts +69 -0
- package/dist/forms/rating.js +103 -0
- package/dist/forms/scrub-input.d.ts +81 -0
- package/dist/forms/scrub-input.js +249 -0
- package/dist/forms/search-input.d.ts +54 -0
- package/dist/forms/search-input.js +112 -0
- package/dist/forms/select.d.ts +75 -0
- package/dist/forms/select.js +91 -0
- package/dist/forms/slider.d.ts +44 -0
- package/dist/forms/slider.js +65 -0
- package/dist/forms/switch.d.ts +36 -0
- package/dist/forms/switch.js +71 -0
- package/dist/forms/tags-input.d.ts +69 -0
- package/dist/forms/tags-input.js +148 -0
- package/dist/forms/textarea.d.ts +27 -0
- package/dist/forms/textarea.js +37 -0
- package/dist/forms/toggle-group.d.ts +41 -0
- package/dist/forms/toggle-group.js +56 -0
- package/dist/forms/toggle.d.ts +41 -0
- package/dist/forms/toggle.js +100 -0
- package/dist/index.d.ts +112 -0
- package/dist/index.js +104 -0
- package/dist/instruments/_ansi.js +116 -0
- package/dist/instruments/_glyphs.js +90 -0
- package/dist/instruments/_motion.js +56 -0
- package/dist/instruments/_rem.js +21 -0
- package/dist/instruments/app-window-frame.d.ts +48 -0
- package/dist/instruments/app-window-frame.js +76 -0
- package/dist/instruments/copy-button.d.ts +41 -0
- package/dist/instruments/copy-button.js +112 -0
- package/dist/instruments/data-table.d.ts +168 -0
- package/dist/instruments/data-table.js +212 -0
- package/dist/instruments/group-bar.d.ts +63 -0
- package/dist/instruments/group-bar.js +122 -0
- package/dist/instruments/index.d.ts +13 -0
- package/dist/instruments/index.js +13 -0
- package/dist/instruments/log-viewer.d.ts +74 -0
- package/dist/instruments/log-viewer.js +215 -0
- package/dist/instruments/meter.d.ts +77 -0
- package/dist/instruments/meter.js +96 -0
- package/dist/instruments/progress.d.ts +45 -0
- package/dist/instruments/progress.js +61 -0
- package/dist/instruments/seam-grid.d.ts +66 -0
- package/dist/instruments/seam-grid.js +78 -0
- package/dist/instruments/sparkline.d.ts +39 -0
- package/dist/instruments/sparkline.js +85 -0
- package/dist/instruments/stat.d.ts +35 -0
- package/dist/instruments/stat.js +59 -0
- package/dist/instruments/table.d.ts +51 -0
- package/dist/instruments/table.js +92 -0
- package/dist/instruments/terminal-frame.d.ts +89 -0
- package/dist/instruments/terminal-frame.js +256 -0
- package/dist/instruments/two-step-button.d.ts +47 -0
- package/dist/instruments/two-step-button.js +147 -0
- package/dist/instruments/usage-chart.d.ts +55 -0
- package/dist/instruments/usage-chart.js +235 -0
- package/dist/layout/_collapse.js +46 -0
- package/dist/layout/_glyphs.js +45 -0
- package/dist/layout/accordion.d.ts +52 -0
- package/dist/layout/accordion.js +81 -0
- package/dist/layout/breadcrumb.d.ts +35 -0
- package/dist/layout/breadcrumb.js +67 -0
- package/dist/layout/card.d.ts +51 -0
- package/dist/layout/card.js +76 -0
- package/dist/layout/carousel.d.ts +96 -0
- package/dist/layout/carousel.js +211 -0
- package/dist/layout/collapsible.d.ts +74 -0
- package/dist/layout/collapsible.js +126 -0
- package/dist/layout/container.d.ts +27 -0
- package/dist/layout/container.js +40 -0
- package/dist/layout/description-list.d.ts +24 -0
- package/dist/layout/description-list.js +37 -0
- package/dist/layout/grid.d.ts +40 -0
- package/dist/layout/grid.js +48 -0
- package/dist/layout/index.d.ts +15 -0
- package/dist/layout/index.js +15 -0
- package/dist/layout/item.d.ts +65 -0
- package/dist/layout/item.js +100 -0
- package/dist/layout/link.d.ts +48 -0
- package/dist/layout/link.js +63 -0
- package/dist/layout/pagination.d.ts +54 -0
- package/dist/layout/pagination.js +121 -0
- package/dist/layout/resizable.d.ts +38 -0
- package/dist/layout/resizable.js +68 -0
- package/dist/layout/sidebar.d.ts +67 -0
- package/dist/layout/sidebar.js +129 -0
- package/dist/layout/stack.d.ts +46 -0
- package/dist/layout/stack.js +62 -0
- package/dist/layout/stepper.d.ts +49 -0
- package/dist/layout/stepper.js +81 -0
- package/dist/layout/timeline.d.ts +43 -0
- package/dist/layout/timeline.js +63 -0
- package/dist/lib/aria-class.js +24 -0
- package/dist/lib/cn.js +18 -0
- package/dist/lib/compose.js +38 -0
- package/dist/lib/cva.d.ts +18 -0
- package/dist/lib/cva.js +65 -0
- package/dist/midi/_notes.d.ts +101 -0
- package/dist/midi/_notes.js +183 -0
- package/dist/midi/_ruler.d.ts +100 -0
- package/dist/midi/_ruler.js +105 -0
- package/dist/midi/_time.d.ts +107 -0
- package/dist/midi/_time.js +130 -0
- package/dist/midi/index.d.ts +9 -0
- package/dist/midi/index.js +9 -0
- package/dist/midi/musical-time-input.d.ts +48 -0
- package/dist/midi/musical-time-input.js +154 -0
- package/dist/midi/piano-keyboard.d.ts +50 -0
- package/dist/midi/piano-keyboard.js +193 -0
- package/dist/midi/spectrum-visualizer.d.ts +65 -0
- package/dist/midi/spectrum-visualizer.js +213 -0
- package/dist/midi/threshold-rail.d.ts +72 -0
- package/dist/midi/threshold-rail.js +214 -0
- package/dist/midi/timeline-ruler.d.ts +83 -0
- package/dist/midi/timeline-ruler.js +152 -0
- package/dist/overlays/_debounce.js +34 -0
- package/dist/overlays/_glyphs.js +59 -0
- package/dist/overlays/_surface.d.ts +70 -0
- package/dist/overlays/_surface.js +70 -0
- package/dist/overlays/_wheel.js +42 -0
- package/dist/overlays/alert-dialog.d.ts +67 -0
- package/dist/overlays/alert-dialog.js +117 -0
- package/dist/overlays/command-palette.d.ts +93 -0
- package/dist/overlays/command-palette.js +193 -0
- package/dist/overlays/context-menu.d.ts +64 -0
- package/dist/overlays/context-menu.js +78 -0
- package/dist/overlays/dialog.d.ts +72 -0
- package/dist/overlays/dialog.js +124 -0
- package/dist/overlays/drawer.d.ts +75 -0
- package/dist/overlays/drawer.js +151 -0
- package/dist/overlays/dropdown-menu.d.ts +79 -0
- package/dist/overlays/dropdown-menu.js +156 -0
- package/dist/overlays/hover-card.d.ts +58 -0
- package/dist/overlays/hover-card.js +91 -0
- package/dist/overlays/index.d.ts +15 -0
- package/dist/overlays/index.js +15 -0
- package/dist/overlays/info-tip.d.ts +41 -0
- package/dist/overlays/info-tip.js +45 -0
- package/dist/overlays/menubar.d.ts +72 -0
- package/dist/overlays/menubar.js +100 -0
- package/dist/overlays/popover.d.ts +66 -0
- package/dist/overlays/popover.js +114 -0
- package/dist/overlays/sheet.d.ts +78 -0
- package/dist/overlays/sheet.js +131 -0
- package/dist/overlays/toast.d.ts +106 -0
- package/dist/overlays/toast.js +146 -0
- package/dist/overlays/tooltip.d.ts +57 -0
- package/dist/overlays/tooltip.js +95 -0
- package/dist/primitives/avatar.d.ts +51 -0
- package/dist/primitives/avatar.js +93 -0
- package/dist/primitives/button.d.ts +46 -0
- package/dist/primitives/button.js +94 -0
- package/dist/primitives/chip.d.ts +47 -0
- package/dist/primitives/chip.js +152 -0
- package/dist/primitives/icon-button.d.ts +41 -0
- package/dist/primitives/icon-button.js +59 -0
- package/dist/primitives/index.d.ts +10 -0
- package/dist/primitives/index.js +10 -0
- package/dist/primitives/kbd.d.ts +17 -0
- package/dist/primitives/kbd.js +24 -0
- package/dist/primitives/separator.d.ts +25 -0
- package/dist/primitives/separator.js +30 -0
- package/dist/primitives/skeleton.d.ts +20 -0
- package/dist/primitives/skeleton.js +27 -0
- package/dist/primitives/spinner.d.ts +26 -0
- package/dist/primitives/spinner.js +31 -0
- package/dist/primitives/status-dot.d.ts +44 -0
- package/dist/primitives/status-dot.js +50 -0
- package/dist/styles.css +19 -0
- package/dist/system/density.d.ts +33 -0
- package/dist/system/density.js +49 -0
- package/dist/system/index.d.ts +8 -0
- package/dist/system/index.js +7 -0
- package/dist/system/portal.d.ts +51 -0
- package/dist/system/portal.js +122 -0
- package/dist/system/prepaint.d.ts +38 -0
- package/dist/system/prepaint.js +37 -0
- package/dist/system/theme-provider.d.ts +72 -0
- package/dist/system/theme-provider.js +252 -0
- package/dist/system/use-density.d.ts +33 -0
- package/dist/system/use-density.js +84 -0
- package/dist/system/use-isomorphic-layout-effect.js +15 -0
- package/dist/system/use-theme.d.ts +19 -0
- package/dist/system/use-theme.js +25 -0
- package/dist/theming/_presets.d.ts +11 -0
- package/dist/theming/_presets.js +487 -0
- package/dist/theming/contrast.d.ts +110 -0
- package/dist/theming/contrast.js +167 -0
- package/dist/theming/create-theme.d.ts +165 -0
- package/dist/theming/create-theme.js +442 -0
- package/dist/theming/index.d.ts +5 -0
- package/dist/theming/index.js +5 -0
- package/dist/theming/serialize.d.ts +145 -0
- package/dist/theming/serialize.js +165 -0
- package/package.json +216 -0
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import { cn } from "../lib/cn.js";
|
|
2
|
+
import * as React from "react";
|
|
3
|
+
import { jsx } from "react/jsx-runtime";
|
|
4
|
+
//#region src/layout/description-list.tsx
|
|
5
|
+
const LAYOUTS = {
|
|
6
|
+
inline: "grid grid-cols-[max-content_minmax(0,1fr)] gap-x-(--cue-space-5) gap-y-(--cue-space-2)",
|
|
7
|
+
stacked: "flex flex-col gap-(--cue-space-3)"
|
|
8
|
+
};
|
|
9
|
+
/** The `<dl>` family: {@link DescriptionListRoot}, `Term` and `Detail`. */
|
|
10
|
+
const DescriptionList = {
|
|
11
|
+
Root: React.forwardRef(function DescriptionListRoot({ className, layout = "inline", ...elementProps }, ref) {
|
|
12
|
+
return /* @__PURE__ */ jsx("dl", {
|
|
13
|
+
ref,
|
|
14
|
+
"data-slot": "description-list",
|
|
15
|
+
className: cn(LAYOUTS[layout], className),
|
|
16
|
+
...elementProps
|
|
17
|
+
});
|
|
18
|
+
}),
|
|
19
|
+
Term: React.forwardRef(function DescriptionListTerm({ className, ...elementProps }, ref) {
|
|
20
|
+
return /* @__PURE__ */ jsx("dt", {
|
|
21
|
+
ref,
|
|
22
|
+
"data-slot": "description-list-term",
|
|
23
|
+
className: cn("font-mono text-(length:--cue-text-label) tracking-[0.15em] text-fg-subtle uppercase", className),
|
|
24
|
+
...elementProps
|
|
25
|
+
});
|
|
26
|
+
}),
|
|
27
|
+
Detail: React.forwardRef(function DescriptionListDetail({ className, ...elementProps }, ref) {
|
|
28
|
+
return /* @__PURE__ */ jsx("dd", {
|
|
29
|
+
ref,
|
|
30
|
+
"data-slot": "description-list-detail",
|
|
31
|
+
className: cn("m-0 font-mono text-(length:--cue-text-ui) text-fg", className),
|
|
32
|
+
...elementProps
|
|
33
|
+
});
|
|
34
|
+
})
|
|
35
|
+
};
|
|
36
|
+
//#endregion
|
|
37
|
+
export { DescriptionList };
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import { SpaceStep, StackAlign, StackJustify } from "./stack.js";
|
|
2
|
+
import * as React from "react";
|
|
3
|
+
//#region src/layout/grid.d.ts
|
|
4
|
+
/** How many equal columns to lay out. */
|
|
5
|
+
type GridColumns = 1 | 2 | 3 | 4 | 5 | 6;
|
|
6
|
+
interface GridProps extends React.ComponentPropsWithoutRef<"div"> {
|
|
7
|
+
/** How many equal columns. Defaults to `1`. Ignored when `minItemWidth` is set. */
|
|
8
|
+
cols?: GridColumns;
|
|
9
|
+
/** Which rung of the density space ladder to spend between cells. Defaults to `4`. */
|
|
10
|
+
gap?: SpaceStep;
|
|
11
|
+
/**
|
|
12
|
+
* Fill the row with as many columns of at least this width as fit, instead of
|
|
13
|
+
* a fixed count. Any CSS length (`"12rem"`, `"200px"`).
|
|
14
|
+
*
|
|
15
|
+
* Prefer this over a column count wherever the content has a natural minimum
|
|
16
|
+
* measure — it is responsive without a single breakpoint.
|
|
17
|
+
*/
|
|
18
|
+
minItemWidth?: string;
|
|
19
|
+
/** Cross-axis alignment of the cells. */
|
|
20
|
+
align?: StackAlign;
|
|
21
|
+
/** Main-axis distribution of the tracks. */
|
|
22
|
+
justify?: StackJustify;
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* Two-dimensional layout: equal columns, or as many as fit.
|
|
26
|
+
*
|
|
27
|
+
* Same bargain as `Stack` — the gap is a rung of the density ladder rather than
|
|
28
|
+
* a hand-picked pixel value, so a card grid tightens with the rest of the
|
|
29
|
+
* console when the user asks for ultra-compact.
|
|
30
|
+
*
|
|
31
|
+
* Static markup — no `"use client"`.
|
|
32
|
+
*
|
|
33
|
+
* @example
|
|
34
|
+
* <Grid cols={3} gap={5}>{cards}</Grid>
|
|
35
|
+
* @example
|
|
36
|
+
* <Grid minItemWidth="14rem" gap={4}>{cards}</Grid>
|
|
37
|
+
*/
|
|
38
|
+
declare const Grid: React.ForwardRefExoticComponent<GridProps & React.RefAttributes<HTMLDivElement>>;
|
|
39
|
+
//#endregion
|
|
40
|
+
export { Grid, GridColumns, GridProps };
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import { cn } from "../lib/cn.js";
|
|
2
|
+
import { ALIGN_CLASSES, GAP_CLASSES, JUSTIFY_CLASSES } from "./stack.js";
|
|
3
|
+
import * as React from "react";
|
|
4
|
+
import { jsx } from "react/jsx-runtime";
|
|
5
|
+
//#region src/layout/grid.tsx
|
|
6
|
+
/** Static class per count — Tailwind scans source text, not computed strings. */
|
|
7
|
+
const COLUMN_CLASSES = {
|
|
8
|
+
1: "grid-cols-1",
|
|
9
|
+
2: "grid-cols-2",
|
|
10
|
+
3: "grid-cols-3",
|
|
11
|
+
4: "grid-cols-4",
|
|
12
|
+
5: "grid-cols-5",
|
|
13
|
+
6: "grid-cols-6"
|
|
14
|
+
};
|
|
15
|
+
/**
|
|
16
|
+
* The auto-filling track. The measure travels as a custom property rather than
|
|
17
|
+
* as an arbitrary value, so the track definition is one static class the
|
|
18
|
+
* scanner always sees instead of a fresh one per call site.
|
|
19
|
+
*/
|
|
20
|
+
const AUTO_FILL_CLASS = "grid-cols-[repeat(auto-fill,minmax(var(--cue-grid-min),1fr))]";
|
|
21
|
+
/**
|
|
22
|
+
* Two-dimensional layout: equal columns, or as many as fit.
|
|
23
|
+
*
|
|
24
|
+
* Same bargain as `Stack` — the gap is a rung of the density ladder rather than
|
|
25
|
+
* a hand-picked pixel value, so a card grid tightens with the rest of the
|
|
26
|
+
* console when the user asks for ultra-compact.
|
|
27
|
+
*
|
|
28
|
+
* Static markup — no `"use client"`.
|
|
29
|
+
*
|
|
30
|
+
* @example
|
|
31
|
+
* <Grid cols={3} gap={5}>{cards}</Grid>
|
|
32
|
+
* @example
|
|
33
|
+
* <Grid minItemWidth="14rem" gap={4}>{cards}</Grid>
|
|
34
|
+
*/
|
|
35
|
+
const Grid = React.forwardRef(function Grid({ className, cols = 1, gap = 4, minItemWidth, align, justify, style, ...elementProps }, ref) {
|
|
36
|
+
return /* @__PURE__ */ jsx("div", {
|
|
37
|
+
ref,
|
|
38
|
+
"data-slot": "grid",
|
|
39
|
+
className: cn("grid", minItemWidth === void 0 ? COLUMN_CLASSES[cols] : AUTO_FILL_CLASS, GAP_CLASSES[gap], align === void 0 ? null : ALIGN_CLASSES[align], justify === void 0 ? null : JUSTIFY_CLASSES[justify], className),
|
|
40
|
+
style: minItemWidth === void 0 ? style : {
|
|
41
|
+
"--cue-grid-min": minItemWidth,
|
|
42
|
+
...style
|
|
43
|
+
},
|
|
44
|
+
...elementProps
|
|
45
|
+
});
|
|
46
|
+
});
|
|
47
|
+
//#endregion
|
|
48
|
+
export { Grid };
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { Accordion, AccordionHeaderProps, AccordionItemProps, AccordionPanelProps, AccordionRootProps, AccordionTriggerProps } from "./accordion.js";
|
|
2
|
+
import { Breadcrumb, BreadcrumbItem, BreadcrumbProps } from "./breadcrumb.js";
|
|
3
|
+
import { Card, CardContentProps, CardDescriptionProps, CardFooterProps, CardHeaderProps, CardRootProps, CardTitleProps } from "./card.js";
|
|
4
|
+
import { Collapsible, CollapsiblePanelProps, CollapsibleRootProps, CollapsibleTriggerProps, Disclosure, DisclosureProps } from "./collapsible.js";
|
|
5
|
+
import { Container, ContainerProps, ContainerWidth } from "./container.js";
|
|
6
|
+
import { DescriptionList, DescriptionListDetailProps, DescriptionListLayout, DescriptionListRootProps, DescriptionListTermProps } from "./description-list.js";
|
|
7
|
+
import { SpaceStep, Stack, StackAlign, StackJustify, StackProps } from "./stack.js";
|
|
8
|
+
import { Grid, GridColumns, GridProps } from "./grid.js";
|
|
9
|
+
import { Item, ItemProps, itemVariants } from "./item.js";
|
|
10
|
+
import { Link, LinkProps, linkVariants } from "./link.js";
|
|
11
|
+
import { Pagination, PaginationEntry, PaginationProps, paginationRange } from "./pagination.js";
|
|
12
|
+
import { Sidebar, SidebarItemProps, SidebarRailProps, SidebarRootProps, SidebarSectionProps, useSidebar } from "./sidebar.js";
|
|
13
|
+
import { Stepper, StepperProps, StepperState, StepperStep } from "./stepper.js";
|
|
14
|
+
import { Timeline, TimelineContentProps, TimelineItemProps, TimelineMarkerProps, TimelineRootProps } from "./timeline.js";
|
|
15
|
+
export { Accordion, type AccordionHeaderProps, type AccordionItemProps, type AccordionPanelProps, type AccordionRootProps, type AccordionTriggerProps, Breadcrumb, type BreadcrumbItem, type BreadcrumbProps, Card, type CardContentProps, type CardDescriptionProps, type CardFooterProps, type CardHeaderProps, type CardRootProps, type CardTitleProps, Collapsible, type CollapsiblePanelProps, type CollapsibleRootProps, type CollapsibleTriggerProps, Container, type ContainerProps, type ContainerWidth, DescriptionList, type DescriptionListDetailProps, type DescriptionListLayout, type DescriptionListRootProps, type DescriptionListTermProps, Disclosure, type DisclosureProps, Grid, type GridColumns, type GridProps, Item, type ItemProps, Link, type LinkProps, Pagination, type PaginationEntry, type PaginationProps, Sidebar, type SidebarItemProps, type SidebarRailProps, type SidebarRootProps, type SidebarSectionProps, type SpaceStep, Stack, type StackAlign, type StackJustify, type StackProps, Stepper, type StepperProps, type StepperState, type StepperStep, Timeline, type TimelineContentProps, type TimelineItemProps, type TimelineMarkerProps, type TimelineRootProps, itemVariants, linkVariants, paginationRange, useSidebar };
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { Accordion } from "./accordion.js";
|
|
2
|
+
import { Breadcrumb } from "./breadcrumb.js";
|
|
3
|
+
import { Card } from "./card.js";
|
|
4
|
+
import { Collapsible, Disclosure } from "./collapsible.js";
|
|
5
|
+
import { Container } from "./container.js";
|
|
6
|
+
import { DescriptionList } from "./description-list.js";
|
|
7
|
+
import { Stack } from "./stack.js";
|
|
8
|
+
import { Grid } from "./grid.js";
|
|
9
|
+
import { Item, itemVariants } from "./item.js";
|
|
10
|
+
import { Link, linkVariants } from "./link.js";
|
|
11
|
+
import { Pagination, paginationRange } from "./pagination.js";
|
|
12
|
+
import { Sidebar, useSidebar } from "./sidebar.js";
|
|
13
|
+
import { Stepper } from "./stepper.js";
|
|
14
|
+
import { Timeline } from "./timeline.js";
|
|
15
|
+
export { Accordion, Breadcrumb, Card, Collapsible, Container, DescriptionList, Disclosure, Grid, Item, Link, Pagination, Sidebar, Stack, Stepper, Timeline, itemVariants, linkVariants, paginationRange, useSidebar };
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
import { ClassProp, VariantProps } from "../lib/cva.js";
|
|
2
|
+
import * as React from "react";
|
|
3
|
+
//#region src/layout/item.d.ts
|
|
4
|
+
/**
|
|
5
|
+
* The media-object recipe: an optional leading glyph, two lines of text and a
|
|
6
|
+
* trailing slot, on the row padding rung.
|
|
7
|
+
*
|
|
8
|
+
* Framing and hover feedback are split across `variants` for the same reason as
|
|
9
|
+
* `chipVariants`: emitting a fill from one variant and cancelling it from
|
|
10
|
+
* another would leave two competing background utilities in the class string
|
|
11
|
+
* and lean on `tailwind-merge` to pick a winner.
|
|
12
|
+
*
|
|
13
|
+
* @example
|
|
14
|
+
* <div className={itemVariants({ variant: "outline" })} />
|
|
15
|
+
*/
|
|
16
|
+
declare const itemVariants: (props?: ({
|
|
17
|
+
variant?: "outline" | "plain" | "soft" | null | undefined;
|
|
18
|
+
interactive?: boolean | null | undefined;
|
|
19
|
+
} & ClassProp) | undefined) => string;
|
|
20
|
+
interface ItemProps extends Omit<React.HTMLAttributes<HTMLElement>, "title">, VariantProps<typeof itemVariants> {
|
|
21
|
+
/** Leading slot: an icon, an avatar, a status dot. */
|
|
22
|
+
media?: React.ReactNode;
|
|
23
|
+
/** The item's name — one line, truncated rather than wrapped. */
|
|
24
|
+
title?: React.ReactNode;
|
|
25
|
+
/** One supporting line under the title, a rung smaller and muted. */
|
|
26
|
+
description?: React.ReactNode;
|
|
27
|
+
/**
|
|
28
|
+
* Trailing slot: a value, a chip, a control.
|
|
29
|
+
*
|
|
30
|
+
* Do not combine with `interactive` — the whole item is then a `<button>`,
|
|
31
|
+
* and a button may not contain another one. Put the controls beside the item
|
|
32
|
+
* instead, or drop `interactive` and make the title itself the link.
|
|
33
|
+
*/
|
|
34
|
+
actions?: React.ReactNode;
|
|
35
|
+
/** Which framing to paint. Defaults to `"plain"`. */
|
|
36
|
+
variant?: "plain" | "outline" | "soft";
|
|
37
|
+
/**
|
|
38
|
+
* Render as a `<button>` with hover feedback and a focus ring instead of a
|
|
39
|
+
* static `<div>`. Use for items that select, open or toggle something.
|
|
40
|
+
*/
|
|
41
|
+
interactive?: boolean;
|
|
42
|
+
/** Disable the interactive form. Ignored when `interactive` is not set. */
|
|
43
|
+
disabled?: boolean;
|
|
44
|
+
/** Extra content between the text column and the action slot. */
|
|
45
|
+
children?: React.ReactNode;
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* One thing in a list, with room for a glyph, a name, a line of detail and a
|
|
49
|
+
* control — the shape a settings entry, a search hit and a device row all want.
|
|
50
|
+
*
|
|
51
|
+
* Where `Row` is a line of a hairline table, `Item` is a self-contained object
|
|
52
|
+
* that can stand alone, sit in a `Stack` or fill a `Grid` cell. It is a real
|
|
53
|
+
* `<button>` when interactive rather than a `<div>` with an `onClick`, so
|
|
54
|
+
* keyboard users get it for free.
|
|
55
|
+
*
|
|
56
|
+
* Static markup — no `"use client"`.
|
|
57
|
+
*
|
|
58
|
+
* @example
|
|
59
|
+
* <Item media={<StatusDot tone="ok" />} title="Node 12" description="10.0.0.12" />
|
|
60
|
+
* @example
|
|
61
|
+
* <Item interactive variant="outline" title="Front truss" onClick={open} />
|
|
62
|
+
*/
|
|
63
|
+
declare const Item: React.ForwardRefExoticComponent<ItemProps & React.RefAttributes<HTMLElement>>;
|
|
64
|
+
//#endregion
|
|
65
|
+
export { Item, ItemProps, itemVariants };
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
import { cn } from "../lib/cn.js";
|
|
2
|
+
import { cva } from "../lib/cva.js";
|
|
3
|
+
import * as React from "react";
|
|
4
|
+
import { Fragment, jsx, jsxs } from "react/jsx-runtime";
|
|
5
|
+
//#region src/layout/item.tsx
|
|
6
|
+
/**
|
|
7
|
+
* The media-object recipe: an optional leading glyph, two lines of text and a
|
|
8
|
+
* trailing slot, on the row padding rung.
|
|
9
|
+
*
|
|
10
|
+
* Framing and hover feedback are split across `variants` for the same reason as
|
|
11
|
+
* `chipVariants`: emitting a fill from one variant and cancelling it from
|
|
12
|
+
* another would leave two competing background utilities in the class string
|
|
13
|
+
* and lean on `tailwind-merge` to pick a winner.
|
|
14
|
+
*
|
|
15
|
+
* @example
|
|
16
|
+
* <div className={itemVariants({ variant: "outline" })} />
|
|
17
|
+
*/
|
|
18
|
+
const itemVariants = cva("flex w-full items-center gap-(--cue-space-4) rounded-(--radius-control) px-(--cue-pad-row-x) py-(--cue-pad-row-y) text-left font-mono text-(length:--cue-text-ui) text-fg", {
|
|
19
|
+
variants: {
|
|
20
|
+
variant: {
|
|
21
|
+
plain: "",
|
|
22
|
+
outline: "border border-border",
|
|
23
|
+
soft: "bg-surface-2"
|
|
24
|
+
},
|
|
25
|
+
interactive: {
|
|
26
|
+
true: "cursor-pointer transition-colors duration-150 outline-none hover:bg-surface-2 focus-visible:outline-2 focus-visible:outline-solid focus-visible:outline-offset-1 focus-visible:outline-accent disabled:pointer-events-none disabled:opacity-40",
|
|
27
|
+
false: ""
|
|
28
|
+
}
|
|
29
|
+
},
|
|
30
|
+
defaultVariants: {
|
|
31
|
+
variant: "plain",
|
|
32
|
+
interactive: false
|
|
33
|
+
}
|
|
34
|
+
});
|
|
35
|
+
/**
|
|
36
|
+
* One thing in a list, with room for a glyph, a name, a line of detail and a
|
|
37
|
+
* control — the shape a settings entry, a search hit and a device row all want.
|
|
38
|
+
*
|
|
39
|
+
* Where `Row` is a line of a hairline table, `Item` is a self-contained object
|
|
40
|
+
* that can stand alone, sit in a `Stack` or fill a `Grid` cell. It is a real
|
|
41
|
+
* `<button>` when interactive rather than a `<div>` with an `onClick`, so
|
|
42
|
+
* keyboard users get it for free.
|
|
43
|
+
*
|
|
44
|
+
* Static markup — no `"use client"`.
|
|
45
|
+
*
|
|
46
|
+
* @example
|
|
47
|
+
* <Item media={<StatusDot tone="ok" />} title="Node 12" description="10.0.0.12" />
|
|
48
|
+
* @example
|
|
49
|
+
* <Item interactive variant="outline" title="Front truss" onClick={open} />
|
|
50
|
+
*/
|
|
51
|
+
const Item = React.forwardRef(function Item({ className, media, title, description, actions, variant, interactive = false, disabled, children, ...elementProps }, ref) {
|
|
52
|
+
const classes = cn(itemVariants({
|
|
53
|
+
variant,
|
|
54
|
+
interactive
|
|
55
|
+
}), className);
|
|
56
|
+
const content = /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
57
|
+
media === void 0 ? null : /* @__PURE__ */ jsx("span", {
|
|
58
|
+
"data-slot": "item-media",
|
|
59
|
+
className: "flex shrink-0 items-center text-fg-muted",
|
|
60
|
+
children: media
|
|
61
|
+
}),
|
|
62
|
+
title === void 0 && description === void 0 ? null : /* @__PURE__ */ jsxs("span", {
|
|
63
|
+
"data-slot": "item-text",
|
|
64
|
+
className: "flex min-w-0 flex-1 flex-col gap-(--cue-space-1)",
|
|
65
|
+
children: [title === void 0 ? null : /* @__PURE__ */ jsx("span", {
|
|
66
|
+
"data-slot": "item-title",
|
|
67
|
+
className: "truncate text-fg",
|
|
68
|
+
children: title
|
|
69
|
+
}), description === void 0 ? null : /* @__PURE__ */ jsx("span", {
|
|
70
|
+
"data-slot": "item-description",
|
|
71
|
+
className: "truncate text-(length:--cue-text-label) text-fg-muted",
|
|
72
|
+
children: description
|
|
73
|
+
})]
|
|
74
|
+
}),
|
|
75
|
+
children,
|
|
76
|
+
actions === void 0 ? null : /* @__PURE__ */ jsx("span", {
|
|
77
|
+
"data-slot": "item-actions",
|
|
78
|
+
className: "flex shrink-0 items-center gap-(--cue-space-2)",
|
|
79
|
+
children: actions
|
|
80
|
+
})
|
|
81
|
+
] });
|
|
82
|
+
if (interactive) return /* @__PURE__ */ jsx("button", {
|
|
83
|
+
ref,
|
|
84
|
+
type: "button",
|
|
85
|
+
disabled,
|
|
86
|
+
"data-slot": "item",
|
|
87
|
+
className: classes,
|
|
88
|
+
...elementProps,
|
|
89
|
+
children: content
|
|
90
|
+
});
|
|
91
|
+
return /* @__PURE__ */ jsx("div", {
|
|
92
|
+
ref,
|
|
93
|
+
"data-slot": "item",
|
|
94
|
+
className: classes,
|
|
95
|
+
...elementProps,
|
|
96
|
+
children: content
|
|
97
|
+
});
|
|
98
|
+
});
|
|
99
|
+
//#endregion
|
|
100
|
+
export { Item, itemVariants };
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import { ClassProp, VariantProps } from "../lib/cva.js";
|
|
2
|
+
import * as React from "react";
|
|
3
|
+
import { useRender } from "@base-ui/react/use-render";
|
|
4
|
+
//#region src/layout/link.d.ts
|
|
5
|
+
/**
|
|
6
|
+
* The link recipe.
|
|
7
|
+
*
|
|
8
|
+
* The house rule is that a link is **not** underlined: in a console, body copy
|
|
9
|
+
* is rare and links are mostly labels inside dense furniture, where a rule
|
|
10
|
+
* under every one of them turns a panel into a page of hyperlinks. Colour on
|
|
11
|
+
* hover carries the affordance instead. The `underline` variant exists for the
|
|
12
|
+
* one place the rule is right — links inside a paragraph of prose, where colour
|
|
13
|
+
* alone would fail WCAG 1.4.1 — and it offsets the rule by 4px so descenders
|
|
14
|
+
* are not struck through.
|
|
15
|
+
*
|
|
16
|
+
* @example
|
|
17
|
+
* <a className={linkVariants({ variant: "underline" })} href="/docs">Docs</a>
|
|
18
|
+
*/
|
|
19
|
+
declare const linkVariants: (props?: ({
|
|
20
|
+
variant?: "plain" | "underline" | null | undefined;
|
|
21
|
+
} & ClassProp) | undefined) => string;
|
|
22
|
+
interface LinkProps extends React.ComponentPropsWithoutRef<"a">, VariantProps<typeof linkVariants> {
|
|
23
|
+
/**
|
|
24
|
+
* Open in a new tab, mark the anchor `rel="noreferrer noopener"` and append a
|
|
25
|
+
* `↗`. The glyph is not decoration: a link that replaces the user's context
|
|
26
|
+
* without warning is a WCAG 3.2.5 failure, and the arrow is the warning.
|
|
27
|
+
*/
|
|
28
|
+
external?: boolean;
|
|
29
|
+
/**
|
|
30
|
+
* Replace the rendered element (Base UI render prop). Accepts an element —
|
|
31
|
+
* `render={<NextLink href="/x" />}` — or a function returning one. This is
|
|
32
|
+
* how the design system composes with a router without depending on one.
|
|
33
|
+
*/
|
|
34
|
+
render?: useRender.RenderProp;
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* A text link: accent on hover, no rule unless you ask for one.
|
|
38
|
+
*
|
|
39
|
+
* @example
|
|
40
|
+
* <Link href="/patch">Patch</Link>
|
|
41
|
+
* @example
|
|
42
|
+
* <Link href="https://base-ui.com" external variant="underline">Base UI</Link>
|
|
43
|
+
* @example
|
|
44
|
+
* <Link render={<NextLink href="/cues" />}>Cues</Link>
|
|
45
|
+
*/
|
|
46
|
+
declare const Link: React.ForwardRefExoticComponent<LinkProps & React.RefAttributes<HTMLAnchorElement>>;
|
|
47
|
+
//#endregion
|
|
48
|
+
export { Link, LinkProps, linkVariants };
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { cn } from "../lib/cn.js";
|
|
3
|
+
import { cva } from "../lib/cva.js";
|
|
4
|
+
import * as React from "react";
|
|
5
|
+
import { Fragment, jsx, jsxs } from "react/jsx-runtime";
|
|
6
|
+
import { useRender } from "@base-ui/react/use-render";
|
|
7
|
+
//#region src/layout/link.tsx
|
|
8
|
+
/**
|
|
9
|
+
* The link recipe.
|
|
10
|
+
*
|
|
11
|
+
* The house rule is that a link is **not** underlined: in a console, body copy
|
|
12
|
+
* is rare and links are mostly labels inside dense furniture, where a rule
|
|
13
|
+
* under every one of them turns a panel into a page of hyperlinks. Colour on
|
|
14
|
+
* hover carries the affordance instead. The `underline` variant exists for the
|
|
15
|
+
* one place the rule is right — links inside a paragraph of prose, where colour
|
|
16
|
+
* alone would fail WCAG 1.4.1 — and it offsets the rule by 4px so descenders
|
|
17
|
+
* are not struck through.
|
|
18
|
+
*
|
|
19
|
+
* @example
|
|
20
|
+
* <a className={linkVariants({ variant: "underline" })} href="/docs">Docs</a>
|
|
21
|
+
*/
|
|
22
|
+
const linkVariants = cva("cursor-pointer rounded-(--radius-control) font-mono text-fg transition-colors duration-150 outline-none hover:text-accent focus-visible:outline-2 focus-visible:outline-solid focus-visible:outline-offset-2 focus-visible:outline-accent", {
|
|
23
|
+
variants: { variant: {
|
|
24
|
+
plain: "no-underline",
|
|
25
|
+
underline: "underline decoration-border underline-offset-4 hover:decoration-accent"
|
|
26
|
+
} },
|
|
27
|
+
defaultVariants: { variant: "plain" }
|
|
28
|
+
});
|
|
29
|
+
/**
|
|
30
|
+
* A text link: accent on hover, no rule unless you ask for one.
|
|
31
|
+
*
|
|
32
|
+
* @example
|
|
33
|
+
* <Link href="/patch">Patch</Link>
|
|
34
|
+
* @example
|
|
35
|
+
* <Link href="https://base-ui.com" external variant="underline">Base UI</Link>
|
|
36
|
+
* @example
|
|
37
|
+
* <Link render={<NextLink href="/cues" />}>Cues</Link>
|
|
38
|
+
*/
|
|
39
|
+
const Link = React.forwardRef(function Link({ className, variant, external = false, render, children, ...elementProps }, ref) {
|
|
40
|
+
const externalProps = external ? {
|
|
41
|
+
target: "_blank",
|
|
42
|
+
rel: elementProps.rel ?? "noreferrer noopener"
|
|
43
|
+
} : null;
|
|
44
|
+
return useRender({
|
|
45
|
+
render,
|
|
46
|
+
ref,
|
|
47
|
+
defaultTagName: "a",
|
|
48
|
+
props: {
|
|
49
|
+
...elementProps,
|
|
50
|
+
...externalProps,
|
|
51
|
+
"data-slot": "link",
|
|
52
|
+
className: cn(linkVariants({ variant }), external ? "inline-flex items-center gap-(--cue-space-1)" : null, className),
|
|
53
|
+
children: /* @__PURE__ */ jsxs(Fragment, { children: [children, external ? /* @__PURE__ */ jsx("span", {
|
|
54
|
+
"data-slot": "link-external-glyph",
|
|
55
|
+
"aria-hidden": "true",
|
|
56
|
+
className: "shrink-0 text-(length:--cue-text-micro) leading-none select-none",
|
|
57
|
+
children: "↗"
|
|
58
|
+
}) : null] })
|
|
59
|
+
}
|
|
60
|
+
});
|
|
61
|
+
});
|
|
62
|
+
//#endregion
|
|
63
|
+
export { Link, linkVariants };
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import * as React from "react";
|
|
2
|
+
//#region src/layout/pagination.d.ts
|
|
3
|
+
/** A page number, or the ellipsis standing in for a run of hidden pages. */
|
|
4
|
+
type PaginationEntry = number | "gap";
|
|
5
|
+
/**
|
|
6
|
+
* Which page buttons to draw for a given position in a run of pages.
|
|
7
|
+
*
|
|
8
|
+
* Exported and pure so the layout rule can be unit-tested on its own — the
|
|
9
|
+
* awkward cases (a window that runs off either end, a gap standing in for one
|
|
10
|
+
* page) are arithmetic, not rendering, and every pager that gets them wrong
|
|
11
|
+
* gets them wrong here.
|
|
12
|
+
*
|
|
13
|
+
* The window keeps a constant width as it travels: near either end the missing
|
|
14
|
+
* siblings are spent on the near side instead, so the control does not change
|
|
15
|
+
* size as the user pages through. A gap that would hide exactly one page is
|
|
16
|
+
* replaced by that page, because an ellipsis costs the same room as the number
|
|
17
|
+
* it is hiding.
|
|
18
|
+
*
|
|
19
|
+
* @param page The current page, 1-based.
|
|
20
|
+
* @param pageCount How many pages there are in total.
|
|
21
|
+
* @param siblingCount How many pages to show either side of the current one.
|
|
22
|
+
* @returns Page numbers and `"gap"` markers, in display order.
|
|
23
|
+
* @example
|
|
24
|
+
* paginationRange(10, 20) // [1, "gap", 9, 10, 11, "gap", 20]
|
|
25
|
+
*/
|
|
26
|
+
declare function paginationRange(page: number, pageCount: number, siblingCount?: number): PaginationEntry[];
|
|
27
|
+
interface PaginationProps extends Omit<React.ComponentPropsWithoutRef<"nav">, "onChange" | "children"> {
|
|
28
|
+
/** The current page, 1-based. */
|
|
29
|
+
page: number;
|
|
30
|
+
/** How many pages there are in total. */
|
|
31
|
+
pageCount: number;
|
|
32
|
+
/** Called with the page a control asked for. Always within `1..pageCount`. */
|
|
33
|
+
onPageChange: (page: number) => void;
|
|
34
|
+
/** How many pages to show either side of the current one. Defaults to `1`. */
|
|
35
|
+
siblingCount?: number;
|
|
36
|
+
/** The nav's accessible name. Defaults to `"Pagination"`. */
|
|
37
|
+
label?: string;
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* The pager: previous, a window of page numbers, next.
|
|
41
|
+
*
|
|
42
|
+
* Renders nothing at all when there is a single page — a control offering no
|
|
43
|
+
* choice is chrome that says "there is more here" when there is not.
|
|
44
|
+
*
|
|
45
|
+
* Every page number is a real button with a spoken name ("Page 3"), because the
|
|
46
|
+
* bare numeral is meaningless read aloud out of context; the ellipses are
|
|
47
|
+
* `aria-hidden` for the same reason breadcrumb separators are.
|
|
48
|
+
*
|
|
49
|
+
* @example
|
|
50
|
+
* <Pagination page={page} pageCount={12} onPageChange={setPage} />
|
|
51
|
+
*/
|
|
52
|
+
declare const Pagination: React.ForwardRefExoticComponent<PaginationProps & React.RefAttributes<HTMLElement>>;
|
|
53
|
+
//#endregion
|
|
54
|
+
export { Pagination, PaginationEntry, PaginationProps, paginationRange };
|
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { cn } from "../lib/cn.js";
|
|
3
|
+
import { ChevronLeftGlyph, ChevronRightGlyph } from "./_glyphs.js";
|
|
4
|
+
import { IconButton } from "../primitives/icon-button.js";
|
|
5
|
+
import * as React from "react";
|
|
6
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
7
|
+
//#region src/layout/pagination.tsx
|
|
8
|
+
/**
|
|
9
|
+
* Which page buttons to draw for a given position in a run of pages.
|
|
10
|
+
*
|
|
11
|
+
* Exported and pure so the layout rule can be unit-tested on its own — the
|
|
12
|
+
* awkward cases (a window that runs off either end, a gap standing in for one
|
|
13
|
+
* page) are arithmetic, not rendering, and every pager that gets them wrong
|
|
14
|
+
* gets them wrong here.
|
|
15
|
+
*
|
|
16
|
+
* The window keeps a constant width as it travels: near either end the missing
|
|
17
|
+
* siblings are spent on the near side instead, so the control does not change
|
|
18
|
+
* size as the user pages through. A gap that would hide exactly one page is
|
|
19
|
+
* replaced by that page, because an ellipsis costs the same room as the number
|
|
20
|
+
* it is hiding.
|
|
21
|
+
*
|
|
22
|
+
* @param page The current page, 1-based.
|
|
23
|
+
* @param pageCount How many pages there are in total.
|
|
24
|
+
* @param siblingCount How many pages to show either side of the current one.
|
|
25
|
+
* @returns Page numbers and `"gap"` markers, in display order.
|
|
26
|
+
* @example
|
|
27
|
+
* paginationRange(10, 20) // [1, "gap", 9, 10, 11, "gap", 20]
|
|
28
|
+
*/
|
|
29
|
+
function paginationRange(page, pageCount, siblingCount = 1) {
|
|
30
|
+
if (pageCount < 1) return [];
|
|
31
|
+
const run = (from, to) => Array.from({ length: Math.max(to - from + 1, 0) }, (_, index) => from + index);
|
|
32
|
+
if (pageCount <= siblingCount * 2 + 5) return run(1, pageCount);
|
|
33
|
+
const left = Math.max(page - siblingCount, 1);
|
|
34
|
+
const right = Math.min(page + siblingCount, pageCount);
|
|
35
|
+
const gapLeft = left > 2;
|
|
36
|
+
const gapRight = right < pageCount - 1;
|
|
37
|
+
const edgeRun = siblingCount * 2 + 3;
|
|
38
|
+
const entries = gapLeft ? gapRight ? [
|
|
39
|
+
1,
|
|
40
|
+
"gap",
|
|
41
|
+
...run(left, right),
|
|
42
|
+
"gap",
|
|
43
|
+
pageCount
|
|
44
|
+
] : [
|
|
45
|
+
1,
|
|
46
|
+
"gap",
|
|
47
|
+
...run(pageCount - edgeRun + 1, pageCount)
|
|
48
|
+
] : [
|
|
49
|
+
...run(1, edgeRun),
|
|
50
|
+
"gap",
|
|
51
|
+
pageCount
|
|
52
|
+
];
|
|
53
|
+
return entries.map((entry, index) => {
|
|
54
|
+
if (entry !== "gap") return entry;
|
|
55
|
+
const before = entries[index - 1];
|
|
56
|
+
const after = entries[index + 1];
|
|
57
|
+
return typeof before === "number" && typeof after === "number" && after - before === 2 ? before + 1 : entry;
|
|
58
|
+
});
|
|
59
|
+
}
|
|
60
|
+
/**
|
|
61
|
+
* One page button: a square on the short rung of the control ladder, tinted
|
|
62
|
+
* with `accent-soft` when it is the page you are on — never a solid accent
|
|
63
|
+
* fill, which at console density reads as a second, louder button.
|
|
64
|
+
*/
|
|
65
|
+
const PAGE_BUTTON_CLASSES = "inline-flex h-control-sm min-w-control-sm cursor-pointer items-center justify-center rounded-(--radius-control) border-0 bg-transparent px-(--cue-space-2) font-mono text-(length:--cue-text-ui) tabular-nums text-fg-muted 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";
|
|
66
|
+
/**
|
|
67
|
+
* The pager: previous, a window of page numbers, next.
|
|
68
|
+
*
|
|
69
|
+
* Renders nothing at all when there is a single page — a control offering no
|
|
70
|
+
* choice is chrome that says "there is more here" when there is not.
|
|
71
|
+
*
|
|
72
|
+
* Every page number is a real button with a spoken name ("Page 3"), because the
|
|
73
|
+
* bare numeral is meaningless read aloud out of context; the ellipses are
|
|
74
|
+
* `aria-hidden` for the same reason breadcrumb separators are.
|
|
75
|
+
*
|
|
76
|
+
* @example
|
|
77
|
+
* <Pagination page={page} pageCount={12} onPageChange={setPage} />
|
|
78
|
+
*/
|
|
79
|
+
const Pagination = React.forwardRef(function Pagination({ className, page, pageCount, onPageChange, siblingCount = 1, label = "Pagination", ...elementProps }, ref) {
|
|
80
|
+
if (pageCount <= 1) return null;
|
|
81
|
+
const entries = paginationRange(page, pageCount, siblingCount);
|
|
82
|
+
return /* @__PURE__ */ jsxs("nav", {
|
|
83
|
+
ref,
|
|
84
|
+
"data-slot": "pagination",
|
|
85
|
+
"aria-label": label,
|
|
86
|
+
className: cn("flex items-center gap-(--cue-space-1)", className),
|
|
87
|
+
...elementProps,
|
|
88
|
+
children: [
|
|
89
|
+
/* @__PURE__ */ jsx(IconButton, {
|
|
90
|
+
"aria-label": "Previous page",
|
|
91
|
+
icon: ChevronLeftGlyph,
|
|
92
|
+
size: "sm",
|
|
93
|
+
disabled: page <= 1,
|
|
94
|
+
onClick: () => onPageChange(page - 1)
|
|
95
|
+
}),
|
|
96
|
+
entries.map((entry, index) => entry === "gap" ? /* @__PURE__ */ jsx("span", {
|
|
97
|
+
"data-slot": "pagination-gap",
|
|
98
|
+
"aria-hidden": "true",
|
|
99
|
+
className: "inline-flex h-control-sm items-center justify-center px-(--cue-space-1) font-mono text-(length:--cue-text-ui) text-fg-subtle select-none",
|
|
100
|
+
children: "…"
|
|
101
|
+
}, `gap-${index}`) : /* @__PURE__ */ jsx("button", {
|
|
102
|
+
type: "button",
|
|
103
|
+
"data-slot": "pagination-page",
|
|
104
|
+
"aria-label": `Page ${entry}`,
|
|
105
|
+
"aria-current": entry === page ? "page" : void 0,
|
|
106
|
+
onClick: () => onPageChange(entry),
|
|
107
|
+
className: cn(PAGE_BUTTON_CLASSES, entry === page ? "bg-accent-soft text-accent" : null),
|
|
108
|
+
children: entry
|
|
109
|
+
}, entry)),
|
|
110
|
+
/* @__PURE__ */ jsx(IconButton, {
|
|
111
|
+
"aria-label": "Next page",
|
|
112
|
+
icon: ChevronRightGlyph,
|
|
113
|
+
size: "sm",
|
|
114
|
+
disabled: page >= pageCount,
|
|
115
|
+
onClick: () => onPageChange(page + 1)
|
|
116
|
+
})
|
|
117
|
+
]
|
|
118
|
+
});
|
|
119
|
+
});
|
|
120
|
+
//#endregion
|
|
121
|
+
export { Pagination, paginationRange };
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import * as React from "react";
|
|
2
|
+
import { Group, Panel, Separator } from "react-resizable-panels";
|
|
3
|
+
//#region src/layout/resizable.d.ts
|
|
4
|
+
/** Which way the panels are laid out. */
|
|
5
|
+
type ResizableOrientation = "horizontal" | "vertical";
|
|
6
|
+
interface ResizableGroupProps extends React.ComponentProps<typeof Group> {}
|
|
7
|
+
interface ResizablePanelProps extends React.ComponentProps<typeof Panel> {}
|
|
8
|
+
interface ResizableHandleProps extends React.ComponentProps<typeof Separator> {
|
|
9
|
+
/**
|
|
10
|
+
* Draw a short grip line down the middle of the handle.
|
|
11
|
+
*
|
|
12
|
+
* A 4px strip that only colours on hover is easy to miss on first sight; the
|
|
13
|
+
* grip is the standing hint that the seam is draggable, for the price of one
|
|
14
|
+
* hairline.
|
|
15
|
+
*/
|
|
16
|
+
withGrip?: boolean;
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* Split panes the user can drag, on `react-resizable-panels`.
|
|
20
|
+
*
|
|
21
|
+
* `react-resizable-panels` is an **optional peer**: import this from
|
|
22
|
+
* `@cueplusplus/ui/layout/resizable`, never from the core barrel, so an app
|
|
23
|
+
* with no split view never installs one.
|
|
24
|
+
*
|
|
25
|
+
* @example
|
|
26
|
+
* <Resizable.Group orientation="horizontal">
|
|
27
|
+
* <Resizable.Panel id="tree" defaultSize={25} minSize={15}>…</Resizable.Panel>
|
|
28
|
+
* <Resizable.Handle withGrip />
|
|
29
|
+
* <Resizable.Panel id="editor">…</Resizable.Panel>
|
|
30
|
+
* </Resizable.Group>
|
|
31
|
+
*/
|
|
32
|
+
declare const Resizable: {
|
|
33
|
+
Group: React.ForwardRefExoticComponent<ResizableGroupProps & React.RefAttributes<HTMLDivElement>>;
|
|
34
|
+
Panel: React.ForwardRefExoticComponent<ResizablePanelProps & React.RefAttributes<HTMLDivElement>>;
|
|
35
|
+
Handle: React.ForwardRefExoticComponent<ResizableHandleProps & React.RefAttributes<HTMLDivElement>>;
|
|
36
|
+
};
|
|
37
|
+
//#endregion
|
|
38
|
+
export { Resizable, ResizableGroupProps, ResizableHandleProps, ResizableOrientation, ResizablePanelProps };
|