@heyramzi/ui 2.1.0 → 2.3.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.
Files changed (317) hide show
  1. package/COMPONENTS.md +1 -1
  2. package/package.json +7 -8
  3. package/scripts/sync-shadcn.mjs +3 -4
  4. package/src/agents/agent-avatar.svelte +604 -575
  5. package/src/agents/agent-cast.svelte +179 -183
  6. package/src/agents/demo.svelte +125 -113
  7. package/src/agents/helpers.ts +23 -17
  8. package/src/agents/index.ts +4 -4
  9. package/src/agents/page-state.ts +6 -6
  10. package/src/agents/types.ts +6 -6
  11. package/src/ai/ai-button/AiButton.svelte +4 -12
  12. package/src/ai/generation-progress/GenerationProgress.svelte +10 -3
  13. package/src/ai/prompt-input/PromptInputTextarea.svelte +1 -2
  14. package/src/ai/response/Response.css +2 -3
  15. package/src/animations/avatar-group-hover.css +2 -16
  16. package/src/animations/card-tilt.css +3 -6
  17. package/src/animations/digit-pop-in.css +2 -15
  18. package/src/animations/dropdown.css +4 -17
  19. package/src/animations/input-clear-dissolve.css +5 -18
  20. package/src/animations/input-shake.css +9 -41
  21. package/src/animations/learn-more-hover.css +17 -9
  22. package/src/animations/like-button.css +2 -4
  23. package/src/animations/page-side-by-side.css +2 -10
  24. package/src/animations/plus-menu-morph.css +2 -5
  25. package/src/animations/shimmer-text.css +5 -18
  26. package/src/animations/spinning-counter.css +2 -6
  27. package/src/animations/success-check.css +2 -15
  28. package/src/animations/thinking-states.css +2 -7
  29. package/src/brand/brand.test.ts +21 -5
  30. package/src/brand/index.ts +4 -10
  31. package/src/canvas/card/card-frame.svelte +43 -39
  32. package/src/canvas/card/resize-handles.svelte +89 -80
  33. package/src/canvas/chrome/chrome-zoom.svelte +101 -100
  34. package/src/canvas/chrome/lock-badge.svelte +8 -8
  35. package/src/canvas/chrome/side-handles.svelte +24 -19
  36. package/src/canvas/chrome/size-chip.svelte +30 -30
  37. package/src/canvas/chrome/snap-guides.svelte +20 -20
  38. package/src/canvas/components/icons/ToolIcon.svelte +8 -8
  39. package/src/canvas/components/shared/svg/PreviewSvg.svelte +19 -19
  40. package/src/canvas/components/shared/svg/ShapeOutline.svelte +71 -48
  41. package/src/canvas/components/shared/svg/StrokeNode.svelte +21 -27
  42. package/src/canvas/components/shared/svg/TextRule.svelte +25 -17
  43. package/src/canvas/edges/bend-handle.svelte +46 -46
  44. package/src/canvas/edges/edge-gradient.svelte +10 -10
  45. package/src/canvas/edges/gradient-edge.svelte +45 -29
  46. package/src/canvas/editor/lock.test.ts +6 -1
  47. package/src/canvas/editor/style.ts +7 -1
  48. package/src/canvas/headless/canvas-cleanup.test.ts +1 -1
  49. package/src/canvas/headless/svg-figure.test.ts +5 -1
  50. package/src/canvas/lod/lod-switch.svelte +111 -106
  51. package/src/canvas/ops/ops.ts +1 -1
  52. package/src/canvas/pen/PenField.svelte +87 -81
  53. package/src/canvas/pen/PenOverlay.svelte +127 -127
  54. package/src/canvas/pen/ShapeNode.svelte +31 -32
  55. package/src/canvas/pen/TextNode.svelte +54 -53
  56. package/src/canvas/pen/host-field.test.svelte +7 -7
  57. package/src/canvas/pen/shapes.ts +7 -1
  58. package/src/canvas/screen/GlyphIcon.svelte +22 -17
  59. package/src/canvas/screen/PartView.svelte +138 -72
  60. package/src/canvas/screen/ScreenBody.svelte +81 -60
  61. package/src/canvas/screen/ScreenCard.svelte +20 -20
  62. package/src/canvas/ui/CanvasToolbar.svelte +173 -85
  63. package/src/canvas/ui/FrameLayer.svelte +59 -59
  64. package/src/canvas/ui/PenLayer.svelte +39 -30
  65. package/src/canvas/ui/StylePanel.svelte +119 -102
  66. package/src/canvas/ui/canvas-grid.svelte +137 -129
  67. package/src/charts/animated-value.svelte +1 -1
  68. package/src/charts/area-chart.css +2 -5
  69. package/src/charts/area-chart.svelte +1 -1
  70. package/src/charts/bar-chart.css +2 -3
  71. package/src/charts/bar-chart.svelte +1 -1
  72. package/src/charts/charts.css +5 -17
  73. package/src/charts/crosshair.svelte +1 -1
  74. package/src/charts/dashboard/dashboard-empty.svelte +25 -25
  75. package/src/charts/dashboard/dashboard-section.svelte +24 -24
  76. package/src/charts/dashboard/data-panel.svelte +50 -50
  77. package/src/charts/dashboard/data-sort-head.svelte +56 -56
  78. package/src/charts/dashboard/data-table.svelte +138 -138
  79. package/src/charts/dashboard/panel-grid.svelte +30 -30
  80. package/src/charts/dashboard/period-filter.svelte +25 -25
  81. package/src/charts/dashboard/rating-chip.svelte +19 -19
  82. package/src/charts/dashboard/stat-band.svelte +32 -32
  83. package/src/charts/dashboard/stat-tile.svelte +106 -99
  84. package/src/charts/donut-chart.svelte +1 -1
  85. package/src/charts/edge-fade.svelte +1 -1
  86. package/src/charts/figure.svelte +1 -1
  87. package/src/charts/gauge-chart.css +4 -7
  88. package/src/charts/gauge-chart.svelte +1 -1
  89. package/src/charts/hover-focus.svelte +1 -1
  90. package/src/charts/legend.css +1 -3
  91. package/src/charts/legend.svelte +1 -1
  92. package/src/charts/line-chart.svelte +1 -1
  93. package/src/charts/number-chart.css +6 -9
  94. package/src/charts/number-chart.svelte +1 -1
  95. package/src/charts/reference-line.svelte +19 -19
  96. package/src/charts/reveal.svelte +1 -1
  97. package/src/charts/ring-chart.css +2 -4
  98. package/src/charts/ring-chart.svelte +1 -1
  99. package/src/charts/sparkline.svelte +5 -2
  100. package/src/charts/stat-card.svelte +1 -1
  101. package/src/charts/time-series-chart.css +2 -5
  102. package/src/charts/trend-pill.css +2 -4
  103. package/src/charts/trend-pill.svelte +1 -1
  104. package/src/components/copy/copy-button.svelte +93 -98
  105. package/src/components/copy/copy-button.test.ts +10 -2
  106. package/src/components/data-table/infinite-scroll.svelte +42 -42
  107. package/src/components/data-table/pagination.svelte +34 -22
  108. package/src/components/data-table/row-arrow.svelte +19 -16
  109. package/src/components/data-table/row-context-menu.svelte +52 -52
  110. package/src/components/data-table/sortable-head.svelte +25 -25
  111. package/src/components/data-table/table-skeleton.svelte +41 -36
  112. package/src/components/docs/doc-page.svelte +18 -9
  113. package/src/components/docs/on-this-page.svelte +16 -3
  114. package/src/components/docs/scroll-spy.svelte.ts +2 -3
  115. package/src/components/field-row/field-row.svelte +10 -8
  116. package/src/components/hold-to-confirm/hold-to-confirm.svelte +5 -1
  117. package/src/components/icon/icon.svelte +14 -14
  118. package/src/components/language-flag/language-flag.svelte +3 -1
  119. package/src/components/list-page/detail-empty.svelte +34 -34
  120. package/src/components/list-page/detail-header.svelte +55 -47
  121. package/src/components/list-page/detail-panel.svelte +51 -59
  122. package/src/components/list-page/detail-row.svelte +19 -19
  123. package/src/components/list-page/detail-stack.svelte +21 -21
  124. package/src/components/list-page/empty-state.svelte +30 -30
  125. package/src/components/list-page/filter-item.svelte +20 -20
  126. package/src/components/list-page/filter-popover.svelte +60 -55
  127. package/src/components/list-page/grouped-list.svelte +4 -2
  128. package/src/components/list-page/index.ts +5 -1
  129. package/src/components/list-page/list-page-shell.svelte +2 -5
  130. package/src/components/list-page/master-detail.svelte +87 -88
  131. package/src/components/list-page/notice-bar.svelte +38 -38
  132. package/src/components/list-page/prev-next.svelte +63 -63
  133. package/src/components/list-page/rail-body.svelte +18 -18
  134. package/src/components/list-page/rail-empty.svelte +23 -30
  135. package/src/components/list-page/rail-head.svelte +24 -24
  136. package/src/components/list-page/rail-row.svelte +77 -73
  137. package/src/components/list-page/section-host.ts +2 -3
  138. package/src/components/locale-switch/locale-switch.svelte +41 -41
  139. package/src/components/mark/mark.svelte +34 -38
  140. package/src/components/open-in/index.ts +1 -5
  141. package/src/components/open-in/open-in.svelte +40 -40
  142. package/src/components/picker/mark-picker.svelte +49 -49
  143. package/src/components/picker/picker.svelte +5 -3
  144. package/src/components/section-header/section-header.test.ts +7 -1
  145. package/src/components/section-header/section-label.svelte +20 -20
  146. package/src/components/segmented/animated-tabs.svelte +31 -2
  147. package/src/components/segmented/collapse.test.ts +2 -1
  148. package/src/components/segmented/index.ts +2 -0
  149. package/src/components/segmented/segment.svelte +52 -49
  150. package/src/components/segmented/segmented-filter.svelte +79 -80
  151. package/src/components/segmented/segmented-nav.svelte +34 -40
  152. package/src/components/segmented/segmented-overflow.svelte +53 -50
  153. package/src/components/segmented/segmented-track.svelte +62 -46
  154. package/src/components/segmented/segmented.ts +2 -3
  155. package/src/components/star-rating-input/star-rating-input.svelte +103 -103
  156. package/src/components/svg/svg.svelte +4 -4
  157. package/src/components/table-view/index.ts +1 -1
  158. package/src/components/table-view/table-view.svelte +352 -13
  159. package/src/components/table-view/table-view.test.ts +108 -1
  160. package/src/components/table-view/types.ts +22 -11
  161. package/src/components/tags-input/index.ts +13 -0
  162. package/src/components/tags-input/tags-input.svelte +305 -0
  163. package/src/components/tags-input/tags.test.ts +64 -0
  164. package/src/components/tags-input/tags.ts +142 -0
  165. package/src/components/theme/index.ts +2 -4
  166. package/src/components/theme/theme-provider.svelte +1 -3
  167. package/src/components/toolbar/toolbar-search.svelte +25 -25
  168. package/src/components/toolbar/toolbar.svelte +11 -7
  169. package/src/components/toolbar/toolbar.test.ts +10 -1
  170. package/src/design/index.css +21 -78
  171. package/src/design/polish.css +26 -35
  172. package/src/editor/editor-toolbar.svelte +104 -99
  173. package/src/editor/editor.svelte +296 -266
  174. package/src/editor/image-toolbar.svelte +20 -22
  175. package/src/editor/index.ts +1 -4
  176. package/src/editor/inline-editor.svelte +280 -238
  177. package/src/editor/markdown.ts +15 -15
  178. package/src/editor/renderer.svelte +71 -71
  179. package/src/editor/slash-menu.svelte +24 -27
  180. package/src/effects/animated-beam/diagrams/BeamSvg.svelte +1 -1
  181. package/src/effects/image-comparison/ImageComparison.svelte +11 -1
  182. package/src/effects/interactive-hover-button/InteractiveHoverButton.svelte +59 -46
  183. package/src/effects/magic-card/MagicCard.css +14 -7
  184. package/src/effects/marquee/Marquee.svelte +3 -5
  185. package/src/effects/reveal/observe.ts +0 -3
  186. package/src/effects/spotlight/Spotlight.svelte +1 -1
  187. package/src/effects/theme-toggle/ThemeToggle.css +25 -22
  188. package/src/effects/theme-toggle/ThemeToggle.svelte +6 -7
  189. package/src/gallery.test.ts +14 -4
  190. package/src/icons/trades.ts +1 -1
  191. package/src/inbox/README.md +1 -3
  192. package/src/inbox/inbox.test.ts +181 -138
  193. package/src/inbox/index.ts +20 -20
  194. package/src/inbox/logic.ts +114 -111
  195. package/src/inbox/thread-inbox.svelte +227 -151
  196. package/src/inbox/types.ts +130 -108
  197. package/src/lib/theme-transition.ts +2 -4
  198. package/src/lib/tone.ts +2 -4
  199. package/src/lib/utils.ts +2 -2
  200. package/src/modules.test.ts +79 -69
  201. package/src/onboarding/define-tours.test.ts +55 -40
  202. package/src/onboarding/define-tours.ts +23 -23
  203. package/src/onboarding/demo.svelte +24 -5
  204. package/src/onboarding/index.ts +1 -8
  205. package/src/onboarding/onboarding-provider.svelte +19 -7
  206. package/src/onboarding/onboarding.svelte.ts +16 -16
  207. package/src/onboarding/pick.test.ts +61 -52
  208. package/src/onboarding/pick.ts +16 -13
  209. package/src/onboarding/stores.test.ts +80 -80
  210. package/src/onboarding/stores.ts +41 -39
  211. package/src/onboarding/tour-card.svelte +30 -5
  212. package/src/onboarding/tour-runner.svelte +12 -3
  213. package/src/onboarding/types.ts +20 -12
  214. package/src/onboarding/wait.ts +22 -22
  215. package/src/panel/side-panel.svelte +94 -93
  216. package/src/record/demo-data.ts +291 -225
  217. package/src/record/field-section.svelte +38 -34
  218. package/src/record/fields.ts +148 -96
  219. package/src/record/format.ts +63 -56
  220. package/src/record/index.ts +49 -35
  221. package/src/record/info-list.svelte +145 -114
  222. package/src/record/kinds.ts +31 -31
  223. package/src/record/logic.ts +216 -214
  224. package/src/record/next-up.svelte +45 -34
  225. package/src/record/project-list.svelte +56 -50
  226. package/src/record/record-demo.svelte +130 -110
  227. package/src/record/record-header.svelte +37 -28
  228. package/src/record/record-shell.svelte +54 -54
  229. package/src/record/record-stats.svelte +25 -25
  230. package/src/record/record-timeline.svelte +134 -114
  231. package/src/record/record.test.ts +430 -309
  232. package/src/record/steps-rail.svelte +225 -216
  233. package/src/record/types.ts +234 -215
  234. package/src/record/where-we-are.svelte +62 -58
  235. package/src/shadcn/button/button.svelte +1 -1
  236. package/src/shadcn/card/card-title.svelte +1 -5
  237. package/src/shadcn/hooks/use-highlighted-code.svelte.ts +2 -13
  238. package/src/shadcn/sheet/sheet-content.svelte +2 -4
  239. package/src/shadcn/table/table-cell.svelte +2 -3
  240. package/src/shadcn/utilities.css +3 -8
  241. package/src/slides/Controls.svelte +150 -124
  242. package/src/slides/Deck.svelte +243 -238
  243. package/src/slides/Fragment.svelte +64 -57
  244. package/src/slides/Overview.svelte +106 -101
  245. package/src/slides/Presenter.svelte +300 -266
  246. package/src/slides/Slide.svelte +185 -170
  247. package/src/slides/SlideList.svelte +16 -12
  248. package/src/slides/ambient.d.ts +1 -1
  249. package/src/slides/bridges.ts +42 -23
  250. package/src/slides/deck-controller.svelte.ts +47 -35
  251. package/src/slides/demo-slides.svelte +330 -306
  252. package/src/slides/demo.svelte +164 -160
  253. package/src/slides/export/capture.ts +20 -16
  254. package/src/slides/export/ffmpeg.ts +43 -38
  255. package/src/slides/export/index.ts +5 -5
  256. package/src/slides/export/launch.ts +3 -1
  257. package/src/slides/export/pdf.ts +30 -27
  258. package/src/slides/export/types.ts +10 -8
  259. package/src/slides/index.ts +11 -11
  260. package/src/slides/labels.ts +22 -19
  261. package/src/slides/layout.ts +9 -2
  262. package/src/slides/model.ts +4 -4
  263. package/src/slides/navigation.ts +43 -31
  264. package/src/slides/theme.css +5 -7
  265. package/src/slides/types.ts +9 -10
  266. package/src/status/define-statuses.ts +17 -24
  267. package/src/status/index.ts +5 -5
  268. package/src/status/status-badge.svelte +3 -1
  269. package/src/status/status-dot.svelte +1 -3
  270. package/src/status/status-icon.svelte +1 -1
  271. package/src/status/status-types.ts +21 -21
  272. package/src/tasks/board-order.ts +2 -4
  273. package/src/tasks/demo.svelte +189 -31
  274. package/src/tasks/detail/detail-demo.svelte +73 -13
  275. package/src/tasks/detail/detail-types.ts +45 -45
  276. package/src/tasks/detail/task-detail.svelte +40 -10
  277. package/src/tasks/detail/task-property.svelte +8 -2
  278. package/src/tasks/detail/task-thread.svelte +53 -12
  279. package/src/tasks/gantt/gantt-bar.svelte +17 -6
  280. package/src/tasks/gantt/gantt-grid.svelte +40 -9
  281. package/src/tasks/gantt/gantt-group-row.svelte +8 -2
  282. package/src/tasks/gantt/gantt-header.svelte +9 -3
  283. package/src/tasks/gantt/gantt-task-row.svelte +26 -6
  284. package/src/tasks/gantt/gantt.css +2 -1
  285. package/src/tasks/gantt/gantt.test.ts +3 -1
  286. package/src/tasks/gantt/logic.test.ts +110 -20
  287. package/src/tasks/gantt/logic.ts +42 -6
  288. package/src/tasks/inbox/inbox-card.svelte +13 -5
  289. package/src/tasks/inbox/inbox-draft.svelte +1 -1
  290. package/src/tasks/inbox/inbox-logic.ts +6 -40
  291. package/src/tasks/inbox/inbox-statuses.ts +23 -23
  292. package/src/tasks/inbox/inbox-trace.svelte +9 -3
  293. package/src/tasks/inbox/inbox-types.ts +54 -58
  294. package/src/tasks/inbox/index.ts +22 -21
  295. package/src/tasks/index.ts +49 -52
  296. package/src/tasks/kanban-board.svelte +16 -12
  297. package/src/tasks/kanban-types.ts +2 -3
  298. package/src/tasks/presets/sales.ts +6 -6
  299. package/src/tasks/task-gantt.svelte +28 -8
  300. package/src/tasks/task-list.svelte +41 -17
  301. package/src/tasks/time/duration.ts +40 -40
  302. package/src/tasks/time/time-chip.svelte +9 -2
  303. package/src/tasks/time/time-dot.svelte +1 -1
  304. package/src/tasks/time/time-ring.svelte +11 -3
  305. package/src/tasks/time/time-tracker.svelte +57 -15
  306. package/src/tasks/time/time-types.ts +57 -57
  307. package/src/tasks/use-kanban-dnd.svelte.ts +2 -3
  308. package/src/thread/index.ts +7 -7
  309. package/src/thread/logic.ts +36 -33
  310. package/src/thread/thread.svelte +82 -16
  311. package/src/thread/thread.test.ts +58 -47
  312. package/src/thread/types.ts +68 -68
  313. package/src/tokens/craft.css +17 -53
  314. package/src/tokens/index.css +3 -13
  315. package/src/tokens/palette.css +13 -11
  316. package/src/tokens/primitives.css +10 -23
  317. package/src/tasks/inbox/inbox.svelte +0 -203
