@surflane/ui 0.0.0-stage → 0.2.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/LICENSE-APACHE +202 -0
- package/LICENSE-MIT +18 -0
- package/README.md +55 -2
- package/dist/advanced-forms.d.ts +115 -0
- package/dist/advanced-forms.js +93 -0
- package/dist/app-shell.d.ts +23 -0
- package/dist/app-shell.js +29 -0
- package/dist/button.d.ts +11 -0
- package/dist/button.js +16 -0
- package/dist/chart.d.ts +48 -0
- package/dist/chart.js +126 -0
- package/dist/commands.d.ts +47 -0
- package/dist/commands.js +27 -0
- package/dist/content.d.ts +59 -0
- package/dist/content.js +104 -0
- package/dist/context-overlays.d.ts +95 -0
- package/dist/context-overlays.js +50 -0
- package/dist/data.d.ts +95 -0
- package/dist/data.js +40 -0
- package/dist/date-picker.d.ts +23 -0
- package/dist/date-picker.js +39 -0
- package/dist/dialog-focus.d.ts +5 -0
- package/dist/dialog-focus.js +35 -0
- package/dist/dialog.d.ts +59 -0
- package/dist/dialog.js +49 -0
- package/dist/feedback.d.ts +76 -0
- package/dist/feedback.js +35 -0
- package/dist/file-upload.d.ts +77 -0
- package/dist/file-upload.js +344 -0
- package/dist/filter-bar.d.ts +17 -0
- package/dist/filter-bar.js +23 -0
- package/dist/form-state.d.ts +5 -0
- package/dist/form-state.js +63 -0
- package/dist/forms.d.ts +91 -0
- package/dist/forms.js +109 -0
- package/dist/foundations.d.ts +51 -0
- package/dist/foundations.js +55 -0
- package/dist/icon.d.ts +37 -0
- package/dist/icon.js +28 -0
- package/dist/index.d.ts +37 -0
- package/dist/index.js +38 -0
- package/dist/input-extensions.d.ts +117 -0
- package/dist/input-extensions.js +64 -0
- package/dist/input.d.ts +7 -0
- package/dist/input.js +10 -0
- package/dist/markdown.d.ts +15 -0
- package/dist/markdown.js +121 -0
- package/dist/menu.d.ts +79 -0
- package/dist/menu.js +44 -0
- package/dist/messages.d.ts +63 -0
- package/dist/messages.js +38 -0
- package/dist/navigation-menu.d.ts +52 -0
- package/dist/navigation-menu.js +31 -0
- package/dist/navigation.d.ts +107 -0
- package/dist/navigation.js +108 -0
- package/dist/otp-field.d.ts +12 -0
- package/dist/otp-field.js +46 -0
- package/dist/pagination.d.ts +23 -0
- package/dist/pagination.js +44 -0
- package/dist/panels.d.ts +66 -0
- package/dist/panels.js +99 -0
- package/dist/parts.d.ts +9 -0
- package/dist/parts.js +22 -0
- package/dist/popover.d.ts +21 -0
- package/dist/popover.js +13 -0
- package/dist/scroll-area.d.ts +8 -0
- package/dist/scroll-area.js +39 -0
- package/dist/select.d.ts +33 -0
- package/dist/select.js +97 -0
- package/dist/sizing.d.ts +13 -0
- package/dist/sizing.js +23 -0
- package/dist/slot.d.ts +2 -0
- package/dist/slot.js +10 -0
- package/dist/status.d.ts +22 -0
- package/dist/status.js +17 -0
- package/dist/syntax-engine.d.ts +5 -0
- package/dist/syntax-engine.js +129 -0
- package/dist/syntax-highlighter.d.ts +17 -0
- package/dist/syntax-highlighter.js +64 -0
- package/dist/toast.d.ts +59 -0
- package/dist/toast.js +99 -0
- package/dist/tone-transition.d.ts +4 -0
- package/dist/tone-transition.js +81 -0
- package/dist/tooltip.d.ts +11 -0
- package/dist/tooltip.js +13 -0
- package/dist/tree.d.ts +28 -0
- package/dist/tree.js +311 -0
- package/package.json +109 -4
- package/src/styles.css +3799 -0
package/dist/chart.d.ts
ADDED
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import * as React from 'react';
|
|
2
|
+
export type ChartDatum = {
|
|
3
|
+
id: string;
|
|
4
|
+
label: string;
|
|
5
|
+
values: Readonly<Record<string, number | null | undefined>>;
|
|
6
|
+
};
|
|
7
|
+
export type ChartSeries = {
|
|
8
|
+
key: string;
|
|
9
|
+
label: string;
|
|
10
|
+
};
|
|
11
|
+
export type ChartProps = Omit<React.ComponentPropsWithoutRef<'figure'>, 'children' | 'title'> & {
|
|
12
|
+
title: string;
|
|
13
|
+
description: string;
|
|
14
|
+
data: readonly ChartDatum[];
|
|
15
|
+
series: readonly ChartSeries[];
|
|
16
|
+
unit: string;
|
|
17
|
+
xLabel: string;
|
|
18
|
+
yLabel: string;
|
|
19
|
+
type?: 'line' | 'bar' | 'area';
|
|
20
|
+
height?: number;
|
|
21
|
+
locale?: string;
|
|
22
|
+
formatValue?: (value: number) => string;
|
|
23
|
+
missingLabel?: string;
|
|
24
|
+
emptyLabel?: string;
|
|
25
|
+
hiddenSeries?: readonly string[];
|
|
26
|
+
defaultHiddenSeries?: readonly string[];
|
|
27
|
+
onHiddenSeriesChange?: (keys: string[]) => void;
|
|
28
|
+
};
|
|
29
|
+
/** Cartesian trends with a persistent, keyboard-readable tooltip region and a
|
|
30
|
+
* full data-table alternative. Missing values are gaps, never fabricated zeros. */
|
|
31
|
+
export declare const Chart: React.ForwardRefExoticComponent<Omit<Omit<React.DetailedHTMLProps<React.HTMLAttributes<HTMLElement>, HTMLElement>, "ref">, "children" | "title"> & {
|
|
32
|
+
title: string;
|
|
33
|
+
description: string;
|
|
34
|
+
data: readonly ChartDatum[];
|
|
35
|
+
series: readonly ChartSeries[];
|
|
36
|
+
unit: string;
|
|
37
|
+
xLabel: string;
|
|
38
|
+
yLabel: string;
|
|
39
|
+
type?: "line" | "bar" | "area";
|
|
40
|
+
height?: number;
|
|
41
|
+
locale?: string;
|
|
42
|
+
formatValue?: (value: number) => string;
|
|
43
|
+
missingLabel?: string;
|
|
44
|
+
emptyLabel?: string;
|
|
45
|
+
hiddenSeries?: readonly string[];
|
|
46
|
+
defaultHiddenSeries?: readonly string[];
|
|
47
|
+
onHiddenSeriesChange?: (keys: string[]) => void;
|
|
48
|
+
} & React.RefAttributes<HTMLElement>>;
|
package/dist/chart.js
ADDED
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
3
|
+
import * as React from 'react';
|
|
4
|
+
import { Area, Bar, CartesianGrid, ComposedChart, Line, ReferenceLine, ResponsiveContainer, Tooltip, XAxis, YAxis, } from 'recharts';
|
|
5
|
+
import { Table } from './data.js';
|
|
6
|
+
import { Button } from './button.js';
|
|
7
|
+
const dashes = [undefined, '7 4', '2 4', '10 3 2 3', '12 5', '4 3'];
|
|
8
|
+
const colorFor = (index) => `var(--chart-series-${(index % 3) + 1})`;
|
|
9
|
+
function Marker({ cx, cy, color, index, }) {
|
|
10
|
+
if (typeof cx !== 'number' ||
|
|
11
|
+
typeof cy !== 'number' ||
|
|
12
|
+
!Number.isFinite(cx) ||
|
|
13
|
+
!Number.isFinite(cy))
|
|
14
|
+
return null;
|
|
15
|
+
const props = { fill: 'var(--canvas)', stroke: color, strokeWidth: 1.8 };
|
|
16
|
+
return index % 3 === 0 ? (_jsx("circle", { cx: cx, cy: cy, r: 3.5, ...props })) : index % 3 === 1 ? (_jsx("rect", { x: cx - 3.5, y: cy - 3.5, width: 7, height: 7, ...props })) : (_jsx("path", { d: `M${cx},${cy - 4.5}l4.5,8h-9Z`, ...props }));
|
|
17
|
+
}
|
|
18
|
+
function Pattern({ id, index, color, }) {
|
|
19
|
+
return (_jsxs("pattern", { id: id, patternUnits: 'userSpaceOnUse', width: '8', height: '8', children: [_jsx("rect", { width: '8', height: '8', fill: color }), index % 3 === 1 ? (_jsx("path", { d: 'M-2 2L2-2M0 8L8 0M6 10L10 6', stroke: 'var(--canvas)', strokeWidth: '1.5' })) : index % 3 === 2 ? (_jsx("circle", { cx: '4', cy: '4', r: '1.4', fill: 'var(--canvas)' })) : null] }));
|
|
20
|
+
}
|
|
21
|
+
/** Cartesian trends with a persistent, keyboard-readable tooltip region and a
|
|
22
|
+
* full data-table alternative. Missing values are gaps, never fabricated zeros. */
|
|
23
|
+
export const Chart = React.forwardRef(function Chart({ title, description, data, series, unit, xLabel, yLabel, type = 'line', height = 280, locale = 'en-US', formatValue, missingLabel = 'Not available', emptyLabel = 'No numeric measurements to display.', hiddenSeries, defaultHiddenSeries = [], onHiddenSeriesChange, className, ...props }, ref) {
|
|
24
|
+
const id = React.useId().replace(/[^a-zA-Z0-9_-]/g, '_');
|
|
25
|
+
const [internalHidden, setInternalHidden] = React.useState(defaultHiddenSeries);
|
|
26
|
+
const hidden = new Set(hiddenSeries ?? internalHidden);
|
|
27
|
+
const visible = series.filter((s) => !hidden.has(s.key));
|
|
28
|
+
const [host, setHost] = React.useState(null);
|
|
29
|
+
const [dismissed, setDismissed] = React.useState(false);
|
|
30
|
+
const firstLegend = React.useRef(null);
|
|
31
|
+
const [restoreRequested, setRestoreRequested] = React.useState(false);
|
|
32
|
+
React.useLayoutEffect(() => {
|
|
33
|
+
if (!restoreRequested)
|
|
34
|
+
return;
|
|
35
|
+
if (visible.length > 0)
|
|
36
|
+
firstLegend.current?.focus();
|
|
37
|
+
setRestoreRequested(false);
|
|
38
|
+
}, [restoreRequested, visible.length]);
|
|
39
|
+
const number = React.useMemo(() => new Intl.NumberFormat(locale, { maximumFractionDigits: 2 }), [locale]);
|
|
40
|
+
const compact = React.useMemo(() => new Intl.NumberFormat(locale, {
|
|
41
|
+
notation: 'compact',
|
|
42
|
+
maximumFractionDigits: 1,
|
|
43
|
+
}), [locale]);
|
|
44
|
+
const format = (value) => typeof value === 'number' && Number.isFinite(value)
|
|
45
|
+
? `${formatValue ? formatValue(value) : number.format(value)} ${unit}`
|
|
46
|
+
: missingLabel;
|
|
47
|
+
const rows = React.useMemo(() => {
|
|
48
|
+
const ids = new Set(), keys = new Set();
|
|
49
|
+
for (const s of series) {
|
|
50
|
+
if (!s.key || keys.has(s.key))
|
|
51
|
+
throw new Error('Chart series keys must be non-empty and unique');
|
|
52
|
+
keys.add(s.key);
|
|
53
|
+
}
|
|
54
|
+
return data.map((row) => {
|
|
55
|
+
if (!row.id || ids.has(row.id))
|
|
56
|
+
throw new Error('Chart datum IDs must be non-empty and unique');
|
|
57
|
+
ids.add(row.id);
|
|
58
|
+
return {
|
|
59
|
+
...row,
|
|
60
|
+
values: Object.fromEntries(series.map((s) => [
|
|
61
|
+
s.key,
|
|
62
|
+
typeof row.values[s.key] === 'number' &&
|
|
63
|
+
Number.isFinite(row.values[s.key])
|
|
64
|
+
? row.values[s.key]
|
|
65
|
+
: null,
|
|
66
|
+
])),
|
|
67
|
+
};
|
|
68
|
+
});
|
|
69
|
+
}, [data, series]);
|
|
70
|
+
const byId = new Map(rows.map((row) => [row.id, row]));
|
|
71
|
+
const values = rows
|
|
72
|
+
.flatMap((row) => visible.map((s) => row.values[s.key]))
|
|
73
|
+
.filter((value) => typeof value === 'number');
|
|
74
|
+
const min = values.reduce((a, b) => Math.min(a, b), 0), max = values.reduce((a, b) => Math.max(a, b), 0);
|
|
75
|
+
const hasValues = values.length > 0;
|
|
76
|
+
const changeHidden = (next) => {
|
|
77
|
+
if (hiddenSeries === undefined)
|
|
78
|
+
setInternalHidden(next);
|
|
79
|
+
onHiddenSeriesChange?.(next);
|
|
80
|
+
};
|
|
81
|
+
const toggle = (key) => changeHidden(series
|
|
82
|
+
.filter((s) => (s.key === key ? !hidden.has(key) : hidden.has(s.key)))
|
|
83
|
+
.map((s) => s.key));
|
|
84
|
+
const chartHeight = Number.isFinite(height) ? Math.max(200, height) : 280;
|
|
85
|
+
return (_jsxs("figure", { ...props, ref: ref, className: ['pui-chart', className].filter(Boolean).join(' '), "aria-labelledby": `${id}-title`, children: [_jsxs("figcaption", { className: 'pui-chart-caption', children: [_jsx("strong", { id: `${id}-title`, children: title }), _jsx("p", { id: `${id}-summary`, children: description })] }), _jsx("ul", { className: 'pui-chart-legend', "aria-label": `${title} series`, children: series.map((s, index) => (_jsx("li", { children: _jsxs("button", { ref: index === 0 ? firstLegend : undefined, type: 'button', className: 'pui-chart-legend-button', "aria-label": `${s.label} series`, "aria-pressed": !hidden.has(s.key), onClick: () => toggle(s.key), children: [_jsx("svg", { width: '32', height: '20', viewBox: '0 0 32 20', "aria-hidden": 'true', children: type === 'bar' ? (_jsxs(_Fragment, { children: [_jsx("defs", { children: _jsx(Pattern, { id: `${id}-legend-${index}`, color: colorFor(index), index: index }) }), _jsx("rect", { x: '4', y: '3', width: '24', height: '14', rx: '2', fill: `url(#${id}-legend-${index})` })] })) : (_jsxs(_Fragment, { children: [_jsx("path", { d: 'M1 10h30', stroke: colorFor(index), strokeWidth: '2', strokeDasharray: dashes[index % dashes.length] }), _jsx(Marker, { cx: 16, cy: 10, index: index, color: colorFor(index) })] })) }), _jsx("span", { children: s.label })] }) }, s.key))) }), _jsxs("p", { className: 'pui-chart-axis-label', children: [yLabel, " (", unit, ")"] }), hasValues ? (_jsxs(_Fragment, { children: [_jsx("p", { className: 'pui-chart-help', id: `${id}-keys`, children: "Focus the chart and use Left/Right to inspect points. Escape clears details. The data table includes every series." }), _jsx("div", { className: 'pui-chart-plot', onKeyDownCapture: (event) => {
|
|
86
|
+
if (event.key === 'Escape')
|
|
87
|
+
setDismissed(true);
|
|
88
|
+
else if (event.key === 'ArrowLeft' || event.key === 'ArrowRight')
|
|
89
|
+
setDismissed(false);
|
|
90
|
+
}, onMouseMoveCapture: () => setDismissed(false), onTouchStartCapture: () => setDismissed(false), onFocusCapture: () => setDismissed(false), children: _jsx(ResponsiveContainer, { width: '100%', height: chartHeight, minWidth: 0, initialDimension: { width: 320, height: chartHeight }, children: _jsxs(ComposedChart, { data: rows, accessibilityLayer: true, role: 'application', "aria-label": title, "aria-describedby": `${id}-summary ${id}-keys`, margin: { top: 16, right: 20, bottom: 8, left: 0 }, children: [_jsx("defs", { children: series.map((s, index) => (_jsx(Pattern, { id: `${id}-pattern-${index}`, index: index, color: colorFor(index) }, s.key))) }), _jsx(CartesianGrid, { vertical: false, stroke: 'var(--line)' }), _jsx(XAxis, { dataKey: 'id', tickFormatter: (value) => {
|
|
91
|
+
const label = byId.get(String(value))?.label ?? String(value);
|
|
92
|
+
// minTickGap already drops ticks that would overlap; the cap
|
|
93
|
+
// only keeps one very long label from crowding the axis.
|
|
94
|
+
return label.length > 24 ? label.slice(0, 23) + '…' : label;
|
|
95
|
+
}, tick: { fill: 'var(--ink-muted)', fontSize: 12 }, tickLine: false, axisLine: { stroke: 'var(--line)' }, minTickGap: 24, interval: 'preserveStartEnd' }), _jsx(YAxis, { width: 56, tickFormatter: (value) => compact.format(Number(value)), tick: { fill: 'var(--ink-muted)', fontSize: 12 }, tickLine: false, axisLine: false, domain: [min, max === min ? max + 1 : max] }), _jsx(ReferenceLine, { y: 0, stroke: 'var(--ink-muted)' }), host && (_jsx(Tooltip, { portal: host, isAnimationActive: false, active: dismissed ? false : undefined, filterNull: false, cursor: dismissed
|
|
96
|
+
? false
|
|
97
|
+
: {
|
|
98
|
+
stroke: 'var(--control-border)',
|
|
99
|
+
fill: 'transparent',
|
|
100
|
+
}, wrapperStyle: {
|
|
101
|
+
position: 'static',
|
|
102
|
+
visibility: 'visible',
|
|
103
|
+
pointerEvents: 'auto',
|
|
104
|
+
}, content: (tooltip) => {
|
|
105
|
+
const row = tooltip.active && !dismissed
|
|
106
|
+
? byId.get(String(tooltip.label))
|
|
107
|
+
: undefined;
|
|
108
|
+
return (_jsx("div", { className: 'pui-chart-readout', "data-chart-readout": row?.id, children: row ? (_jsxs(_Fragment, { children: [_jsx("strong", { children: row.label }), _jsx("ul", { children: visible.map((s) => (_jsxs("li", { children: [s.label, ": ", format(row.values[s.key])] }, s.key))) })] })) : (_jsx("span", { children: "Hover, touch or use chart arrow keys to inspect a measurement." })) }));
|
|
109
|
+
} })), series.map((s, index) => {
|
|
110
|
+
const common = {
|
|
111
|
+
name: s.label,
|
|
112
|
+
dataKey: (row) => row.values[s.key] ?? null,
|
|
113
|
+
hide: hidden.has(s.key),
|
|
114
|
+
isAnimationActive: false,
|
|
115
|
+
stroke: colorFor(index),
|
|
116
|
+
};
|
|
117
|
+
return type === 'bar' ? (_jsx(Bar, { ...common, fill: `url(#${id}-pattern-${index})`, maxBarSize: 48 }, s.key)) : type === 'area' ? (_jsx(Area, { ...common, type: 'linear', strokeWidth: 2, strokeDasharray: dashes[index % dashes.length], fill: `url(#${id}-pattern-${index})`, fillOpacity: 0.12, connectNulls: false, dot: rows.length > 40
|
|
118
|
+
? false
|
|
119
|
+
: (dot) => (_jsx(Marker, { ...dot, color: colorFor(index), index: index })), activeDot: false }, s.key)) : (_jsx(Line, { ...common, type: 'linear', strokeWidth: 2, strokeDasharray: dashes[index % dashes.length], connectNulls: false, dot: rows.length > 40
|
|
120
|
+
? false
|
|
121
|
+
: (dot) => (_jsx(Marker, { ...dot, color: colorFor(index), index: index })), activeDot: false }, s.key));
|
|
122
|
+
})] }) }) }), _jsx("p", { className: 'pui-chart-axis-label pui-chart-x-label', children: xLabel })] })) : (_jsx("div", { className: 'pui-chart-empty', role: 'status', children: visible.length === 0 && series.length > 0 ? (_jsxs(_Fragment, { children: [_jsx("p", { children: "No series selected." }), _jsx(Button, { variant: 'outline', onClick: () => {
|
|
123
|
+
setRestoreRequested(true);
|
|
124
|
+
changeHidden([]);
|
|
125
|
+
}, children: "Show all series" })] })) : (_jsx("p", { children: emptyLabel })) })), _jsx("div", { className: 'pui-chart-inspector', ref: setHost, role: 'status', "aria-live": 'polite', "aria-atomic": 'true', "aria-label": `${title} values`, hidden: !hasValues }), _jsxs("details", { className: 'pui-chart-table', children: [_jsx("summary", { children: "View data table" }), _jsx(Table.Container, { label: `${title} data table`, orientation: 'both', scrollChain: 'contain', style: { maxHeight: 320 }, children: _jsxs(Table.Root, { children: [_jsxs(Table.Caption, { children: ["All input measurements, including hidden series. Unit: ", unit, "."] }), _jsx(Table.Head, { children: _jsxs(Table.Row, { children: [_jsx(Table.HeaderCell, { scope: 'col', children: xLabel }), series.map((s) => (_jsxs(Table.HeaderCell, { scope: 'col', children: [s.label, " (", unit, ")"] }, s.key)))] }) }), _jsx(Table.Body, { children: rows.length ? (rows.map((row) => (_jsxs(Table.Row, { children: [_jsx(Table.HeaderCell, { scope: 'row', children: row.label }), series.map((s) => (_jsx(Table.Cell, { children: format(row.values[s.key]) }, s.key)))] }, row.id)))) : (_jsx(Table.Row, { children: _jsx(Table.Cell, { colSpan: series.length + 1, children: "No rows." }) })) })] }) })] })] }));
|
|
126
|
+
});
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import * as React from 'react';
|
|
2
|
+
import { type ComponentSizeAlias } from './sizing.js';
|
|
3
|
+
import { Toggle as BaseToggle } from '@base-ui/react/toggle';
|
|
4
|
+
import { ToggleGroup as BaseToggleGroup } from '@base-ui/react/toggle-group';
|
|
5
|
+
export declare function Toggle<Value extends string>({ className, size, ref, ...props }: BaseToggle.Props<Value> & {
|
|
6
|
+
size?: ComponentSizeAlias | 'icon';
|
|
7
|
+
ref?: React.Ref<HTMLButtonElement>;
|
|
8
|
+
}): React.JSX.Element;
|
|
9
|
+
export declare function ToggleGroup<Value extends string>({ className, ref, ...props }: BaseToggleGroup.Props<Value> & {
|
|
10
|
+
ref?: React.Ref<HTMLDivElement>;
|
|
11
|
+
}): React.JSX.Element;
|
|
12
|
+
export declare const Toolbar: {
|
|
13
|
+
Root: React.ForwardRefExoticComponent<Omit<Omit<Omit<import("@base-ui/react/toolbar").ToolbarRootProps, "ref"> & React.RefAttributes<HTMLDivElement>, "ref">, "size"> & {
|
|
14
|
+
size?: import("./sizing.js").ComponentSize;
|
|
15
|
+
} & React.RefAttributes<HTMLDivElement>>;
|
|
16
|
+
Group: React.ForwardRefExoticComponent<Omit<Omit<Omit<import("@base-ui/react/toolbar").ToolbarGroupProps, "ref"> & React.RefAttributes<HTMLDivElement>, "ref">, "size"> & {
|
|
17
|
+
size?: import("./sizing.js").ComponentSize;
|
|
18
|
+
} & React.RefAttributes<HTMLDivElement>>;
|
|
19
|
+
Button: React.ForwardRefExoticComponent<Omit<Omit<Omit<import("@base-ui/react/toolbar").ToolbarButtonProps, "ref"> & React.RefAttributes<HTMLButtonElement>, "ref">, "size"> & {
|
|
20
|
+
size?: import("./sizing.js").ComponentSize;
|
|
21
|
+
} & React.RefAttributes<HTMLButtonElement>>;
|
|
22
|
+
Link: React.ForwardRefExoticComponent<Omit<Omit<Omit<import("@base-ui/react/toolbar").ToolbarLinkProps, "ref"> & React.RefAttributes<HTMLAnchorElement>, "ref">, "size"> & {
|
|
23
|
+
size?: import("./sizing.js").ComponentSize;
|
|
24
|
+
} & React.RefAttributes<HTMLAnchorElement>>;
|
|
25
|
+
Input: React.ForwardRefExoticComponent<Omit<Omit<Omit<import("@base-ui/react/toolbar").ToolbarInputProps, "ref"> & React.RefAttributes<HTMLInputElement>, "ref">, "size"> & {
|
|
26
|
+
size?: import("./sizing.js").ComponentSize;
|
|
27
|
+
} & React.RefAttributes<HTMLInputElement>>;
|
|
28
|
+
Separator: React.ForwardRefExoticComponent<Omit<Omit<Omit<import("@base-ui/react/toolbar").ToolbarSeparatorProps, "ref"> & React.RefAttributes<HTMLDivElement>, "ref">, "size"> & {
|
|
29
|
+
size?: import("./sizing.js").ComponentSize;
|
|
30
|
+
} & React.RefAttributes<HTMLDivElement>>;
|
|
31
|
+
};
|
|
32
|
+
export declare const Menubar: React.ForwardRefExoticComponent<Omit<Omit<Omit<import("@base-ui/react/menubar").MenubarProps, "ref"> & React.RefAttributes<HTMLDivElement>, "ref">, "size"> & {
|
|
33
|
+
size?: import("./sizing.js").ComponentSize;
|
|
34
|
+
} & React.RefAttributes<HTMLDivElement>>;
|
|
35
|
+
export declare const ToolbarButton: React.ForwardRefExoticComponent<Omit<Omit<Omit<import("@base-ui/react/toolbar").ToolbarButtonProps, "ref"> & React.RefAttributes<HTMLButtonElement>, "ref">, "size"> & {
|
|
36
|
+
size?: import("./sizing.js").ComponentSize;
|
|
37
|
+
} & React.RefAttributes<HTMLButtonElement>>, ToolbarGroup: React.ForwardRefExoticComponent<Omit<Omit<Omit<import("@base-ui/react/toolbar").ToolbarGroupProps, "ref"> & React.RefAttributes<HTMLDivElement>, "ref">, "size"> & {
|
|
38
|
+
size?: import("./sizing.js").ComponentSize;
|
|
39
|
+
} & React.RefAttributes<HTMLDivElement>>, ToolbarInput: React.ForwardRefExoticComponent<Omit<Omit<Omit<import("@base-ui/react/toolbar").ToolbarInputProps, "ref"> & React.RefAttributes<HTMLInputElement>, "ref">, "size"> & {
|
|
40
|
+
size?: import("./sizing.js").ComponentSize;
|
|
41
|
+
} & React.RefAttributes<HTMLInputElement>>, ToolbarLink: React.ForwardRefExoticComponent<Omit<Omit<Omit<import("@base-ui/react/toolbar").ToolbarLinkProps, "ref"> & React.RefAttributes<HTMLAnchorElement>, "ref">, "size"> & {
|
|
42
|
+
size?: import("./sizing.js").ComponentSize;
|
|
43
|
+
} & React.RefAttributes<HTMLAnchorElement>>, ToolbarRoot: React.ForwardRefExoticComponent<Omit<Omit<Omit<import("@base-ui/react/toolbar").ToolbarRootProps, "ref"> & React.RefAttributes<HTMLDivElement>, "ref">, "size"> & {
|
|
44
|
+
size?: import("./sizing.js").ComponentSize;
|
|
45
|
+
} & React.RefAttributes<HTMLDivElement>>, ToolbarSeparator: React.ForwardRefExoticComponent<Omit<Omit<Omit<import("@base-ui/react/toolbar").ToolbarSeparatorProps, "ref"> & React.RefAttributes<HTMLDivElement>, "ref">, "size"> & {
|
|
46
|
+
size?: import("./sizing.js").ComponentSize;
|
|
47
|
+
} & React.RefAttributes<HTMLDivElement>>;
|
package/dist/commands.js
ADDED
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
3
|
+
import { useComponentSize } from './sizing.js';
|
|
4
|
+
import { Toggle as BaseToggle } from '@base-ui/react/toggle';
|
|
5
|
+
import { ToggleGroup as BaseToggleGroup } from '@base-ui/react/toggle-group';
|
|
6
|
+
import { Toolbar as BaseToolbar } from '@base-ui/react/toolbar';
|
|
7
|
+
import { Menubar as BaseMenubar } from '@base-ui/react/menubar';
|
|
8
|
+
import { skin, part } from './parts.js';
|
|
9
|
+
export function Toggle({ className, size, ref, ...props }) {
|
|
10
|
+
const scheme = useComponentSize(size === 'icon' ? undefined : size);
|
|
11
|
+
return (_jsx(BaseToggle, { ...props, ref: ref, className: skin('pui-button pui-toggle', className), "data-size": size, "data-ui-size": scheme }));
|
|
12
|
+
}
|
|
13
|
+
export function ToggleGroup({ className, ref, ...props }) {
|
|
14
|
+
return (_jsx(BaseToggleGroup, { ...props, ref: ref, className: skin('pui-toggle-group', className) }));
|
|
15
|
+
}
|
|
16
|
+
export const Toolbar = {
|
|
17
|
+
...BaseToolbar,
|
|
18
|
+
Root: part(BaseToolbar.Root, 'pui-toolbar'),
|
|
19
|
+
Group: part(BaseToolbar.Group, 'pui-toolbar-group'),
|
|
20
|
+
Button: part(BaseToolbar.Button, 'pui-button pui-toolbar-button'),
|
|
21
|
+
Link: part(BaseToolbar.Link, 'pui-button pui-toolbar-link'),
|
|
22
|
+
Input: part(BaseToolbar.Input, 'pui-input pui-toolbar-input'),
|
|
23
|
+
Separator: part(BaseToolbar.Separator, 'pui-toolbar-separator'),
|
|
24
|
+
};
|
|
25
|
+
export const Menubar = part(BaseMenubar, 'pui-menubar');
|
|
26
|
+
// Flat names for React Server Components, which cannot dot into client exports.
|
|
27
|
+
export const { Button: ToolbarButton, Group: ToolbarGroup, Input: ToolbarInput, Link: ToolbarLink, Root: ToolbarRoot, Separator: ToolbarSeparator, } = Toolbar;
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
import * as React from 'react';
|
|
2
|
+
declare const CardRoot: React.ForwardRefExoticComponent<Omit<Omit<React.ClassAttributes<HTMLDivElement> & React.HTMLAttributes<HTMLDivElement> & {
|
|
3
|
+
tone?: "canvas" | "subtle";
|
|
4
|
+
padding?: import("./foundations.js").Space;
|
|
5
|
+
}, "ref"> & React.RefAttributes<HTMLDivElement>, "ref"> & React.RefAttributes<HTMLDivElement>>;
|
|
6
|
+
declare const CardTitle: React.ForwardRefExoticComponent<Omit<React.DetailedHTMLProps<React.HTMLAttributes<HTMLHeadingElement>, HTMLHeadingElement>, "ref"> & {
|
|
7
|
+
level?: 2 | 3 | 4 | 5 | 6;
|
|
8
|
+
} & React.RefAttributes<HTMLHeadingElement>>;
|
|
9
|
+
export declare const Card: {
|
|
10
|
+
Root: React.ForwardRefExoticComponent<Omit<Omit<React.ClassAttributes<HTMLDivElement> & React.HTMLAttributes<HTMLDivElement> & {
|
|
11
|
+
tone?: "canvas" | "subtle";
|
|
12
|
+
padding?: import("./foundations.js").Space;
|
|
13
|
+
}, "ref"> & React.RefAttributes<HTMLDivElement>, "ref"> & React.RefAttributes<HTMLDivElement>>;
|
|
14
|
+
Header: React.ForwardRefExoticComponent<Omit<Omit<React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>, "ref">, "size"> & {
|
|
15
|
+
size?: import("./sizing.js").ComponentSize;
|
|
16
|
+
} & React.RefAttributes<HTMLDivElement>>;
|
|
17
|
+
Title: React.ForwardRefExoticComponent<Omit<React.DetailedHTMLProps<React.HTMLAttributes<HTMLHeadingElement>, HTMLHeadingElement>, "ref"> & {
|
|
18
|
+
level?: 2 | 3 | 4 | 5 | 6;
|
|
19
|
+
} & React.RefAttributes<HTMLHeadingElement>>;
|
|
20
|
+
Description: React.ForwardRefExoticComponent<Omit<Omit<React.DetailedHTMLProps<React.HTMLAttributes<HTMLParagraphElement>, HTMLParagraphElement>, "ref">, "size"> & {
|
|
21
|
+
size?: import("./sizing.js").ComponentSize;
|
|
22
|
+
} & React.RefAttributes<HTMLParagraphElement>>;
|
|
23
|
+
Body: React.ForwardRefExoticComponent<Omit<Omit<React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>, "ref">, "size"> & {
|
|
24
|
+
size?: import("./sizing.js").ComponentSize;
|
|
25
|
+
} & React.RefAttributes<HTMLDivElement>>;
|
|
26
|
+
Footer: React.ForwardRefExoticComponent<Omit<Omit<React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>, "ref">, "size"> & {
|
|
27
|
+
size?: import("./sizing.js").ComponentSize;
|
|
28
|
+
} & React.RefAttributes<HTMLDivElement>>;
|
|
29
|
+
};
|
|
30
|
+
export type CodeBlockProps = Omit<React.ComponentPropsWithoutRef<'div'>, 'children' | 'onCopy'> & {
|
|
31
|
+
code: string;
|
|
32
|
+
label?: string;
|
|
33
|
+
language?: string;
|
|
34
|
+
wrap?: boolean;
|
|
35
|
+
copyLabel?: string;
|
|
36
|
+
copiedLabel?: string;
|
|
37
|
+
copyErrorLabel?: string;
|
|
38
|
+
onCopy?: (code: string) => void | Promise<void>;
|
|
39
|
+
};
|
|
40
|
+
export declare const CodeBlock: React.ForwardRefExoticComponent<Omit<Omit<React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>, "ref">, "children" | "onCopy"> & {
|
|
41
|
+
code: string;
|
|
42
|
+
label?: string;
|
|
43
|
+
language?: string;
|
|
44
|
+
wrap?: boolean;
|
|
45
|
+
copyLabel?: string;
|
|
46
|
+
copiedLabel?: string;
|
|
47
|
+
copyErrorLabel?: string;
|
|
48
|
+
onCopy?: (code: string) => void | Promise<void>;
|
|
49
|
+
} & React.RefAttributes<HTMLDivElement>>;
|
|
50
|
+
export { CardRoot, CardTitle };
|
|
51
|
+
export declare const CardHeader: React.ForwardRefExoticComponent<Omit<Omit<React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>, "ref">, "size"> & {
|
|
52
|
+
size?: import("./sizing.js").ComponentSize;
|
|
53
|
+
} & React.RefAttributes<HTMLDivElement>>, CardDescription: React.ForwardRefExoticComponent<Omit<Omit<React.DetailedHTMLProps<React.HTMLAttributes<HTMLParagraphElement>, HTMLParagraphElement>, "ref">, "size"> & {
|
|
54
|
+
size?: import("./sizing.js").ComponentSize;
|
|
55
|
+
} & React.RefAttributes<HTMLParagraphElement>>, CardBody: React.ForwardRefExoticComponent<Omit<Omit<React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>, "ref">, "size"> & {
|
|
56
|
+
size?: import("./sizing.js").ComponentSize;
|
|
57
|
+
} & React.RefAttributes<HTMLDivElement>>, CardFooter: React.ForwardRefExoticComponent<Omit<Omit<React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>, "ref">, "size"> & {
|
|
58
|
+
size?: import("./sizing.js").ComponentSize;
|
|
59
|
+
} & React.RefAttributes<HTMLDivElement>>;
|
package/dist/content.js
ADDED
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
|
+
import * as React from 'react';
|
|
4
|
+
import { Surface } from './foundations.js';
|
|
5
|
+
import { part } from './parts.js';
|
|
6
|
+
import { Button } from './button.js';
|
|
7
|
+
import { SyntaxHighlighter } from './syntax-highlighter.js';
|
|
8
|
+
import { ScrollArea } from './scroll-area.js';
|
|
9
|
+
const CardRoot = React.forwardRef(function CardRoot({ className, padding, ...props }, ref) {
|
|
10
|
+
return (_jsx(Surface, { ...props, padding: padding, ref: ref, className: ['pui-card', className].filter(Boolean).join(' ') }));
|
|
11
|
+
});
|
|
12
|
+
const CardTitle = React.forwardRef(function CardTitle({ level = 3, className, ...props }, ref) {
|
|
13
|
+
return React.createElement(`h${level}`, {
|
|
14
|
+
...props,
|
|
15
|
+
ref,
|
|
16
|
+
className: ['pui-card-title', className].filter(Boolean).join(' '),
|
|
17
|
+
});
|
|
18
|
+
});
|
|
19
|
+
export const Card = {
|
|
20
|
+
Root: CardRoot,
|
|
21
|
+
Header: part('div', 'pui-card-header'),
|
|
22
|
+
Title: CardTitle,
|
|
23
|
+
Description: part('p', 'pui-card-description'),
|
|
24
|
+
Body: part('div', 'pui-card-body'),
|
|
25
|
+
Footer: part('div', 'pui-card-footer'),
|
|
26
|
+
};
|
|
27
|
+
const copyIcons = {
|
|
28
|
+
idle: (_jsxs(_Fragment, { children: [_jsx("rect", { x: '8', y: '8', width: '12', height: '12', rx: '2' }), _jsx("path", { d: 'M16 8V4H4v12h4' })] })),
|
|
29
|
+
copied: _jsx("path", { d: 'm5 12.5 4.5 4.5L19 7.5' }),
|
|
30
|
+
failed: (_jsx("path", { d: 'M12 7v6m0 4v.01M4.5 12a7.5 7.5 0 1 0 15 0 7.5 7.5 0 0 0-15 0' })),
|
|
31
|
+
};
|
|
32
|
+
// Feedback stays inside the copy button and returns to the action after this long.
|
|
33
|
+
const copyFeedbackDuration = 2000;
|
|
34
|
+
export const CodeBlock = React.forwardRef(function CodeBlock({ code, label = 'Code', language, wrap = false, copyLabel = 'Copy code', copiedLabel = 'Copied', copyErrorLabel = 'Copy unavailable', onCopy, className, ...props }, ref) {
|
|
35
|
+
const [state, setState] = React.useState('idle');
|
|
36
|
+
// After the first copy, each change of label fades in; the first render does not.
|
|
37
|
+
const [used, setUsed] = React.useState(false);
|
|
38
|
+
const revision = React.useRef(0), mounted = React.useRef(false), timer = React.useRef(undefined);
|
|
39
|
+
const button = React.useRef(null), source = React.useRef(null);
|
|
40
|
+
React.useEffect(() => {
|
|
41
|
+
mounted.current = true;
|
|
42
|
+
return () => {
|
|
43
|
+
mounted.current = false;
|
|
44
|
+
revision.current++;
|
|
45
|
+
clearTimeout(timer.current);
|
|
46
|
+
};
|
|
47
|
+
}, []);
|
|
48
|
+
React.useEffect(() => {
|
|
49
|
+
revision.current++;
|
|
50
|
+
clearTimeout(timer.current);
|
|
51
|
+
setState('idle');
|
|
52
|
+
}, [code]);
|
|
53
|
+
// The button keeps its resting width, so the feedback never moves the toolbar.
|
|
54
|
+
React.useLayoutEffect(() => {
|
|
55
|
+
const element = button.current;
|
|
56
|
+
if (!element || state !== 'idle')
|
|
57
|
+
return;
|
|
58
|
+
const measure = () => {
|
|
59
|
+
element.style.minInlineSize = '';
|
|
60
|
+
element.style.minInlineSize = `${element.getBoundingClientRect().width}px`;
|
|
61
|
+
};
|
|
62
|
+
measure();
|
|
63
|
+
document.fonts?.ready.then(() => {
|
|
64
|
+
if (mounted.current)
|
|
65
|
+
measure();
|
|
66
|
+
});
|
|
67
|
+
}, [copyLabel, state]);
|
|
68
|
+
async function copy() {
|
|
69
|
+
const request = ++revision.current;
|
|
70
|
+
clearTimeout(timer.current);
|
|
71
|
+
setUsed(true);
|
|
72
|
+
setState('busy');
|
|
73
|
+
let outcome;
|
|
74
|
+
try {
|
|
75
|
+
if (onCopy)
|
|
76
|
+
await onCopy(code);
|
|
77
|
+
else
|
|
78
|
+
await navigator.clipboard.writeText(code);
|
|
79
|
+
outcome = 'copied';
|
|
80
|
+
}
|
|
81
|
+
catch {
|
|
82
|
+
outcome = 'failed';
|
|
83
|
+
}
|
|
84
|
+
if (!mounted.current || request !== revision.current)
|
|
85
|
+
return;
|
|
86
|
+
setState(outcome);
|
|
87
|
+
// A failed copy selects the source, so the keyboard copy shortcut works next.
|
|
88
|
+
if (outcome === 'failed' && source.current)
|
|
89
|
+
window.getSelection()?.selectAllChildren(source.current);
|
|
90
|
+
timer.current = setTimeout(() => {
|
|
91
|
+
if (mounted.current && request === revision.current)
|
|
92
|
+
setState('idle');
|
|
93
|
+
}, copyFeedbackDuration);
|
|
94
|
+
}
|
|
95
|
+
const icon = state === 'copied' || state === 'failed' ? state : 'idle';
|
|
96
|
+
return (_jsxs("div", { ...props, ref: ref, "data-wrap": wrap || undefined, className: ['pui-code-block', className].filter(Boolean).join(' '), children: [_jsxs("div", { className: 'pui-code-toolbar', children: [_jsxs("span", { className: 'pui-code-label', children: [label, language && _jsx("span", { className: 'pui-code-language', children: language })] }), _jsxs(Button, { ref: button, type: 'button', variant: 'outline', size: 'sm', className: 'pui-code-copy', onClick: copy, disabled: state === 'busy', "aria-busy": state === 'busy' || undefined, "data-copy-state": icon === 'idle' ? undefined : icon, "data-copy-used": used || undefined, children: [_jsx("svg", { className: 'pui-code-copy-icon', width: '14', height: '14', viewBox: '0 0 24 24', fill: 'none', stroke: 'currentColor', strokeWidth: '1.6', strokeLinecap: 'round', strokeLinejoin: 'round', "aria-hidden": 'true', children: copyIcons[icon] }, icon), _jsx("span", { "aria-live": 'polite', children: _jsx("span", { className: 'pui-code-copy-label', children: state === 'copied'
|
|
97
|
+
? copiedLabel
|
|
98
|
+
: state === 'failed'
|
|
99
|
+
? copyErrorLabel
|
|
100
|
+
: copyLabel }, icon) })] })] }), _jsx(ScrollArea, { label: label, orientation: 'horizontal', children: _jsx("pre", { ref: source, className: 'pui-code-text', children: _jsx(SyntaxHighlighter, { code: code, language: language, inline: true }) }) })] }));
|
|
101
|
+
});
|
|
102
|
+
// Flat names for React Server Components, which cannot dot into client exports.
|
|
103
|
+
export { CardRoot, CardTitle };
|
|
104
|
+
export const { Header: CardHeader, Description: CardDescription, Body: CardBody, Footer: CardFooter, } = Card;
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
import * as React from 'react';
|
|
2
|
+
import { ContextMenu as BaseContextMenu } from '@base-ui/react/context-menu';
|
|
3
|
+
import { PreviewCard as BasePreviewCard } from '@base-ui/react/preview-card';
|
|
4
|
+
/** Same menu anatomy and styling, with the context-specific cursor positioner. */
|
|
5
|
+
export declare const ContextMenu: {
|
|
6
|
+
Trigger: React.ForwardRefExoticComponent<Omit<Omit<Omit<import("@base-ui/react/context-menu").ContextMenuTriggerProps, "ref"> & React.RefAttributes<HTMLDivElement>, "ref">, "size"> & {
|
|
7
|
+
size?: import("./sizing.js").ComponentSize;
|
|
8
|
+
} & React.RefAttributes<HTMLDivElement>>;
|
|
9
|
+
Positioner: React.ForwardRefExoticComponent<Omit<Omit<import("@base-ui/react/context-menu").ContextMenuPositionerProps & React.RefAttributes<HTMLDivElement>, "ref">, "size"> & {
|
|
10
|
+
size?: import("./sizing.js").ComponentSize;
|
|
11
|
+
} & React.RefAttributes<HTMLDivElement>>;
|
|
12
|
+
Content: React.ForwardRefExoticComponent<Omit<Omit<import("@base-ui/react/context-menu").ContextMenuPopupProps, "ref"> & React.RefAttributes<HTMLDivElement>, "ref"> & {
|
|
13
|
+
positionerProps?: React.ComponentPropsWithoutRef<typeof BaseContextMenu.Positioner>;
|
|
14
|
+
} & React.RefAttributes<HTMLDivElement>>;
|
|
15
|
+
Popup: React.ForwardRefExoticComponent<Omit<Omit<Omit<import("@base-ui/react/context-menu").ContextMenuPopupProps, "ref"> & React.RefAttributes<HTMLDivElement>, "ref">, "size"> & {
|
|
16
|
+
size?: import("./sizing.js").ComponentSize;
|
|
17
|
+
} & React.RefAttributes<HTMLDivElement>>;
|
|
18
|
+
Item: React.ForwardRefExoticComponent<Omit<Omit<Omit<import("@base-ui/react/context-menu").ContextMenuItemProps, "ref"> & React.RefAttributes<HTMLElement>, "ref">, "size"> & {
|
|
19
|
+
size?: import("./sizing.js").ComponentSize;
|
|
20
|
+
} & React.RefAttributes<HTMLDivElement>>;
|
|
21
|
+
LinkItem: React.ForwardRefExoticComponent<Omit<Omit<Omit<import("@base-ui/react/context-menu").ContextMenuLinkItemProps, "ref"> & React.RefAttributes<Element>, "ref">, "size"> & {
|
|
22
|
+
size?: import("./sizing.js").ComponentSize;
|
|
23
|
+
} & React.RefAttributes<HTMLAnchorElement>>;
|
|
24
|
+
CheckboxItem: React.ForwardRefExoticComponent<Omit<Omit<Omit<import("@base-ui/react/context-menu").ContextMenuCheckboxItemProps, "ref"> & React.RefAttributes<HTMLElement>, "ref">, "size"> & {
|
|
25
|
+
size?: import("./sizing.js").ComponentSize;
|
|
26
|
+
} & React.RefAttributes<HTMLDivElement>>;
|
|
27
|
+
CheckboxItemIndicator: React.ForwardRefExoticComponent<Omit<Omit<import("@base-ui/react/context-menu").ContextMenuCheckboxItemIndicatorProps, "ref"> & React.RefAttributes<HTMLSpanElement>, "ref"> & React.RefAttributes<HTMLSpanElement>>;
|
|
28
|
+
RadioItem: React.ForwardRefExoticComponent<Omit<Omit<Omit<import("@base-ui/react/context-menu").ContextMenuRadioItemProps, "ref"> & React.RefAttributes<HTMLElement>, "ref">, "size"> & {
|
|
29
|
+
size?: import("./sizing.js").ComponentSize;
|
|
30
|
+
} & React.RefAttributes<HTMLDivElement>>;
|
|
31
|
+
RadioItemIndicator: React.ForwardRefExoticComponent<Omit<Omit<import("@base-ui/react/context-menu").ContextMenuRadioItemIndicatorProps, "ref"> & React.RefAttributes<HTMLSpanElement>, "ref"> & React.RefAttributes<HTMLSpanElement>>;
|
|
32
|
+
GroupLabel: React.ForwardRefExoticComponent<Omit<Omit<Omit<import("@base-ui/react/context-menu").ContextMenuGroupLabelProps, "ref"> & React.RefAttributes<HTMLDivElement>, "ref">, "size"> & {
|
|
33
|
+
size?: import("./sizing.js").ComponentSize;
|
|
34
|
+
} & React.RefAttributes<HTMLDivElement>>;
|
|
35
|
+
Separator: React.ForwardRefExoticComponent<Omit<Omit<Omit<import("@base-ui/react").SeparatorProps, "ref"> & React.RefAttributes<HTMLDivElement>, "ref">, "size"> & {
|
|
36
|
+
size?: import("./sizing.js").ComponentSize;
|
|
37
|
+
} & React.RefAttributes<HTMLDivElement>>;
|
|
38
|
+
SubmenuTrigger: React.ForwardRefExoticComponent<Omit<Omit<import("@base-ui/react/context-menu").ContextMenuSubmenuTriggerProps, "ref"> & React.RefAttributes<HTMLElement>, "ref"> & {
|
|
39
|
+
indicator?: React.ReactNode;
|
|
40
|
+
} & React.RefAttributes<HTMLDivElement>>;
|
|
41
|
+
Root: typeof BaseContextMenu.Root;
|
|
42
|
+
Backdrop: React.ForwardRefExoticComponent<Omit<import("@base-ui/react/context-menu").ContextMenuBackdropProps, "ref"> & React.RefAttributes<HTMLDivElement>>;
|
|
43
|
+
Portal: React.ForwardRefExoticComponent<Omit<import("@base-ui/react/context-menu").ContextMenuPortalProps, "ref"> & React.RefAttributes<HTMLDivElement>>;
|
|
44
|
+
Arrow: React.ForwardRefExoticComponent<Omit<import("@base-ui/react/context-menu").ContextMenuArrowProps, "ref"> & React.RefAttributes<HTMLDivElement>>;
|
|
45
|
+
Group: React.ForwardRefExoticComponent<Omit<import("@base-ui/react/context-menu").ContextMenuGroupProps, "ref"> & React.RefAttributes<HTMLDivElement>>;
|
|
46
|
+
RadioGroup: React.NamedExoticComponent<Omit<import("@base-ui/react/context-menu").ContextMenuRadioGroupProps, "ref"> & React.RefAttributes<HTMLDivElement>>;
|
|
47
|
+
SubmenuRoot: typeof BaseContextMenu.SubmenuRoot;
|
|
48
|
+
};
|
|
49
|
+
declare function PreviewTrigger<Payload>(props: BasePreviewCard.Trigger.Props<Payload> & React.RefAttributes<HTMLElement>): React.JSX.Element;
|
|
50
|
+
export declare const PreviewCard: {
|
|
51
|
+
Trigger: typeof PreviewTrigger;
|
|
52
|
+
Positioner: React.ForwardRefExoticComponent<Omit<Omit<Omit<import("@base-ui/react/preview-card").PreviewCardPositionerProps, "ref"> & React.RefAttributes<HTMLDivElement>, "ref">, "size"> & {
|
|
53
|
+
size?: import("./sizing.js").ComponentSize;
|
|
54
|
+
} & React.RefAttributes<HTMLDivElement>>;
|
|
55
|
+
Popup: React.ForwardRefExoticComponent<Omit<Omit<import("@base-ui/react/preview-card").PreviewCardPopupProps, "ref"> & React.RefAttributes<HTMLDivElement>, "ref"> & React.RefAttributes<HTMLDivElement>>;
|
|
56
|
+
Content: React.ForwardRefExoticComponent<Omit<Omit<import("@base-ui/react/preview-card").PreviewCardPopupProps, "ref"> & React.RefAttributes<HTMLDivElement>, "ref"> & {
|
|
57
|
+
positionerProps?: React.ComponentPropsWithoutRef<typeof BasePreviewCard.Positioner>;
|
|
58
|
+
} & React.RefAttributes<HTMLDivElement>>;
|
|
59
|
+
Root: <Payload>(props: BasePreviewCard.Root.Props<Payload>) => React.JSX.Element;
|
|
60
|
+
Portal: React.ForwardRefExoticComponent<Omit<import("@base-ui/react/preview-card").PreviewCardPortalProps, "ref"> & React.RefAttributes<HTMLDivElement>>;
|
|
61
|
+
Arrow: React.ForwardRefExoticComponent<Omit<import("@base-ui/react/preview-card").PreviewCardArrowProps, "ref"> & React.RefAttributes<HTMLDivElement>>;
|
|
62
|
+
Backdrop: React.ForwardRefExoticComponent<Omit<import("@base-ui/react/preview-card").PreviewCardBackdropProps, "ref"> & React.RefAttributes<HTMLDivElement>>;
|
|
63
|
+
Viewport: React.ForwardRefExoticComponent<Omit<import("@base-ui/react/preview-card").PreviewCardViewportProps, "ref"> & React.RefAttributes<HTMLDivElement>>;
|
|
64
|
+
createHandle: typeof BasePreviewCard.createHandle;
|
|
65
|
+
Handle: typeof BasePreviewCard.Handle;
|
|
66
|
+
};
|
|
67
|
+
export declare const ContextMenuArrow: React.ForwardRefExoticComponent<Omit<import("@base-ui/react/context-menu").ContextMenuArrowProps, "ref"> & React.RefAttributes<HTMLDivElement>>, ContextMenuBackdrop: React.ForwardRefExoticComponent<Omit<import("@base-ui/react/context-menu").ContextMenuBackdropProps, "ref"> & React.RefAttributes<HTMLDivElement>>, ContextMenuCheckboxItem: React.ForwardRefExoticComponent<Omit<Omit<Omit<import("@base-ui/react/context-menu").ContextMenuCheckboxItemProps, "ref"> & React.RefAttributes<HTMLElement>, "ref">, "size"> & {
|
|
68
|
+
size?: import("./sizing.js").ComponentSize;
|
|
69
|
+
} & React.RefAttributes<HTMLDivElement>>, ContextMenuCheckboxItemIndicator: React.ForwardRefExoticComponent<Omit<Omit<import("@base-ui/react/context-menu").ContextMenuCheckboxItemIndicatorProps, "ref"> & React.RefAttributes<HTMLSpanElement>, "ref"> & React.RefAttributes<HTMLSpanElement>>, ContextMenuGroup: React.ForwardRefExoticComponent<Omit<import("@base-ui/react/context-menu").ContextMenuGroupProps, "ref"> & React.RefAttributes<HTMLDivElement>>, ContextMenuGroupLabel: React.ForwardRefExoticComponent<Omit<Omit<Omit<import("@base-ui/react/context-menu").ContextMenuGroupLabelProps, "ref"> & React.RefAttributes<HTMLDivElement>, "ref">, "size"> & {
|
|
70
|
+
size?: import("./sizing.js").ComponentSize;
|
|
71
|
+
} & React.RefAttributes<HTMLDivElement>>, ContextMenuItem: React.ForwardRefExoticComponent<Omit<Omit<Omit<import("@base-ui/react/context-menu").ContextMenuItemProps, "ref"> & React.RefAttributes<HTMLElement>, "ref">, "size"> & {
|
|
72
|
+
size?: import("./sizing.js").ComponentSize;
|
|
73
|
+
} & React.RefAttributes<HTMLDivElement>>, ContextMenuLinkItem: React.ForwardRefExoticComponent<Omit<Omit<Omit<import("@base-ui/react/context-menu").ContextMenuLinkItemProps, "ref"> & React.RefAttributes<Element>, "ref">, "size"> & {
|
|
74
|
+
size?: import("./sizing.js").ComponentSize;
|
|
75
|
+
} & React.RefAttributes<HTMLAnchorElement>>, ContextMenuPopup: React.ForwardRefExoticComponent<Omit<Omit<Omit<import("@base-ui/react/context-menu").ContextMenuPopupProps, "ref"> & React.RefAttributes<HTMLDivElement>, "ref">, "size"> & {
|
|
76
|
+
size?: import("./sizing.js").ComponentSize;
|
|
77
|
+
} & React.RefAttributes<HTMLDivElement>>, ContextMenuPortal: React.ForwardRefExoticComponent<Omit<import("@base-ui/react/context-menu").ContextMenuPortalProps, "ref"> & React.RefAttributes<HTMLDivElement>>, ContextMenuPositioner: React.ForwardRefExoticComponent<Omit<Omit<import("@base-ui/react/context-menu").ContextMenuPositionerProps & React.RefAttributes<HTMLDivElement>, "ref">, "size"> & {
|
|
78
|
+
size?: import("./sizing.js").ComponentSize;
|
|
79
|
+
} & React.RefAttributes<HTMLDivElement>>, ContextMenuRadioGroup: React.NamedExoticComponent<Omit<import("@base-ui/react/context-menu").ContextMenuRadioGroupProps, "ref"> & React.RefAttributes<HTMLDivElement>>, ContextMenuRadioItem: React.ForwardRefExoticComponent<Omit<Omit<Omit<import("@base-ui/react/context-menu").ContextMenuRadioItemProps, "ref"> & React.RefAttributes<HTMLElement>, "ref">, "size"> & {
|
|
80
|
+
size?: import("./sizing.js").ComponentSize;
|
|
81
|
+
} & React.RefAttributes<HTMLDivElement>>, ContextMenuRadioItemIndicator: React.ForwardRefExoticComponent<Omit<Omit<import("@base-ui/react/context-menu").ContextMenuRadioItemIndicatorProps, "ref"> & React.RefAttributes<HTMLSpanElement>, "ref"> & React.RefAttributes<HTMLSpanElement>>, ContextMenuRoot: typeof BaseContextMenu.Root, ContextMenuSeparator: React.ForwardRefExoticComponent<Omit<Omit<Omit<import("@base-ui/react").SeparatorProps, "ref"> & React.RefAttributes<HTMLDivElement>, "ref">, "size"> & {
|
|
82
|
+
size?: import("./sizing.js").ComponentSize;
|
|
83
|
+
} & React.RefAttributes<HTMLDivElement>>, ContextMenuSubmenuRoot: typeof BaseContextMenu.SubmenuRoot, ContextMenuSubmenuTrigger: React.ForwardRefExoticComponent<Omit<Omit<import("@base-ui/react/context-menu").ContextMenuSubmenuTriggerProps, "ref"> & React.RefAttributes<HTMLElement>, "ref"> & {
|
|
84
|
+
indicator?: React.ReactNode;
|
|
85
|
+
} & React.RefAttributes<HTMLDivElement>>, ContextMenuTrigger: React.ForwardRefExoticComponent<Omit<Omit<Omit<import("@base-ui/react/context-menu").ContextMenuTriggerProps, "ref"> & React.RefAttributes<HTMLDivElement>, "ref">, "size"> & {
|
|
86
|
+
size?: import("./sizing.js").ComponentSize;
|
|
87
|
+
} & React.RefAttributes<HTMLDivElement>>, ContextMenuContent: React.ForwardRefExoticComponent<Omit<Omit<import("@base-ui/react/context-menu").ContextMenuPopupProps, "ref"> & React.RefAttributes<HTMLDivElement>, "ref"> & {
|
|
88
|
+
positionerProps?: React.ComponentPropsWithoutRef<typeof BaseContextMenu.Positioner>;
|
|
89
|
+
} & React.RefAttributes<HTMLDivElement>>;
|
|
90
|
+
export declare const PreviewCardArrow: React.ForwardRefExoticComponent<Omit<import("@base-ui/react/preview-card").PreviewCardArrowProps, "ref"> & React.RefAttributes<HTMLDivElement>>, PreviewCardBackdrop: React.ForwardRefExoticComponent<Omit<import("@base-ui/react/preview-card").PreviewCardBackdropProps, "ref"> & React.RefAttributes<HTMLDivElement>>, PreviewCardHandle: typeof BasePreviewCard.Handle, PreviewCardPopup: React.ForwardRefExoticComponent<Omit<Omit<import("@base-ui/react/preview-card").PreviewCardPopupProps, "ref"> & React.RefAttributes<HTMLDivElement>, "ref"> & React.RefAttributes<HTMLDivElement>>, PreviewCardPortal: React.ForwardRefExoticComponent<Omit<import("@base-ui/react/preview-card").PreviewCardPortalProps, "ref"> & React.RefAttributes<HTMLDivElement>>, PreviewCardPositioner: React.ForwardRefExoticComponent<Omit<Omit<Omit<import("@base-ui/react/preview-card").PreviewCardPositionerProps, "ref"> & React.RefAttributes<HTMLDivElement>, "ref">, "size"> & {
|
|
91
|
+
size?: import("./sizing.js").ComponentSize;
|
|
92
|
+
} & React.RefAttributes<HTMLDivElement>>, PreviewCardRoot: <Payload>(props: BasePreviewCard.Root.Props<Payload>) => React.JSX.Element, PreviewCardTrigger: typeof PreviewTrigger, PreviewCardViewport: React.ForwardRefExoticComponent<Omit<import("@base-ui/react/preview-card").PreviewCardViewportProps, "ref"> & React.RefAttributes<HTMLDivElement>>, PreviewCardContent: React.ForwardRefExoticComponent<Omit<Omit<import("@base-ui/react/preview-card").PreviewCardPopupProps, "ref"> & React.RefAttributes<HTMLDivElement>, "ref"> & {
|
|
93
|
+
positionerProps?: React.ComponentPropsWithoutRef<typeof BasePreviewCard.Positioner>;
|
|
94
|
+
} & React.RefAttributes<HTMLDivElement>>;
|
|
95
|
+
export {};
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
3
|
+
import * as React from 'react';
|
|
4
|
+
import { ContextMenu as BaseContextMenu } from '@base-ui/react/context-menu';
|
|
5
|
+
import { PreviewCard as BasePreviewCard } from '@base-ui/react/preview-card';
|
|
6
|
+
import { Menu } from './menu.js';
|
|
7
|
+
import { part, skin } from './parts.js';
|
|
8
|
+
const ContextPositioner = part(BaseContextMenu.Positioner, 'pui-positioner');
|
|
9
|
+
const ContextContent = React.forwardRef(function ContextContent({ positionerProps, ...props }, ref) {
|
|
10
|
+
return (_jsx(ContextPositioner, { ...positionerProps, children: _jsx(Menu.Popup, { ...props, ref: ref }) }));
|
|
11
|
+
});
|
|
12
|
+
/** Same menu anatomy and styling, with the context-specific cursor positioner. */
|
|
13
|
+
export const ContextMenu = {
|
|
14
|
+
...BaseContextMenu,
|
|
15
|
+
Trigger: part(BaseContextMenu.Trigger, 'pui-context-trigger'),
|
|
16
|
+
Positioner: ContextPositioner,
|
|
17
|
+
Content: ContextContent,
|
|
18
|
+
Popup: Menu.Popup,
|
|
19
|
+
Item: Menu.Item,
|
|
20
|
+
LinkItem: Menu.LinkItem,
|
|
21
|
+
CheckboxItem: Menu.CheckboxItem,
|
|
22
|
+
CheckboxItemIndicator: Menu.CheckboxItemIndicator,
|
|
23
|
+
RadioItem: Menu.RadioItem,
|
|
24
|
+
RadioItemIndicator: Menu.RadioItemIndicator,
|
|
25
|
+
GroupLabel: Menu.GroupLabel,
|
|
26
|
+
Separator: Menu.Separator,
|
|
27
|
+
SubmenuTrigger: Menu.SubmenuTrigger,
|
|
28
|
+
};
|
|
29
|
+
const PreviewPositioner = part(BasePreviewCard.Positioner, 'pui-positioner');
|
|
30
|
+
// The preview is visual enhancement; its destination is the accessible interface.
|
|
31
|
+
const PreviewPopup = React.forwardRef(function PreviewPopup({ className, ...props }, ref) {
|
|
32
|
+
return (_jsx(BasePreviewCard.Popup, { ...props, ref: ref, "aria-hidden": 'true', className: skin('pui-preview-card', className) }));
|
|
33
|
+
});
|
|
34
|
+
function PreviewTrigger(props) {
|
|
35
|
+
const { className, ...rest } = props;
|
|
36
|
+
return (_jsx(BasePreviewCard.Trigger, { ...rest, className: skin('pui-link pui-preview-trigger', className) }));
|
|
37
|
+
}
|
|
38
|
+
const PreviewContent = React.forwardRef(function PreviewContent({ positionerProps, ...props }, ref) {
|
|
39
|
+
return (_jsx(PreviewPositioner, { sideOffset: 8, collisionPadding: 12, ...positionerProps, children: _jsx(PreviewPopup, { ...props, ref: ref }) }));
|
|
40
|
+
});
|
|
41
|
+
export const PreviewCard = {
|
|
42
|
+
...BasePreviewCard,
|
|
43
|
+
Trigger: PreviewTrigger,
|
|
44
|
+
Positioner: PreviewPositioner,
|
|
45
|
+
Popup: PreviewPopup,
|
|
46
|
+
Content: PreviewContent,
|
|
47
|
+
};
|
|
48
|
+
// Flat names for React Server Components, which cannot dot into client exports.
|
|
49
|
+
export const { Arrow: ContextMenuArrow, Backdrop: ContextMenuBackdrop, CheckboxItem: ContextMenuCheckboxItem, CheckboxItemIndicator: ContextMenuCheckboxItemIndicator, Group: ContextMenuGroup, GroupLabel: ContextMenuGroupLabel, Item: ContextMenuItem, LinkItem: ContextMenuLinkItem, Popup: ContextMenuPopup, Portal: ContextMenuPortal, Positioner: ContextMenuPositioner, RadioGroup: ContextMenuRadioGroup, RadioItem: ContextMenuRadioItem, RadioItemIndicator: ContextMenuRadioItemIndicator, Root: ContextMenuRoot, Separator: ContextMenuSeparator, SubmenuRoot: ContextMenuSubmenuRoot, SubmenuTrigger: ContextMenuSubmenuTrigger, Trigger: ContextMenuTrigger, Content: ContextMenuContent, } = ContextMenu;
|
|
50
|
+
export const { Arrow: PreviewCardArrow, Backdrop: PreviewCardBackdrop, Handle: PreviewCardHandle, Popup: PreviewCardPopup, Portal: PreviewCardPortal, Positioner: PreviewCardPositioner, Root: PreviewCardRoot, Trigger: PreviewCardTrigger, Viewport: PreviewCardViewport, Content: PreviewCardContent, } = PreviewCard;
|