@rinzai/zen 0.10.2 → 0.11.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +3 -3
- package/dist/avatar/index.d.ts +1 -1
- package/dist/avatar/index.d.ts.map +1 -1
- package/dist/avatar/index.js +23 -21
- package/dist/canvas/geometry.d.ts +51 -0
- package/dist/canvas/geometry.d.ts.map +1 -0
- package/dist/canvas/geometry.js +91 -0
- package/dist/canvas/index.d.ts +59 -0
- package/dist/canvas/index.d.ts.map +1 -0
- package/dist/canvas/index.js +303 -0
- package/dist/code-block/index.d.ts.map +1 -1
- package/dist/code-block/index.js +24 -31
- package/dist/color-picker/index.d.ts +36 -0
- package/dist/color-picker/index.d.ts.map +1 -0
- package/dist/color-picker/index.js +210 -0
- package/dist/combobox/index.js +46 -46
- package/dist/date-picker/index.js +5 -5
- package/dist/index.d.ts +4 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/input/index.js +4 -4
- package/dist/input-group/index.js +8 -8
- package/dist/lib.js +84 -80
- package/dist/money-input/index.js +8 -8
- package/dist/month-picker/index.js +11 -11
- package/dist/repeat-picker/index.js +8 -8
- package/dist/select/index.js +16 -16
- package/dist/sortable/index.d.ts.map +1 -1
- package/dist/sortable/index.js +1 -1
- package/dist/tag-input/index.js +4 -4
- package/dist/textarea/index.js +4 -4
- package/dist/utils/color.d.ts +35 -0
- package/dist/utils/color.d.ts.map +1 -0
- package/dist/utils/color.js +66 -0
- package/dist/utils/theme-wave.d.ts.map +1 -1
- package/dist/utils/theme-wave.js +70 -69
- package/dist/utils/theme.d.ts.map +1 -1
- package/dist/utils/theme.js +56 -59
- package/dist/utils/useCopyToClipboard.d.ts +13 -0
- package/dist/utils/useCopyToClipboard.d.ts.map +1 -0
- package/dist/utils/useCopyToClipboard.js +26 -0
- package/dist/zen.css +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -57,11 +57,11 @@ export default function App() {
|
|
|
57
57
|
## What's inside
|
|
58
58
|
|
|
59
59
|
- **Surfaces:** Card, Inset, Alert, Stat, Dialog (and sheets from an edge), ConfirmDialog, Popover, Tooltip, Toast (a stacked deck), Disclosure, Backdrop (aurora, contours or dots, and a pointer light)
|
|
60
|
-
- **Inputs:** Button, Input, TextArea, InputGroup, MoneyInput (with currency conversion), Select, Combobox, Calendar, DatePicker, DateRangePicker, MonthPicker, Checkbox, RadioGroup, RadioCards, Segmented, Slider, Toggle, Chip, Field
|
|
61
|
-
- **Data:** Chart (areas, lines, bars) and DonutChart in plain SVG, composable Table with sticky edges and sorting, tree rows, editable cells, virtual rows, Meter, ProgressRing, AnimatedNumber, Badge, StatusPill (a live save status), Skeleton, Spinner
|
|
60
|
+
- **Inputs:** Button, Input, TextArea, InputGroup, MoneyInput (with currency conversion), Select, Combobox, Calendar, DatePicker, DateRangePicker, MonthPicker, ColorPicker, Checkbox, RadioGroup, RadioCards, Segmented, Slider, Toggle, Chip, Field
|
|
61
|
+
- **Data:** Chart (areas, lines, bars) and DonutChart in plain SVG, composable Table with sticky edges and sorting, tree rows, editable cells, virtual rows, Meter, ProgressRing, AnimatedNumber, Badge, StatusPill (a live save status), Skeleton, Spinner, Canvas (items placed freely, with snapping)
|
|
62
62
|
- **Navigation:** Header, Pills, Tabs, TabBar, SideNav, TableOfContents, Menu
|
|
63
63
|
- **Theming:** dark and light, OKLCH tokens, and a theme generator (presets or any hue) that keeps contrast readable
|
|
64
|
-
- **Hooks and utilities:** `themeWave` (the theme spreads from the switch like a drop falling into water: ripples, glints and a rainbow edge, drawn on the GPU; `prepareThemeWave` readies it when the pointer reaches your own switch), `useAnchoredPopup`, `useVirtualList`, `useTree`, `useSort`, money, currency, month and date helpers, `cx` (Tailwind-aware class merging), `cva`
|
|
64
|
+
- **Hooks and utilities:** `themeWave` (the theme spreads from the switch like a drop falling into water: ripples, glints and a rainbow edge, drawn on the GPU; `prepareThemeWave` readies it when the pointer reaches your own switch), `useAnchoredPopup`, `useVirtualList`, `useTree`, `useSort`, `useCopyToClipboard`, money, currency, month and date helpers, `hexToOklch` and `oklchToHex`, `cx` (Tailwind-aware class merging), `cva`
|
|
65
65
|
|
|
66
66
|
Every component takes `className`, and a class you pass always overrides the component's default.
|
|
67
67
|
|
package/dist/avatar/index.d.ts
CHANGED
|
@@ -12,7 +12,7 @@ export declare class ImageCropError extends Error {
|
|
|
12
12
|
*/
|
|
13
13
|
export declare function cropImageToSquare(file: Blob, size?: number, quality?: number): Promise<string>;
|
|
14
14
|
export interface AvatarProps {
|
|
15
|
-
/** Image URL (or data URL); without it, the initial is shown. */
|
|
15
|
+
/** Image URL (or data URL); without it, or if it fails to load, the initial is shown. */
|
|
16
16
|
src?: string | null;
|
|
17
17
|
/** Name or email, for the initial. */
|
|
18
18
|
name: string;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../packages/avatar/index.tsx"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../packages/avatar/index.tsx"],"names":[],"mappings":"AAGA;;;GAGG;AACH,MAAM,CAAC,OAAO,UAAU,MAAM,CAAC,EAAE,GAAG,EAAE,IAAI,EAAE,GAAG,EAAE,SAAS,EAAE,EAAE,WAAW,+BA+BxE;AAED,qBAAa,cAAe,SAAQ,KAAK;CAAG;AAE5C;;;;GAIG;AACH,wBAAsB,iBAAiB,CAAC,IAAI,EAAE,IAAI,EAAE,IAAI,SAAM,EAAE,OAAO,SAAO,GAAG,OAAO,CAAC,MAAM,CAAC,CAkB/F;AAED,MAAM,WAAW,WAAW;IACxB,yFAAyF;IACzF,GAAG,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACpB,sCAAsC;IACtC,IAAI,EAAE,MAAM,CAAC;IACb,4EAA4E;IAC5E,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,8DAA8D;IAC9D,SAAS,CAAC,EAAE,MAAM,CAAC;CACtB"}
|
package/dist/avatar/index.js
CHANGED
|
@@ -1,41 +1,43 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
import { cx as e } from "../utils/cx.js";
|
|
3
|
-
import {
|
|
3
|
+
import { useState as t } from "react";
|
|
4
|
+
import { jsx as n, jsxs as r } from "react/jsx-runtime";
|
|
4
5
|
//#region packages/avatar/index.tsx
|
|
5
|
-
function
|
|
6
|
-
let
|
|
7
|
-
return /* @__PURE__ */
|
|
8
|
-
role:
|
|
9
|
-
"aria-label":
|
|
10
|
-
"aria-hidden": !
|
|
11
|
-
className: e("zen__avatar relative inline-grid shrink-0 place-items-center overflow-hidden rounded-full font-semibold select-none", "size-9 text-sm", "text-primary-foreground bg-[radial-gradient(circle_at_30%_25%,oklch(var(--glow)/0.9),oklch(var(--primary)/0.55))]", "shadow-[0_0_0_1px_oklch(var(--tint)/0.12),0_0_18px_-6px_oklch(var(--glow)/calc(0.9*var(--glow-strength)))]",
|
|
12
|
-
children: [/* @__PURE__ */
|
|
13
|
-
className:
|
|
14
|
-
children:
|
|
15
|
-
}),
|
|
16
|
-
src:
|
|
6
|
+
function i({ src: i, name: a, alt: o, className: s }) {
|
|
7
|
+
let c = (a.trim()[0] ?? "?").toUpperCase(), [l, u] = t(null), d = i && i !== l ? i : null;
|
|
8
|
+
return /* @__PURE__ */ r("span", {
|
|
9
|
+
role: o ? "img" : void 0,
|
|
10
|
+
"aria-label": o,
|
|
11
|
+
"aria-hidden": !o || void 0,
|
|
12
|
+
className: e("zen__avatar relative inline-grid shrink-0 place-items-center overflow-hidden rounded-full font-semibold select-none", "size-9 text-sm", "text-primary-foreground bg-[radial-gradient(circle_at_30%_25%,oklch(var(--glow)/0.9),oklch(var(--primary)/0.55))]", "shadow-[0_0_0_1px_oklch(var(--tint)/0.12),0_0_18px_-6px_oklch(var(--glow)/calc(0.9*var(--glow-strength)))]", s),
|
|
13
|
+
children: [/* @__PURE__ */ n("span", {
|
|
14
|
+
className: d ? "invisible" : void 0,
|
|
15
|
+
children: c
|
|
16
|
+
}), d && /* @__PURE__ */ n("img", {
|
|
17
|
+
src: d,
|
|
17
18
|
alt: "",
|
|
19
|
+
onError: () => u(d),
|
|
18
20
|
className: "absolute inset-0 size-full object-cover",
|
|
19
21
|
draggable: !1
|
|
20
22
|
})]
|
|
21
23
|
});
|
|
22
24
|
}
|
|
23
|
-
var
|
|
24
|
-
async function
|
|
25
|
-
if (!e.type.startsWith("image/")) throw new
|
|
26
|
-
if (e.size > 20971520) throw new
|
|
25
|
+
var a = class extends Error {};
|
|
26
|
+
async function o(e, t = 160, n = .85) {
|
|
27
|
+
if (!e.type.startsWith("image/")) throw new a("Choose an image file.");
|
|
28
|
+
if (e.size > 20971520) throw new a("That image is too large (over 20 MB).");
|
|
27
29
|
let r;
|
|
28
30
|
try {
|
|
29
31
|
r = await createImageBitmap(e);
|
|
30
32
|
} catch {
|
|
31
|
-
throw new
|
|
33
|
+
throw new a("That image couldn't be read.");
|
|
32
34
|
}
|
|
33
|
-
let
|
|
35
|
+
let i = Math.min(r.width, r.height), o = document.createElement("canvas");
|
|
34
36
|
o.width = o.height = t;
|
|
35
37
|
let s = o.getContext("2d");
|
|
36
|
-
s.imageSmoothingQuality = "high", s.drawImage(r, (r.width -
|
|
38
|
+
s.imageSmoothingQuality = "high", s.drawImage(r, (r.width - i) / 2, (r.height - i) / 2, i, i, 0, 0, t, t), r.close();
|
|
37
39
|
let c = o.toDataURL("image/webp", n);
|
|
38
40
|
return c.startsWith("data:image/webp") ? c : o.toDataURL("image/jpeg", n);
|
|
39
41
|
}
|
|
40
42
|
//#endregion
|
|
41
|
-
export {
|
|
43
|
+
export { a as ImageCropError, o as cropImageToSquare, i as default };
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
export interface CanvasRect {
|
|
2
|
+
x: number;
|
|
3
|
+
y: number;
|
|
4
|
+
w: number;
|
|
5
|
+
h: number;
|
|
6
|
+
}
|
|
7
|
+
/** A snap line: a vertical one at x, or a horizontal one at y. */
|
|
8
|
+
export interface CanvasGuide {
|
|
9
|
+
axis: 'x' | 'y';
|
|
10
|
+
at: number;
|
|
11
|
+
}
|
|
12
|
+
/** Which corner or edge a resize handle is on. */
|
|
13
|
+
export type CanvasHandle = 'n' | 'ne' | 'e' | 'se' | 's' | 'sw' | 'w' | 'nw';
|
|
14
|
+
export interface Bounds {
|
|
15
|
+
width: number;
|
|
16
|
+
height: number;
|
|
17
|
+
/** Smallest width and height. */
|
|
18
|
+
min: number;
|
|
19
|
+
}
|
|
20
|
+
export interface SnapOptions {
|
|
21
|
+
/** Rects to line up with, besides the surface. */
|
|
22
|
+
others?: readonly CanvasRect[];
|
|
23
|
+
/** How close counts for lines, in surface units; 0 or left out, no lines. */
|
|
24
|
+
threshold?: number;
|
|
25
|
+
/** Round to multiples of this when no line is in reach. */
|
|
26
|
+
grid?: number;
|
|
27
|
+
}
|
|
28
|
+
/** The box around several rects. */
|
|
29
|
+
export declare function boundsOf(rects: readonly CanvasRect[]): CanvasRect;
|
|
30
|
+
/** Whether two rects overlap. */
|
|
31
|
+
export declare function intersects(a: CanvasRect, b: CanvasRect): boolean;
|
|
32
|
+
/**
|
|
33
|
+
* `start` moved by dx, dy, then snapped: an edge or its centre onto a line in
|
|
34
|
+
* reach, otherwise its corner onto the grid. Kept on the surface, in whole units.
|
|
35
|
+
*/
|
|
36
|
+
export declare function moveRect(start: CanvasRect, dx: number, dy: number, bounds: Bounds, snap?: SnapOptions): {
|
|
37
|
+
rect: CanvasRect;
|
|
38
|
+
guides: CanvasGuide[];
|
|
39
|
+
};
|
|
40
|
+
/**
|
|
41
|
+
* `start` resized by dragging `handle` by dx, dy: its moving edges snapped to a
|
|
42
|
+
* line or the grid, no smaller than `min`, kept on the surface, in whole units.
|
|
43
|
+
* With `keepRatio`, its shape stays the same (and it doesn't snap).
|
|
44
|
+
*/
|
|
45
|
+
export declare function resizeRect(start: CanvasRect, handle: CanvasHandle, dx: number, dy: number, bounds: Bounds, { keepRatio, ...snap }?: SnapOptions & {
|
|
46
|
+
keepRatio?: boolean;
|
|
47
|
+
}): {
|
|
48
|
+
rect: CanvasRect;
|
|
49
|
+
guides: CanvasGuide[];
|
|
50
|
+
};
|
|
51
|
+
//# sourceMappingURL=geometry.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"geometry.d.ts","sourceRoot":"","sources":["../../packages/canvas/geometry.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,UAAU;IACvB,CAAC,EAAE,MAAM,CAAC;IACV,CAAC,EAAE,MAAM,CAAC;IACV,CAAC,EAAE,MAAM,CAAC;IACV,CAAC,EAAE,MAAM,CAAC;CACb;AAED,kEAAkE;AAClE,MAAM,WAAW,WAAW;IACxB,IAAI,EAAE,GAAG,GAAG,GAAG,CAAC;IAChB,EAAE,EAAE,MAAM,CAAC;CACd;AAED,kDAAkD;AAClD,MAAM,MAAM,YAAY,GAAG,GAAG,GAAG,IAAI,GAAG,GAAG,GAAG,IAAI,GAAG,GAAG,GAAG,IAAI,GAAG,GAAG,GAAG,IAAI,CAAC;AAE7E,MAAM,WAAW,MAAM;IACnB,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf,iCAAiC;IACjC,GAAG,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,WAAW;IACxB,kDAAkD;IAClD,MAAM,CAAC,EAAE,SAAS,UAAU,EAAE,CAAC;IAC/B,6EAA6E;IAC7E,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,2DAA2D;IAC3D,IAAI,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,oCAAoC;AACpC,wBAAgB,QAAQ,CAAC,KAAK,EAAE,SAAS,UAAU,EAAE,GAAG,UAAU,CASjE;AAED,iCAAiC;AACjC,wBAAgB,UAAU,CAAC,CAAC,EAAE,UAAU,EAAE,CAAC,EAAE,UAAU,GAAG,OAAO,CAEhE;AA2BD;;;GAGG;AACH,wBAAgB,QAAQ,CACpB,KAAK,EAAE,UAAU,EACjB,EAAE,EAAE,MAAM,EACV,EAAE,EAAE,MAAM,EACV,MAAM,EAAE,MAAM,EACd,IAAI,GAAE,WAAgB,GACvB;IAAE,IAAI,EAAE,UAAU,CAAC;IAAC,MAAM,EAAE,WAAW,EAAE,CAAA;CAAE,CAqB7C;AAED;;;;GAIG;AACH,wBAAgB,UAAU,CACtB,KAAK,EAAE,UAAU,EACjB,MAAM,EAAE,YAAY,EACpB,EAAE,EAAE,MAAM,EACV,EAAE,EAAE,MAAM,EACV,MAAM,EAAE,MAAM,EACd,EAAE,SAAiB,EAAE,GAAG,IAAI,EAAE,GAAE,WAAW,GAAG;IAAE,SAAS,CAAC,EAAE,OAAO,CAAA;CAAO,GAC3E;IAAE,IAAI,EAAE,UAAU,CAAC;IAAC,MAAM,EAAE,WAAW,EAAE,CAAA;CAAE,CAqD7C"}
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
//#region packages/canvas/geometry.ts
|
|
3
|
+
function e(e) {
|
|
4
|
+
let t = Math.min(...e.map((e) => e.x)), n = Math.min(...e.map((e) => e.y));
|
|
5
|
+
return {
|
|
6
|
+
x: t,
|
|
7
|
+
y: n,
|
|
8
|
+
w: Math.max(...e.map((e) => e.x + e.w)) - t,
|
|
9
|
+
h: Math.max(...e.map((e) => e.y + e.h)) - n
|
|
10
|
+
};
|
|
11
|
+
}
|
|
12
|
+
function t(e, t) {
|
|
13
|
+
return e.x < t.x + t.w && t.x < e.x + e.w && e.y < t.y + t.h && t.y < e.y + e.h;
|
|
14
|
+
}
|
|
15
|
+
function n(e, t, n) {
|
|
16
|
+
let r = e === "x" ? t.width : t.height, i = [
|
|
17
|
+
0,
|
|
18
|
+
r / 2,
|
|
19
|
+
r
|
|
20
|
+
];
|
|
21
|
+
for (let t of n) {
|
|
22
|
+
let [n, r] = e === "x" ? [t.x, t.w] : [t.y, t.h];
|
|
23
|
+
i.push(n, n + r / 2, n + r);
|
|
24
|
+
}
|
|
25
|
+
return i;
|
|
26
|
+
}
|
|
27
|
+
function r(e, t, n) {
|
|
28
|
+
let r = null;
|
|
29
|
+
for (let i of e) for (let e of t) {
|
|
30
|
+
let t = e - i;
|
|
31
|
+
Math.abs(t) <= n && (!r || Math.abs(t) < Math.abs(r.by)) && (r = {
|
|
32
|
+
by: t,
|
|
33
|
+
at: e
|
|
34
|
+
});
|
|
35
|
+
}
|
|
36
|
+
return r;
|
|
37
|
+
}
|
|
38
|
+
var i = (e, t) => t ? Math.round(e / t) * t : e;
|
|
39
|
+
function a(e, t, a, o, s = {}) {
|
|
40
|
+
let c = [], l = (e, t, a) => {
|
|
41
|
+
let l = s.threshold && r([
|
|
42
|
+
t,
|
|
43
|
+
t + a / 2,
|
|
44
|
+
t + a
|
|
45
|
+
], n(e, o, s.others ?? []), s.threshold);
|
|
46
|
+
return l ? (c.push({
|
|
47
|
+
axis: e,
|
|
48
|
+
at: l.at
|
|
49
|
+
}), t + l.by) : i(t, s.grid);
|
|
50
|
+
}, u = l("x", e.x + t, e.w), d = l("y", e.y + a, e.h);
|
|
51
|
+
return {
|
|
52
|
+
rect: {
|
|
53
|
+
x: Math.round(Math.min(Math.max(0, u), o.width - e.w)),
|
|
54
|
+
y: Math.round(Math.min(Math.max(0, d), o.height - e.h)),
|
|
55
|
+
w: e.w,
|
|
56
|
+
h: e.h
|
|
57
|
+
},
|
|
58
|
+
guides: c
|
|
59
|
+
};
|
|
60
|
+
}
|
|
61
|
+
function o(e, t, a, o, s, { keepRatio: c = !1, ...l } = {}) {
|
|
62
|
+
let u = t.includes("w"), d = t.includes("e"), f = t.includes("n"), p = t.includes("s"), m = e.x + e.w, h = e.y + e.h, g = e.x + (u ? a : 0), _ = m + (d ? a : 0), v = e.y + (f ? o : 0), y = h + (p ? o : 0), b = [];
|
|
63
|
+
if (!c) {
|
|
64
|
+
let e = (e, t) => {
|
|
65
|
+
let a = l.threshold && r([t], n(e, s, l.others ?? []), l.threshold);
|
|
66
|
+
return a ? (b.push({
|
|
67
|
+
axis: e,
|
|
68
|
+
at: a.at
|
|
69
|
+
}), a.at) : i(t, l.grid);
|
|
70
|
+
};
|
|
71
|
+
u && (g = e("x", g)), d && (_ = e("x", _)), f && (v = e("y", v)), p && (y = e("y", y));
|
|
72
|
+
}
|
|
73
|
+
let x = u ? m : s.width - e.x, S = f ? h : s.height - e.y, C = Math.min(x, Math.max(s.min, _ - g)), w = Math.min(S, Math.max(s.min, y - v));
|
|
74
|
+
if (c) {
|
|
75
|
+
let t = e.w / e.h;
|
|
76
|
+
(u || d) && (!(f || p) || Math.abs(C / e.w - 1) >= Math.abs(w / e.h - 1)) ? w = C / t : C = w * t;
|
|
77
|
+
let n = Math.min(1, x / C, S / w), r = Math.max(1, s.min / C, s.min / w), i = n < 1 ? n : r;
|
|
78
|
+
C *= i, w *= i;
|
|
79
|
+
}
|
|
80
|
+
return C = Math.round(C), w = Math.round(w), {
|
|
81
|
+
rect: {
|
|
82
|
+
x: u ? m - C : e.x,
|
|
83
|
+
y: f ? h - w : e.y,
|
|
84
|
+
w: C,
|
|
85
|
+
h: w
|
|
86
|
+
},
|
|
87
|
+
guides: b
|
|
88
|
+
};
|
|
89
|
+
}
|
|
90
|
+
//#endregion
|
|
91
|
+
export { e as boundsOf, t as intersects, a as moveRect, o as resizeRect };
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
import { ComponentProps } from 'react';
|
|
2
|
+
import { CanvasRect } from './geometry';
|
|
3
|
+
export type { CanvasRect } from './geometry';
|
|
4
|
+
/**
|
|
5
|
+
* A fixed-size surface where items sit anywhere, such as the cards of a
|
|
6
|
+
* stream overlay or a slide. Drag an item to move it, and the handles of the
|
|
7
|
+
* selected one to resize it (Shift keeps its shape); Escape mid-drag puts it
|
|
8
|
+
* back. Shift- or Cmd-click, or drag a box on empty space, to select several
|
|
9
|
+
* and move them together. From the keyboard, Tab reaches each item, the arrow
|
|
10
|
+
* keys move the selection (Shift by 10), Alt and the arrow keys resize, Cmd or
|
|
11
|
+
* Ctrl+A selects all, and Escape deselects; each change is announced.
|
|
12
|
+
*
|
|
13
|
+
* Items stay on the surface; with `snap` they line up with its edges and
|
|
14
|
+
* centre and with each other, and with `grid` they keep to a grid. `scale`
|
|
15
|
+
* shows the design larger or smaller, or `"fit"` fills the width it's given.
|
|
16
|
+
* `onChange` gets the items with every step of a change; `onChangeEnd`, once
|
|
17
|
+
* it's made, with the items before it, for undo or saving.
|
|
18
|
+
*/
|
|
19
|
+
export declare function Canvas<T extends CanvasItemRect>({ width, height, scale, items, onChange, onChangeEnd, selected, onSelect, minSize, snap, grid, className, style, children, onPointerDown, ...rest }: CanvasProps<T>): import('react').JSX.Element;
|
|
20
|
+
/**
|
|
21
|
+
* One item on a Canvas, placed where the canvas's `items` say for its `id`;
|
|
22
|
+
* later items sit on top of earlier ones. `label` names it ("Title") in what's
|
|
23
|
+
* announced. Its content is yours: fields and buttons in it work as usual,
|
|
24
|
+
* and pressing them doesn't drag it (nor anything with data-canvas-no-drag).
|
|
25
|
+
*/
|
|
26
|
+
export declare function CanvasItem({ id, label, className, style, children, ...rest }: CanvasItemProps): import('react').JSX.Element | null;
|
|
27
|
+
export interface CanvasItemRect extends CanvasRect {
|
|
28
|
+
id: string;
|
|
29
|
+
/** Not moved or resized, and presses go through it to the surface (Tab still reaches it): a background, say. */
|
|
30
|
+
locked?: boolean;
|
|
31
|
+
}
|
|
32
|
+
export interface CanvasProps<T extends CanvasItemRect = CanvasItemRect> extends Omit<ComponentProps<'div'>, 'onChange' | 'onSelect'> {
|
|
33
|
+
/** The surface's size, in your design's units (px at scale 1). */
|
|
34
|
+
width: number;
|
|
35
|
+
height: number;
|
|
36
|
+
/** How large to show it: 2 shows a 400×120 design 800×240; "fit" fills the width it's given. Positions stay in design units. */
|
|
37
|
+
scale?: number | 'fit';
|
|
38
|
+
/** Where each item is (other fields are kept); render a CanvasItem for each. */
|
|
39
|
+
items: readonly T[];
|
|
40
|
+
/** The items, with every step of a move or resize. */
|
|
41
|
+
onChange: (items: T[]) => void;
|
|
42
|
+
/** The items once a change is made (a drag let go, a key pressed), and as they were before: for undo or saving. */
|
|
43
|
+
onChangeEnd?: (items: T[], before: readonly T[]) => void;
|
|
44
|
+
/** The selected items' ids. */
|
|
45
|
+
selected?: readonly string[];
|
|
46
|
+
onSelect?: (ids: string[]) => void;
|
|
47
|
+
/** Smallest width and height an item can be resized to. */
|
|
48
|
+
minSize?: number;
|
|
49
|
+
/** Line items up with the surface and each other: true, or how close counts, in screen px (true is 6). */
|
|
50
|
+
snap?: boolean | number;
|
|
51
|
+
/** Keep positions and sizes to multiples of this (design units) when no line is in reach. */
|
|
52
|
+
grid?: number;
|
|
53
|
+
}
|
|
54
|
+
export interface CanvasItemProps extends ComponentProps<'div'> {
|
|
55
|
+
id: string;
|
|
56
|
+
/** The item's name, e.g. "Title", for what's announced. */
|
|
57
|
+
label: string;
|
|
58
|
+
}
|
|
59
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../packages/canvas/index.tsx"],"names":[],"mappings":"AACA,OAAO,EACH,cAAc,EAWjB,MAAM,OAAO,CAAC;AAEf,OAAO,EAIH,KAAK,UAAU,EAKlB,MAAM,YAAY,CAAC;AAEpB,YAAY,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAyC7C;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,MAAM,CAAC,CAAC,SAAS,cAAc,EAAE,EAC7C,KAAK,EACL,MAAM,EACN,KAAS,EACT,KAAK,EACL,QAAQ,EACR,WAAW,EACX,QAAa,EACb,QAAQ,EACR,OAAW,EACX,IAAY,EACZ,IAAI,EACJ,SAAS,EACT,KAAK,EACL,QAAQ,EACR,aAAa,EACb,GAAG,IAAI,EACV,EAAE,WAAW,CAAC,CAAC,CAAC,+BAsUhB;AAED;;;;;GAKG;AACH,wBAAgB,UAAU,CAAC,EAAE,EAAE,EAAE,KAAK,EAAE,SAAS,EAAE,KAAK,EAAE,QAAQ,EAAE,GAAG,IAAI,EAAE,EAAE,eAAe,sCA2D7F;AAED,MAAM,WAAW,cAAe,SAAQ,UAAU;IAC9C,EAAE,EAAE,MAAM,CAAC;IACX,gHAAgH;IAChH,MAAM,CAAC,EAAE,OAAO,CAAC;CACpB;AAED,MAAM,WAAW,WAAW,CAAC,CAAC,SAAS,cAAc,GAAG,cAAc,CAAE,SAAQ,IAAI,CAChF,cAAc,CAAC,KAAK,CAAC,EACrB,UAAU,GAAG,UAAU,CAC1B;IACG,kEAAkE;IAClE,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf,gIAAgI;IAChI,KAAK,CAAC,EAAE,MAAM,GAAG,KAAK,CAAC;IACvB,gFAAgF;IAChF,KAAK,EAAE,SAAS,CAAC,EAAE,CAAC;IACpB,sDAAsD;IACtD,QAAQ,EAAE,CAAC,KAAK,EAAE,CAAC,EAAE,KAAK,IAAI,CAAC;IAC/B,mHAAmH;IACnH,WAAW,CAAC,EAAE,CAAC,KAAK,EAAE,CAAC,EAAE,EAAE,MAAM,EAAE,SAAS,CAAC,EAAE,KAAK,IAAI,CAAC;IACzD,+BAA+B;IAC/B,QAAQ,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IAC7B,QAAQ,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,IAAI,CAAC;IACnC,2DAA2D;IAC3D,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,0GAA0G;IAC1G,IAAI,CAAC,EAAE,OAAO,GAAG,MAAM,CAAC;IACxB,6FAA6F;IAC7F,IAAI,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,eAAgB,SAAQ,cAAc,CAAC,KAAK,CAAC;IAC1D,EAAE,EAAE,MAAM,CAAC;IACX,2DAA2D;IAC3D,KAAK,EAAE,MAAM,CAAC;CACjB"}
|
|
@@ -0,0 +1,303 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { cx as e } from "../utils/cx.js";
|
|
3
|
+
import { boundsOf as t, intersects as n, moveRect as r, resizeRect as i } from "./geometry.js";
|
|
4
|
+
import { createContext as a, useContext as o, useEffect as s, useId as c, useLayoutEffect as l, useRef as u, useState as d } from "react";
|
|
5
|
+
import { jsx as f, jsxs as p } from "react/jsx-runtime";
|
|
6
|
+
//#region packages/canvas/index.tsx
|
|
7
|
+
var m = typeof window > "u" ? s : l, h = 3, ee = "input, textarea, select, button, a[href], [contenteditable=\"\"], [contenteditable=\"true\"], [data-canvas-no-drag]", g = [
|
|
8
|
+
"nw",
|
|
9
|
+
"n",
|
|
10
|
+
"ne",
|
|
11
|
+
"e",
|
|
12
|
+
"se",
|
|
13
|
+
"s",
|
|
14
|
+
"sw",
|
|
15
|
+
"w"
|
|
16
|
+
], _ = {
|
|
17
|
+
nw: "left-0 top-0 cursor-nwse-resize",
|
|
18
|
+
n: "left-1/2 top-0 cursor-ns-resize",
|
|
19
|
+
ne: "left-full top-0 cursor-nesw-resize",
|
|
20
|
+
e: "left-full top-1/2 cursor-ew-resize",
|
|
21
|
+
se: "left-full top-full cursor-nwse-resize",
|
|
22
|
+
s: "left-1/2 top-full cursor-ns-resize",
|
|
23
|
+
sw: "left-0 top-full cursor-nesw-resize",
|
|
24
|
+
w: "left-0 top-1/2 cursor-ew-resize"
|
|
25
|
+
}, v = {
|
|
26
|
+
ArrowLeft: [-1, 0],
|
|
27
|
+
ArrowRight: [1, 0],
|
|
28
|
+
ArrowUp: [0, -1],
|
|
29
|
+
ArrowDown: [0, 1]
|
|
30
|
+
}, y = (e, t) => e.x === t.x && e.y === t.y && e.w === t.w && e.h === t.h, b = (e, t) => e.length === t.length && e.every((e, n) => e === t[n]), x = a(null);
|
|
31
|
+
function S({ width: a, height: o, scale: s = 1, items: l, onChange: g, onChangeEnd: _, selected: S = [], onSelect: C, minSize: w = 8, snap: T = !1, grid: E, className: D, style: O, children: k, onPointerDown: te, ...ne }) {
|
|
32
|
+
let A = u(null), j = u(!1), [M, re] = d(null), [ie, N] = d([]), [P, F] = d(null), [I, L] = d(null), [R, z] = d(!1), [B, V] = d(""), H = c();
|
|
33
|
+
m(() => {
|
|
34
|
+
let e = A.current;
|
|
35
|
+
if (s !== "fit" || !e) return;
|
|
36
|
+
let t = () => e.clientWidth && re(e.clientWidth / a);
|
|
37
|
+
if (t(), typeof ResizeObserver > "u") return;
|
|
38
|
+
let n = new ResizeObserver(t);
|
|
39
|
+
return n.observe(e), () => n.disconnect();
|
|
40
|
+
}, [s, a]);
|
|
41
|
+
let U = s === "fit" ? M ?? 1 : s, W = new Map(l.map((e) => [e.id, e])), G = {
|
|
42
|
+
width: a,
|
|
43
|
+
height: o,
|
|
44
|
+
min: w
|
|
45
|
+
}, ae = T === !1 ? 0 : (T === !0 ? 6 : T) / U, K = (e) => ({
|
|
46
|
+
others: l.filter((t) => !e.has(t.id)),
|
|
47
|
+
threshold: ae,
|
|
48
|
+
grid: E
|
|
49
|
+
}), q = (e) => {
|
|
50
|
+
b(e, S) || C?.(e);
|
|
51
|
+
}, J = (e) => l.map((t) => {
|
|
52
|
+
let n = e.get(t.id);
|
|
53
|
+
return n ? {
|
|
54
|
+
...t,
|
|
55
|
+
...n
|
|
56
|
+
} : t;
|
|
57
|
+
}), Y = (e, n, i, a) => {
|
|
58
|
+
let o = t(e), s = r(o, n, i, G, a), [c, l] = [s.rect.x - o.x, s.rect.y - o.y];
|
|
59
|
+
return {
|
|
60
|
+
rects: new Map(e.map((e) => [e.id, {
|
|
61
|
+
x: e.x + c,
|
|
62
|
+
y: e.y + l,
|
|
63
|
+
w: e.w,
|
|
64
|
+
h: e.h
|
|
65
|
+
}])),
|
|
66
|
+
box: s.rect,
|
|
67
|
+
guides: s.guides
|
|
68
|
+
};
|
|
69
|
+
}, X = (e, t, n) => {
|
|
70
|
+
n.w !== t.w || n.h !== t.h ? V(`${e} resized to ${n.w} by ${n.h}.`) : (n.x !== t.x || n.y !== t.y) && V(`${e} moved to ${n.x}, ${n.y}.`);
|
|
71
|
+
}, Z = (e, t, n) => e.length === 1 && e[0].id === t ? n : `${e.length} items`, oe = (e, n, r, a) => {
|
|
72
|
+
let o = W.get(n);
|
|
73
|
+
if (e.button !== 0 || !o || o.locked && !a) return;
|
|
74
|
+
let s = e.target.closest(ee);
|
|
75
|
+
if (!a && s && s !== e.currentTarget && e.currentTarget.contains(s)) return;
|
|
76
|
+
e.preventDefault(), e.stopPropagation();
|
|
77
|
+
let c = e.shiftKey || e.metaKey || e.ctrlKey, u;
|
|
78
|
+
if (u = a ? [n] : c ? S.includes(n) ? S.filter((e) => e !== n) : [...S, n] : S.includes(n) ? [...S] : [n], q(u), j.current = !0, e.currentTarget.closest("[data-canvas-id]")?.focus({ preventScroll: !0 }), j.current = !1, !u.includes(n)) return;
|
|
79
|
+
let d = a ? [o] : u.flatMap((e) => W.get(e) ?? []).filter((e) => !e.locked);
|
|
80
|
+
if (!d.length) return;
|
|
81
|
+
let f = e.currentTarget;
|
|
82
|
+
f.setPointerCapture?.(e.pointerId);
|
|
83
|
+
let p = new Set(d.map((e) => e.id)), m = l, v = t(d), y = Z(d, n, r), b = !1, x = [...l], C = v, w = (t) => {
|
|
84
|
+
if (t.pointerId !== e.pointerId) return;
|
|
85
|
+
let [r, s] = [t.clientX - e.clientX, t.clientY - e.clientY];
|
|
86
|
+
if (!b) {
|
|
87
|
+
if (Math.hypot(r, s) < h) return;
|
|
88
|
+
b = !0, z(!0);
|
|
89
|
+
}
|
|
90
|
+
let [c, l] = [r / U, s / U], u;
|
|
91
|
+
if (a) {
|
|
92
|
+
let e = i(o, a, c, l, G, {
|
|
93
|
+
keepRatio: t.shiftKey,
|
|
94
|
+
...K(p)
|
|
95
|
+
});
|
|
96
|
+
u = {
|
|
97
|
+
rects: /* @__PURE__ */ new Map([[n, e.rect]]),
|
|
98
|
+
box: e.rect,
|
|
99
|
+
guides: e.guides
|
|
100
|
+
};
|
|
101
|
+
} else u = Y(d, c, l, K(p));
|
|
102
|
+
C = u.box, x = J(u.rects), g(x), N(u.guides), L({
|
|
103
|
+
box: u.box,
|
|
104
|
+
text: a ? `${u.box.w} × ${u.box.h}` : `${u.box.x}, ${u.box.y}`
|
|
105
|
+
});
|
|
106
|
+
}, T = (t) => {
|
|
107
|
+
f.removeEventListener("pointermove", w), f.removeEventListener("pointerup", E), f.removeEventListener("pointercancel", D), window.removeEventListener("keydown", O, !0), f.hasPointerCapture?.(e.pointerId) && f.releasePointerCapture(e.pointerId), N([]), L(null), z(!1), b && (t ? (_?.(x, m), X(y, v, C)) : (g([...m]), V(`${y} put back.`)));
|
|
108
|
+
}, E = (t) => t.pointerId === e.pointerId && T(!0), D = (t) => t.pointerId === e.pointerId && T(!1), O = (e) => {
|
|
109
|
+
e.key === "Escape" && (e.preventDefault(), e.stopPropagation(), T(!1));
|
|
110
|
+
};
|
|
111
|
+
f.addEventListener("pointermove", w), f.addEventListener("pointerup", E), f.addEventListener("pointercancel", D), window.addEventListener("keydown", O, !0);
|
|
112
|
+
}, se = (e) => {
|
|
113
|
+
if (e.button !== 0 || e.target.closest("[data-canvas-id]:not([data-locked])")) return;
|
|
114
|
+
let t = e.currentTarget, r = t.getBoundingClientRect(), i = (e) => ({
|
|
115
|
+
x: Math.min(a, Math.max(0, (e.clientX - r.left) / U)),
|
|
116
|
+
y: Math.min(o, Math.max(0, (e.clientY - r.top) / U))
|
|
117
|
+
}), s = e.shiftKey || e.metaKey || e.ctrlKey ? [...S] : [], c = i(e), u = !1, d = S;
|
|
118
|
+
t.setPointerCapture?.(e.pointerId);
|
|
119
|
+
let f = (t) => {
|
|
120
|
+
if (t.pointerId !== e.pointerId || !u && Math.hypot(t.clientX - e.clientX, t.clientY - e.clientY) < h) return;
|
|
121
|
+
u = !0;
|
|
122
|
+
let r = i(t), a = {
|
|
123
|
+
x: Math.min(c.x, r.x),
|
|
124
|
+
y: Math.min(c.y, r.y),
|
|
125
|
+
w: Math.abs(r.x - c.x),
|
|
126
|
+
h: Math.abs(r.y - c.y)
|
|
127
|
+
};
|
|
128
|
+
F(a);
|
|
129
|
+
let o = l.filter((e) => !e.locked && n(e, a)).map((e) => e.id), f = [...s, ...o.filter((e) => !s.includes(e))];
|
|
130
|
+
b(f, d) || (d = f, C?.(f));
|
|
131
|
+
}, p = (n) => {
|
|
132
|
+
n.pointerId === e.pointerId && (t.removeEventListener("pointermove", f), t.removeEventListener("pointerup", p), t.removeEventListener("pointercancel", p), F(null), n.type !== "pointercancel" && (u ? V(`${d.length} ${d.length === 1 ? "item" : "items"} selected.`) : s.length || q([])));
|
|
133
|
+
};
|
|
134
|
+
t.addEventListener("pointermove", f), t.addEventListener("pointerup", p), t.addEventListener("pointercancel", p);
|
|
135
|
+
}, ce = (e, n, r) => {
|
|
136
|
+
let a = W.get(n);
|
|
137
|
+
if (!a || e.target !== e.currentTarget) return;
|
|
138
|
+
if (e.key === "Escape") {
|
|
139
|
+
if (!S.length) return;
|
|
140
|
+
e.preventDefault(), q([]);
|
|
141
|
+
return;
|
|
142
|
+
}
|
|
143
|
+
if ((e.metaKey || e.ctrlKey) && e.key.toLowerCase() === "a") {
|
|
144
|
+
e.preventDefault();
|
|
145
|
+
let t = l.filter((e) => !e.locked).map((e) => e.id);
|
|
146
|
+
q(t), V(`${t.length} items selected.`);
|
|
147
|
+
return;
|
|
148
|
+
}
|
|
149
|
+
let o = v[e.key];
|
|
150
|
+
if (!o) return;
|
|
151
|
+
e.preventDefault();
|
|
152
|
+
let s = e.shiftKey ? 10 : 1, [c, u] = [o[0] * s, o[1] * s], d = (S.includes(n) ? S : [n]).flatMap((e) => W.get(e) ?? []).filter((e) => !e.locked), f = e.altKey ? d.filter((e) => e.id === n) : d;
|
|
153
|
+
if (!f.length) return;
|
|
154
|
+
let p = e.altKey ? /* @__PURE__ */ new Map([[n, i(a, "se", c, u, G).rect]]) : Y(f, c, u).rects;
|
|
155
|
+
if ([...p].every(([e, t]) => y(t, W.get(e)))) return;
|
|
156
|
+
let m = J(p);
|
|
157
|
+
g(m), _?.(m, l), X(Z(f, n, r), t(f), t([...p.values()]));
|
|
158
|
+
}, le = (e) => {
|
|
159
|
+
!j.current && !S.includes(e) && q([e]);
|
|
160
|
+
}, Q = I && {
|
|
161
|
+
left: Math.min(a * U - 28, Math.max(28, (I.box.x + I.box.w / 2) * U)),
|
|
162
|
+
top: (I.box.y + I.box.h) * U + 26 > o * U ? Math.max(4, I.box.y * U - 26) : (I.box.y + I.box.h) * U + 6
|
|
163
|
+
}, $ = R && E && E * U >= 6 ? E * U : 0;
|
|
164
|
+
return /* @__PURE__ */ p(x.Provider, {
|
|
165
|
+
value: {
|
|
166
|
+
item: (e) => W.get(e),
|
|
167
|
+
selected: S,
|
|
168
|
+
grab: oe,
|
|
169
|
+
key: ce,
|
|
170
|
+
focus: le,
|
|
171
|
+
hintId: H
|
|
172
|
+
},
|
|
173
|
+
children: [
|
|
174
|
+
/* @__PURE__ */ p("div", {
|
|
175
|
+
ref: A,
|
|
176
|
+
role: "group",
|
|
177
|
+
...ne,
|
|
178
|
+
onPointerDown: (e) => {
|
|
179
|
+
te?.(e), e.defaultPrevented || se(e);
|
|
180
|
+
},
|
|
181
|
+
style: {
|
|
182
|
+
...O,
|
|
183
|
+
...s === "fit" ? {
|
|
184
|
+
width: "100%",
|
|
185
|
+
aspectRatio: `${a} / ${o}`
|
|
186
|
+
} : {
|
|
187
|
+
width: a * U,
|
|
188
|
+
height: o * U
|
|
189
|
+
}
|
|
190
|
+
},
|
|
191
|
+
className: e("zen__canvas bg-tint/[0.03] relative shrink-0 overflow-hidden rounded-lg shadow-[inset_0_0_0_1px_oklch(var(--tint)/0.08)] select-none", D),
|
|
192
|
+
children: [/* @__PURE__ */ f("div", {
|
|
193
|
+
style: {
|
|
194
|
+
width: a,
|
|
195
|
+
height: o,
|
|
196
|
+
scale: String(U),
|
|
197
|
+
"--canvas-scale": U
|
|
198
|
+
},
|
|
199
|
+
className: e("absolute top-0 left-0 origin-top-left", s === "fit" && M === null && "invisible"),
|
|
200
|
+
children: k
|
|
201
|
+
}), /* @__PURE__ */ p("div", {
|
|
202
|
+
"aria-hidden": !0,
|
|
203
|
+
className: "pointer-events-none absolute inset-0",
|
|
204
|
+
children: [
|
|
205
|
+
$ > 0 && /* @__PURE__ */ f("div", {
|
|
206
|
+
"data-canvas-grid": "",
|
|
207
|
+
className: "absolute inset-0",
|
|
208
|
+
style: {
|
|
209
|
+
backgroundImage: "radial-gradient(circle, oklch(var(--tint) / 0.22) 1px, transparent 1.5px)",
|
|
210
|
+
backgroundSize: `${$}px ${$}px`,
|
|
211
|
+
backgroundPosition: `${-$ / 2}px ${-$ / 2}px`
|
|
212
|
+
}
|
|
213
|
+
}),
|
|
214
|
+
ie.map((e) => /* @__PURE__ */ f("span", {
|
|
215
|
+
"data-canvas-guide": "",
|
|
216
|
+
className: "bg-primary absolute shadow-[0_0_6px_oklch(var(--glow)/0.8)]",
|
|
217
|
+
style: e.axis === "x" ? {
|
|
218
|
+
left: e.at * U,
|
|
219
|
+
top: 0,
|
|
220
|
+
bottom: 0,
|
|
221
|
+
width: 1
|
|
222
|
+
} : {
|
|
223
|
+
top: e.at * U,
|
|
224
|
+
left: 0,
|
|
225
|
+
right: 0,
|
|
226
|
+
height: 1
|
|
227
|
+
}
|
|
228
|
+
}, `${e.axis}${e.at}`)),
|
|
229
|
+
P && /* @__PURE__ */ f("span", {
|
|
230
|
+
"data-canvas-marquee": "",
|
|
231
|
+
className: "border-primary/60 bg-primary/10 absolute rounded-sm border",
|
|
232
|
+
style: {
|
|
233
|
+
left: P.x * U,
|
|
234
|
+
top: P.y * U,
|
|
235
|
+
width: P.w * U,
|
|
236
|
+
height: P.h * U
|
|
237
|
+
}
|
|
238
|
+
}),
|
|
239
|
+
Q && /* @__PURE__ */ f("span", {
|
|
240
|
+
"data-canvas-readout": "",
|
|
241
|
+
className: "bg-primary text-primary-foreground absolute -translate-x-1/2 rounded-md px-1.5 py-0.5 text-[11px] leading-4 font-medium whitespace-nowrap tabular-nums shadow-[0_4px_14px_-4px_oklch(var(--glow)/0.7)]",
|
|
242
|
+
style: Q,
|
|
243
|
+
children: I.text
|
|
244
|
+
})
|
|
245
|
+
]
|
|
246
|
+
})]
|
|
247
|
+
}),
|
|
248
|
+
/* @__PURE__ */ f("span", {
|
|
249
|
+
id: H,
|
|
250
|
+
hidden: !0,
|
|
251
|
+
children: "Arrow keys move the selection, Shift with them by 10. Alt with the arrow keys resizes. Escape deselects."
|
|
252
|
+
}),
|
|
253
|
+
/* @__PURE__ */ f("span", {
|
|
254
|
+
"aria-live": "assertive",
|
|
255
|
+
className: "sr-only",
|
|
256
|
+
children: B
|
|
257
|
+
})
|
|
258
|
+
]
|
|
259
|
+
});
|
|
260
|
+
}
|
|
261
|
+
function C({ id: t, label: n, className: r, style: i, children: a, ...s }) {
|
|
262
|
+
let c = o(x);
|
|
263
|
+
if (!c) throw Error("<CanvasItem> must be inside <Canvas>");
|
|
264
|
+
let l = c.item(t);
|
|
265
|
+
if (!l) return null;
|
|
266
|
+
let u = c.selected.includes(t), d = u && c.selected.length === 1;
|
|
267
|
+
return /* @__PURE__ */ p("div", {
|
|
268
|
+
role: "group",
|
|
269
|
+
"aria-roledescription": l.locked ? "locked item" : "movable item",
|
|
270
|
+
"aria-label": n,
|
|
271
|
+
"aria-describedby": l.locked ? void 0 : c.hintId,
|
|
272
|
+
tabIndex: 0,
|
|
273
|
+
"data-canvas-id": t,
|
|
274
|
+
"data-selected": u || void 0,
|
|
275
|
+
"data-locked": l.locked || void 0,
|
|
276
|
+
...s,
|
|
277
|
+
onFocus: (e) => {
|
|
278
|
+
s.onFocus?.(e), e.target === e.currentTarget && c.focus(t);
|
|
279
|
+
},
|
|
280
|
+
onPointerDown: (e) => {
|
|
281
|
+
s.onPointerDown?.(e), c.grab(e, t, n);
|
|
282
|
+
},
|
|
283
|
+
onKeyDown: (e) => {
|
|
284
|
+
s.onKeyDown?.(e), c.key(e, t, n);
|
|
285
|
+
},
|
|
286
|
+
style: {
|
|
287
|
+
...i,
|
|
288
|
+
left: l.x,
|
|
289
|
+
top: l.y,
|
|
290
|
+
width: l.w,
|
|
291
|
+
height: l.h
|
|
292
|
+
},
|
|
293
|
+
className: e("zen__canvas-item absolute cursor-move touch-none outline-hidden data-locked:cursor-default data-locked:touch-auto", "[outline-offset:calc(1px/var(--canvas-scale))]", "not-data-selected:hover:outline-solid not-data-selected:hover:outline-[length:calc(1px/var(--canvas-scale))] not-data-selected:hover:outline-[color:oklch(var(--tint)/0.35)]", "data-selected:outline-solid data-selected:outline-[length:calc(2px/var(--canvas-scale))] data-selected:outline-[color:oklch(var(--primary)/0.8)]", "focus-visible:outline-solid focus-visible:outline-[length:calc(2px/var(--canvas-scale))] focus-visible:outline-[color:oklch(var(--ring)/0.7)]", r),
|
|
294
|
+
children: [a, d && !l.locked && g.map((r) => /* @__PURE__ */ f("span", {
|
|
295
|
+
"aria-hidden": !0,
|
|
296
|
+
"data-handle": r,
|
|
297
|
+
onPointerDown: (e) => c.grab(e, t, n, r),
|
|
298
|
+
className: e("bg-foreground absolute z-10 size-[calc(10px/var(--canvas-scale))] -translate-1/2 rounded-full border-[length:calc(2px/var(--canvas-scale))] border-[color:oklch(var(--primary))] shadow-[0_0_8px_oklch(var(--glow)/0.6)]", "after:absolute after:-inset-[calc(6px/var(--canvas-scale))] pointer-coarse:after:-inset-[calc(14px/var(--canvas-scale))]", _[r])
|
|
299
|
+
}, r))]
|
|
300
|
+
});
|
|
301
|
+
}
|
|
302
|
+
//#endregion
|
|
303
|
+
export { S as Canvas, C as CanvasItem };
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../packages/code-block/index.tsx"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../packages/code-block/index.tsx"],"names":[],"mappings":"AAEA,OAAO,EAAE,cAAc,EAA+B,MAAM,OAAO,CAAC;AAEpE;;;;GAIG;AACH,MAAM,CAAC,OAAO,UAAU,SAAS,CAAC,EAC9B,IAAI,EACJ,QAAQ,EACR,SAAS,EACT,QAAe,EACf,OAAiB,EACjB,SAAS,EACT,GAAG,IAAI,EACV,EAAE,cAAc,+BAsDhB;AAED,MAAM,WAAW,cAAe,SAAQ,IAAI,CAAC,cAAc,CAAC,KAAK,CAAC,EAAE,UAAU,CAAC;IAC3E,IAAI,EAAE,MAAM,CAAC;IACb,uDAAuD;IACvD,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,6EAA6E;IAC7E,SAAS,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,MAAM,KAAK,MAAM,CAAC;IACxD,iDAAiD;IACjD,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,wGAAwG;IACxG,OAAO,CAAC,EAAE,OAAO,GAAG,OAAO,CAAC;CAC/B"}
|