@heyramzi/ui 2.1.0 → 2.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.
Files changed (312) hide show
  1. package/package.json +7 -8
  2. package/scripts/sync-shadcn.mjs +3 -4
  3. package/src/agents/agent-avatar.svelte +604 -575
  4. package/src/agents/agent-cast.svelte +179 -183
  5. package/src/agents/demo.svelte +125 -113
  6. package/src/agents/helpers.ts +23 -17
  7. package/src/agents/index.ts +4 -4
  8. package/src/agents/page-state.ts +6 -6
  9. package/src/agents/types.ts +6 -6
  10. package/src/ai/ai-button/AiButton.svelte +4 -12
  11. package/src/ai/generation-progress/GenerationProgress.svelte +10 -3
  12. package/src/ai/prompt-input/PromptInputTextarea.svelte +1 -2
  13. package/src/ai/response/Response.css +2 -3
  14. package/src/animations/avatar-group-hover.css +2 -16
  15. package/src/animations/card-tilt.css +3 -6
  16. package/src/animations/digit-pop-in.css +2 -15
  17. package/src/animations/dropdown.css +4 -17
  18. package/src/animations/input-clear-dissolve.css +5 -18
  19. package/src/animations/input-shake.css +9 -41
  20. package/src/animations/learn-more-hover.css +17 -9
  21. package/src/animations/like-button.css +2 -4
  22. package/src/animations/page-side-by-side.css +2 -10
  23. package/src/animations/plus-menu-morph.css +2 -5
  24. package/src/animations/shimmer-text.css +5 -18
  25. package/src/animations/spinning-counter.css +2 -6
  26. package/src/animations/success-check.css +2 -15
  27. package/src/animations/thinking-states.css +2 -7
  28. package/src/brand/brand.test.ts +21 -5
  29. package/src/brand/index.ts +4 -10
  30. package/src/canvas/card/card-frame.svelte +43 -39
  31. package/src/canvas/card/resize-handles.svelte +89 -80
  32. package/src/canvas/chrome/chrome-zoom.svelte +101 -100
  33. package/src/canvas/chrome/lock-badge.svelte +8 -8
  34. package/src/canvas/chrome/side-handles.svelte +24 -19
  35. package/src/canvas/chrome/size-chip.svelte +30 -30
  36. package/src/canvas/chrome/snap-guides.svelte +20 -20
  37. package/src/canvas/components/icons/ToolIcon.svelte +8 -8
  38. package/src/canvas/components/shared/svg/PreviewSvg.svelte +19 -19
  39. package/src/canvas/components/shared/svg/ShapeOutline.svelte +71 -48
  40. package/src/canvas/components/shared/svg/StrokeNode.svelte +21 -27
  41. package/src/canvas/components/shared/svg/TextRule.svelte +25 -17
  42. package/src/canvas/edges/bend-handle.svelte +46 -46
  43. package/src/canvas/edges/edge-gradient.svelte +10 -10
  44. package/src/canvas/edges/gradient-edge.svelte +45 -29
  45. package/src/canvas/editor/lock.test.ts +6 -1
  46. package/src/canvas/editor/style.ts +7 -1
  47. package/src/canvas/headless/svg-figure.test.ts +5 -1
  48. package/src/canvas/lod/lod-switch.svelte +111 -106
  49. package/src/canvas/pen/PenField.svelte +87 -81
  50. package/src/canvas/pen/PenOverlay.svelte +127 -127
  51. package/src/canvas/pen/ShapeNode.svelte +31 -32
  52. package/src/canvas/pen/TextNode.svelte +54 -53
  53. package/src/canvas/pen/host-field.test.svelte +7 -7
  54. package/src/canvas/pen/shapes.ts +7 -1
  55. package/src/canvas/screen/GlyphIcon.svelte +22 -17
  56. package/src/canvas/screen/PartView.svelte +138 -72
  57. package/src/canvas/screen/ScreenBody.svelte +81 -60
  58. package/src/canvas/screen/ScreenCard.svelte +20 -20
  59. package/src/canvas/ui/CanvasToolbar.svelte +173 -85
  60. package/src/canvas/ui/FrameLayer.svelte +59 -59
  61. package/src/canvas/ui/PenLayer.svelte +39 -30
  62. package/src/canvas/ui/StylePanel.svelte +119 -102
  63. package/src/canvas/ui/canvas-grid.svelte +137 -129
  64. package/src/charts/animated-value.svelte +1 -1
  65. package/src/charts/area-chart.css +2 -5
  66. package/src/charts/area-chart.svelte +1 -1
  67. package/src/charts/bar-chart.css +2 -3
  68. package/src/charts/bar-chart.svelte +1 -1
  69. package/src/charts/charts.css +5 -17
  70. package/src/charts/crosshair.svelte +1 -1
  71. package/src/charts/dashboard/dashboard-empty.svelte +25 -25
  72. package/src/charts/dashboard/dashboard-section.svelte +24 -24
  73. package/src/charts/dashboard/data-panel.svelte +50 -50
  74. package/src/charts/dashboard/data-sort-head.svelte +56 -56
  75. package/src/charts/dashboard/data-table.svelte +138 -138
  76. package/src/charts/dashboard/panel-grid.svelte +30 -30
  77. package/src/charts/dashboard/period-filter.svelte +25 -25
  78. package/src/charts/dashboard/rating-chip.svelte +19 -19
  79. package/src/charts/dashboard/stat-band.svelte +32 -32
  80. package/src/charts/dashboard/stat-tile.svelte +106 -99
  81. package/src/charts/donut-chart.svelte +1 -1
  82. package/src/charts/edge-fade.svelte +1 -1
  83. package/src/charts/figure.svelte +1 -1
  84. package/src/charts/gauge-chart.css +4 -7
  85. package/src/charts/gauge-chart.svelte +1 -1
  86. package/src/charts/hover-focus.svelte +1 -1
  87. package/src/charts/legend.css +1 -3
  88. package/src/charts/legend.svelte +1 -1
  89. package/src/charts/line-chart.svelte +1 -1
  90. package/src/charts/number-chart.css +6 -9
  91. package/src/charts/number-chart.svelte +1 -1
  92. package/src/charts/reference-line.svelte +19 -19
  93. package/src/charts/reveal.svelte +1 -1
  94. package/src/charts/ring-chart.css +2 -4
  95. package/src/charts/ring-chart.svelte +1 -1
  96. package/src/charts/sparkline.svelte +5 -2
  97. package/src/charts/stat-card.svelte +1 -1
  98. package/src/charts/time-series-chart.css +2 -5
  99. package/src/charts/trend-pill.css +2 -4
  100. package/src/charts/trend-pill.svelte +1 -1
  101. package/src/components/copy/copy-button.svelte +93 -98
  102. package/src/components/copy/copy-button.test.ts +10 -2
  103. package/src/components/data-table/infinite-scroll.svelte +42 -42
  104. package/src/components/data-table/pagination.svelte +34 -22
  105. package/src/components/data-table/row-arrow.svelte +19 -16
  106. package/src/components/data-table/row-context-menu.svelte +52 -52
  107. package/src/components/data-table/sortable-head.svelte +25 -25
  108. package/src/components/data-table/table-skeleton.svelte +41 -36
  109. package/src/components/docs/doc-page.svelte +18 -9
  110. package/src/components/docs/on-this-page.svelte +16 -3
  111. package/src/components/docs/scroll-spy.svelte.ts +2 -3
  112. package/src/components/field-row/field-row.svelte +10 -8
  113. package/src/components/hold-to-confirm/hold-to-confirm.svelte +5 -1
  114. package/src/components/icon/icon.svelte +14 -14
  115. package/src/components/language-flag/language-flag.svelte +3 -1
  116. package/src/components/list-page/detail-empty.svelte +34 -34
  117. package/src/components/list-page/detail-header.svelte +55 -47
  118. package/src/components/list-page/detail-panel.svelte +51 -59
  119. package/src/components/list-page/detail-row.svelte +19 -19
  120. package/src/components/list-page/detail-stack.svelte +21 -21
  121. package/src/components/list-page/empty-state.svelte +30 -30
  122. package/src/components/list-page/filter-item.svelte +20 -20
  123. package/src/components/list-page/filter-popover.svelte +60 -55
  124. package/src/components/list-page/grouped-list.svelte +4 -2
  125. package/src/components/list-page/index.ts +5 -1
  126. package/src/components/list-page/list-page-shell.svelte +2 -5
  127. package/src/components/list-page/master-detail.svelte +87 -88
  128. package/src/components/list-page/notice-bar.svelte +38 -38
  129. package/src/components/list-page/prev-next.svelte +63 -63
  130. package/src/components/list-page/rail-body.svelte +18 -18
  131. package/src/components/list-page/rail-empty.svelte +23 -30
  132. package/src/components/list-page/rail-head.svelte +24 -24
  133. package/src/components/list-page/rail-row.svelte +77 -73
  134. package/src/components/list-page/section-host.ts +2 -3
  135. package/src/components/locale-switch/locale-switch.svelte +41 -41
  136. package/src/components/mark/mark.svelte +34 -38
  137. package/src/components/open-in/index.ts +1 -5
  138. package/src/components/open-in/open-in.svelte +40 -40
  139. package/src/components/picker/mark-picker.svelte +49 -49
  140. package/src/components/picker/picker.svelte +5 -3
  141. package/src/components/section-header/section-header.test.ts +7 -1
  142. package/src/components/section-header/section-label.svelte +20 -20
  143. package/src/components/segmented/animated-tabs.svelte +31 -2
  144. package/src/components/segmented/collapse.test.ts +2 -1
  145. package/src/components/segmented/index.ts +2 -0
  146. package/src/components/segmented/segment.svelte +52 -49
  147. package/src/components/segmented/segmented-filter.svelte +79 -80
  148. package/src/components/segmented/segmented-nav.svelte +34 -40
  149. package/src/components/segmented/segmented-overflow.svelte +53 -50
  150. package/src/components/segmented/segmented-track.svelte +62 -46
  151. package/src/components/segmented/segmented.ts +2 -3
  152. package/src/components/star-rating-input/star-rating-input.svelte +103 -103
  153. package/src/components/svg/svg.svelte +4 -4
  154. package/src/components/table-view/table-view.svelte +17 -2
  155. package/src/components/table-view/table-view.test.ts +7 -1
  156. package/src/components/table-view/types.ts +11 -11
  157. package/src/components/tags-input/index.ts +13 -0
  158. package/src/components/tags-input/tags-input.svelte +305 -0
  159. package/src/components/tags-input/tags.test.ts +64 -0
  160. package/src/components/tags-input/tags.ts +142 -0
  161. package/src/components/theme/index.ts +2 -4
  162. package/src/components/theme/theme-provider.svelte +1 -3
  163. package/src/components/toolbar/toolbar-search.svelte +25 -25
  164. package/src/components/toolbar/toolbar.svelte +11 -7
  165. package/src/components/toolbar/toolbar.test.ts +10 -1
  166. package/src/design/index.css +21 -78
  167. package/src/design/polish.css +26 -35
  168. package/src/editor/editor-toolbar.svelte +104 -99
  169. package/src/editor/editor.svelte +296 -266
  170. package/src/editor/image-toolbar.svelte +20 -22
  171. package/src/editor/index.ts +1 -4
  172. package/src/editor/inline-editor.svelte +280 -238
  173. package/src/editor/markdown.ts +15 -15
  174. package/src/editor/renderer.svelte +71 -71
  175. package/src/editor/slash-menu.svelte +24 -27
  176. package/src/effects/animated-beam/diagrams/BeamSvg.svelte +1 -1
  177. package/src/effects/image-comparison/ImageComparison.svelte +11 -1
  178. package/src/effects/interactive-hover-button/InteractiveHoverButton.svelte +59 -46
  179. package/src/effects/magic-card/MagicCard.css +14 -7
  180. package/src/effects/marquee/Marquee.svelte +3 -5
  181. package/src/effects/reveal/observe.ts +0 -3
  182. package/src/effects/spotlight/Spotlight.svelte +1 -1
  183. package/src/effects/theme-toggle/ThemeToggle.css +25 -22
  184. package/src/effects/theme-toggle/ThemeToggle.svelte +6 -7
  185. package/src/gallery.test.ts +14 -4
  186. package/src/inbox/README.md +1 -3
  187. package/src/inbox/inbox.test.ts +181 -138
  188. package/src/inbox/index.ts +20 -20
  189. package/src/inbox/logic.ts +114 -111
  190. package/src/inbox/thread-inbox.svelte +227 -151
  191. package/src/inbox/types.ts +130 -108
  192. package/src/lib/theme-transition.ts +2 -4
  193. package/src/lib/tone.ts +2 -4
  194. package/src/lib/utils.ts +2 -2
  195. package/src/modules.test.ts +79 -69
  196. package/src/onboarding/define-tours.test.ts +55 -40
  197. package/src/onboarding/define-tours.ts +23 -23
  198. package/src/onboarding/demo.svelte +24 -5
  199. package/src/onboarding/index.ts +1 -8
  200. package/src/onboarding/onboarding-provider.svelte +19 -7
  201. package/src/onboarding/onboarding.svelte.ts +16 -16
  202. package/src/onboarding/pick.test.ts +61 -52
  203. package/src/onboarding/pick.ts +16 -13
  204. package/src/onboarding/stores.test.ts +80 -80
  205. package/src/onboarding/stores.ts +41 -39
  206. package/src/onboarding/tour-card.svelte +30 -5
  207. package/src/onboarding/tour-runner.svelte +12 -3
  208. package/src/onboarding/types.ts +20 -12
  209. package/src/onboarding/wait.ts +22 -22
  210. package/src/panel/side-panel.svelte +94 -93
  211. package/src/record/demo-data.ts +291 -225
  212. package/src/record/field-section.svelte +38 -34
  213. package/src/record/fields.ts +148 -96
  214. package/src/record/format.ts +63 -56
  215. package/src/record/index.ts +49 -35
  216. package/src/record/info-list.svelte +145 -114
  217. package/src/record/kinds.ts +31 -31
  218. package/src/record/logic.ts +216 -214
  219. package/src/record/next-up.svelte +45 -34
  220. package/src/record/project-list.svelte +56 -50
  221. package/src/record/record-demo.svelte +130 -110
  222. package/src/record/record-header.svelte +37 -28
  223. package/src/record/record-shell.svelte +54 -54
  224. package/src/record/record-stats.svelte +25 -25
  225. package/src/record/record-timeline.svelte +134 -114
  226. package/src/record/record.test.ts +430 -309
  227. package/src/record/steps-rail.svelte +225 -216
  228. package/src/record/types.ts +234 -215
  229. package/src/record/where-we-are.svelte +62 -58
  230. package/src/shadcn/button/button.svelte +1 -1
  231. package/src/shadcn/card/card-title.svelte +1 -5
  232. package/src/shadcn/hooks/use-highlighted-code.svelte.ts +2 -13
  233. package/src/shadcn/sheet/sheet-content.svelte +2 -4
  234. package/src/shadcn/table/table-cell.svelte +2 -3
  235. package/src/shadcn/utilities.css +3 -8
  236. package/src/slides/Controls.svelte +150 -124
  237. package/src/slides/Deck.svelte +243 -238
  238. package/src/slides/Fragment.svelte +64 -57
  239. package/src/slides/Overview.svelte +106 -101
  240. package/src/slides/Presenter.svelte +300 -266
  241. package/src/slides/Slide.svelte +185 -170
  242. package/src/slides/SlideList.svelte +16 -12
  243. package/src/slides/ambient.d.ts +1 -1
  244. package/src/slides/bridges.ts +42 -23
  245. package/src/slides/deck-controller.svelte.ts +47 -35
  246. package/src/slides/demo-slides.svelte +330 -306
  247. package/src/slides/demo.svelte +164 -160
  248. package/src/slides/export/capture.ts +20 -16
  249. package/src/slides/export/ffmpeg.ts +43 -38
  250. package/src/slides/export/index.ts +5 -5
  251. package/src/slides/export/launch.ts +3 -1
  252. package/src/slides/export/pdf.ts +30 -27
  253. package/src/slides/export/types.ts +10 -8
  254. package/src/slides/index.ts +11 -11
  255. package/src/slides/labels.ts +22 -19
  256. package/src/slides/layout.ts +9 -2
  257. package/src/slides/model.ts +4 -4
  258. package/src/slides/navigation.ts +43 -31
  259. package/src/slides/theme.css +5 -7
  260. package/src/slides/types.ts +9 -10
  261. package/src/status/define-statuses.ts +17 -24
  262. package/src/status/index.ts +5 -5
  263. package/src/status/status-badge.svelte +3 -1
  264. package/src/status/status-dot.svelte +1 -3
  265. package/src/status/status-icon.svelte +1 -1
  266. package/src/status/status-types.ts +21 -21
  267. package/src/tasks/board-order.ts +2 -4
  268. package/src/tasks/demo.svelte +189 -31
  269. package/src/tasks/detail/detail-demo.svelte +73 -13
  270. package/src/tasks/detail/detail-types.ts +45 -45
  271. package/src/tasks/detail/task-detail.svelte +40 -10
  272. package/src/tasks/detail/task-property.svelte +8 -2
  273. package/src/tasks/detail/task-thread.svelte +53 -12
  274. package/src/tasks/gantt/gantt-bar.svelte +17 -6
  275. package/src/tasks/gantt/gantt-grid.svelte +40 -9
  276. package/src/tasks/gantt/gantt-group-row.svelte +8 -2
  277. package/src/tasks/gantt/gantt-header.svelte +9 -3
  278. package/src/tasks/gantt/gantt-task-row.svelte +26 -6
  279. package/src/tasks/gantt/gantt.css +2 -1
  280. package/src/tasks/gantt/gantt.test.ts +3 -1
  281. package/src/tasks/gantt/logic.test.ts +110 -20
  282. package/src/tasks/gantt/logic.ts +42 -6
  283. package/src/tasks/inbox/inbox-card.svelte +13 -5
  284. package/src/tasks/inbox/inbox-draft.svelte +1 -1
  285. package/src/tasks/inbox/inbox-logic.ts +6 -40
  286. package/src/tasks/inbox/inbox-statuses.ts +23 -23
  287. package/src/tasks/inbox/inbox-trace.svelte +9 -3
  288. package/src/tasks/inbox/inbox-types.ts +54 -58
  289. package/src/tasks/inbox/index.ts +22 -21
  290. package/src/tasks/index.ts +49 -52
  291. package/src/tasks/kanban-board.svelte +16 -12
  292. package/src/tasks/kanban-types.ts +2 -3
  293. package/src/tasks/presets/sales.ts +6 -6
  294. package/src/tasks/task-gantt.svelte +28 -8
  295. package/src/tasks/task-list.svelte +41 -17
  296. package/src/tasks/time/duration.ts +40 -40
  297. package/src/tasks/time/time-chip.svelte +9 -2
  298. package/src/tasks/time/time-dot.svelte +1 -1
  299. package/src/tasks/time/time-ring.svelte +11 -3
  300. package/src/tasks/time/time-tracker.svelte +57 -15
  301. package/src/tasks/time/time-types.ts +57 -57
  302. package/src/tasks/use-kanban-dnd.svelte.ts +2 -3
  303. package/src/thread/index.ts +7 -7
  304. package/src/thread/logic.ts +36 -33
  305. package/src/thread/thread.svelte +82 -16
  306. package/src/thread/thread.test.ts +58 -47
  307. package/src/thread/types.ts +68 -68
  308. package/src/tokens/craft.css +17 -53
  309. package/src/tokens/index.css +3 -13
  310. package/src/tokens/palette.css +13 -11
  311. package/src/tokens/primitives.css +10 -23
  312. 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>