@@ -1,24 +1,24 @@
1
1
  <script lang="ts">
2
- // =========================
3
- // IMPORTS
4
- // =========================
5
- import { Handle, Position } from "@xyflow/svelte";
2
+ // =========================
3
+ // IMPORTS
4
+ // =========================
5
+ import { Handle, Position } from "@xyflow/svelte";
6
6
 
7
- // =========================
8
- // CONSTANTS
9
- // =========================
10
- // Each side has an invisible source over the visible target. An edge saved without handle ids takes the first, so top and bottom stay first.
11
- const SIDES = [
12
- { id: "top", position: Position.Top },
13
- { id: "bottom", position: Position.Bottom },
14
- { id: "left", position: Position.Left },
15
- { id: "right", position: Position.Right },
16
- ] as const;
7
+ // =========================
8
+ // CONSTANTS
9
+ // =========================
10
+ // Each side has an invisible source over the visible target. An edge saved without handle ids takes the first, so top and bottom stay first.
11
+ const SIDES = [
12
+ { id: "top", position: Position.Top },
13
+ { id: "bottom", position: Position.Bottom },
14
+ { id: "left", position: Position.Left },
15
+ { id: "right", position: Position.Right },
16
+ ] as const;
17
17
 
18
- // =========================
19
- // PROPS
20
- // =========================
21
- let { class: className = "" }: { class?: string } = $props();
18
+ // =========================
19
+ // PROPS
20
+ // =========================
21
+ let { class: className = "" }: { class?: string } = $props();
22
22
  </script>
