@pebble-software/bonsai 0.0.8 → 0.1.1
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 +21 -0
- package/README.md +371 -88
- package/dist/ast.js +10 -0
- package/dist/ast.js.map +1 -0
- package/dist/chunks/builder.meta-WpXc5VBB.js +666 -0
- package/dist/chunks/builder.meta-WpXc5VBB.js.map +1 -0
- package/dist/chunks/button-jfJanilw.js +161 -0
- package/dist/chunks/button-jfJanilw.js.map +1 -0
- package/dist/chunks/create-renderer-DHneTPd-.js +280 -0
- package/dist/chunks/create-renderer-DHneTPd-.js.map +1 -0
- package/dist/chunks/index-DzpRdatr.js +359 -0
- package/dist/chunks/index-DzpRdatr.js.map +1 -0
- package/dist/chunks/render-shared-Ci28BpkI.js +1989 -0
- package/dist/chunks/render-shared-Ci28BpkI.js.map +1 -0
- package/dist/components/core/bonsai.d.ts +5 -0
- package/dist/components/core/render-shared.d.ts +123 -0
- package/dist/components/core/render-tree-client.d.ts +4 -0
- package/dist/components/core/render-tree-server.d.ts +2 -0
- package/dist/components/ui/a.d.ts +3 -0
- package/dist/components/ui/accordion.d.ts +17 -0
- package/dist/components/ui/alert-dialog.d.ts +23 -0
- package/dist/components/ui/alert.d.ts +12 -0
- package/dist/components/ui/avatar.d.ts +21 -0
- package/dist/components/ui/badge.d.ts +10 -0
- package/dist/components/ui/breadcrumb.d.ts +10 -0
- package/dist/components/ui/button.d.ts +14 -0
- package/dist/components/ui/calendar.d.ts +9 -0
- package/dist/components/ui/card.d.ts +15 -0
- package/dist/components/ui/checkbox.d.ts +7 -0
- package/dist/components/ui/collapsible.d.ts +5 -0
- package/dist/components/ui/combobox.d.ts +31 -0
- package/dist/components/ui/command.d.ts +23 -0
- package/dist/components/ui/dialog.d.ts +23 -0
- package/dist/components/ui/drawer.d.ts +22 -0
- package/dist/components/ui/dropdown-menu.d.ts +29 -0
- package/dist/components/ui/form.d.ts +24 -0
- package/dist/components/ui/h.d.ts +10 -0
- package/dist/components/ui/input-group.d.ts +18 -0
- package/dist/components/ui/input-otp.d.ts +11 -0
- package/dist/components/ui/input.d.ts +3 -0
- package/dist/components/ui/label.d.ts +10 -0
- package/dist/components/ui/loader.d.ts +14 -0
- package/dist/components/ui/p.d.ts +11 -0
- package/dist/components/ui/popover.d.ts +9 -0
- package/dist/components/ui/progress.d.ts +31 -0
- package/dist/components/ui/scroll-area.d.ts +13 -0
- package/dist/components/ui/select.d.ts +17 -0
- package/dist/components/ui/separator.d.ts +8 -0
- package/dist/components/ui/sidebar.d.ts +70 -0
- package/dist/components/ui/signature-pad.d.ts +7 -0
- package/dist/components/ui/skeleton.d.ts +7 -0
- package/dist/components/ui/switch.d.ts +8 -0
- package/dist/components/ui/table.d.ts +14 -0
- package/dist/components/ui/tabs.d.ts +15 -0
- package/dist/components/ui/textarea.d.ts +5 -0
- package/dist/components/ui/toast.d.ts +46 -0
- package/dist/components/ui/tooltip.d.ts +15 -0
- package/dist/constants.d.ts +1 -0
- package/dist/constants.js +11 -0
- package/dist/constants.js.map +1 -0
- package/dist/core.d.ts +12 -0
- package/dist/core.js +17 -0
- package/dist/core.js.map +1 -0
- package/dist/hooks/haptics.d.ts +8 -0
- package/dist/hooks/use-mobile.d.ts +1 -0
- package/dist/index.css +7 -0
- package/dist/index.d.ts +27 -339
- package/dist/index.js +532 -4297
- package/dist/index.js.map +1 -0
- package/dist/lib/ast/cache.d.ts +8 -0
- package/dist/lib/ast/evaluator.d.ts +2 -0
- package/dist/lib/ast/helpers.d.ts +2 -0
- package/dist/lib/ast/index.d.ts +29 -0
- package/dist/lib/ast/setup.d.ts +2 -0
- package/dist/lib/ast/types.d.ts +1 -0
- package/dist/lib/ast/utils.d.ts +4 -0
- package/dist/lib/haptics.d.ts +8 -0
- package/dist/lib/registry/drift.d.ts +17 -0
- package/dist/lib/registry/identity.d.ts +24 -0
- package/dist/lib/registry/json-schema-to-zod.d.ts +32 -0
- package/dist/lib/registry/manifest-schema.d.ts +62 -0
- package/dist/lib/registry/manifest.d.ts +26 -0
- package/dist/lib/registry/merge-generated.d.ts +7 -0
- package/dist/lib/registry/pebble-registry.d.ts +1 -0
- package/dist/lib/registry/types.d.ts +29 -0
- package/dist/lib/registry/validate.d.ts +18 -0
- package/dist/lib/renderer/compile-template.d.ts +70 -0
- package/dist/lib/ui/registry.d.ts +19 -0
- package/dist/lib/utils.d.ts +3 -0
- package/dist/library/constants/src/components.d.ts +59 -0
- package/dist/library/constants/src/index.d.ts +2 -0
- package/dist/library/constants/src/webhook-events.d.ts +6 -0
- package/dist/library/schemas/src/bonsai.schema.d.ts +24 -0
- package/dist/library/schemas/src/builder.meta.d.ts +26 -0
- package/dist/presets/calendar.js +374 -0
- package/dist/presets/calendar.js.map +1 -0
- package/dist/presets/signature.js +405 -0
- package/dist/presets/signature.js.map +1 -0
- package/dist/renderer/core-registry.d.ts +52 -0
- package/dist/renderer/create-renderer.d.ts +38 -0
- package/dist/renderer/presets/calendar.d.ts +5 -0
- package/dist/renderer/presets/signature.d.ts +6 -0
- package/dist/schemas.d.ts +2 -0
- package/dist/schemas.js +13 -0
- package/dist/schemas.js.map +1 -0
- package/dist/styles/css/base.css +144 -0
- package/dist/styles/css/fonts.css +25 -0
- package/dist/styles/css/maplibre.css +29 -0
- package/dist/styles/css/overrides.css +7 -0
- package/dist/styles/css/tailwind.css +1 -0
- package/dist/styles/css/theme.css +197 -0
- package/dist/styles/css/tw-animate.css +1 -0
- package/dist/styles/css/utilities.css +44 -0
- package/dist/styles/presets.json +20 -0
- package/dist/styles/vendor/maplibre-gl.css +701 -0
- package/dist/styles/vendor/tw-animate.css +692 -0
- package/dist/types.d.ts +1 -0
- package/package.json +64 -19
|
@@ -0,0 +1,405 @@
|
|
|
1
|
+
import { COMPONENT as C } from "../constants.js";
|
|
2
|
+
import { jsx as a, jsxs as u } from "react/jsx-runtime";
|
|
3
|
+
import { useState as S, useRef as x, useCallback as D, useEffect as v } from "react";
|
|
4
|
+
import { c as n, H as G, B as L } from "../chunks/button-jfJanilw.js";
|
|
5
|
+
import { Tabs as _ } from "@base-ui/react/tabs";
|
|
6
|
+
import { cva as B } from "class-variance-authority";
|
|
7
|
+
import { useWebHaptics as U } from "web-haptics/react";
|
|
8
|
+
import F from "react-signature-canvas";
|
|
9
|
+
import { IconWriting as O, IconTextSize as $, IconEraser as H } from "@tabler/icons-react";
|
|
10
|
+
import { u as W, I as V, g as X, h as Z } from "../chunks/render-shared-Ci28BpkI.js";
|
|
11
|
+
function q({
|
|
12
|
+
className: r,
|
|
13
|
+
orientation: s = "horizontal",
|
|
14
|
+
...i
|
|
15
|
+
}) {
|
|
16
|
+
return /* @__PURE__ */ a(
|
|
17
|
+
_.Root,
|
|
18
|
+
{
|
|
19
|
+
"data-slot": "tabs",
|
|
20
|
+
"data-orientation": s,
|
|
21
|
+
className: n(
|
|
22
|
+
"gap-2 group/tabs flex",
|
|
23
|
+
"data-[orientation=horizontal]:flex-col",
|
|
24
|
+
"data-[orientation=vertical]:w-full",
|
|
25
|
+
r
|
|
26
|
+
),
|
|
27
|
+
...i
|
|
28
|
+
}
|
|
29
|
+
);
|
|
30
|
+
}
|
|
31
|
+
const Y = B(
|
|
32
|
+
"overflow-auto inline-flex bg-transparent w-fit items-start justify-start group-data-horizontal/tabs:h-9 group-data-[orientation=vertical]/tabs:h-fit group-data-[orientation=vertical]/tabs:flex-col",
|
|
33
|
+
{
|
|
34
|
+
variants: {
|
|
35
|
+
variant: {
|
|
36
|
+
default: "gap-1.5 border-2 rounded-base p-[calc(var(--trigger-translate)+6px)]",
|
|
37
|
+
ghost: "gap-1 border-none rounded-none p-[calc(var(--trigger-translate)+6px)]",
|
|
38
|
+
icon: "gap-1.5 border-2 rounded-base p-[calc(var(--trigger-translate)+6px)]",
|
|
39
|
+
contained: "gap-0 border-0 rounded-md p-[calc(var(--trigger-translate)+2px)]"
|
|
40
|
+
},
|
|
41
|
+
size: {
|
|
42
|
+
sm: "",
|
|
43
|
+
md: "",
|
|
44
|
+
lg: "",
|
|
45
|
+
xl: ""
|
|
46
|
+
},
|
|
47
|
+
extrude: {
|
|
48
|
+
default: "[--trigger-shadow:var(--shadow-none)] [--trigger-translate:0px] [--focus-trigger-translate:0px]",
|
|
49
|
+
xs: "[--trigger-shadow:var(--shadow-min)] [--trigger-translate:1px] [--focus-trigger-shadow:var(--shadow-none)] [--focus-trigger-translate:0px]",
|
|
50
|
+
sm: "[--trigger-shadow:var(--shadow-xs)] [--trigger-translate:2px] [--focus-trigger-shadow:var(--shadow-min)] [--focus-trigger-translate:1px]",
|
|
51
|
+
md: "[--trigger-shadow:var(--shadow-sm)] [--trigger-translate:3px] [--focus-trigger-shadow:var(--shadow-xs)] [--focus-trigger-translate:2px]",
|
|
52
|
+
lg: "[--trigger-shadow:var(--shadow-md)] [--trigger-translate:4px] [--focus-trigger-shadow:var(--shadow-xs)] [--focus-trigger-translate:2px]",
|
|
53
|
+
xl: "[--trigger-shadow:var(--shadow-lg)] [--trigger-translate:5px] [--focus-trigger-shadow:var(--shadow-xs)] [--focus-trigger-translate:2px]"
|
|
54
|
+
}
|
|
55
|
+
},
|
|
56
|
+
defaultVariants: {
|
|
57
|
+
variant: "default",
|
|
58
|
+
size: "md",
|
|
59
|
+
extrude: "default"
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
);
|
|
63
|
+
function J({
|
|
64
|
+
className: r,
|
|
65
|
+
variant: s = "default",
|
|
66
|
+
size: i = "md",
|
|
67
|
+
extrude: d = "default",
|
|
68
|
+
...c
|
|
69
|
+
}) {
|
|
70
|
+
return /* @__PURE__ */ a(
|
|
71
|
+
_.List,
|
|
72
|
+
{
|
|
73
|
+
"data-slot": "tabs-list",
|
|
74
|
+
"data-variant": s,
|
|
75
|
+
"data-size": i,
|
|
76
|
+
className: n(
|
|
77
|
+
Y({ variant: s, size: i, extrude: d }),
|
|
78
|
+
"group/tabs-list",
|
|
79
|
+
r
|
|
80
|
+
),
|
|
81
|
+
...c
|
|
82
|
+
}
|
|
83
|
+
);
|
|
84
|
+
}
|
|
85
|
+
function R({
|
|
86
|
+
label: r,
|
|
87
|
+
description: s,
|
|
88
|
+
children: i,
|
|
89
|
+
className: d,
|
|
90
|
+
onClick: c,
|
|
91
|
+
...t
|
|
92
|
+
}) {
|
|
93
|
+
const { trigger: l } = U();
|
|
94
|
+
return /* @__PURE__ */ u(
|
|
95
|
+
_.Tab,
|
|
96
|
+
{
|
|
97
|
+
"data-slot": "tabs-trigger",
|
|
98
|
+
"aria-label": t.value ?? "tabs-trigger",
|
|
99
|
+
className: n(
|
|
100
|
+
"group/tabs-trigger neo-base relative inline-flex flex-1 items-center justify-center overflow-hidden cursor-pointer rounded-base border-2 py-1",
|
|
101
|
+
"bg-surface data-active:bg-main",
|
|
102
|
+
"font-medium h-[calc(100%-1px)] whitespace-nowrap [&_svg]:shrink-0",
|
|
103
|
+
"transition-[translate,box-shadow,border,color] duration-200",
|
|
104
|
+
"aria-disabled:pointer-events-none aria-disabled:opacity-50 aria-disabled:shadow-none aria-disabled:translate-0",
|
|
105
|
+
"group-data-[orientation=vertical]/tabs:w-full group-data-[orientation=vertical]/tabs:justify-start",
|
|
106
|
+
"active:shadow-none active:translate-0",
|
|
107
|
+
"data-active:shadow-(--trigger-shadow) data-active:-translate-(--trigger-translate)",
|
|
108
|
+
"hover:shadow-(--trigger-shadow) hover:-translate-(--trigger-translate)",
|
|
109
|
+
"focus-visible:shadow-(--focus-trigger-shadow) focus-visible:-translate-(--focus-trigger-translate)",
|
|
110
|
+
"focus-visible:hover:-translate-(--focus-trigger-translate) focus-visible:**:font-semibold",
|
|
111
|
+
"group-data-[size=xl]/tabs-list:min-h-12",
|
|
112
|
+
"group-data-[size=sm]/tabs-list:[&_svg:not([class*='size-'])]:size-4",
|
|
113
|
+
"group-data-[size=md]/tabs-list:[&_svg:not([class*='size-'])]:size-5",
|
|
114
|
+
"group-data-[size=lg]/tabs-list:[&_svg:not([class*='size-'])]:size-6",
|
|
115
|
+
"group-data-[size=xl]/tabs-list:[&_svg:not([class*='size-'])]:size-7",
|
|
116
|
+
"group-data-[variant=default]/tabs-list:group-data-[size=sm]/tabs-list:px-3",
|
|
117
|
+
"group-data-[variant=default]/tabs-list:group-data-[size=md]/tabs-list:px-4",
|
|
118
|
+
"group-data-[variant=default]/tabs-list:group-data-[size=lg]/tabs-list:px-5",
|
|
119
|
+
"group-data-[variant=default]/tabs-list:group-data-[size=xl]/tabs-list:px-6",
|
|
120
|
+
"group-data-[variant=ghost]/tabs-list:group-data-[size=sm]/tabs-list:px-3",
|
|
121
|
+
"group-data-[variant=ghost]/tabs-list:group-data-[size=md]/tabs-list:px-4",
|
|
122
|
+
"group-data-[variant=ghost]/tabs-list:group-data-[size=lg]/tabs-list:px-5",
|
|
123
|
+
"group-data-[variant=ghost]/tabs-list:group-data-[size=xl]/tabs-list:px-6",
|
|
124
|
+
"group-data-[variant=ghost]/tabs-list:border-none",
|
|
125
|
+
"group-data-[variant=ghost]/tabs-list:data-active:bg-transparent group-data-[variant=ghost]/tabs-list:shadow-none",
|
|
126
|
+
"group-data-[variant=icon]/tabs-list:group-data-[size=sm]/tabs-list:px-1.5",
|
|
127
|
+
"group-data-[variant=icon]/tabs-list:group-data-[size=md]/tabs-list:px-2",
|
|
128
|
+
"group-data-[variant=icon]/tabs-list:group-data-[size=lg]/tabs-list:px-2.5",
|
|
129
|
+
"group-data-[variant=icon]/tabs-list:group-data-[size=xl]/tabs-list:px-3",
|
|
130
|
+
"group-data-[variant=icon]/tabs-list:m-auto group-data-[variant=icon]/tabs-list:max-w-fit group-data-[variant=icon]/tabs-list:aspect-square group-data-[variant=icon]/tabs-list:items-center group-data-[variant=icon]/tabs-list:justify-center group-data-[variant=icon]/tabs-list:hover:border-foreground group-data-[variant=icon]/tabs-list:border-transparent group-data-[variant=icon]/tabs-list:data-active:border-border",
|
|
131
|
+
"group-data-[variant=contained]/tabs-list:group-data-[size=sm]/tabs-list:px-3",
|
|
132
|
+
"group-data-[variant=contained]/tabs-list:group-data-[size=md]/tabs-list:px-4",
|
|
133
|
+
"group-data-[variant=contained]/tabs-list:group-data-[size=lg]/tabs-list:px-5",
|
|
134
|
+
"group-data-[variant=contained]/tabs-list:group-data-[size=xl]/tabs-list:px-6",
|
|
135
|
+
"group-data-[orientation=horizontal]/tabs:group-data-[variant=contained]/tabs-list:not-last:rounded-r-none group-data-[orientation=horizontal]/tabs:group-data-[variant=contained]/tabs-list:not-first:rounded-l-none group-data-[orientation=vertical]/tabs:group-data-[variant=contained]/tabs-list:not-last:rounded-b-none group-data-[orientation=vertical]/tabs:group-data-[variant=contained]/tabs-list:not-first:rounded-t-none group-data-[variant=contained]/tabs-list:-m-px",
|
|
136
|
+
i ? "gap-1.5" : "flex-col gap-0.5",
|
|
137
|
+
d
|
|
138
|
+
),
|
|
139
|
+
onClick: (o) => {
|
|
140
|
+
l(G), c?.(o);
|
|
141
|
+
},
|
|
142
|
+
...t,
|
|
143
|
+
children: [
|
|
144
|
+
r && /* @__PURE__ */ a(
|
|
145
|
+
"span",
|
|
146
|
+
{
|
|
147
|
+
"data-slot": "tabs-trigger-label",
|
|
148
|
+
className: n(
|
|
149
|
+
"[&_svg]:pointer-events-none [&_svg]:shrink-0 font-medium font-heading",
|
|
150
|
+
"group-data-[size=sm]/tabs-list:text-sm",
|
|
151
|
+
"group-data-[size=md]/tabs-list:text-base",
|
|
152
|
+
"group-data-[size=lg]/tabs-list:text-lg",
|
|
153
|
+
"group-data-[size=xl]/tabs-list:text-2xl"
|
|
154
|
+
),
|
|
155
|
+
children: r
|
|
156
|
+
}
|
|
157
|
+
),
|
|
158
|
+
s && /* @__PURE__ */ a(
|
|
159
|
+
"span",
|
|
160
|
+
{
|
|
161
|
+
"data-slot": "tabs-trigger-description",
|
|
162
|
+
className: n(
|
|
163
|
+
"[&_svg]:pointer-events-none [&_svg]:shrink-0 whitespace-normal",
|
|
164
|
+
"group-data-[size=sm]/tabs-list:text-xs",
|
|
165
|
+
"group-data-[size=md]/tabs-list:text-sm",
|
|
166
|
+
"group-data-[size=lg]/tabs-list:text-base",
|
|
167
|
+
"group-data-[size=xl]/tabs-list:text-lg"
|
|
168
|
+
),
|
|
169
|
+
children: s
|
|
170
|
+
}
|
|
171
|
+
),
|
|
172
|
+
i,
|
|
173
|
+
/* @__PURE__ */ a(
|
|
174
|
+
"div",
|
|
175
|
+
{
|
|
176
|
+
"data-slot": "tabs-trigger-indicator",
|
|
177
|
+
className: n(
|
|
178
|
+
"pointer-events-none h-[3px] rounded-full bg-foreground absolute hidden bottom-0 left-1 right-1",
|
|
179
|
+
"group-data-[variant=ghost]/tabs-list:group-data-active/tabs-trigger:block"
|
|
180
|
+
)
|
|
181
|
+
}
|
|
182
|
+
)
|
|
183
|
+
]
|
|
184
|
+
}
|
|
185
|
+
);
|
|
186
|
+
}
|
|
187
|
+
const E = '"Great Vibes", cursive', K = 64, Q = 24, tt = 20;
|
|
188
|
+
function k({
|
|
189
|
+
canvas: r,
|
|
190
|
+
text: s,
|
|
191
|
+
width: i,
|
|
192
|
+
height: d,
|
|
193
|
+
ratio: c
|
|
194
|
+
}) {
|
|
195
|
+
const t = r.getContext("2d");
|
|
196
|
+
if (!t) return !1;
|
|
197
|
+
const l = Math.max(1, Math.floor(i)), o = Math.max(1, Math.floor(d)), p = Math.max(c || 1, 1);
|
|
198
|
+
r.width = Math.max(1, Math.floor(l * p)), r.height = Math.max(1, Math.floor(o * p)), t.setTransform(p, 0, 0, p, 0, 0), t.clearRect(0, 0, l, o);
|
|
199
|
+
const g = s.trim();
|
|
200
|
+
if (!g) return !1;
|
|
201
|
+
const f = Math.max(1, l - tt * 2);
|
|
202
|
+
t.fillStyle = "#000", t.textAlign = "center", t.textBaseline = "middle";
|
|
203
|
+
let b = K;
|
|
204
|
+
for (; b > Q && (t.font = `${b}px ${E}`, !(t.measureText(g).width <= f)); )
|
|
205
|
+
b -= 1;
|
|
206
|
+
return t.font = `${b}px ${E}`, t.fillText(g, l / 2, o / 2, f), !0;
|
|
207
|
+
}
|
|
208
|
+
function at({
|
|
209
|
+
value: r,
|
|
210
|
+
onChange: s,
|
|
211
|
+
canvasClassname: i,
|
|
212
|
+
imageType: d = "image/png"
|
|
213
|
+
}) {
|
|
214
|
+
const c = W(), [t, l] = S("sign"), [o, p] = S(""), g = x(null), f = x(null), b = x(s), w = x(r ?? null), N = x(!1), z = x({ width: 0, height: 0 }), m = D((e) => {
|
|
215
|
+
w.current !== e && (w.current = e, b.current?.(e));
|
|
216
|
+
}, []);
|
|
217
|
+
v(() => {
|
|
218
|
+
b.current = s;
|
|
219
|
+
}, [s]), v(() => {
|
|
220
|
+
w.current = r ?? null;
|
|
221
|
+
}, [r]), v(() => {
|
|
222
|
+
if (N.current || (N.current = !0, !r || t !== "sign")) return;
|
|
223
|
+
const e = g.current;
|
|
224
|
+
if (e)
|
|
225
|
+
try {
|
|
226
|
+
e.fromDataURL(r);
|
|
227
|
+
} catch {
|
|
228
|
+
e.clear();
|
|
229
|
+
}
|
|
230
|
+
}, []), v(() => {
|
|
231
|
+
if (t !== "type") return;
|
|
232
|
+
const e = f.current;
|
|
233
|
+
if (!e) return;
|
|
234
|
+
if (z.current.width === 0) {
|
|
235
|
+
const I = e.getBoundingClientRect();
|
|
236
|
+
z.current = {
|
|
237
|
+
width: Math.max(1, Math.floor(I.width)),
|
|
238
|
+
height: Math.max(1, Math.floor(I.height))
|
|
239
|
+
};
|
|
240
|
+
}
|
|
241
|
+
const h = z.current;
|
|
242
|
+
if (!h.width || !h.height) return;
|
|
243
|
+
const M = window.devicePixelRatio || 1;
|
|
244
|
+
if (!k({
|
|
245
|
+
canvas: e,
|
|
246
|
+
text: o,
|
|
247
|
+
width: h.width,
|
|
248
|
+
height: h.height,
|
|
249
|
+
ratio: M
|
|
250
|
+
})) {
|
|
251
|
+
m(null);
|
|
252
|
+
return;
|
|
253
|
+
}
|
|
254
|
+
const y = document.createElement("canvas");
|
|
255
|
+
k({
|
|
256
|
+
canvas: y,
|
|
257
|
+
text: o,
|
|
258
|
+
width: h.width,
|
|
259
|
+
height: h.height,
|
|
260
|
+
ratio: M
|
|
261
|
+
}), m(y.toDataURL(d));
|
|
262
|
+
}, [t, o, d, m]);
|
|
263
|
+
const T = () => {
|
|
264
|
+
g.current?.clear(), p(""), m(null);
|
|
265
|
+
}, A = () => {
|
|
266
|
+
if (t !== "sign") return;
|
|
267
|
+
const e = g.current?.toDataURL(d) ?? null;
|
|
268
|
+
m(e);
|
|
269
|
+
}, j = (e) => {
|
|
270
|
+
e !== t && (T(), l(e));
|
|
271
|
+
}, P = (e) => {
|
|
272
|
+
p(e.target.value);
|
|
273
|
+
};
|
|
274
|
+
return c === "pdf" ? /* @__PURE__ */ a("div", { id: "signature", className: "w-full", children: r ? /* @__PURE__ */ a(
|
|
275
|
+
"img",
|
|
276
|
+
{
|
|
277
|
+
src: r,
|
|
278
|
+
alt: "Signature",
|
|
279
|
+
className: n(
|
|
280
|
+
"w-full h-[256px] object-contain",
|
|
281
|
+
"bg-size-[32px_32px] bg-surface",
|
|
282
|
+
"bg-[linear-gradient(to_right,#80808022_1px,transparent_1px),linear-gradient(to_bottom,#80808022_1px,transparent_1px)]",
|
|
283
|
+
"border-border border-2 rounded-base",
|
|
284
|
+
i
|
|
285
|
+
)
|
|
286
|
+
}
|
|
287
|
+
) : /* @__PURE__ */ a(
|
|
288
|
+
"div",
|
|
289
|
+
{
|
|
290
|
+
"aria-label": "Unsigned",
|
|
291
|
+
className: n(
|
|
292
|
+
"w-full h-[256px] flex items-end",
|
|
293
|
+
"bg-size-[32px_32px] bg-surface",
|
|
294
|
+
"bg-[linear-gradient(to_right,#80808022_1px,transparent_1px),linear-gradient(to_bottom,#80808022_1px,transparent_1px)]",
|
|
295
|
+
"border-border border-2 rounded-base",
|
|
296
|
+
i
|
|
297
|
+
),
|
|
298
|
+
children: /* @__PURE__ */ a("div", { className: "w-full border-t-2 border-dashed border-border mx-6 mb-8 pb-1 text-center text-sm text-muted-foreground", children: "Signature" })
|
|
299
|
+
}
|
|
300
|
+
) }) : /* @__PURE__ */ a("div", { id: "signature", children: /* @__PURE__ */ u(
|
|
301
|
+
V,
|
|
302
|
+
{
|
|
303
|
+
className: n(
|
|
304
|
+
t === "type" ? "max-h-84" : "max-h-69",
|
|
305
|
+
"overflow-hidden transition-[max-height] duration-300 has-[>[data-align=block-start]]:p-2 gap-2"
|
|
306
|
+
),
|
|
307
|
+
children: [
|
|
308
|
+
/* @__PURE__ */ a(X, { align: "block-start", className: "p-0!", children: /* @__PURE__ */ u("div", { className: "relative w-full rounded-base", children: [
|
|
309
|
+
/* @__PURE__ */ u("div", { className: "absolute top-4 left-4 right-3 bg-transparent flex flex-row items-start justify-between gap-3", children: [
|
|
310
|
+
/* @__PURE__ */ a(
|
|
311
|
+
q,
|
|
312
|
+
{
|
|
313
|
+
value: t,
|
|
314
|
+
onValueChange: (e) => j(e),
|
|
315
|
+
className: "-mt-1",
|
|
316
|
+
children: /* @__PURE__ */ u(J, { variant: "contained", extrude: "sm", size: "md", children: [
|
|
317
|
+
/* @__PURE__ */ u(R, { value: "sign", children: [
|
|
318
|
+
/* @__PURE__ */ a(O, {}),
|
|
319
|
+
/* @__PURE__ */ a("span", { className: "hidden sm:flex", children: "Draw" })
|
|
320
|
+
] }),
|
|
321
|
+
/* @__PURE__ */ u(R, { value: "type", children: [
|
|
322
|
+
/* @__PURE__ */ a($, {}),
|
|
323
|
+
/* @__PURE__ */ a("span", { className: "hidden sm:flex", children: "Type" })
|
|
324
|
+
] })
|
|
325
|
+
] })
|
|
326
|
+
}
|
|
327
|
+
),
|
|
328
|
+
/* @__PURE__ */ u(
|
|
329
|
+
L,
|
|
330
|
+
{
|
|
331
|
+
size: "sm",
|
|
332
|
+
raised: "xs",
|
|
333
|
+
variant: "outline",
|
|
334
|
+
onClick: T,
|
|
335
|
+
children: [
|
|
336
|
+
/* @__PURE__ */ a(H, {}),
|
|
337
|
+
/* @__PURE__ */ a("span", { className: "hidden sm:flex", children: "Clear" })
|
|
338
|
+
]
|
|
339
|
+
}
|
|
340
|
+
)
|
|
341
|
+
] }),
|
|
342
|
+
t === "sign" ? /* @__PURE__ */ a(
|
|
343
|
+
F,
|
|
344
|
+
{
|
|
345
|
+
ref: g,
|
|
346
|
+
onEnd: A,
|
|
347
|
+
canvasProps: {
|
|
348
|
+
className: i ?? n(
|
|
349
|
+
"w-full h-[256px]",
|
|
350
|
+
"bg-size-[32px_32px] bg-surface",
|
|
351
|
+
"bg-[linear-gradient(to_right,#80808022_1px,transparent_1px),linear-gradient(to_bottom,#80808022_1px,transparent_1px)]",
|
|
352
|
+
"inset-shadow-sm",
|
|
353
|
+
"border-border border-2 rounded-base",
|
|
354
|
+
"cursor-crosshair"
|
|
355
|
+
)
|
|
356
|
+
}
|
|
357
|
+
}
|
|
358
|
+
) : /* @__PURE__ */ a(
|
|
359
|
+
"canvas",
|
|
360
|
+
{
|
|
361
|
+
ref: f,
|
|
362
|
+
className: n(
|
|
363
|
+
"w-full h-64",
|
|
364
|
+
"bg-size-[32px_32px] bg-surface",
|
|
365
|
+
"bg-[linear-gradient(to_right,#80808022_1px,transparent_1px),linear-gradient(to_bottom,#80808022_1px,transparent_1px)]",
|
|
366
|
+
"inset-shadow-sm",
|
|
367
|
+
"border-border border-2 rounded-base"
|
|
368
|
+
)
|
|
369
|
+
}
|
|
370
|
+
)
|
|
371
|
+
] }) }),
|
|
372
|
+
/* @__PURE__ */ a(
|
|
373
|
+
Z,
|
|
374
|
+
{
|
|
375
|
+
disabled: t !== "type",
|
|
376
|
+
className: n(
|
|
377
|
+
t === "type" ? "animate-in zoom-in-0 spin-in-20 scale-100" : "animate-out zoom-out-0 spin-out-20 scale-0",
|
|
378
|
+
"py-2 text-lg font-medium transition-[scale,translate,box-shadow] duration-300 origin-bottom-left"
|
|
379
|
+
),
|
|
380
|
+
placeholder: "Enter Full Name",
|
|
381
|
+
value: o,
|
|
382
|
+
onChange: P
|
|
383
|
+
}
|
|
384
|
+
)
|
|
385
|
+
]
|
|
386
|
+
}
|
|
387
|
+
) });
|
|
388
|
+
}
|
|
389
|
+
const pt = {
|
|
390
|
+
components: {
|
|
391
|
+
[C.SIGNATURE]: at
|
|
392
|
+
},
|
|
393
|
+
controlledInputs: {
|
|
394
|
+
[C.SIGNATURE]: {
|
|
395
|
+
valueProp: "value",
|
|
396
|
+
changeProp: "onChange",
|
|
397
|
+
extractor: (r) => r
|
|
398
|
+
}
|
|
399
|
+
}
|
|
400
|
+
};
|
|
401
|
+
export {
|
|
402
|
+
at as Signature,
|
|
403
|
+
pt as signaturePreset
|
|
404
|
+
};
|
|
405
|
+
//# sourceMappingURL=signature.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"signature.js","sources":["../../src/components/ui/tabs.tsx","../../src/components/ui/signature-pad.tsx","../../src/renderer/presets/signature.ts"],"sourcesContent":["\"use client\";\n\nimport { Tabs as TabsPrimitive } from \"@base-ui/react/tabs\";\nimport { cva, type VariantProps } from \"class-variance-authority\";\nimport { cn } from \"@/lib/utils\";\nimport { useHaptics, HAPTIC_TAB } from \"@/lib/haptics\";\n\nfunction Tabs({\n className,\n orientation = \"horizontal\",\n ...props\n}: TabsPrimitive.Root.Props) {\n return (\n <TabsPrimitive.Root\n data-slot=\"tabs\"\n data-orientation={orientation}\n className={cn(\n \"gap-2 group/tabs flex\",\n \"data-[orientation=horizontal]:flex-col\",\n \"data-[orientation=vertical]:w-full\",\n className,\n )}\n {...props}\n />\n );\n}\n\nconst tabsListVariants = cva(\n \"overflow-auto inline-flex bg-transparent w-fit items-start justify-start group-data-horizontal/tabs:h-9 group-data-[orientation=vertical]/tabs:h-fit group-data-[orientation=vertical]/tabs:flex-col\",\n {\n variants: {\n variant: {\n default:\n \"gap-1.5 border-2 rounded-base p-[calc(var(--trigger-translate)+6px)]\",\n ghost:\n \"gap-1 border-none rounded-none p-[calc(var(--trigger-translate)+6px)]\",\n icon: \"gap-1.5 border-2 rounded-base p-[calc(var(--trigger-translate)+6px)]\",\n contained:\n \"gap-0 border-0 rounded-md p-[calc(var(--trigger-translate)+2px)]\",\n },\n size: {\n sm: \"\",\n md: \"\",\n lg: \"\",\n xl: \"\",\n },\n extrude: {\n default:\n \"[--trigger-shadow:var(--shadow-none)] [--trigger-translate:0px] [--focus-trigger-translate:0px]\",\n xs: \"[--trigger-shadow:var(--shadow-min)] [--trigger-translate:1px] [--focus-trigger-shadow:var(--shadow-none)] [--focus-trigger-translate:0px]\",\n sm: \"[--trigger-shadow:var(--shadow-xs)] [--trigger-translate:2px] [--focus-trigger-shadow:var(--shadow-min)] [--focus-trigger-translate:1px]\",\n md: \"[--trigger-shadow:var(--shadow-sm)] [--trigger-translate:3px] [--focus-trigger-shadow:var(--shadow-xs)] [--focus-trigger-translate:2px]\",\n lg: \"[--trigger-shadow:var(--shadow-md)] [--trigger-translate:4px] [--focus-trigger-shadow:var(--shadow-xs)] [--focus-trigger-translate:2px]\",\n xl: \"[--trigger-shadow:var(--shadow-lg)] [--trigger-translate:5px] [--focus-trigger-shadow:var(--shadow-xs)] [--focus-trigger-translate:2px]\",\n },\n },\n defaultVariants: {\n variant: \"default\",\n size: \"md\",\n extrude: \"default\",\n },\n },\n);\n\nfunction TabsList({\n className,\n variant = \"default\",\n size = \"md\",\n extrude = \"default\",\n ...props\n}: TabsPrimitive.List.Props & VariantProps<typeof tabsListVariants>) {\n return (\n <TabsPrimitive.List\n data-slot=\"tabs-list\"\n data-variant={variant}\n data-size={size}\n className={cn(\n tabsListVariants({ variant, size, extrude }),\n \"group/tabs-list\",\n className,\n )}\n {...props}\n />\n );\n}\n\nfunction TabsTrigger({\n label,\n description,\n children,\n className,\n onClick,\n ...props\n}: TabsPrimitive.Tab.Props & {\n label?: React.ReactNode;\n description?: React.ReactNode;\n}) {\n const { trigger } = useHaptics();\n return (\n <TabsPrimitive.Tab\n data-slot=\"tabs-trigger\"\n aria-label={props.value ?? \"tabs-trigger\"}\n className={cn(\n \"group/tabs-trigger neo-base relative inline-flex flex-1 items-center justify-center overflow-hidden cursor-pointer rounded-base border-2 py-1\",\n \"bg-surface data-active:bg-main\",\n \"font-medium h-[calc(100%-1px)] whitespace-nowrap [&_svg]:shrink-0\",\n \"transition-[translate,box-shadow,border,color] duration-200\",\n \"aria-disabled:pointer-events-none aria-disabled:opacity-50 aria-disabled:shadow-none aria-disabled:translate-0\",\n \"group-data-[orientation=vertical]/tabs:w-full group-data-[orientation=vertical]/tabs:justify-start\",\n\n \"active:shadow-none active:translate-0\",\n \"data-active:shadow-(--trigger-shadow) data-active:-translate-(--trigger-translate)\",\n \"hover:shadow-(--trigger-shadow) hover:-translate-(--trigger-translate)\",\n \"focus-visible:shadow-(--focus-trigger-shadow) focus-visible:-translate-(--focus-trigger-translate)\",\n \"focus-visible:hover:-translate-(--focus-trigger-translate) focus-visible:**:font-semibold\",\n\n \"group-data-[size=xl]/tabs-list:min-h-12\",\n\n \"group-data-[size=sm]/tabs-list:[&_svg:not([class*='size-'])]:size-4\",\n \"group-data-[size=md]/tabs-list:[&_svg:not([class*='size-'])]:size-5\",\n \"group-data-[size=lg]/tabs-list:[&_svg:not([class*='size-'])]:size-6\",\n \"group-data-[size=xl]/tabs-list:[&_svg:not([class*='size-'])]:size-7\",\n\n \"group-data-[variant=default]/tabs-list:group-data-[size=sm]/tabs-list:px-3\",\n \"group-data-[variant=default]/tabs-list:group-data-[size=md]/tabs-list:px-4\",\n \"group-data-[variant=default]/tabs-list:group-data-[size=lg]/tabs-list:px-5\",\n \"group-data-[variant=default]/tabs-list:group-data-[size=xl]/tabs-list:px-6\",\n\n \"group-data-[variant=ghost]/tabs-list:group-data-[size=sm]/tabs-list:px-3\",\n \"group-data-[variant=ghost]/tabs-list:group-data-[size=md]/tabs-list:px-4\",\n \"group-data-[variant=ghost]/tabs-list:group-data-[size=lg]/tabs-list:px-5\",\n \"group-data-[variant=ghost]/tabs-list:group-data-[size=xl]/tabs-list:px-6\",\n \"group-data-[variant=ghost]/tabs-list:border-none\",\n \"group-data-[variant=ghost]/tabs-list:data-active:bg-transparent group-data-[variant=ghost]/tabs-list:shadow-none\",\n\n \"group-data-[variant=icon]/tabs-list:group-data-[size=sm]/tabs-list:px-1.5\",\n \"group-data-[variant=icon]/tabs-list:group-data-[size=md]/tabs-list:px-2\",\n \"group-data-[variant=icon]/tabs-list:group-data-[size=lg]/tabs-list:px-2.5\",\n \"group-data-[variant=icon]/tabs-list:group-data-[size=xl]/tabs-list:px-3\",\n \"group-data-[variant=icon]/tabs-list:m-auto group-data-[variant=icon]/tabs-list:max-w-fit group-data-[variant=icon]/tabs-list:aspect-square group-data-[variant=icon]/tabs-list:items-center group-data-[variant=icon]/tabs-list:justify-center group-data-[variant=icon]/tabs-list:hover:border-foreground group-data-[variant=icon]/tabs-list:border-transparent group-data-[variant=icon]/tabs-list:data-active:border-border\",\n\n \"group-data-[variant=contained]/tabs-list:group-data-[size=sm]/tabs-list:px-3\",\n \"group-data-[variant=contained]/tabs-list:group-data-[size=md]/tabs-list:px-4\",\n \"group-data-[variant=contained]/tabs-list:group-data-[size=lg]/tabs-list:px-5\",\n \"group-data-[variant=contained]/tabs-list:group-data-[size=xl]/tabs-list:px-6\",\n \"group-data-[orientation=horizontal]/tabs:group-data-[variant=contained]/tabs-list:not-last:rounded-r-none group-data-[orientation=horizontal]/tabs:group-data-[variant=contained]/tabs-list:not-first:rounded-l-none group-data-[orientation=vertical]/tabs:group-data-[variant=contained]/tabs-list:not-last:rounded-b-none group-data-[orientation=vertical]/tabs:group-data-[variant=contained]/tabs-list:not-first:rounded-t-none group-data-[variant=contained]/tabs-list:-m-px\",\n\n children ? \"gap-1.5\" : \"flex-col gap-0.5\",\n className,\n )}\n onClick={(event) => {\n trigger(HAPTIC_TAB);\n onClick?.(event);\n }}\n {...props}\n >\n {label && (\n <span\n data-slot=\"tabs-trigger-label\"\n className={cn(\n \"[&_svg]:pointer-events-none [&_svg]:shrink-0 font-medium font-heading\",\n \"group-data-[size=sm]/tabs-list:text-sm\",\n \"group-data-[size=md]/tabs-list:text-base\",\n \"group-data-[size=lg]/tabs-list:text-lg\",\n \"group-data-[size=xl]/tabs-list:text-2xl\",\n )}\n >\n {label}\n </span>\n )}\n {description && (\n <span\n data-slot=\"tabs-trigger-description\"\n className={cn(\n \"[&_svg]:pointer-events-none [&_svg]:shrink-0 whitespace-normal\",\n \"group-data-[size=sm]/tabs-list:text-xs\",\n \"group-data-[size=md]/tabs-list:text-sm\",\n \"group-data-[size=lg]/tabs-list:text-base\",\n \"group-data-[size=xl]/tabs-list:text-lg\",\n )}\n >\n {description}\n </span>\n )}\n {children}\n <div\n data-slot=\"tabs-trigger-indicator\"\n className={cn(\n \"pointer-events-none h-[3px] rounded-full bg-foreground absolute hidden bottom-0 left-1 right-1\",\n \"group-data-[variant=ghost]/tabs-list:group-data-active/tabs-trigger:block\",\n )}\n />\n </TabsPrimitive.Tab>\n );\n}\n\nfunction TabsContent({ className, ...props }: TabsPrimitive.Panel.Props) {\n return (\n <TabsPrimitive.Panel\n data-slot=\"tabs-content\"\n className={cn(\n \"text-sm flex-1 neo-base border-l-2 border-l-transparent focus-visible:border-l-border -ml-0.5 pl-0.5\",\n className,\n )}\n {...props}\n />\n );\n}\n\nexport { Tabs, TabsList, TabsTrigger, TabsContent, tabsListVariants };\n","\"use client\";\n\nimport { useCallback, useEffect, useRef, useState } from \"react\";\nimport { Button } from \"./button\";\nimport { Tabs, TabsList, TabsTrigger } from \"./tabs\";\nimport SignatureCanvas from \"react-signature-canvas\";\nimport type { ChangeEvent } from \"react\";\nimport { IconEraser, IconWriting, IconTextSize } from \"@tabler/icons-react\";\nimport { InputGroup, InputGroupAddon, InputGroupInput } from \"./input-group\";\nimport { cn } from \"@/lib/utils\";\nimport { useBonsaiRenderMode } from \"../core/bonsai\";\n\nexport type SignatureProps = {\n value?: string | null;\n onChange?: (value: string | null) => void;\n canvasClassname?: string;\n imageType?: \"image/png\" | \"image/jpeg\" | \"image/webp\";\n};\n\nconst FONT_FAMILY = '\"Great Vibes\", cursive';\nconst FONT_SIZE_MAX = 64;\nconst FONT_SIZE_MIN = 24;\nconst TEXT_PADDING_X = 20;\n\nfunction renderTypedSignature({\n canvas,\n text,\n width,\n height,\n ratio,\n}: {\n canvas: HTMLCanvasElement;\n text: string;\n width: number;\n height: number;\n ratio: number;\n}) {\n const ctx = canvas.getContext(\"2d\");\n if (!ctx) return false;\n\n const displayWidth = Math.max(1, Math.floor(width));\n const displayHeight = Math.max(1, Math.floor(height));\n const pixelRatio = Math.max(ratio || 1, 1);\n\n canvas.width = Math.max(1, Math.floor(displayWidth * pixelRatio));\n canvas.height = Math.max(1, Math.floor(displayHeight * pixelRatio));\n ctx.setTransform(pixelRatio, 0, 0, pixelRatio, 0, 0);\n ctx.clearRect(0, 0, displayWidth, displayHeight);\n\n const value = text.trim();\n if (!value) return false;\n\n const maxTextWidth = Math.max(1, displayWidth - TEXT_PADDING_X * 2);\n\n ctx.fillStyle = \"#000\";\n ctx.textAlign = \"center\";\n ctx.textBaseline = \"middle\";\n\n let fontSize = FONT_SIZE_MAX;\n while (fontSize > FONT_SIZE_MIN) {\n ctx.font = `${fontSize}px ${FONT_FAMILY}`;\n if (ctx.measureText(value).width <= maxTextWidth) break;\n fontSize -= 1;\n }\n\n ctx.font = `${fontSize}px ${FONT_FAMILY}`;\n ctx.fillText(value, displayWidth / 2, displayHeight / 2, maxTextWidth);\n\n return true;\n}\n\nexport function Signature({\n value,\n onChange,\n canvasClassname,\n imageType = \"image/png\",\n}: SignatureProps) {\n const renderMode = useBonsaiRenderMode();\n const [mode, setMode] = useState<\"sign\" | \"type\">(\"sign\");\n const [text, setText] = useState(\"\");\n\n const signature = useRef<SignatureCanvas | null>(null);\n const textCanvas = useRef<HTMLCanvasElement | null>(null);\n const onChangeRef = useRef(onChange);\n const lastEmittedValue = useRef<string | null>(value ?? null);\n const initialized = useRef(false);\n const textCanvasSizeRef = useRef({ width: 0, height: 0 });\n\n const emitChange = useCallback((nextValue: string | null) => {\n if (lastEmittedValue.current === nextValue) return;\n lastEmittedValue.current = nextValue;\n onChangeRef.current?.(nextValue);\n }, []);\n\n useEffect(() => {\n onChangeRef.current = onChange;\n }, [onChange]);\n\n useEffect(() => {\n lastEmittedValue.current = value ?? null;\n }, [value]);\n\n useEffect(() => {\n if (initialized.current) return;\n initialized.current = true;\n\n if (!value || mode !== \"sign\") return;\n const instance = signature.current;\n if (!instance) return;\n\n try {\n instance.fromDataURL(value);\n } catch {\n instance.clear();\n }\n }, []);\n\n useEffect(() => {\n if (mode !== \"type\") return;\n\n const canvas = textCanvas.current;\n if (!canvas) return;\n\n if (textCanvasSizeRef.current.width === 0) {\n const rect = canvas.getBoundingClientRect();\n textCanvasSizeRef.current = {\n width: Math.max(1, Math.floor(rect.width)),\n height: Math.max(1, Math.floor(rect.height)),\n };\n }\n\n const size = textCanvasSizeRef.current;\n if (!size.width || !size.height) return;\n\n const ratio = window.devicePixelRatio || 1;\n const hasText = renderTypedSignature({\n canvas,\n text,\n width: size.width,\n height: size.height,\n ratio,\n });\n\n if (!hasText) {\n emitChange(null);\n return;\n }\n\n const exportCanvas = document.createElement(\"canvas\");\n renderTypedSignature({\n canvas: exportCanvas,\n text,\n width: size.width,\n height: size.height,\n ratio,\n });\n\n emitChange(exportCanvas.toDataURL(imageType));\n }, [mode, text, imageType, emitChange]);\n\n const clearSignature = () => {\n signature.current?.clear();\n setText(\"\");\n emitChange(null);\n };\n\n const handleDrawEnd = () => {\n if (mode !== \"sign\") return;\n const data = signature.current?.toDataURL(imageType) ?? null;\n emitChange(data);\n };\n\n const handleModeChange = (next: \"sign\" | \"type\") => {\n if (next === mode) return;\n clearSignature();\n setMode(next);\n };\n\n const handleTextChange = (event: ChangeEvent<HTMLInputElement>) => {\n setText(event.target.value);\n };\n\n // In a non-interactive document there is no client JS to draw a canvas, so\n // the captured value (a base64 data URI baked in at capture time) is shown as\n // a plain image, and an unsigned pad as an empty signature line — never the\n // interactive control, which would render as a blank grid with a toolbar.\n if (renderMode === \"pdf\") {\n return (\n <div id=\"signature\" className=\"w-full\">\n {value ? (\n <img\n src={value}\n alt=\"Signature\"\n className={cn(\n \"w-full h-[256px] object-contain\",\n \"bg-size-[32px_32px] bg-surface\",\n \"bg-[linear-gradient(to_right,#80808022_1px,transparent_1px),linear-gradient(to_bottom,#80808022_1px,transparent_1px)]\",\n \"border-border border-2 rounded-base\",\n canvasClassname,\n )}\n />\n ) : (\n <div\n aria-label=\"Unsigned\"\n className={cn(\n \"w-full h-[256px] flex items-end\",\n \"bg-size-[32px_32px] bg-surface\",\n \"bg-[linear-gradient(to_right,#80808022_1px,transparent_1px),linear-gradient(to_bottom,#80808022_1px,transparent_1px)]\",\n \"border-border border-2 rounded-base\",\n canvasClassname,\n )}\n >\n <div className=\"w-full border-t-2 border-dashed border-border mx-6 mb-8 pb-1 text-center text-sm text-muted-foreground\">\n Signature\n </div>\n </div>\n )}\n </div>\n );\n }\n\n return (\n <div id=\"signature\">\n <InputGroup\n className={cn(\n mode === \"type\" ? \"max-h-84\" : \"max-h-69\",\n \"overflow-hidden transition-[max-height] duration-300 has-[>[data-align=block-start]]:p-2 gap-2\",\n )}\n >\n <InputGroupAddon align=\"block-start\" className=\"p-0!\">\n <div className=\"relative w-full rounded-base\">\n <div className=\"absolute top-4 left-4 right-3 bg-transparent flex flex-row items-start justify-between gap-3\">\n <Tabs\n value={mode}\n onValueChange={(next) =>\n handleModeChange(next as \"sign\" | \"type\")\n }\n className=\"-mt-1\"\n >\n <TabsList variant=\"contained\" extrude=\"sm\" size=\"md\">\n <TabsTrigger value=\"sign\">\n <IconWriting />\n <span className=\"hidden sm:flex\">Draw</span>\n </TabsTrigger>\n <TabsTrigger value=\"type\">\n <IconTextSize />\n <span className=\"hidden sm:flex\">Type</span>\n </TabsTrigger>\n </TabsList>\n </Tabs>\n <Button\n size=\"sm\"\n raised=\"xs\"\n variant=\"outline\"\n onClick={clearSignature}\n >\n <IconEraser />\n <span className=\"hidden sm:flex\">Clear</span>\n </Button>\n </div>\n {mode === \"sign\" ? (\n <SignatureCanvas\n ref={signature}\n onEnd={handleDrawEnd}\n canvasProps={{\n className:\n canvasClassname ??\n cn(\n \"w-full h-[256px]\",\n \"bg-size-[32px_32px] bg-surface\",\n \"bg-[linear-gradient(to_right,#80808022_1px,transparent_1px),linear-gradient(to_bottom,#80808022_1px,transparent_1px)]\",\n \"inset-shadow-sm\",\n \"border-border border-2 rounded-base\",\n \"cursor-crosshair\",\n ),\n }}\n />\n ) : (\n <canvas\n ref={textCanvas}\n className={cn(\n \"w-full h-64\",\n \"bg-size-[32px_32px] bg-surface\",\n \"bg-[linear-gradient(to_right,#80808022_1px,transparent_1px),linear-gradient(to_bottom,#80808022_1px,transparent_1px)]\",\n \"inset-shadow-sm\",\n \"border-border border-2 rounded-base\",\n )}\n />\n )}\n </div>\n </InputGroupAddon>\n <InputGroupInput\n disabled={mode !== \"type\"}\n className={cn(\n mode === \"type\"\n ? \"animate-in zoom-in-0 spin-in-20 scale-100\"\n : \"animate-out zoom-out-0 spin-out-20 scale-0\",\n \"py-2 text-lg font-medium transition-[scale,translate,box-shadow] duration-300 origin-bottom-left\",\n )}\n placeholder=\"Enter Full Name\"\n value={text}\n onChange={handleTextChange}\n />\n </InputGroup>\n </div>\n );\n}\n","import { COMPONENT } from \"@bonsai/constants\";\n\nimport { Signature } from \"../../components/ui/signature-pad\";\nimport type { BonsaiPreset } from \"../core-registry\";\n\n/** Opt-in `signature` component. Pulls in react-signature-canvas. */\nexport const signaturePreset: BonsaiPreset = {\n components: {\n [COMPONENT.SIGNATURE]: Signature,\n },\n controlledInputs: {\n [COMPONENT.SIGNATURE]: {\n valueProp: \"value\",\n changeProp: \"onChange\",\n extractor: (val: string | null) => val,\n },\n },\n};\n\nexport { Signature };\nexport type { SignatureProps } from \"../../components/ui/signature-pad\";\n"],"names":["Tabs","className","orientation","props","jsx","TabsPrimitive","cn","tabsListVariants","cva","TabsList","variant","size","extrude","TabsTrigger","label","description","children","onClick","trigger","useHaptics","jsxs","event","HAPTIC_TAB","FONT_FAMILY","FONT_SIZE_MAX","FONT_SIZE_MIN","TEXT_PADDING_X","renderTypedSignature","canvas","text","width","height","ratio","ctx","displayWidth","displayHeight","pixelRatio","value","maxTextWidth","fontSize","Signature","onChange","canvasClassname","imageType","renderMode","useBonsaiRenderMode","mode","setMode","useState","setText","signature","useRef","textCanvas","onChangeRef","lastEmittedValue","initialized","textCanvasSizeRef","emitChange","useCallback","nextValue","useEffect","instance","rect","exportCanvas","clearSignature","handleDrawEnd","data","handleModeChange","next","handleTextChange","InputGroup","InputGroupAddon","IconWriting","IconTextSize","Button","IconEraser","SignatureCanvas","InputGroupInput","signaturePreset","COMPONENT","val"],"mappings":"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"}
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import { ElementType } from 'react';
|
|
2
|
+
import { BonsaiRegistry } from '../lib/registry/types.js';
|
|
3
|
+
/**
|
|
4
|
+
* Describes how the renderer two-way-binds a component to the store: which prop
|
|
5
|
+
* carries the value, which prop reports a change, and how to pull the new value
|
|
6
|
+
* out of whatever that prop is called with.
|
|
7
|
+
*/
|
|
8
|
+
export interface ControlledInput {
|
|
9
|
+
valueProp: string;
|
|
10
|
+
changeProp: string;
|
|
11
|
+
extractor: (eventOrValue: any) => any;
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* A controlled-input entry is either a single binding or, for components whose
|
|
15
|
+
* binding depends on `args.type` (e.g. `input`), a map of subtype -> binding
|
|
16
|
+
* with a `default` fallback.
|
|
17
|
+
*/
|
|
18
|
+
export type ControlledInputEntry = ControlledInput | Record<string, ControlledInput>;
|
|
19
|
+
export type ComponentRegistry = Record<string, ElementType>;
|
|
20
|
+
export type ControlledInputRegistry = Record<string, ControlledInputEntry>;
|
|
21
|
+
/**
|
|
22
|
+
* A bundle of components plus their controlled-input bindings. Both the
|
|
23
|
+
* built-in heavy presets (`renderer/presets/*`) and consumer-supplied
|
|
24
|
+
* extensions to `createBonsaiRenderer` use this shape; `extendRegistry`
|
|
25
|
+
* layers it onto the `BonsaiRegistry` the renderer consumes.
|
|
26
|
+
*/
|
|
27
|
+
export interface BonsaiPreset {
|
|
28
|
+
components?: ComponentRegistry;
|
|
29
|
+
controlledInputs?: ControlledInputRegistry;
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* Layers a preset over `base`, type by type: a supplied component replaces the
|
|
33
|
+
* base's component but keeps its binding, and a supplied binding re-binds the
|
|
34
|
+
* base's component — the same "caller wins per key" semantics as spreading the
|
|
35
|
+
* two maps separately.
|
|
36
|
+
*/
|
|
37
|
+
export declare function extendRegistry(base: BonsaiRegistry, { components, controlledInputs }: BonsaiPreset): BonsaiRegistry;
|
|
38
|
+
/**
|
|
39
|
+
* Every built-in component that carries no heavy third-party dependency.
|
|
40
|
+
* Deliberately excludes `map`, `calendar` and `signature` — those live in
|
|
41
|
+
* `renderer/presets/*` so a core consumer never bundles MapLibre,
|
|
42
|
+
* react-day-picker or react-signature-canvas.
|
|
43
|
+
*/
|
|
44
|
+
export declare const coreComponents: ComponentRegistry;
|
|
45
|
+
/** Controlled-input bindings for the components in `coreComponents`. */
|
|
46
|
+
export declare const coreControlledInputs: ControlledInputRegistry;
|
|
47
|
+
/**
|
|
48
|
+
* The registry used when no renderer-scoped registry is provided. Same library
|
|
49
|
+
* identity as `pebbleRegistry` (it is a subset of it), but without per-component
|
|
50
|
+
* `propsSchema`s so the core entry never bundles `@bonsai/schemas`.
|
|
51
|
+
*/
|
|
52
|
+
export declare const coreRegistry: BonsaiRegistry;
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import { BonsaiProps } from '../components/core/bonsai.js';
|
|
2
|
+
import { ComponentRegistry, ControlledInputRegistry } from './core-registry.js';
|
|
3
|
+
import { BonsaiRegistry } from '../lib/registry/types.js';
|
|
4
|
+
export interface BonsaiRendererOptions {
|
|
5
|
+
/** Base registry. Defaults to the lightweight core registry. */
|
|
6
|
+
registry?: BonsaiRegistry;
|
|
7
|
+
/** Extra components layered over `registry` (they win on key collision). */
|
|
8
|
+
components?: Partial<ComponentRegistry>;
|
|
9
|
+
controlledInputs?: Partial<ControlledInputRegistry>;
|
|
10
|
+
}
|
|
11
|
+
export interface BonsaiRendererInstance {
|
|
12
|
+
Bonsai: React.ComponentType<BonsaiProps>;
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* Builds a renderer bound to its own component registry.
|
|
16
|
+
*
|
|
17
|
+
* The registry is `options.registry` (the lightweight core set by default)
|
|
18
|
+
* plus whatever components the caller supplies (caller entries win on key
|
|
19
|
+
* collision); a `registry` prop on an individual `<Bonsai>` still overrides it. It is captured in a React context at
|
|
20
|
+
* this call, so registries never leak between renderer instances and consumers
|
|
21
|
+
* never have to mutate the exported `componentMap`.
|
|
22
|
+
*
|
|
23
|
+
* Heavy built-ins are opt-in via the presets in `renderer/presets/*`:
|
|
24
|
+
*
|
|
25
|
+
* ```ts
|
|
26
|
+
* import { createBonsaiRenderer } from "@pebble-software/bonsai/core";
|
|
27
|
+
* import { calendarPreset } from "@pebble-software/bonsai/presets/calendar";
|
|
28
|
+
*
|
|
29
|
+
* const { Bonsai } = createBonsaiRenderer({
|
|
30
|
+
* components: { ...calendarPreset.components, rating: Rating },
|
|
31
|
+
* controlledInputs: { ...calendarPreset.controlledInputs },
|
|
32
|
+
* });
|
|
33
|
+
* ```
|
|
34
|
+
*
|
|
35
|
+
* Call this at module scope: each call returns a fresh component type, so
|
|
36
|
+
* calling it during render would remount the whole tree every time.
|
|
37
|
+
*/
|
|
38
|
+
export declare function createBonsaiRenderer(options?: BonsaiRendererOptions): BonsaiRendererInstance;
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import { Signature } from '../../components/ui/signature-pad.js';
|
|
2
|
+
import { BonsaiPreset } from '../core-registry.js';
|
|
3
|
+
/** Opt-in `signature` component. Pulls in react-signature-canvas. */
|
|
4
|
+
export declare const signaturePreset: BonsaiPreset;
|
|
5
|
+
export { Signature };
|
|
6
|
+
export type { SignatureProps } from '../../components/ui/signature-pad.js';
|
package/dist/schemas.js
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { C as s, a as o, N as t, P as m, c as n, f as N, g as c, b as d, n as g } from "./chunks/builder.meta-WpXc5VBB.js";
|
|
2
|
+
export {
|
|
3
|
+
s as ComponentNode,
|
|
4
|
+
o as Config,
|
|
5
|
+
t as NodeSchemas,
|
|
6
|
+
m as PEBBLE_COMPONENT_SCHEMAS,
|
|
7
|
+
n as createTemplateSchema,
|
|
8
|
+
N as fieldHints,
|
|
9
|
+
c as getArgsSchema,
|
|
10
|
+
d as getNodeRules,
|
|
11
|
+
g as nodeRules
|
|
12
|
+
};
|
|
13
|
+
//# sourceMappingURL=schemas.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"schemas.js","sources":[],"sourcesContent":[],"names":[],"mappings":";"}
|