entasis 0.13.5 → 0.13.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/components/Address/Address.svelte +44 -0
- package/dist/components/Address/Address.svelte.d.ts +4 -0
- package/dist/components/Address/address.d.ts +99 -0
- package/dist/components/Address/address.google.d.ts +89 -0
- package/dist/components/Address/address.google.fixtures.json +808 -0
- package/dist/components/Address/address.google.js +184 -0
- package/dist/components/Address/address.js +109 -0
- package/dist/components/Address/address.mcp.d.ts +1 -0
- package/dist/components/Address/address.mcp.js +100 -0
- package/dist/components/Address/address.props.d.ts +26 -0
- package/dist/components/Address/address.props.js +1 -0
- package/dist/components/Address/address.provider.d.ts +19 -0
- package/dist/components/Address/address.provider.js +69 -0
- package/dist/components/Address/address.theme.d.ts +63 -0
- package/dist/components/Address/address.theme.js +42 -0
- package/dist/components/Address/index.d.ts +6 -0
- package/dist/components/Address/index.js +5 -0
- package/dist/components/Form/AddressInput/AddressInput.svelte +482 -0
- package/dist/components/Form/AddressInput/AddressInput.svelte.d.ts +4 -0
- package/dist/components/Form/AddressInput/addressInput.mcp.d.ts +1 -0
- package/dist/components/Form/AddressInput/addressInput.mcp.js +110 -0
- package/dist/components/Form/AddressInput/addressInput.props.d.ts +72 -0
- package/dist/components/Form/AddressInput/addressInput.props.js +1 -0
- package/dist/components/Form/AddressInput/addressInput.theme.d.ts +63 -0
- package/dist/components/Form/AddressInput/addressInput.theme.js +55 -0
- package/dist/components/Form/AddressInput/index.d.ts +3 -0
- package/dist/components/Form/AddressInput/index.js +2 -0
- package/dist/components/Form/Field/field.d.ts +5 -2
- package/dist/components/Form/Field/field.state.svelte.js +4 -0
- package/dist/components/Form/Field/index.d.ts +1 -1
- package/dist/components/Form/Field/schemas.js +8 -0
- package/dist/components/Form/Form/FormInputRenderer.svelte +6 -0
- package/dist/components/Form/Form/form.d.ts +6 -0
- package/dist/components/Form/Form/form.mcp.d.ts +1 -1
- package/dist/components/Form/Form/form.mcp.js +1 -1
- package/dist/components/Form/Form/form.state.svelte.d.ts +142 -11
- package/dist/components/Form/Form/form.state.svelte.js +2 -0
- package/dist/components/Form/Form/visibility.d.ts +186 -20
- package/dist/components/Form/MultiStepForm/multiStepForm.state.svelte.d.ts +136 -0
- package/dist/components/Form/SignatureInput/SignatureInput.svelte +327 -0
- package/dist/components/Form/SignatureInput/SignatureInput.svelte.d.ts +4 -0
- package/dist/components/Form/SignatureInput/index.d.ts +4 -0
- package/dist/components/Form/SignatureInput/index.js +2 -0
- package/dist/components/Form/SignatureInput/signatureInput.mcp.d.ts +1 -0
- package/dist/components/Form/SignatureInput/signatureInput.mcp.js +74 -0
- package/dist/components/Form/SignatureInput/signatureInput.props.d.ts +29 -0
- package/dist/components/Form/SignatureInput/signatureInput.props.js +1 -0
- package/dist/components/Form/SignatureInput/signatureInput.strokes.d.ts +77 -0
- package/dist/components/Form/SignatureInput/signatureInput.strokes.js +149 -0
- package/dist/components/Form/SignatureInput/signatureInput.theme.d.ts +99 -0
- package/dist/components/Form/SignatureInput/signatureInput.theme.js +70 -0
- package/dist/components/Sidebar/Sidebar.svelte +1 -1
- package/dist/components/Sidebar/SidebarMenuItem.svelte +59 -15
- package/dist/components/Sidebar/SidebarMenuSubItem.svelte +43 -12
- package/dist/components/Sidebar/SidebarMenuText.svelte +60 -0
- package/dist/components/Sidebar/SidebarMenuText.svelte.d.ts +18 -0
- package/dist/components/Sidebar/sidebar.mcp.d.ts +1 -1
- package/dist/components/Sidebar/sidebar.mcp.js +53 -0
- package/dist/components/Sidebar/sidebar.props.d.ts +31 -0
- package/dist/components/Sidebar/sidebar.theme.d.ts +99 -0
- package/dist/components/Sidebar/sidebar.theme.js +100 -9
- package/dist/generated/componentAliases.d.ts +3 -0
- package/dist/generated/componentAliases.js +3 -0
- package/dist/generated/componentContract.d.ts +46 -1
- package/dist/generated/componentContract.js +113 -0
- package/dist/generated/componentMcpRegistry.js +6 -0
- package/dist/i18n/ar.js +18 -0
- package/dist/i18n/de.js +18 -0
- package/dist/i18n/en.d.ts +18 -0
- package/dist/i18n/en.js +18 -0
- package/dist/i18n/es.js +18 -0
- package/dist/i18n/fr.js +18 -0
- package/dist/i18n/ja.js +18 -0
- package/dist/i18n/pt.js +18 -0
- package/dist/i18n/zh.js +18 -0
- package/package.json +25 -1
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Strokes of a signature and the images they export to. Pure geometry: no DOM except the
|
|
3
|
+
* canvas context a caller passes in, so it runs the same in a test, on the pad and on export.
|
|
4
|
+
*/
|
|
5
|
+
/** One sampled pointer position, in CSS pixels of the pad. */
|
|
6
|
+
export type SignaturePoint = {
|
|
7
|
+
x: number;
|
|
8
|
+
y: number;
|
|
9
|
+
/** Pen pressure from 0 to 1. Mouse and touch report 0.5. */
|
|
10
|
+
pressure: number;
|
|
11
|
+
};
|
|
12
|
+
/** One continuous line, from a pointer down to its pointer up. */
|
|
13
|
+
export type SignatureStroke = readonly SignaturePoint[];
|
|
14
|
+
export type SignatureBounds = {
|
|
15
|
+
x: number;
|
|
16
|
+
y: number;
|
|
17
|
+
width: number;
|
|
18
|
+
height: number;
|
|
19
|
+
};
|
|
20
|
+
/** Exported image format: a PNG or an SVG, each as a data URL. */
|
|
21
|
+
export type SignatureFormat = 'png' | 'svg';
|
|
22
|
+
export type SignatureRenderOptions = {
|
|
23
|
+
/** CSS color of the ink. */
|
|
24
|
+
color: string;
|
|
25
|
+
/** Base line width in CSS pixels, at a pressure of 0.5. */
|
|
26
|
+
width: number;
|
|
27
|
+
};
|
|
28
|
+
/** Width of a segment drawn at `pressure`: half the base at no pressure, 1.5 times at full. */
|
|
29
|
+
export declare const strokeWidthAt: (pressure: number, width: number) => number;
|
|
30
|
+
/**
|
|
31
|
+
* The segments a stroke is drawn as: quadratic curves through the midpoints of its samples, so
|
|
32
|
+
* the line is smooth however coarse the pointer events were. Each segment carries the pressure it
|
|
33
|
+
* is drawn at, so a pen's line thickens and thins along the way.
|
|
34
|
+
*/
|
|
35
|
+
export declare function strokeSegments(stroke: SignatureStroke): {
|
|
36
|
+
from: SignaturePoint;
|
|
37
|
+
control: SignaturePoint;
|
|
38
|
+
to: SignaturePoint;
|
|
39
|
+
pressure: number;
|
|
40
|
+
}[];
|
|
41
|
+
/** Draws `strokes` on a 2D context already scaled to CSS pixels. A tap draws a dot. */
|
|
42
|
+
export declare function drawStrokes(context: CanvasRenderingContext2D, strokes: readonly SignatureStroke[], { color, width }: SignatureRenderOptions): void;
|
|
43
|
+
/** The box the ink covers, line width included, or null when there is no ink. */
|
|
44
|
+
export declare function strokesBounds(strokes: readonly SignatureStroke[], width: number): SignatureBounds | null;
|
|
45
|
+
/** One drawable piece of a stroke: a dot for a tap, or a path at one line width. */
|
|
46
|
+
export type SignatureShape = {
|
|
47
|
+
kind: 'dot';
|
|
48
|
+
x: number;
|
|
49
|
+
y: number;
|
|
50
|
+
r: number;
|
|
51
|
+
} | {
|
|
52
|
+
kind: 'path';
|
|
53
|
+
d: string;
|
|
54
|
+
width: number;
|
|
55
|
+
};
|
|
56
|
+
/**
|
|
57
|
+
* The shapes a stroke draws as, in SVG path syntax, shifted by `offset`. Consecutive segments
|
|
58
|
+
* at the same width share one path, so a mouse or finger stroke is a single path and only a
|
|
59
|
+
* pen's changing pressure splits it.
|
|
60
|
+
*/
|
|
61
|
+
export declare function strokeShapes(stroke: SignatureStroke, width: number, offset?: {
|
|
62
|
+
x: number;
|
|
63
|
+
y: number;
|
|
64
|
+
}): SignatureShape[];
|
|
65
|
+
/** A standalone SVG of the strokes, cropped to the ink plus `padding`. */
|
|
66
|
+
export declare function strokesToSvg(strokes: readonly SignatureStroke[], { color, width, padding }: SignatureRenderOptions & {
|
|
67
|
+
padding: number;
|
|
68
|
+
}): string | null;
|
|
69
|
+
/**
|
|
70
|
+
* Exports the strokes as a data URL cropped to the ink plus `padding`: an SVG, or a PNG drawn at
|
|
71
|
+
* `scale` device pixels per CSS pixel so it stays sharp in a document. Null when there is no ink.
|
|
72
|
+
*/
|
|
73
|
+
export declare function exportStrokes(strokes: readonly SignatureStroke[], { format, color, width, padding, scale }: SignatureRenderOptions & {
|
|
74
|
+
format: SignatureFormat;
|
|
75
|
+
padding: number;
|
|
76
|
+
scale: number;
|
|
77
|
+
}): string | null;
|
|
@@ -0,0 +1,149 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Strokes of a signature and the images they export to. Pure geometry: no DOM except the
|
|
3
|
+
* canvas context a caller passes in, so it runs the same in a test, on the pad and on export.
|
|
4
|
+
*/
|
|
5
|
+
/** Width of a segment drawn at `pressure`: half the base at no pressure, 1.5 times at full. */
|
|
6
|
+
export const strokeWidthAt = (pressure, width) => width * (0.5 + Math.min(Math.max(pressure, 0), 1));
|
|
7
|
+
const midpoint = (a, b) => ({
|
|
8
|
+
x: (a.x + b.x) / 2,
|
|
9
|
+
y: (a.y + b.y) / 2,
|
|
10
|
+
pressure: (a.pressure + b.pressure) / 2
|
|
11
|
+
});
|
|
12
|
+
/**
|
|
13
|
+
* The segments a stroke is drawn as: quadratic curves through the midpoints of its samples, so
|
|
14
|
+
* the line is smooth however coarse the pointer events were. Each segment carries the pressure it
|
|
15
|
+
* is drawn at, so a pen's line thickens and thins along the way.
|
|
16
|
+
*/
|
|
17
|
+
export function strokeSegments(stroke) {
|
|
18
|
+
const segments = [];
|
|
19
|
+
if (stroke.length < 2)
|
|
20
|
+
return segments;
|
|
21
|
+
let from = stroke[0];
|
|
22
|
+
for (let index = 1; index < stroke.length - 1; index++) {
|
|
23
|
+
const control = stroke[index];
|
|
24
|
+
const to = midpoint(control, stroke[index + 1]);
|
|
25
|
+
segments.push({ from, control, to, pressure: control.pressure });
|
|
26
|
+
from = to;
|
|
27
|
+
}
|
|
28
|
+
const last = stroke[stroke.length - 1];
|
|
29
|
+
segments.push({ from, control: last, to: last, pressure: last.pressure });
|
|
30
|
+
return segments;
|
|
31
|
+
}
|
|
32
|
+
/** Draws `strokes` on a 2D context already scaled to CSS pixels. A tap draws a dot. */
|
|
33
|
+
export function drawStrokes(context, strokes, { color, width }) {
|
|
34
|
+
context.save();
|
|
35
|
+
context.strokeStyle = color;
|
|
36
|
+
context.fillStyle = color;
|
|
37
|
+
context.lineCap = 'round';
|
|
38
|
+
context.lineJoin = 'round';
|
|
39
|
+
for (const stroke of strokes) {
|
|
40
|
+
if (stroke.length === 1) {
|
|
41
|
+
const [dot] = stroke;
|
|
42
|
+
context.beginPath();
|
|
43
|
+
context.arc(dot.x, dot.y, strokeWidthAt(dot.pressure, width) / 2, 0, Math.PI * 2);
|
|
44
|
+
context.fill();
|
|
45
|
+
continue;
|
|
46
|
+
}
|
|
47
|
+
for (const segment of strokeSegments(stroke)) {
|
|
48
|
+
context.beginPath();
|
|
49
|
+
context.lineWidth = strokeWidthAt(segment.pressure, width);
|
|
50
|
+
context.moveTo(segment.from.x, segment.from.y);
|
|
51
|
+
context.quadraticCurveTo(segment.control.x, segment.control.y, segment.to.x, segment.to.y);
|
|
52
|
+
context.stroke();
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
context.restore();
|
|
56
|
+
}
|
|
57
|
+
/** The box the ink covers, line width included, or null when there is no ink. */
|
|
58
|
+
export function strokesBounds(strokes, width) {
|
|
59
|
+
let minX = Infinity;
|
|
60
|
+
let minY = Infinity;
|
|
61
|
+
let maxX = -Infinity;
|
|
62
|
+
let maxY = -Infinity;
|
|
63
|
+
for (const stroke of strokes) {
|
|
64
|
+
for (const point of stroke) {
|
|
65
|
+
const half = strokeWidthAt(point.pressure, width) / 2;
|
|
66
|
+
minX = Math.min(minX, point.x - half);
|
|
67
|
+
minY = Math.min(minY, point.y - half);
|
|
68
|
+
maxX = Math.max(maxX, point.x + half);
|
|
69
|
+
maxY = Math.max(maxY, point.y + half);
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
if (minX === Infinity)
|
|
73
|
+
return null;
|
|
74
|
+
return { x: minX, y: minY, width: maxX - minX, height: maxY - minY };
|
|
75
|
+
}
|
|
76
|
+
const round = (value) => Math.round(value * 100) / 100;
|
|
77
|
+
/**
|
|
78
|
+
* The shapes a stroke draws as, in SVG path syntax, shifted by `offset`. Consecutive segments
|
|
79
|
+
* at the same width share one path, so a mouse or finger stroke is a single path and only a
|
|
80
|
+
* pen's changing pressure splits it.
|
|
81
|
+
*/
|
|
82
|
+
export function strokeShapes(stroke, width, offset = { x: 0, y: 0 }) {
|
|
83
|
+
const x = (value) => round(value - offset.x);
|
|
84
|
+
const y = (value) => round(value - offset.y);
|
|
85
|
+
if (stroke.length === 1) {
|
|
86
|
+
const [dot] = stroke;
|
|
87
|
+
return [
|
|
88
|
+
{ kind: 'dot', x: x(dot.x), y: y(dot.y), r: round(strokeWidthAt(dot.pressure, width) / 2) }
|
|
89
|
+
];
|
|
90
|
+
}
|
|
91
|
+
const shapes = [];
|
|
92
|
+
for (const segment of strokeSegments(stroke)) {
|
|
93
|
+
const segmentWidth = round(strokeWidthAt(segment.pressure, width));
|
|
94
|
+
const curve = `Q${x(segment.control.x)} ${y(segment.control.y)} ${x(segment.to.x)} ${y(segment.to.y)}`;
|
|
95
|
+
const last = shapes.at(-1);
|
|
96
|
+
if (last?.kind === 'path' && last.width === segmentWidth)
|
|
97
|
+
last.d += curve;
|
|
98
|
+
else
|
|
99
|
+
shapes.push({
|
|
100
|
+
kind: 'path',
|
|
101
|
+
d: `M${x(segment.from.x)} ${y(segment.from.y)}${curve}`,
|
|
102
|
+
width: segmentWidth
|
|
103
|
+
});
|
|
104
|
+
}
|
|
105
|
+
return shapes;
|
|
106
|
+
}
|
|
107
|
+
/** A standalone SVG of the strokes, cropped to the ink plus `padding`. */
|
|
108
|
+
export function strokesToSvg(strokes, { color, width, padding }) {
|
|
109
|
+
const bounds = strokesBounds(strokes, width);
|
|
110
|
+
if (!bounds)
|
|
111
|
+
return null;
|
|
112
|
+
const offset = { x: bounds.x - padding, y: bounds.y - padding };
|
|
113
|
+
const boxWidth = round(bounds.width + padding * 2);
|
|
114
|
+
const boxHeight = round(bounds.height + padding * 2);
|
|
115
|
+
const shapes = strokes
|
|
116
|
+
.flatMap((stroke) => strokeShapes(stroke, width, offset))
|
|
117
|
+
.map((shape) => shape.kind === 'dot'
|
|
118
|
+
? `<circle cx="${shape.x}" cy="${shape.y}" r="${shape.r}" fill="${color}"/>`
|
|
119
|
+
: `<path d="${shape.d}" stroke-width="${shape.width}"/>`);
|
|
120
|
+
return [
|
|
121
|
+
`<svg xmlns="http://www.w3.org/2000/svg" width="${boxWidth}" height="${boxHeight}" viewBox="0 0 ${boxWidth} ${boxHeight}">`,
|
|
122
|
+
`<g fill="none" stroke="${color}" stroke-linecap="round" stroke-linejoin="round">`,
|
|
123
|
+
shapes.join(''),
|
|
124
|
+
'</g></svg>'
|
|
125
|
+
].join('');
|
|
126
|
+
}
|
|
127
|
+
/**
|
|
128
|
+
* Exports the strokes as a data URL cropped to the ink plus `padding`: an SVG, or a PNG drawn at
|
|
129
|
+
* `scale` device pixels per CSS pixel so it stays sharp in a document. Null when there is no ink.
|
|
130
|
+
*/
|
|
131
|
+
export function exportStrokes(strokes, { format, color, width, padding, scale }) {
|
|
132
|
+
if (format === 'svg') {
|
|
133
|
+
const svg = strokesToSvg(strokes, { color, width, padding });
|
|
134
|
+
return svg ? `data:image/svg+xml;charset=utf-8,${encodeURIComponent(svg)}` : null;
|
|
135
|
+
}
|
|
136
|
+
const bounds = strokesBounds(strokes, width);
|
|
137
|
+
if (!bounds || typeof document === 'undefined')
|
|
138
|
+
return null;
|
|
139
|
+
const canvas = document.createElement('canvas');
|
|
140
|
+
canvas.width = Math.ceil((bounds.width + padding * 2) * scale);
|
|
141
|
+
canvas.height = Math.ceil((bounds.height + padding * 2) * scale);
|
|
142
|
+
const context = canvas.getContext('2d');
|
|
143
|
+
if (!context)
|
|
144
|
+
return null;
|
|
145
|
+
context.scale(scale, scale);
|
|
146
|
+
context.translate(padding - bounds.x, padding - bounds.y);
|
|
147
|
+
drawStrokes(context, strokes, { color, width });
|
|
148
|
+
return canvas.toDataURL('image/png');
|
|
149
|
+
}
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
import { type InferComponentTheme } from '../../../utils/cva/index.js';
|
|
2
|
+
export declare const signatureInputTheme: {
|
|
3
|
+
frame: (props?: import("../../../utils/cva/types.ts").CVAClassProp | undefined) => string;
|
|
4
|
+
pad: (props?: (import("../../../utils/cva/types.ts").CVAVariantSchema<{
|
|
5
|
+
size: {
|
|
6
|
+
small: string;
|
|
7
|
+
normal: string;
|
|
8
|
+
large: string;
|
|
9
|
+
};
|
|
10
|
+
interactive: {
|
|
11
|
+
true: string;
|
|
12
|
+
false: string;
|
|
13
|
+
};
|
|
14
|
+
disabled: {
|
|
15
|
+
true: string;
|
|
16
|
+
false: string;
|
|
17
|
+
};
|
|
18
|
+
hasError: {
|
|
19
|
+
true: string;
|
|
20
|
+
false: string;
|
|
21
|
+
};
|
|
22
|
+
}> & import("../../../utils/cva/types.ts").CVAClassProp) | undefined) => string;
|
|
23
|
+
ink: (props?: import("../../../utils/cva/types.ts").CVAClassProp | undefined) => string;
|
|
24
|
+
image: (props?: import("../../../utils/cva/types.ts").CVAClassProp | undefined) => string;
|
|
25
|
+
placeholder: (props?: (import("../../../utils/cva/types.ts").CVAVariantSchema<{
|
|
26
|
+
size: {
|
|
27
|
+
small: string;
|
|
28
|
+
normal: string;
|
|
29
|
+
large: string;
|
|
30
|
+
};
|
|
31
|
+
}> & import("../../../utils/cva/types.ts").CVAClassProp) | undefined) => string;
|
|
32
|
+
actions: (props?: import("../../../utils/cva/types.ts").CVAClassProp | undefined) => string;
|
|
33
|
+
};
|
|
34
|
+
export type SignatureInputTheme = typeof signatureInputTheme;
|
|
35
|
+
export type SignatureInputThemeProps = InferComponentTheme<SignatureInputTheme>;
|
|
36
|
+
export declare const setSignatureInputTheme: (theme: InferComponentTheme<{
|
|
37
|
+
frame: (props?: import("../../../utils/cva/types.ts").CVAClassProp | undefined) => string;
|
|
38
|
+
pad: (props?: (import("../../../utils/cva/types.ts").CVAVariantSchema<{
|
|
39
|
+
size: {
|
|
40
|
+
small: string;
|
|
41
|
+
normal: string;
|
|
42
|
+
large: string;
|
|
43
|
+
};
|
|
44
|
+
interactive: {
|
|
45
|
+
true: string;
|
|
46
|
+
false: string;
|
|
47
|
+
};
|
|
48
|
+
disabled: {
|
|
49
|
+
true: string;
|
|
50
|
+
false: string;
|
|
51
|
+
};
|
|
52
|
+
hasError: {
|
|
53
|
+
true: string;
|
|
54
|
+
false: string;
|
|
55
|
+
};
|
|
56
|
+
}> & import("../../../utils/cva/types.ts").CVAClassProp) | undefined) => string;
|
|
57
|
+
ink: (props?: import("../../../utils/cva/types.ts").CVAClassProp | undefined) => string;
|
|
58
|
+
image: (props?: import("../../../utils/cva/types.ts").CVAClassProp | undefined) => string;
|
|
59
|
+
placeholder: (props?: (import("../../../utils/cva/types.ts").CVAVariantSchema<{
|
|
60
|
+
size: {
|
|
61
|
+
small: string;
|
|
62
|
+
normal: string;
|
|
63
|
+
large: string;
|
|
64
|
+
};
|
|
65
|
+
}> & import("../../../utils/cva/types.ts").CVAClassProp) | undefined) => string;
|
|
66
|
+
actions: (props?: import("../../../utils/cva/types.ts").CVAClassProp | undefined) => string;
|
|
67
|
+
}>) => void;
|
|
68
|
+
export declare const useSignatureInputTheme: import("../../../utils/cva/theme.ts").UseComponentTheme<{
|
|
69
|
+
frame: (props?: import("../../../utils/cva/types.ts").CVAClassProp | undefined) => string;
|
|
70
|
+
pad: (props?: (import("../../../utils/cva/types.ts").CVAVariantSchema<{
|
|
71
|
+
size: {
|
|
72
|
+
small: string;
|
|
73
|
+
normal: string;
|
|
74
|
+
large: string;
|
|
75
|
+
};
|
|
76
|
+
interactive: {
|
|
77
|
+
true: string;
|
|
78
|
+
false: string;
|
|
79
|
+
};
|
|
80
|
+
disabled: {
|
|
81
|
+
true: string;
|
|
82
|
+
false: string;
|
|
83
|
+
};
|
|
84
|
+
hasError: {
|
|
85
|
+
true: string;
|
|
86
|
+
false: string;
|
|
87
|
+
};
|
|
88
|
+
}> & import("../../../utils/cva/types.ts").CVAClassProp) | undefined) => string;
|
|
89
|
+
ink: (props?: import("../../../utils/cva/types.ts").CVAClassProp | undefined) => string;
|
|
90
|
+
image: (props?: import("../../../utils/cva/types.ts").CVAClassProp | undefined) => string;
|
|
91
|
+
placeholder: (props?: (import("../../../utils/cva/types.ts").CVAVariantSchema<{
|
|
92
|
+
size: {
|
|
93
|
+
small: string;
|
|
94
|
+
normal: string;
|
|
95
|
+
large: string;
|
|
96
|
+
};
|
|
97
|
+
}> & import("../../../utils/cva/types.ts").CVAClassProp) | undefined) => string;
|
|
98
|
+
actions: (props?: import("../../../utils/cva/types.ts").CVAClassProp | undefined) => string;
|
|
99
|
+
}>;
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
import { cva, setComponentTheme, useComponentTheme } from '../../../utils/cva/index.js';
|
|
2
|
+
// Holds the pad and, over its corner, the buttons: they cannot sit inside the pad, whose image
|
|
3
|
+
// role would hide them from assistive technology.
|
|
4
|
+
const defaultFrame = cva({
|
|
5
|
+
base: 'relative w-full min-w-0'
|
|
6
|
+
});
|
|
7
|
+
// The pad is the control: it takes focus, so its own ring shows keyboard focus, and the strokes
|
|
8
|
+
// are drawn in its text color (an SVG in `currentColor`), so they follow the theme.
|
|
9
|
+
const defaultPad = cva({
|
|
10
|
+
base: 'relative w-full min-w-0 touch-none overflow-hidden rounded-md border border-neutral-muted bg-surface-raised text-neutral outline-none select-none focus-visible:ring-2 focus-visible:ring-focus/50',
|
|
11
|
+
variants: {
|
|
12
|
+
size: {
|
|
13
|
+
small: 'h-28',
|
|
14
|
+
normal: 'h-36',
|
|
15
|
+
large: 'h-44'
|
|
16
|
+
},
|
|
17
|
+
interactive: {
|
|
18
|
+
true: 'cursor-crosshair',
|
|
19
|
+
false: ''
|
|
20
|
+
},
|
|
21
|
+
disabled: {
|
|
22
|
+
true: 'cursor-not-allowed opacity-50',
|
|
23
|
+
false: ''
|
|
24
|
+
},
|
|
25
|
+
hasError: {
|
|
26
|
+
true: 'border-danger focus-visible:ring-danger/50',
|
|
27
|
+
false: ''
|
|
28
|
+
}
|
|
29
|
+
},
|
|
30
|
+
defaultVariants: {
|
|
31
|
+
size: 'normal',
|
|
32
|
+
interactive: true,
|
|
33
|
+
disabled: false,
|
|
34
|
+
hasError: false
|
|
35
|
+
}
|
|
36
|
+
});
|
|
37
|
+
const defaultInk = cva({
|
|
38
|
+
base: 'pointer-events-none absolute inset-0 size-full overflow-visible'
|
|
39
|
+
});
|
|
40
|
+
// A value set from outside (a saved signature) shows as an image, scaled to fit the pad.
|
|
41
|
+
const defaultImage = cva({
|
|
42
|
+
base: 'pointer-events-none absolute inset-0 size-full object-contain p-md'
|
|
43
|
+
});
|
|
44
|
+
// The line to sign on and its hint: decorative, gone as soon as there is ink.
|
|
45
|
+
const defaultPlaceholder = cva({
|
|
46
|
+
base: 'pointer-events-none absolute inset-x-[var(--space-xl)] bottom-1/4 flex items-end gap-sm border-b border-dashed border-neutral-muted pb-xs text-neutral/45',
|
|
47
|
+
variants: {
|
|
48
|
+
size: {
|
|
49
|
+
small: 'text-xs',
|
|
50
|
+
normal: 'text-sm',
|
|
51
|
+
large: 'text-base'
|
|
52
|
+
}
|
|
53
|
+
},
|
|
54
|
+
defaultVariants: {
|
|
55
|
+
size: 'normal'
|
|
56
|
+
}
|
|
57
|
+
});
|
|
58
|
+
const defaultActions = cva({
|
|
59
|
+
base: 'absolute end-[var(--space-xs)] top-[var(--space-xs)] flex items-center gap-xs'
|
|
60
|
+
});
|
|
61
|
+
export const signatureInputTheme = {
|
|
62
|
+
frame: defaultFrame,
|
|
63
|
+
pad: defaultPad,
|
|
64
|
+
ink: defaultInk,
|
|
65
|
+
image: defaultImage,
|
|
66
|
+
placeholder: defaultPlaceholder,
|
|
67
|
+
actions: defaultActions
|
|
68
|
+
};
|
|
69
|
+
export const setSignatureInputTheme = setComponentTheme('signature-input');
|
|
70
|
+
export const useSignatureInputTheme = useComponentTheme('signature-input', signatureInputTheme);
|
|
@@ -28,6 +28,7 @@
|
|
|
28
28
|
import SidebarFlyout from './SidebarFlyout.svelte';
|
|
29
29
|
import SidebarIcon from './SidebarIcon.svelte';
|
|
30
30
|
import SidebarMenuSubItem from './SidebarMenuSubItem.svelte';
|
|
31
|
+
import SidebarMenuText from './SidebarMenuText.svelte';
|
|
31
32
|
import { useSidebarSuffixWidth } from './sidebar.suffix.svelte.js';
|
|
32
33
|
import { useSidebarMotion, useSidebarTheme, type SidebarThemeProps } from './sidebar.theme.js';
|
|
33
34
|
|
|
@@ -82,6 +83,13 @@
|
|
|
82
83
|
);
|
|
83
84
|
const hasSubmenu = $derived(!!item.items?.length);
|
|
84
85
|
const showBadge = $derived(item.badge != null && !isIconCollapsed);
|
|
86
|
+
// A description stacks a second line under the label, so the row takes the large height
|
|
87
|
+
// unless the entry sets its own size.
|
|
88
|
+
const rowSize = $derived(item.size ?? (item.description != null ? 'large' : undefined));
|
|
89
|
+
const lead = $derived(item.media ? 'media' : 'icon');
|
|
90
|
+
// On a two-line row the suffix and the badge sit on the description's line, so the label's
|
|
91
|
+
// line, and its meta, run to the same end on every row.
|
|
92
|
+
const twoLine = $derived(item.description != null);
|
|
85
93
|
// An in-flow chevron or dots after the badge: the row then keeps its action's room at every
|
|
86
94
|
// width, since the action would otherwise cover that glyph when it shows.
|
|
87
95
|
const hasTrailingGlyph = $derived(
|
|
@@ -94,8 +102,12 @@
|
|
|
94
102
|
const endReserve = $derived(
|
|
95
103
|
item.suffix
|
|
96
104
|
? item.action
|
|
97
|
-
?
|
|
98
|
-
|
|
105
|
+
? twoLine
|
|
106
|
+
? 'suffixLineAction'
|
|
107
|
+
: 'suffixAction'
|
|
108
|
+
: twoLine
|
|
109
|
+
? 'suffixLine'
|
|
110
|
+
: 'suffix'
|
|
99
111
|
: !item.action
|
|
100
112
|
? 'none'
|
|
101
113
|
: showBadge && !hasTrailingGlyph
|
|
@@ -176,7 +188,11 @@
|
|
|
176
188
|
</script>
|
|
177
189
|
|
|
178
190
|
{#snippet entryContent()}
|
|
179
|
-
{#if
|
|
191
|
+
{#if item.media}
|
|
192
|
+
<span data-slot="sidebar-menu-media" data-sidebar="menu-media" class={classes.menuMedia()}>
|
|
193
|
+
{@render item.media(api, item)}
|
|
194
|
+
</span>
|
|
195
|
+
{:else if hasIconSurface}
|
|
180
196
|
<span
|
|
181
197
|
data-slot="sidebar-menu-icon"
|
|
182
198
|
data-color={item.iconColor}
|
|
@@ -187,7 +203,25 @@
|
|
|
187
203
|
{:else}
|
|
188
204
|
<SidebarIcon icon={item.icon} class={back ? 'rtl:-scale-x-100' : undefined} />
|
|
189
205
|
{/if}
|
|
190
|
-
|
|
206
|
+
{#if item.description != null || item.meta != null}
|
|
207
|
+
<SidebarMenuText
|
|
208
|
+
label={item.label}
|
|
209
|
+
description={item.description}
|
|
210
|
+
meta={isIconCollapsed ? undefined : item.meta}
|
|
211
|
+
suffix={!!item.suffix}
|
|
212
|
+
trailing={twoLine ? badge : undefined}
|
|
213
|
+
{size}
|
|
214
|
+
{theme}
|
|
215
|
+
/>
|
|
216
|
+
{:else}
|
|
217
|
+
<span class={classes.menuLabel()}>{item.label}</span>
|
|
218
|
+
{/if}
|
|
219
|
+
{#if !twoLine}
|
|
220
|
+
{@render badge()}
|
|
221
|
+
{/if}
|
|
222
|
+
{/snippet}
|
|
223
|
+
|
|
224
|
+
{#snippet badge()}
|
|
191
225
|
{#if showBadge}
|
|
192
226
|
<span
|
|
193
227
|
data-slot="sidebar-menu-badge"
|
|
@@ -224,7 +258,7 @@
|
|
|
224
258
|
role={item.disabled ? 'link' : undefined}
|
|
225
259
|
data-slot="sidebar-menu-button"
|
|
226
260
|
data-sidebar="menu-button"
|
|
227
|
-
data-size={
|
|
261
|
+
data-size={rowSize ?? 'normal'}
|
|
228
262
|
data-active={item.isActive ? 'true' : undefined}
|
|
229
263
|
data-active-variant={activeVariant}
|
|
230
264
|
aria-current={item.isActive ? 'page' : undefined}
|
|
@@ -236,7 +270,8 @@
|
|
|
236
270
|
activeVariant,
|
|
237
271
|
size,
|
|
238
272
|
density,
|
|
239
|
-
itemSize:
|
|
273
|
+
itemSize: rowSize,
|
|
274
|
+
lead,
|
|
240
275
|
endReserve,
|
|
241
276
|
className: item.class
|
|
242
277
|
})}
|
|
@@ -254,7 +289,7 @@
|
|
|
254
289
|
type="button"
|
|
255
290
|
data-slot="sidebar-menu-button"
|
|
256
291
|
data-sidebar="menu-button"
|
|
257
|
-
data-size={
|
|
292
|
+
data-size={rowSize ?? 'normal'}
|
|
258
293
|
data-active={item.isActive ? 'true' : undefined}
|
|
259
294
|
data-active-variant={activeVariant}
|
|
260
295
|
aria-current={item.isActive ? 'page' : undefined}
|
|
@@ -267,7 +302,8 @@
|
|
|
267
302
|
activeVariant,
|
|
268
303
|
size,
|
|
269
304
|
density,
|
|
270
|
-
itemSize:
|
|
305
|
+
itemSize: rowSize,
|
|
306
|
+
lead,
|
|
271
307
|
endReserve,
|
|
272
308
|
className: item.class
|
|
273
309
|
})}
|
|
@@ -302,7 +338,7 @@
|
|
|
302
338
|
type="button"
|
|
303
339
|
data-slot="sidebar-menu-button"
|
|
304
340
|
data-sidebar="menu-button"
|
|
305
|
-
data-size={
|
|
341
|
+
data-size={rowSize ?? 'normal'}
|
|
306
342
|
data-active-variant={activeVariant}
|
|
307
343
|
disabled={item.disabled || undefined}
|
|
308
344
|
class={classes.menuButton({
|
|
@@ -310,7 +346,8 @@
|
|
|
310
346
|
activeVariant,
|
|
311
347
|
size,
|
|
312
348
|
density,
|
|
313
|
-
itemSize:
|
|
349
|
+
itemSize: rowSize,
|
|
350
|
+
lead,
|
|
314
351
|
endReserve,
|
|
315
352
|
className: ['aria-expanded:bg-neutral-muted', item.class]
|
|
316
353
|
})}
|
|
@@ -339,7 +376,7 @@
|
|
|
339
376
|
type="button"
|
|
340
377
|
data-slot="sidebar-menu-button"
|
|
341
378
|
data-sidebar="menu-button"
|
|
342
|
-
data-size={
|
|
379
|
+
data-size={rowSize ?? 'normal'}
|
|
343
380
|
data-active={item.isActive ? 'true' : undefined}
|
|
344
381
|
data-active-variant={activeVariant}
|
|
345
382
|
class={classes.menuButton({
|
|
@@ -347,7 +384,8 @@
|
|
|
347
384
|
activeVariant,
|
|
348
385
|
size,
|
|
349
386
|
density,
|
|
350
|
-
itemSize:
|
|
387
|
+
itemSize: rowSize,
|
|
388
|
+
lead,
|
|
351
389
|
endReserve,
|
|
352
390
|
className: item.class
|
|
353
391
|
})}
|
|
@@ -434,7 +472,7 @@
|
|
|
434
472
|
type="button"
|
|
435
473
|
data-slot="sidebar-menu-button"
|
|
436
474
|
data-sidebar="menu-button"
|
|
437
|
-
data-size={
|
|
475
|
+
data-size={rowSize ?? 'normal'}
|
|
438
476
|
data-active={item.isActive ? 'true' : undefined}
|
|
439
477
|
data-active-variant={activeVariant}
|
|
440
478
|
disabled={item.disabled || undefined}
|
|
@@ -443,7 +481,8 @@
|
|
|
443
481
|
activeVariant,
|
|
444
482
|
size,
|
|
445
483
|
density,
|
|
446
|
-
itemSize:
|
|
484
|
+
itemSize: rowSize,
|
|
485
|
+
lead,
|
|
447
486
|
endReserve,
|
|
448
487
|
className: item.class
|
|
449
488
|
})}
|
|
@@ -473,7 +512,12 @@
|
|
|
473
512
|
data-sidebar="menu-suffix"
|
|
474
513
|
inert={isIconCollapsed ? true : undefined}
|
|
475
514
|
aria-hidden={isIconCollapsed ? 'true' : undefined}
|
|
476
|
-
class={classes.suffix({
|
|
515
|
+
class={classes.suffix({
|
|
516
|
+
size,
|
|
517
|
+
density,
|
|
518
|
+
action: item.action ? 'action' : 'none',
|
|
519
|
+
line: twoLine ? 'two' : 'one'
|
|
520
|
+
})}
|
|
477
521
|
{@attach suffixWidth.measure}
|
|
478
522
|
>
|
|
479
523
|
{@render item.suffix(api, item)}
|