23
23
 
24
24
  <!-- =========================== -->
@@ -26,5 +26,10 @@ let { class: className = "" }: { class?: string } = $props();
26
26
  <!-- =========================== -->
27
27
  {#each SIDES as side (side.id)}
28
28
  <Handle type="target" position={side.position} id={side.id} class="cv-handle {className}" />
29
- <Handle type="source" position={side.position} id={side.id} class="cv-handle !opacity-0 {className}" />
29
+ <Handle
30
+ type="source"
31
+ position={side.position}
32
+ id={side.id}
33
+ class="cv-handle !opacity-0 {className}"
34
+ />
30
35
  {/each}
@@ -1,32 +1,32 @@
1
1
  <script lang="ts">
2
- // =========================
3
- // IMPORTS
4
- // =========================
5
- import { onMount } from "svelte";
2
+ // =========================
3
+ // IMPORTS
4
+ // =========================
5
+ import { onMount } from "svelte";
6
6
 
7
- // =========================
8
- // STATE
9
- // =========================
10
- let chip = $state<HTMLElement>();
11
- let width = $state(0);
12
- let height = $state(0);
7
+ // =========================
8
+ // STATE
9
+ // =========================
10
+ let chip = $state<HTMLElement>();
11
+ let width = $state(0);
12
+ let height = $state(0);
13
13
 
14
- // =========================
15
- // LIFECYCLE
16
- // =========================
17
- // Layout size, which a zoom transform doesn't change. Observing the card's own box keeps the figure live through a resize drag.
18
- onMount(() => {
19
- const card = chip?.parentElement;
20
- if (!card) return;
21
- const read = () => {
22
- width = Math.round(card.offsetWidth);
23
- height = Math.round(card.offsetHeight);
24
- };
25
- read();
26
- const observer = new ResizeObserver(read);
27
- observer.observe(card);
28
- return () => observer.disconnect();
29
- });
14
+ // =========================
15
+ // LIFECYCLE
16
+ // =========================
17
+ // Layout size, which a zoom transform doesn't change. Observing the card's own box keeps the figure live through a resize drag.
18
+ onMount(() => {
19
+ const card = chip?.parentElement;
20
+ if (!card) return;
21
+ const read = () => {
22
+ width = Math.round(card.offsetWidth);
23
+ height = Math.round(card.offsetHeight);
24
+ };
25
+ read();
26
+ const observer = new ResizeObserver(read);
27
+ observer.observe(card);
28
+ return () => observer.disconnect();
29
+ });
30
30
  </script>
31
31
 
32
32
  <!-- =========================== -->
@@ -38,8 +38,8 @@ onMount(() => {
38
38
  <!-- STYLES -->
39
39
  <!-- =========================== -->
40
40
  <style>
41
- /* A table draws its add-row strip from 12 to 32 card pixels under it. The chip hangs under that, 10 screen pixels clear. */
42
- :global(.svelte-flow__node-table .cv-size-chip) {
43
- top: calc(100% + 32px + 10px * var(--canvas-unzoom, 1));
44
- }
41
+ /* A table draws its add-row strip from 12 to 32 card pixels under it. The chip hangs under that, 10 screen pixels clear. */
42
+ :global(.svelte-flow__node-table .cv-size-chip) {
43
+ top: calc(100% + 32px + 10px * var(--canvas-unzoom, 1));
44
+ }
45
45
  </style>
@@ -1,27 +1,27 @@
1
1
  <script lang="ts">
2
- // =========================
3
- // IMPORTS
4
- // =========================
5
- import type { SnapGuide } from "../headless/snap-guides.js";
2
+ // =========================
3
+ // IMPORTS
4
+ // =========================
5
+ import type { SnapGuide } from "../headless/snap-guides.js";
6
6
 
7
- // =========================
8
- // TYPES
9
- // =========================
10
- interface Props {
11
- guides: SnapGuide[];
12
- /** Canvas zoom, so the line stays one screen pixel at every scale. */
13
- zoom: number;
14
- }
7
+ // =========================
8
+ // TYPES
9
+ // =========================
10
+ interface Props {
11
+ guides: SnapGuide[];
12
+ /** Canvas zoom, so the line stays one screen pixel at every scale. */
13
+ zoom: number;
14
+ }
15
15
 
16
- // =========================
17
- // PROPS
18
- // =========================
19
- let { guides, zoom }: Props = $props();
16
+ // =========================
17
+ // PROPS
18
+ // =========================
19
+ let { guides, zoom }: Props = $props();
20
20
 
21
- // =========================
22
- // DERIVED
23
- // =========================
24
- let thickness = $derived(1 / Math.max(zoom, 0.05));
21
+ // =========================
22
+ // DERIVED
23
+ // =========================
24
+ let thickness = $derived(1 / Math.max(zoom, 0.05));
25
25
  </script>
26
26
 
27
27
  <!-- =========================== -->
@@ -1,13 +1,13 @@
1
1
  <script lang="ts">
2
- // =========================
3
- // IMPORTS
4
- // =========================
5
- import { ICON_PATHS, type IconName } from "../../ui/icons.js";
2
+ // =========================
3
+ // IMPORTS
4
+ // =========================
5
+ import { ICON_PATHS, type IconName } from "../../ui/icons.js";
6
6
 
7
- // =========================
8
- // PROPS
9
- // =========================
10
- let { name, size = 18 }: { name: IconName; size?: number } = $props();
7
+ // =========================
8
+ // PROPS
9
+ // =========================
10
+ let { name, size = 18 }: { name: IconName; size?: number } = $props();
11
11
  </script>
12
12
 
13
13
  <!-- =========================== -->
@@ -1,25 +1,25 @@
1
1
  <script lang="ts">
2
- // =========================
3
- // IMPORTS
4
- // =========================
5
- import { penColorVar } from "../../../pen/colors.js";
6
- import type { PenPreview } from "../../../pen/pen-session.js";
7
- import { shapeOutline } from "../../../pen/shapes.js";
8
- import { HIGHLIGHTER_OPACITY } from "../../../pen/types.js";
2
+ // =========================
3
+ // IMPORTS
4
+ // =========================
5
+ import { penColorVar } from "../../../pen/colors.js";
6
+ import type { PenPreview } from "../../../pen/pen-session.js";
7
+ import { shapeOutline } from "../../../pen/shapes.js";
8
+ import { HIGHLIGHTER_OPACITY } from "../../../pen/types.js";
9
9
 
10
- // =========================
11
- // TYPES
12
- // =========================
13
- interface Props {
14
- preview: PenPreview | null;
15
- /** The xyflow viewport, so the preview lines up with the board. */
16
- viewport: { x: number; y: number; zoom: number };
17
- }
10
+ // =========================
11
+ // TYPES
12
+ // =========================
13
+ interface Props {
14
+ preview: PenPreview | null;
15
+ /** The xyflow viewport, so the preview lines up with the board. */
16
+ viewport: { x: number; y: number; zoom: number };
17
+ }
18
18
 
19
- // =========================
20
- // PROPS
21
- // =========================
22
- let { preview, viewport }: Props = $props();
19
+ // =========================
20
+ // PROPS
21
+ // =========================
22
+ let { preview, viewport }: Props = $props();
23
23
  </script>
24
24
 
25
25
  <!-- =========================== -->
@@ -1,44 +1,58 @@
1
1
  <script lang="ts">
2
- // =========================
3
- // IMPORTS
4
- // =========================
5
- import { roughEllipse, roughPolygon, roughRect, seedFrom, sketchColors } from "../../../headless/sketch.js";
6
- import { penColorVar } from "../../../pen/colors.js";
7
- import type { ShapeData } from "../../../pen/types.js";
2
+ // =========================
3
+ // IMPORTS
4
+ // =========================
5
+ import {
6
+ roughEllipse,
7
+ roughPolygon,
8
+ roughRect,
9
+ seedFrom,
10
+ sketchColors,
11
+ } from "../../../headless/sketch.js";
12
+ import { penColorVar } from "../../../pen/colors.js";
13
+ import type { ShapeData } from "../../../pen/types.js";
8
14
 
9
- // =========================
10
- // TYPES
11
- // =========================
12
- interface Props {
13
- shape: ShapeData;
14
- outline: string;
15
- ink: string;
16
- width?: number;
17
- height?: number;
18
- /** Draw the outline with the hand instead of the exact path. */
19
- hand?: boolean;
20
- /** Seeds the hand, so a shape keeps its wobble between renders. */
21
- seed?: string;
22
- }
15
+ // =========================
16
+ // TYPES
17
+ // =========================
18
+ interface Props {
19
+ shape: ShapeData;
20
+ outline: string;
21
+ ink: string;
22
+ width?: number;
23
+ height?: number;
24
+ /** Draw the outline with the hand instead of the exact path. */
25
+ hand?: boolean;
26
+ /** Seeds the hand, so a shape keeps its wobble between renders. */
27
+ seed?: string;
28
+ }
23
29
 
24
- // =========================
25
- // PROPS
26
- // =========================
27
- let { shape, outline, ink, width, height, hand = false, seed = "" }: Props = $props();
30
+ // =========================
31
+ // PROPS
32
+ // =========================
33
+ let { shape, outline, ink, width, height, hand = false, seed = "" }: Props = $props();
28
34
 
29
- let wash = $derived(shape.fill ? penColorVar(shape.fill) : ink);
35
+ let wash = $derived(shape.fill ? penColorVar(shape.fill) : ink);
30
36
 
31
- let rough = $derived.by(() => {
32
- const w = width ?? 0;
33
- const h = height ?? 0;
34
- if (!hand || w < 4 || h < 4) return [];
35
- const pen = { seed: seedFrom(seed), colors: { ...sketchColors("ink", false), stroke: ink } };
36
- if (shape.shape === "ellipse") return roughEllipse(w, h, pen);
37
- if (shape.shape === "diamond") {
38
- return roughPolygon([[w / 2, 1], [w - 1, h / 2], [w / 2, h - 1], [1, h / 2]], pen);
39
- }
40
- return roughRect(w, h, pen);
41
- });
37
+ let rough = $derived.by(() => {
38
+ const w = width ?? 0;
39
+ const h = height ?? 0;
40
+ if (!hand || w < 4 || h < 4) return [];
41
+ const pen = { seed: seedFrom(seed), colors: { ...sketchColors("ink", false), stroke: ink } };
42
+ if (shape.shape === "ellipse") return roughEllipse(w, h, pen);
43
+ if (shape.shape === "diamond") {
44
+ return roughPolygon(
45
+ [
46
+ [w / 2, 1],
47
+ [w - 1, h / 2],
48
+ [w / 2, h - 1],
49
+ [1, h / 2],
50
+ ],
51
+ pen,
52
+ );
53
+ }
54
+ return roughRect(w, h, pen);
55
+ });
42
56
  </script>
43
57
 
44
58
  <!-- =========================== -->
@@ -50,20 +64,29 @@ let rough = $derived.by(() => {
50
64
  <path d={outline} fill={wash} fill-opacity="0.12" stroke="none" pointer-events="all" />
51
65
  {/if}
52
66
  {#each rough as path, i (i)}
53
- <path class="pen-line" style:--sw={shape.strokeWidth} d={path.d} fill="none" stroke={ink} stroke-width={shape.strokeWidth} stroke-linecap="round" stroke-linejoin="round" />
67
+ <path
68
+ class="pen-line"
69
+ style:--sw={shape.strokeWidth}
70
+ d={path.d}
71
+ fill="none"
72
+ stroke={ink}
73
+ stroke-width={shape.strokeWidth}
74
+ stroke-linecap="round"
75
+ stroke-linejoin="round"
76
+ />
54
77
  {/each}
55
78
  {:else}
56
- <path
57
- class="pen-line"
58
- style:--sw={shape.strokeWidth}
59
- d={outline}
60
- fill={shape.filled ? wash : "none"}
61
- fill-opacity={shape.filled ? 0.12 : 0}
62
- stroke={ink}
63
- stroke-width={shape.strokeWidth}
64
- stroke-linejoin="round"
65
- pointer-events={shape.filled ? "all" : "stroke"}
66
- />
79
+ <path
80
+ class="pen-line"
81
+ style:--sw={shape.strokeWidth}
82
+ d={outline}
83
+ fill={shape.filled ? wash : "none"}
84
+ fill-opacity={shape.filled ? 0.12 : 0}
85
+ stroke={ink}
86
+ stroke-width={shape.strokeWidth}
87
+ stroke-linejoin="round"
88
+ pointer-events={shape.filled ? "all" : "stroke"}
89
+ />
67
90
  {/if}
68
91
  </svg>
69
92
 
@@ -1,38 +1,32 @@
1
1
  <script lang="ts">
2
- // =========================
3
- // IMPORTS
4
- // =========================
5
- import type { NodeProps } from "@xyflow/svelte";
6
- import "../../../pen/pen.css";
7
- import { penColorVar } from "../../../pen/colors.js";
8
- import { strokePath } from "../../../pen/stroke-path.js";
9
- import { HIGHLIGHTER_OPACITY, type StrokeData } from "../../../pen/types.js";
2
+ // =========================
3
+ // IMPORTS
4
+ // =========================
5
+ import type { NodeProps } from "@xyflow/svelte";
6
+ import "../../../pen/pen.css";
7
+ import { penColorVar } from "../../../pen/colors.js";
8
+ import { strokePath } from "../../../pen/stroke-path.js";
9
+ import { HIGHLIGHTER_OPACITY, type StrokeData } from "../../../pen/types.js";
10
10
 
11
- // =========================
12
- // PROPS
13
- // =========================
14
- let { data, selected, width, height }: NodeProps = $props();
11
+ // =========================
12
+ // PROPS
13
+ // =========================
14
+ let { data, selected, width, height }: NodeProps = $props();
15
15
 
16
- // =========================
17
- // DERIVED
18
- // =========================
19
- let stroke = $derived(data as StrokeData);
20
- let path = $derived(strokePath(stroke.points, stroke));
21
- // A wide, invisible line along the centre so a thin stroke is easy to click.
22
- let hitPoints = $derived(stroke.points.map((point) => `${point[0]},${point[1]}`).join(" "));
23
- let hitWidth = $derived(Math.max(stroke.size, 14));
16
+ // =========================
17
+ // DERIVED
18
+ // =========================
19
+ let stroke = $derived(data as StrokeData);
20
+ let path = $derived(strokePath(stroke.points, stroke));
21
+ // A wide, invisible line along the centre so a thin stroke is easy to click.
22
+ let hitPoints = $derived(stroke.points.map((point) => `${point[0]},${point[1]}`).join(" "));
23
+ let hitWidth = $derived(Math.max(stroke.size, 14));
24
24
  </script>
25
25
 
26
26
  <!-- =========================== -->
27
27
  <!-- MARKUP -->
28
28
  <!-- =========================== -->
29
- <svg
30
- class="pen-stroke"
31
- {width}
32
- {height}
33
- viewBox="0 0 {width} {height}"
34
- aria-hidden="true"
35
- >
29
+ <svg class="pen-stroke" {width} {height} viewBox="0 0 {width} {height}" aria-hidden="true">
36
30
  <polyline
37
31
  class="hit"
38
32
  points={hitPoints}
@@ -1,22 +1,22 @@
1
1
  <script lang="ts">
2
- // =========================
3
- // IMPORTS
4
- // =========================
5
- import type { SketchPath } from "../../../headless/sketch.js";
2
+ // =========================
3
+ // IMPORTS
4
+ // =========================
5
+ import type { SketchPath } from "../../../headless/sketch.js";
6
6
 
7
- // =========================
8
- // TYPES
9
- // =========================
10
- interface Props {
11
- rule: SketchPath[];
12
- ink: string;
13
- width: number;
14
- }
7
+ // =========================
8
+ // TYPES
9
+ // =========================
10
+ interface Props {
11
+ rule: SketchPath[];
12
+ ink: string;
13
+ width: number;
14
+ }
15
15
 
16
- // =========================
17
- // PROPS
18
- // =========================
19
- let { rule, ink, width }: Props = $props();
16
+ // =========================
17
+ // PROPS
18
+ // =========================
19
+ let { rule, ink, width }: Props = $props();
20
20
  </script>
21
21
 
22
22
  <!-- =========================== -->
@@ -24,7 +24,15 @@ let { rule, ink, width }: Props = $props();
24
24
  <!-- =========================== -->
25
25
  <svg class="pen-rule" {width} height="10" aria-hidden="true">
26
26
  {#each rule as path, i (i)}
27
- <path class="pen-line" style:--sw={path.strokeWidth} d={path.d} fill="none" stroke={ink} stroke-width={path.strokeWidth} stroke-linecap="round" />
27
+ <path
28
+ class="pen-line"
29
+ style:--sw={path.strokeWidth}
30
+ d={path.d}
31
+ fill="none"
32
+ stroke={ink}
33
+ stroke-width={path.strokeWidth}
34
+ stroke-linecap="round"
35
+ />
28
36
  {/each}
29
37
  </svg>
30
38
 
@@ -1,41 +1,41 @@
1
1
  <script lang="ts">
2
- // =========================
3
- // IMPORTS
4
- // =========================
5
- import { useStore } from "@xyflow/svelte";
2
+ // =========================
3
+ // IMPORTS
4
+ // =========================
5
+ import { useStore } from "@xyflow/svelte";
6
6
 
7
- // The grab dot on a selected elbow, one size on screen. Only the edge showing it reads the zoom; a root value restyles every card per frame.
7
+ // The grab dot on a selected elbow, one size on screen. Only the edge showing it reads the zoom; a root value restyles every card per frame.
8
8
 
9
- // =========================
10
- // CONSTANTS
11
- // =========================
12
- const MIN_ZOOM = 0.05;
9
+ // =========================
10
+ // CONSTANTS
11
+ // =========================
12
+ const MIN_ZOOM = 0.05;
13
13
 
14
- // =========================
15
- // TYPES
16
- // =========================
17
- interface Props {
18
- /** The way the run moves: x slides it sideways, y up and down. */
19
- axis: "x" | "y";
20
- title: string;
21
- onpointerdown: (event: PointerEvent) => void;
22
- ondblclick: () => void;
23
- }
14
+ // =========================
15
+ // TYPES
16
+ // =========================
17
+ interface Props {
18
+ /** The way the run moves: x slides it sideways, y up and down. */
19
+ axis: "x" | "y";
20
+ title: string;
21
+ onpointerdown: (event: PointerEvent) => void;
22
+ ondblclick: () => void;
23
+ }
24
24
 
25
- // =========================
26
- // PROPS
27
- // =========================
28
- let { axis, title, onpointerdown, ondblclick }: Props = $props();
25
+ // =========================
26
+ // PROPS
27
+ // =========================
28
+ let { axis, title, onpointerdown, ondblclick }: Props = $props();
29
29
 
30
- // =========================
31
- // STATE
32
- // =========================
33
- const store = useStore();
30
+ // =========================
31
+ // STATE
32
+ // =========================
33
+ const store = useStore();
34
34
 
35
- // =========================
36
- // DERIVED
37
- // =========================
38
- let unzoom = $derived(1 / Math.max(store.viewport.zoom, MIN_ZOOM));
35
+ // =========================
36
+ // DERIVED
37
+ // =========================
38
+ let unzoom = $derived(1 / Math.max(store.viewport.zoom, MIN_ZOOM));
39
39
  </script>
40
40
 
41
41
  <!-- =========================== -->
@@ -57,20 +57,20 @@ let unzoom = $derived(1 / Math.max(store.viewport.zoom, MIN_ZOOM));
57
57
  <!-- STYLES -->
58
58
  <!-- =========================== -->
59
59
  <style>
60
- .cv-bend-handle {
61
- display: block;
62
- box-sizing: border-box;
63
- width: 12px;
64
- height: 12px;
65
- padding: 0;
66
- border: 2px solid var(--cv-chrome-surface, var(--background, #fff));
67
- border-radius: 9999px;
68
- background: var(--cv-chrome-ring, var(--ring, #4a4ad8));
69
- cursor: row-resize;
70
- touch-action: none;
71
- }
60
+ .cv-bend-handle {
61
+ display: block;
62
+ box-sizing: border-box;
63
+ width: 12px;
64
+ height: 12px;
65
+ padding: 0;
66
+ border: 2px solid var(--cv-chrome-surface, var(--background, #fff));
67
+ border-radius: 9999px;
68
+ background: var(--cv-chrome-ring, var(--ring, #4a4ad8));
69
+ cursor: row-resize;
70
+ touch-action: none;
71
+ }
72
72
 
73
- .cv-bend-x {
74
- cursor: col-resize;
75
- }
73
+ .cv-bend-x {
74
+ cursor: col-resize;
75
+ }
76
76
  </style>
@@ -1,18 +1,18 @@
1
1
  <svelte:options namespace="svg" />
2
2
 
3
3
  <script lang="ts">
4
- interface Props {
5
- id: string;
6
- from: { x: number; y: number };
7
- to: { x: number; y: number };
8
- fromColor: string;
9
- toColor: string;
10
- }
4
+ interface Props {
5
+ id: string;
6
+ from: { x: number; y: number };
7
+ to: { x: number; y: number };
8
+ fromColor: string;
9
+ toColor: string;
10
+ }
11
11
 
12
- let { id, from, to, fromColor, toColor }: Props = $props();
12
+ let { id, from, to, fromColor, toColor }: Props = $props();
13
13
 
14
- // A zero-length gradient paints nothing, so a link drawn onto itself keeps one pixel of run.
15
- let flat = $derived(Math.abs(from.x - to.x) < 0.5 && Math.abs(from.y - to.y) < 0.5);
14
+ // A zero-length gradient paints nothing, so a link drawn onto itself keeps one pixel of run.
15
+ let flat = $derived(Math.abs(from.x - to.x) < 0.5 && Math.abs(from.y - to.y) < 0.5);
16
16
  </script>
17
17
 
18
18
  <defs>