@heyramzi/ui 3.1.0 → 3.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/lib/sliding-pill.js +2 -2
- package/dist/record/measure-clamp.js +23 -0
- package/dist/shadcn/button-group/index.js +6 -0
- package/dist/shadcn/checkbox/checkbox-box.js +3 -0
- package/dist/shadcn/input-group/index.js +9 -0
- package/dist/shadcn/item/index.js +13 -0
- package/dist/shadcn/native-select/index.js +6 -0
- package/dist/shadcn/pagination/index.js +12 -0
- package/package.json +1 -1
- package/scripts/sync-shadcn.mjs +0 -5
- package/src/ai/generation-progress/GenerationProgress.svelte +14 -12
- package/src/canvas/pen/PenOverlay.svelte +1 -30
- package/src/canvas/screen/PartView.svelte +13 -8
- package/src/canvas/screen/ScreenBody.svelte +18 -11
- package/src/canvas/ui/BarTooltip.svelte +46 -0
- package/src/canvas/ui/BarTooltip.svelte.d.ts +17 -0
- package/src/canvas/ui/CanvasToolbar.svelte +170 -156
- package/src/canvas/ui/StylePanel.svelte +179 -102
- package/src/canvas/ui/canvas-ui.css +12 -76
- package/src/charts/dashboard/data-table.svelte +80 -80
- package/src/charts/dashboard/hint.svelte +34 -0
- package/src/charts/dashboard/hint.svelte.d.ts +10 -0
- package/src/charts/dashboard/rating-chip.svelte +4 -3
- package/src/charts/legend.css +0 -8
- package/src/charts/legend.svelte +26 -30
- package/src/components/copy/copy-button.svelte +10 -2
- package/src/components/copy/copy-button.test.ts +7 -0
- package/src/components/data-table/table-skeleton.svelte +15 -7
- package/src/components/data-table/table-skeleton.svelte.d.ts +4 -0
- package/src/components/docs/on-this-page.svelte +2 -2
- package/src/components/hold-to-confirm/hold-to-confirm.svelte +2 -1
- package/src/components/list-page/filter-item.svelte +20 -7
- package/src/components/list-page/filter-popover.svelte +41 -16
- package/src/components/list-page/filter-popover.svelte.d.ts +1 -1
- package/src/components/list-page/grouped-list.svelte +41 -23
- package/src/components/picker/picker.svelte +8 -3
- package/src/components/picker/picker.svelte.d.ts +2 -1
- package/src/components/segmented/segmented-filter.svelte +19 -10
- package/src/components/segmented/segmented-track.svelte +11 -3
- package/src/components/table-view/table-view.svelte +22 -6
- package/src/components/tags-input/tags-input.svelte +94 -77
- package/src/components/toolbar/toolbar.svelte +2 -1
- package/src/components/toolbar/toolbar.test.ts +5 -4
- package/src/components/work-parts/group-head.svelte +28 -9
- package/src/components/work-parts/group-head.svelte.d.ts +5 -2
- package/src/editor/editor-toolbar.svelte +223 -193
- package/src/editor/editor.svelte +56 -38
- package/src/editor/image-toolbar.svelte +99 -37
- package/src/editor/image-toolbar.svelte.d.ts +4 -5
- package/src/editor/url-dialog.svelte +96 -0
- package/src/editor/url-dialog.svelte.d.ts +15 -0
- package/src/effects/theme-toggle/ThemeToggle.css +8 -8
- package/src/effects/theme-toggle/ThemeToggle.svelte +20 -6
- package/src/inbox/thread-inbox.svelte +9 -1
- package/src/lib/live-region.svelte +12 -4
- package/src/lib/live-region.svelte.d.ts +5 -1
- package/src/lib/sliding-pill.ts +3 -2
- package/src/record/info-list.svelte +33 -59
- package/src/record/measure-clamp.ts +31 -0
- package/src/record/record-shell.svelte +38 -39
- package/src/record/record-timeline.svelte +10 -5
- package/src/record/steps-rail.svelte +50 -36
- package/src/record/where-we-are.svelte +5 -19
- package/src/shadcn/button-group/button-group-separator.svelte +23 -0
- package/src/shadcn/button-group/button-group-separator.svelte.d.ts +13 -0
- package/src/shadcn/button-group/button-group-text.svelte +28 -0
- package/src/shadcn/button-group/button-group-text.svelte.d.ts +11 -0
- package/src/shadcn/button-group/button-group.svelte +46 -0
- package/src/shadcn/button-group/button-group.svelte.d.ts +16 -0
- package/src/shadcn/button-group/index.ts +15 -0
- package/src/shadcn/checkbox/checkbox-box.ts +4 -0
- package/src/shadcn/checkbox/checkbox.svelte +2 -4
- package/src/shadcn/input-group/index.ts +22 -0
- package/src/shadcn/input-group/input-group-addon.svelte +51 -0
- package/src/shadcn/input-group/input-group-addon.svelte.d.ts +18 -0
- package/src/shadcn/input-group/input-group-button.svelte +49 -0
- package/src/shadcn/input-group/input-group-button.svelte.d.ts +18 -0
- package/src/shadcn/input-group/input-group-input.svelte +20 -0
- package/src/shadcn/input-group/input-group-input.svelte.d.ts +11 -0
- package/src/shadcn/input-group/input-group-text.svelte +19 -0
- package/src/shadcn/input-group/input-group-text.svelte.d.ts +5 -0
- package/src/shadcn/input-group/input-group-textarea.svelte +20 -0
- package/src/shadcn/input-group/input-group-textarea.svelte.d.ts +3 -0
- package/src/shadcn/input-group/input-group.svelte +24 -0
- package/src/shadcn/input-group/input-group.svelte.d.ts +5 -0
- package/src/shadcn/item/index.ts +34 -0
- package/src/shadcn/item/item-actions.svelte +20 -0
- package/src/shadcn/item/item-actions.svelte.d.ts +5 -0
- package/src/shadcn/item/item-content.svelte +23 -0
- package/src/shadcn/item/item-content.svelte.d.ts +5 -0
- package/src/shadcn/item/item-description.svelte +23 -0
- package/src/shadcn/item/item-description.svelte.d.ts +5 -0
- package/src/shadcn/item/item-footer.svelte +20 -0
- package/src/shadcn/item/item-footer.svelte.d.ts +5 -0
- package/src/shadcn/item/item-group.svelte +21 -0
- package/src/shadcn/item/item-group.svelte.d.ts +5 -0
- package/src/shadcn/item/item-header.svelte +20 -0
- package/src/shadcn/item/item-header.svelte.d.ts +5 -0
- package/src/shadcn/item/item-media.svelte +42 -0
- package/src/shadcn/item/item-media.svelte.d.ts +17 -0
- package/src/shadcn/item/item-separator.svelte +19 -0
- package/src/shadcn/item/item-separator.svelte.d.ts +13 -0
- package/src/shadcn/item/item-title.svelte +20 -0
- package/src/shadcn/item/item-title.svelte.d.ts +5 -0
- package/src/shadcn/item/item.svelte +61 -0
- package/src/shadcn/item/item.svelte.d.ts +28 -0
- package/src/shadcn/native-select/index.ts +13 -0
- package/src/shadcn/native-select/native-select-opt-group.svelte +20 -0
- package/src/shadcn/native-select/native-select-opt-group.svelte.d.ts +5 -0
- package/src/shadcn/native-select/native-select-option.svelte +20 -0
- package/src/shadcn/native-select/native-select-option.svelte.d.ts +5 -0
- package/src/shadcn/native-select/native-select.svelte +45 -0
- package/src/shadcn/native-select/native-select.svelte.d.ts +8 -0
- package/src/shadcn/pagination/index.ts +31 -0
- package/src/shadcn/pagination/pagination-content.svelte +20 -0
- package/src/shadcn/pagination/pagination-content.svelte.d.ts +5 -0
- package/src/shadcn/pagination/pagination-ellipsis.svelte +22 -0
- package/src/shadcn/pagination/pagination-ellipsis.svelte.d.ts +5 -0
- package/src/shadcn/pagination/pagination-item.svelte +14 -0
- package/src/shadcn/pagination/pagination-item.svelte.d.ts +5 -0
- package/src/shadcn/pagination/pagination-link.svelte +41 -0
- package/src/shadcn/pagination/pagination-link.svelte.d.ts +9 -0
- package/src/shadcn/pagination/pagination-next-button.svelte +34 -0
- package/src/shadcn/pagination/pagination-next-button.svelte.d.ts +4 -0
- package/src/shadcn/pagination/pagination-next.svelte +26 -0
- package/src/shadcn/pagination/pagination-next.svelte.d.ts +4 -0
- package/src/shadcn/pagination/pagination-prev-button.svelte +34 -0
- package/src/shadcn/pagination/pagination-prev-button.svelte.d.ts +4 -0
- package/src/shadcn/pagination/pagination-previous.svelte +30 -0
- package/src/shadcn/pagination/pagination-previous.svelte.d.ts +4 -0
- package/src/shadcn/pagination/pagination.svelte +27 -0
- package/src/shadcn/pagination/pagination.svelte.d.ts +4 -0
- package/src/slides/Controls.svelte +39 -36
- package/src/slides/Deck.svelte +11 -8
- package/src/thread/thread.svelte +15 -8
- package/src/work/detail/task-detail.svelte +1 -1
- package/src/work/gantt/gantt-task-row.svelte +3 -6
- package/src/work/inbox/inbox-card.svelte +7 -5
- package/src/work/inbox/inbox-trace.svelte +14 -10
- package/src/work/kanban-board.svelte +40 -25
- package/src/work/kanban-hidden-rail.svelte +67 -65
- package/src/work/task-list.svelte +145 -124
- package/src/work/task-list.svelte.test.ts +5 -2
- package/src/work/time/time-tracker.svelte +35 -10
|
@@ -17,11 +17,14 @@
|
|
|
17
17
|
// IMPORTS
|
|
18
18
|
// =========================
|
|
19
19
|
import { Panel } from "@xyflow/svelte";
|
|
20
|
+
import { mergeProps, Toolbar } from "bits-ui";
|
|
20
21
|
import type { Snippet } from "svelte";
|
|
21
22
|
import "../pen/pen.css";
|
|
22
23
|
import { PEN_COLORS } from "../pen/types.js";
|
|
23
24
|
import "./canvas-ui.css";
|
|
24
25
|
import ToolIcon from "../components/icons/ToolIcon.svelte";
|
|
26
|
+
import BarTooltip from "./BarTooltip.svelte";
|
|
27
|
+
import * as Tooltip from "../../shadcn/tooltip/index.js";
|
|
25
28
|
import {
|
|
26
29
|
hasBrush,
|
|
27
30
|
hasColor,
|
|
@@ -63,6 +66,9 @@
|
|
|
63
66
|
// =========================
|
|
64
67
|
let lastShape = $state<"rectangle" | "ellipse" | "diamond">("rectangle");
|
|
65
68
|
let lastBrush = $state<BrushTool>("pen");
|
|
69
|
+
let styleBar = $state<HTMLElement | null>(null);
|
|
70
|
+
/** The value of the style bar item that had focus when its layout changed, or null when focus was elsewhere. */
|
|
71
|
+
let refocus: string | null = null;
|
|
66
72
|
|
|
67
73
|
// =========================
|
|
68
74
|
// DERIVED
|
|
@@ -70,10 +76,17 @@
|
|
|
70
76
|
const BRUSHES = ["pen", "highlighter", "eraser"] as const;
|
|
71
77
|
const SHAPES = ["rectangle", "ellipse", "diamond"] as const;
|
|
72
78
|
const BRUSH_DOT = [4, 7, 11] as const;
|
|
79
|
+
const SINGLE_TOOLS = ["select", "hand", "connect"] as const;
|
|
73
80
|
|
|
74
81
|
let shapeActive = $derived(isShapeTool(tool));
|
|
75
82
|
let brushActive = $derived(isBrushTool(tool));
|
|
76
83
|
let showStyle = $derived(brushActive || shapeActive || hasColor(tool));
|
|
84
|
+
/** The brush and shape buttons stand for a family of tools, so the rail's pick is the family. */
|
|
85
|
+
let railValue = $derived(brushActive ? "brush" : shapeActive ? "shapes" : tool);
|
|
86
|
+
// Roving focus remembers its tab stop by element, so a bar whose items change is rebuilt fresh.
|
|
87
|
+
let styleLayout = $derived(
|
|
88
|
+
`${brushActive ? "brush" : shapeActive ? "shape" : "none"}-${hasColor(tool)}-${hasBrush(tool)}`,
|
|
89
|
+
);
|
|
77
90
|
|
|
78
91
|
// =========================
|
|
79
92
|
// EFFECTS
|
|
@@ -83,175 +96,176 @@
|
|
|
83
96
|
if (isBrushTool(tool)) lastBrush = tool;
|
|
84
97
|
});
|
|
85
98
|
|
|
99
|
+
$effect.pre(() => {
|
|
100
|
+
void styleLayout;
|
|
101
|
+
const active = document.activeElement;
|
|
102
|
+
refocus =
|
|
103
|
+
active instanceof HTMLElement && styleBar?.contains(active)
|
|
104
|
+
? (active.dataset.value ?? "")
|
|
105
|
+
: null;
|
|
106
|
+
});
|
|
107
|
+
|
|
108
|
+
$effect(() => {
|
|
109
|
+
void styleLayout;
|
|
110
|
+
if (refocus === null || !styleBar) return;
|
|
111
|
+
const items = [...styleBar.querySelectorAll<HTMLElement>("[data-toolbar-item]")];
|
|
112
|
+
(items.find((item) => item.dataset.value === refocus) ?? items[0])?.focus();
|
|
113
|
+
refocus = null;
|
|
114
|
+
});
|
|
115
|
+
|
|
86
116
|
// =========================
|
|
87
117
|
// FUNCTIONS
|
|
88
118
|
// =========================
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
119
|
+
// A single-select group sends "" when its pressed item is pressed again. A tool stays picked.
|
|
120
|
+
function pickRail(value: string) {
|
|
121
|
+
if (value === "brush") tool = lastBrush;
|
|
122
|
+
else if (value === "shapes") tool = lastShape;
|
|
123
|
+
else if (value) tool = value as CanvasTool;
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
// Svelte Flow blurs a node a frame after Esc deselects it, which stops the tool letters.
|
|
127
|
+
// A later frame refocuses it. On the window, so it runs after the node's delegated handler.
|
|
128
|
+
function keepNodeFocus(panel: HTMLElement) {
|
|
129
|
+
const flow = panel.closest<HTMLElement>(".svelte-flow");
|
|
130
|
+
if (!flow) return;
|
|
131
|
+
const onkeydown = (event: KeyboardEvent) => {
|
|
132
|
+
const node = event.target;
|
|
133
|
+
if (event.key !== "Escape" || !(node instanceof HTMLElement)) return;
|
|
134
|
+
if (!node.matches(".svelte-flow__node") || !flow.contains(node)) return;
|
|
135
|
+
requestAnimationFrame(() => node.isConnected && node.focus());
|
|
136
|
+
};
|
|
137
|
+
window.addEventListener("keydown", onkeydown);
|
|
138
|
+
return () => window.removeEventListener("keydown", onkeydown);
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
function pickTool(value: string) {
|
|
142
|
+
if (value) tool = value as CanvasTool;
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
function pickColor(value: string) {
|
|
146
|
+
if (value) color = value as PenColor;
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
function pickLevel(value: string) {
|
|
150
|
+
if (value) level = Number(value) as BrushLevel;
|
|
92
151
|
}
|
|
93
152
|
</script>
|
|
94
153
|
|
|
95
154
|
<!-- =========================== -->
|
|
96
155
|
<!-- MARKUP -->
|
|
97
156
|
<!-- =========================== -->
|
|
98
|
-
<Panel position="center-left" class="cv-dock">
|
|
99
|
-
<
|
|
100
|
-
<div
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
<button
|
|
107
|
-
type="button"
|
|
108
|
-
class="cv-btn"
|
|
109
|
-
aria-pressed={tool === "select"}
|
|
110
|
-
aria-label={labels.tools.select}
|
|
111
|
-
data-tip={tip("select")}
|
|
112
|
-
onclick={() => (tool = "select")}
|
|
113
|
-
>
|
|
114
|
-
<ToolIcon name="select" />
|
|
115
|
-
</button>
|
|
116
|
-
<button
|
|
117
|
-
type="button"
|
|
118
|
-
class="cv-btn"
|
|
119
|
-
aria-pressed={tool === "hand"}
|
|
120
|
-
aria-label={labels.tools.hand}
|
|
121
|
-
data-tip={tip("hand")}
|
|
122
|
-
onclick={() => (tool = "hand")}
|
|
123
|
-
>
|
|
124
|
-
<ToolIcon name="hand" />
|
|
125
|
-
</button>
|
|
126
|
-
<button
|
|
127
|
-
type="button"
|
|
128
|
-
class="cv-btn"
|
|
129
|
-
aria-pressed={tool === "connect"}
|
|
130
|
-
aria-label={labels.tools.connect}
|
|
131
|
-
data-tip={tip("connect")}
|
|
132
|
-
onclick={() => (tool = "connect")}
|
|
133
|
-
>
|
|
134
|
-
<ToolIcon name="connect" />
|
|
135
|
-
</button>
|
|
136
|
-
<button
|
|
137
|
-
type="button"
|
|
138
|
-
class="cv-btn"
|
|
139
|
-
aria-pressed={brushActive}
|
|
140
|
-
aria-label={labels.tools[lastBrush]}
|
|
141
|
-
data-tip={tip(lastBrush)}
|
|
142
|
-
onclick={() => (tool = lastBrush)}
|
|
143
|
-
>
|
|
144
|
-
<ToolIcon name={brushActive ? (tool as BrushTool) : lastBrush} />
|
|
145
|
-
</button>
|
|
146
|
-
<button
|
|
147
|
-
type="button"
|
|
148
|
-
class="cv-btn"
|
|
149
|
-
aria-pressed={tool === "text"}
|
|
150
|
-
aria-label={labels.tools.text}
|
|
151
|
-
data-tip={tip("text")}
|
|
152
|
-
onclick={() => (tool = "text")}
|
|
153
|
-
>
|
|
154
|
-
<ToolIcon name="text" />
|
|
155
|
-
</button>
|
|
156
|
-
<button
|
|
157
|
-
type="button"
|
|
158
|
-
class="cv-btn"
|
|
159
|
-
aria-pressed={shapeActive}
|
|
160
|
-
aria-label={labels.tools.shapes}
|
|
161
|
-
data-tip={tip("rectangle", labels.tools.shapes)}
|
|
162
|
-
onclick={() => (tool = lastShape)}
|
|
157
|
+
<Panel position="center-left" class="cv-dock" {@attach keepNodeFocus}>
|
|
158
|
+
<Tooltip.Provider>
|
|
159
|
+
<div class="cv-row">
|
|
160
|
+
<Toolbar.Root
|
|
161
|
+
class="cv-bar cv-rail"
|
|
162
|
+
orientation="vertical"
|
|
163
|
+
aria-orientation="vertical"
|
|
164
|
+
aria-label={labels.toolbar}
|
|
163
165
|
>
|
|
164
|
-
<
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
type="button"
|
|
168
|
-
class="cv-btn"
|
|
169
|
-
aria-pressed={tool === "frame"}
|
|
170
|
-
aria-label={labels.tools.frame}
|
|
171
|
-
data-tip={tip("frame")}
|
|
172
|
-
onclick={() => (tool = "frame")}
|
|
173
|
-
>
|
|
174
|
-
<ToolIcon name="frame" />
|
|
175
|
-
</button>
|
|
176
|
-
{#if onNote}
|
|
177
|
-
<button
|
|
178
|
-
type="button"
|
|
179
|
-
class="cv-btn"
|
|
180
|
-
aria-label={labels.tools.note}
|
|
181
|
-
data-tip="{labels.tools.note} N"
|
|
182
|
-
onclick={onNote}
|
|
183
|
-
>
|
|
184
|
-
<ToolIcon name="note" />
|
|
185
|
-
</button>
|
|
186
|
-
{/if}
|
|
187
|
-
|
|
188
|
-
{#if extra}
|
|
189
|
-
<span class="cv-gap" aria-hidden="true"></span>
|
|
190
|
-
{@render extra()}
|
|
191
|
-
{/if}
|
|
192
|
-
</div>
|
|
193
|
-
|
|
194
|
-
{#if showStyle}
|
|
195
|
-
<div class="cv-bar t-enter" role="toolbar" aria-label={labels.style}>
|
|
196
|
-
{#if brushActive}
|
|
197
|
-
{#each BRUSHES as brush (brush)}
|
|
198
|
-
<button
|
|
199
|
-
type="button"
|
|
200
|
-
class="cv-btn"
|
|
201
|
-
aria-pressed={tool === brush}
|
|
202
|
-
aria-label={labels.tools[brush]}
|
|
203
|
-
data-tip={tip(brush)}
|
|
204
|
-
onclick={() => (tool = brush)}
|
|
205
|
-
>
|
|
206
|
-
<ToolIcon name={brush} />
|
|
207
|
-
</button>
|
|
208
|
-
{/each}
|
|
209
|
-
{:else if shapeActive}
|
|
210
|
-
{#each SHAPES as shape (shape)}
|
|
211
|
-
<button
|
|
212
|
-
type="button"
|
|
213
|
-
class="cv-btn"
|
|
214
|
-
aria-pressed={tool === shape}
|
|
215
|
-
aria-label={labels.tools[shape]}
|
|
216
|
-
data-tip={tip(shape)}
|
|
217
|
-
onclick={() => (tool = shape)}
|
|
218
|
-
>
|
|
219
|
-
<ToolIcon name={shape} />
|
|
220
|
-
</button>
|
|
166
|
+
<Toolbar.Group type="single" class="cv-group" bind:value={() => railValue, pickRail}>
|
|
167
|
+
{#each SINGLE_TOOLS as id (id)}
|
|
168
|
+
{@render railItem(id, labels.tools[id], keyForTool(id), id)}
|
|
221
169
|
{/each}
|
|
170
|
+
{@render railItem(
|
|
171
|
+
"brush",
|
|
172
|
+
labels.tools[lastBrush],
|
|
173
|
+
keyForTool(lastBrush),
|
|
174
|
+
brushActive ? (tool as BrushTool) : lastBrush,
|
|
175
|
+
)}
|
|
176
|
+
{@render railItem("text", labels.tools.text, keyForTool("text"), "text")}
|
|
177
|
+
{@render railItem(
|
|
178
|
+
"shapes",
|
|
179
|
+
labels.tools.shapes,
|
|
180
|
+
keyForTool("rectangle"),
|
|
181
|
+
shapeActive ? (tool as typeof lastShape) : lastShape,
|
|
182
|
+
)}
|
|
183
|
+
{@render railItem("frame", labels.tools.frame, keyForTool("frame"), "frame")}
|
|
184
|
+
</Toolbar.Group>
|
|
185
|
+
{#if onNote}
|
|
186
|
+
<BarTooltip label={labels.tools.note} shortcut="N" side="right">
|
|
187
|
+
{#snippet child({ props })}
|
|
188
|
+
<Toolbar.Button {...mergeProps(props, { onclick: onNote })} class="cv-btn">
|
|
189
|
+
<ToolIcon name="note" />
|
|
190
|
+
</Toolbar.Button>
|
|
191
|
+
{/snippet}
|
|
192
|
+
</BarTooltip>
|
|
222
193
|
{/if}
|
|
223
194
|
|
|
224
|
-
{#if
|
|
225
|
-
{#if brushActive || shapeActive}<span class="cv-gap" aria-hidden="true"></span>{/if}
|
|
226
|
-
{#each PEN_COLORS as swatch (swatch)}
|
|
227
|
-
<button
|
|
228
|
-
type="button"
|
|
229
|
-
class="cv-swatch"
|
|
230
|
-
aria-pressed={color === swatch}
|
|
231
|
-
aria-label={labels.colors[swatch]}
|
|
232
|
-
data-tip={labels.colors[swatch]}
|
|
233
|
-
style:--swatch="var(--pen-{swatch})"
|
|
234
|
-
onclick={() => (color = swatch)}
|
|
235
|
-
></button>
|
|
236
|
-
{/each}
|
|
237
|
-
{/if}
|
|
238
|
-
|
|
239
|
-
{#if hasBrush(tool)}
|
|
195
|
+
{#if extra}
|
|
240
196
|
<span class="cv-gap" aria-hidden="true"></span>
|
|
241
|
-
{
|
|
242
|
-
<button
|
|
243
|
-
type="button"
|
|
244
|
-
class="cv-btn"
|
|
245
|
-
aria-pressed={level === index}
|
|
246
|
-
aria-label={labels.sizes[index]}
|
|
247
|
-
data-tip={labels.sizes[index]}
|
|
248
|
-
onclick={() => (level = index as BrushLevel)}
|
|
249
|
-
>
|
|
250
|
-
<span class="cv-dot" style:--dot="{dot}px"></span>
|
|
251
|
-
</button>
|
|
252
|
-
{/each}
|
|
197
|
+
{@render extra()}
|
|
253
198
|
{/if}
|
|
254
|
-
</
|
|
255
|
-
|
|
256
|
-
|
|
199
|
+
</Toolbar.Root>
|
|
200
|
+
|
|
201
|
+
{#if showStyle}
|
|
202
|
+
<div class="cv-bar t-enter" bind:this={styleBar}>
|
|
203
|
+
{#key styleLayout}
|
|
204
|
+
<Toolbar.Root class="cv-group" aria-label={labels.style}>
|
|
205
|
+
{#if brushActive || shapeActive}
|
|
206
|
+
<Toolbar.Group type="single" class="cv-group" bind:value={() => tool, pickTool}>
|
|
207
|
+
{#each brushActive ? BRUSHES : SHAPES as kind (kind)}
|
|
208
|
+
<BarTooltip label={labels.tools[kind]} shortcut={keyForTool(kind)}>
|
|
209
|
+
{#snippet child({ props })}
|
|
210
|
+
<Toolbar.GroupItem {...props} value={kind} class="cv-btn">
|
|
211
|
+
<ToolIcon name={kind} />
|
|
212
|
+
</Toolbar.GroupItem>
|
|
213
|
+
{/snippet}
|
|
214
|
+
</BarTooltip>
|
|
215
|
+
{/each}
|
|
216
|
+
</Toolbar.Group>
|
|
217
|
+
{/if}
|
|
218
|
+
|
|
219
|
+
{#if hasColor(tool)}
|
|
220
|
+
{#if brushActive || shapeActive}<span class="cv-gap" aria-hidden="true"></span>{/if}
|
|
221
|
+
<Toolbar.Group type="single" class="cv-group" bind:value={() => color, pickColor}>
|
|
222
|
+
{#each PEN_COLORS as swatch (swatch)}
|
|
223
|
+
<BarTooltip label={labels.colors[swatch]}>
|
|
224
|
+
{#snippet child({ props })}
|
|
225
|
+
<Toolbar.GroupItem
|
|
226
|
+
{...props}
|
|
227
|
+
value={swatch}
|
|
228
|
+
class="cv-swatch"
|
|
229
|
+
style="--swatch: var(--pen-{swatch})"
|
|
230
|
+
/>
|
|
231
|
+
{/snippet}
|
|
232
|
+
</BarTooltip>
|
|
233
|
+
{/each}
|
|
234
|
+
</Toolbar.Group>
|
|
235
|
+
{/if}
|
|
236
|
+
|
|
237
|
+
{#if hasBrush(tool)}
|
|
238
|
+
<span class="cv-gap" aria-hidden="true"></span>
|
|
239
|
+
<Toolbar.Group
|
|
240
|
+
type="single"
|
|
241
|
+
class="cv-group"
|
|
242
|
+
bind:value={() => String(level), pickLevel}
|
|
243
|
+
>
|
|
244
|
+
{#each BRUSH_DOT as dot, index (index)}
|
|
245
|
+
<BarTooltip label={labels.sizes[index]}>
|
|
246
|
+
{#snippet child({ props })}
|
|
247
|
+
<Toolbar.GroupItem {...props} value={String(index)} class="cv-btn">
|
|
248
|
+
<span class="cv-dot" style:--dot="{dot}px"></span>
|
|
249
|
+
</Toolbar.GroupItem>
|
|
250
|
+
{/snippet}
|
|
251
|
+
</BarTooltip>
|
|
252
|
+
{/each}
|
|
253
|
+
</Toolbar.Group>
|
|
254
|
+
{/if}
|
|
255
|
+
</Toolbar.Root>
|
|
256
|
+
{/key}
|
|
257
|
+
</div>
|
|
258
|
+
{/if}
|
|
259
|
+
</div>
|
|
260
|
+
</Tooltip.Provider>
|
|
257
261
|
</Panel>
|
|
262
|
+
|
|
263
|
+
{#snippet railItem(value: string, label: string, shortcut: string, icon: CanvasTool)}
|
|
264
|
+
<BarTooltip {label} {shortcut} side="right">
|
|
265
|
+
{#snippet child({ props })}
|
|
266
|
+
<Toolbar.GroupItem {...props} {value} class="cv-btn">
|
|
267
|
+
<ToolIcon name={icon} />
|
|
268
|
+
</Toolbar.GroupItem>
|
|
269
|
+
{/snippet}
|
|
270
|
+
</BarTooltip>
|
|
271
|
+
{/snippet}
|