@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,83 +1,86 @@
1
1
  <script lang="ts">
2
- // =========================
3
- // IMPORTS
4
- // =========================
5
- import type { Snippet } from "svelte";
6
- import { getContext } from "svelte";
7
- import { cn } from "../../lib/utils.js";
8
- import { MASTER_DETAIL_PANE, type MasterDetailPane } from "./queue-rail.js";
2
+ // =========================
3
+ // IMPORTS
4
+ // =========================
5
+ import type { Snippet } from "svelte";
6
+ import { getContext } from "svelte";
7
+ import { cn } from "../../lib/utils.js";
8
+ import {
9
+ MASTER_DETAIL_PANE,
10
+ type MasterDetailPane,
11
+ } from "./queue-rail.js";
9
12
 
10
- // =========================
11
- // TYPES
12
- // =========================
13
- interface Props {
14
- // One row shape for every queue rail, in a fixed order: identity, preview,
15
- // facts. Three pages used to draw three different rows.
16
- title: string;
17
- selected?: boolean;
18
- onclick: () => void;
19
- // A thumbnail or avatar ahead of the title.
20
- leading?: Snippet;
21
- // The record's state, at the end of the preview line. Never beside the title,
22
- // where it competes with the name.
23
- trailing?: Snippet;
24
- // One line of the record's own words, under the title.
25
- preview?: string | null;
26
- // Dot-separated facts under the preview. Falsy entries drop out.
27
- meta?: Array<string | null | undefined | false>;
28
- // Which fact gives up its width first. The others hold their full text, so
29
- // a date or a count never truncates to nonsense.
30
- metaTruncate?: "first" | "last";
31
- // Icons that qualify the facts (a waiting reply, a removed comment).
32
- metaTrail?: Snippet;
33
- // Controls that appear on hover, over the row's top-right corner.
34
- actions?: Snippet;
35
- // Long records (thread titles) need two lines to be recognisable.
36
- titleLines?: 1 | 2;
37
- class?: string;
38
- };
13
+ // =========================
14
+ // TYPES
15
+ // =========================
16
+ interface Props {
17
+ // One row shape for every queue rail, in a fixed order: identity, preview,
18
+ // facts. Three pages used to draw three different rows.
19
+ title: string;
20
+ selected?: boolean;
21
+ onclick: () => void;
22
+ // A thumbnail or avatar ahead of the title.
23
+ leading?: Snippet;
24
+ // The record's state, at the end of the preview line. Never beside the title,
25
+ // where it competes with the name.
26
+ trailing?: Snippet;
27
+ // One line of the record's own words, under the title.
28
+ preview?: string | null;
29
+ // Dot-separated facts under the preview. Falsy entries drop out.
30
+ meta?: Array<string | null | undefined | false>;
31
+ // Which fact gives up its width first. The others hold their full text, so
32
+ // a date or a count never truncates to nonsense.
33
+ metaTruncate?: "first" | "last";
34
+ // Icons that qualify the facts (a waiting reply, a removed comment).
35
+ metaTrail?: Snippet;
36
+ // Controls that appear on hover, over the row's top-right corner.
37
+ actions?: Snippet;
38
+ // Long records (thread titles) need two lines to be recognisable.
39
+ titleLines?: 1 | 2;
40
+ class?: string;
41
+ }
39
42
 
40
- // =========================
41
- // PROPS
42
- // =========================
43
- let {
44
- title,
45
- selected = false,
46
- onclick,
47
- leading,
48
- trailing,
49
- preview,
50
- meta,
51
- metaTruncate = "first",
52
- metaTrail,
53
- actions,
54
- titleLines = 1,
55
- class: className,
56
- }: Props = $props();
43
+ // =========================
44
+ // PROPS
45
+ // =========================
46
+ let {
47
+ title,
48
+ selected = false,
49
+ onclick,
50
+ leading,
51
+ trailing,
52
+ preview,
53
+ meta,
54
+ metaTruncate = "first",
55
+ metaTrail,
56
+ actions,
57
+ titleLines = 1,
58
+ class: className,
59
+ }: Props = $props();
57
60
 
58
- // =========================
59
- // DERIVED
60
- // =========================
61
- let facts = $derived((meta ?? []).filter((item): item is string => Boolean(item)));
61
+ // =========================
62
+ // DERIVED
63
+ // =========================
64
+ let facts = $derived((meta ?? []).filter((item): item is string => Boolean(item)));
62
65
 
63
- // =========================
64
- // FUNCTIONS
65
- // =========================
66
- // Picking a row moves a phone from list to record. `undefined` outside a
67
- // `MasterDetail`, where a rail is just a list.
68
- let row = $state<HTMLDivElement>();
66
+ // =========================
67
+ // FUNCTIONS
68
+ // =========================
69
+ // Picking a row moves a phone from list to record. `undefined` outside a
70
+ // `MasterDetail`, where a rail is just a list.
71
+ let row = $state<HTMLDivElement>();
69
72
 
70
- // A row picked from a link, a shortcut or the next arrow can sit below the fold.
71
- $effect(() => {
72
- if (selected) row?.scrollIntoView({ block: "nearest" });
73
- });
73
+ // A row picked from a link, a shortcut or the next arrow can sit below the fold.
74
+ $effect(() => {
75
+ if (selected) row?.scrollIntoView({ block: "nearest" });
76
+ });
74
77
 
75
- let pane = getContext<MasterDetailPane | undefined>(MASTER_DETAIL_PANE);
78
+ let pane = getContext<MasterDetailPane | undefined>(MASTER_DETAIL_PANE);
76
79
 
77
- function select() {
78
- onclick();
79
- pane?.open();
80
- }
80
+ function select() {
81
+ onclick();
82
+ pane?.open();
83
+ }
81
84
  </script>
82
85
 
83
86
  <!-- =========================== -->
@@ -130,7 +133,8 @@ function select() {
130
133
  <span class="truncate">{preview}</span>
131
134
  {/if}
132
135
  {#if trailing}
133
- <span class="ml-auto flex shrink-0 items-center gap-1.5 pl-2">{@render trailing()}</span>
136
+ <span class="ml-auto flex shrink-0 items-center gap-1.5 pl-2">{@render trailing()}</span
137
+ >
134
138
  {/if}
135
139
  </span>
136
140
  {/if}
@@ -2,9 +2,8 @@ import { getContext, setContext } from "svelte";
2
2
  import type { SectionStrip } from "../segmented/section-runs.svelte";
3
3
 
4
4
  /**
5
- * What an app shell gives a list page so the page's toolbar can draw the
6
- * section strip. `strip` must be reactive (a `$state` field), and `claim` tells
7
- * the shell a toolbar is drawing it and returns the release.
5
+ * What an app shell gives a list page's toolbar to draw the section strip; `strip` must be
6
+ * reactive (a `$state` field), and `claim` returns the release.
8
7
  */
9
8
  export interface SectionHost {
10
9
  readonly strip: SectionStrip | null;
@@ -1,49 +1,49 @@
1
1
  <script lang="ts">
2
- // =========================
3
- // IMPORTS
4
- // =========================
5
- import { SegmentedFilter, type TabDef } from "../segmented/index.js";
2
+ // =========================
3
+ // IMPORTS
4
+ // =========================
5
+ import { SegmentedFilter, type TabDef } from "../segmented/index.js";
6
6
 
7
- // =========================
8
- // TYPES
9
- // =========================
10
- type LocaleOption = {
11
- value: string;
12
- label: string;
13
- flag: string;
14
- };
7
+ // =========================
8
+ // TYPES
9
+ // =========================
10
+ type LocaleOption = {
11
+ value: string;
12
+ label: string;
13
+ flag: string;
14
+ };
15
15
 
16
- interface Props {
17
- // Wraps `SegmentedFilter` so it shares one track with every other strip. It
18
- // only adds each language's flag.
19
- value: string;
20
- onchange: (value: string) => void;
21
- options?: LocaleOption[];
22
- /** Names the control for a screen reader. Without it the group is two bare letters. */
23
- ariaLabel?: string;
24
- class?: string;
25
- };
16
+ interface Props {
17
+ // Wraps `SegmentedFilter` so it shares one track with every other strip. It
18
+ // only adds each language's flag.
19
+ value: string;
20
+ onchange: (value: string) => void;
21
+ options?: LocaleOption[];
22
+ /** Names the control for a screen reader. Without it the group is two bare letters. */
23
+ ariaLabel?: string;
24
+ class?: string;
25
+ }
26
26
 
27
- // =========================
28
- // PROPS
29
- // =========================
30
- let {
31
- value,
32
- onchange,
33
- options = [
34
- { value: "en", label: "EN", flag: "/flags/US.svg" },
35
- { value: "fr", label: "FR", flag: "/flags/FR.svg" },
36
- ],
37
- ariaLabel = "Language",
38
- class: className,
39
- }: Props = $props();
27
+ // =========================
28
+ // PROPS
29
+ // =========================
30
+ let {
31
+ value,
32
+ onchange,
33
+ options = [
34
+ { value: "en", label: "EN", flag: "/flags/US.svg" },
35
+ { value: "fr", label: "FR", flag: "/flags/FR.svg" },
36
+ ],
37
+ ariaLabel = "Language",
38
+ class: className,
39
+ }: Props = $props();
40
40
 
41
- // =========================
42
- // DERIVED
43
- // =========================
44
- let segments = $derived<TabDef<string>[]>(
45
- options.map((option) => ({ value: option.value, label: option.label, image: option.flag })),
46
- );
41
+ // =========================
42
+ // DERIVED
43
+ // =========================
44
+ let segments = $derived<TabDef<string>[]>(
45
+ options.map((option) => ({ value: option.value, label: option.label, image: option.flag })),
46
+ );
47
47
  </script>
48
48
 
49
49
  <!-- =========================== -->
@@ -1,42 +1,42 @@
1
1
  <script lang="ts">
2
- // =========================
3
- // IMPORTS
4
- // =========================
5
- import { cn } from "../../lib/utils.js";
2
+ // =========================
3
+ // IMPORTS
4
+ // =========================
5
+ import { cn } from "../../lib/utils.js";
6
6
 
7
- // =========================
8
- // TYPES
9
- // =========================
7
+ // =========================
8
+ // TYPES
9
+ // =========================
10
10
 
11
- /**
12
- * A brand's mark at glyph size: a kit icon, a channel avatar, a client logo.
13
- * One renderer, because three places each handled a missing file their own way.
14
- */
15
- interface Props {
16
- /** The file. A missing or broken one falls back to the label's initial. */
17
- src?: string;
18
- /** Read for the fallback letter. The mark itself is decorative. */
19
- label: string;
20
- /** `circle` crops a photograph to a disc, `square` fits a logo whole. */
21
- shape?: "square" | "circle";
22
- class?: string;
23
- };
11
+ /**
12
+ * A brand's mark at glyph size: a kit icon, a channel avatar, a client logo.
13
+ * One renderer, because three places each handled a missing file their own way.
14
+ */
15
+ interface Props {
16
+ /** The file. A missing or broken one falls back to the label's initial. */
17
+ src?: string;
18
+ /** Read for the fallback letter. The mark itself is decorative. */
19
+ label: string;
20
+ /** `circle` crops a photograph to a disc, `square` fits a logo whole. */
21
+ shape?: "square" | "circle";
22
+ class?: string;
23
+ }
24
24
 
25
- // =========================
26
- // PROPS
27
- // =========================
28
- let { src, label, shape = "square", class: className }: Props = $props();
25
+ // =========================
26
+ // PROPS
27
+ // =========================
28
+ let { src, label, shape = "square", class: className }: Props = $props();
29
29
 
30
- // =========================
31
- // STATE
32
- // =========================
33
- /** The src that failed, so a later one gets its own chance to load. */
34
- let broken = $state("");
30
+ // =========================
31
+ // STATE
32
+ // =========================
33
+ /** The src that failed, so a later one gets its own chance to load. */
34
+ let broken = $state("");
35
35
 
36
- // =========================
37
- // DERIVED
38
- // =========================
39
- let round = $derived(shape === "circle");
36
+ // =========================
37
+ // DERIVED
38
+ // =========================
39
+ let round = $derived(shape === "circle");
40
40
  </script>
41
41
 
42
42
  <!-- =========================== -->
@@ -50,11 +50,7 @@ let round = $derived(shape === "circle");
50
50
  alt=""
51
51
  loading="lazy"
52
52
  referrerpolicy="no-referrer"
53
- class={cn(
54
- "size-4 shrink-0",
55
- round ? "rounded-full object-cover" : "object-contain",
56
- className,
57
- )}
53
+ class={cn("size-4 shrink-0", round ? "rounded-full object-cover" : "object-contain", className)}
58
54
  onerror={() => (broken = src)}
59
55
  />
60
56
  {:else}
@@ -1,6 +1,2 @@
1
1
  export { default as OpenIn } from "./open-in.svelte";
2
- export type {
3
- OpenInSize,
4
- OpenInTool,
5
- OpenInVariant,
6
- } from "./open-in.svelte";
2
+ export type { OpenInSize, OpenInTool, OpenInVariant } from "./open-in.svelte";
@@ -20,49 +20,49 @@
20
20
  </script>
21
21
 
22
22
  <script lang="ts">
23
- // =========================
24
- // IMPORTS
25
- // =========================
26
- import { ArrowSquareOut } from "phosphor-svelte";
27
- import { cn } from "../../lib/utils.js";
28
- import { buttonVariants } from "../../shadcn/button/index.js";
23
+ // =========================
24
+ // IMPORTS
25
+ // =========================
26
+ import { ArrowSquareOut } from "phosphor-svelte";
27
+ import { cn } from "../../lib/utils.js";
28
+ import { buttonVariants } from "../../shadcn/button/index.js";
29
29
 
30
- // =========================
31
- // TYPES
32
- // =========================
33
- interface Props {
34
- /** The tool to link to: its name, accessible sentence and mark. */
35
- tool: OpenInTool;
36
- href: string;
37
- variant?: OpenInVariant;
38
- size?: OpenInSize;
39
- /** Overrides the visible text. The accessible name is `title`, never this. */
40
- label?: string;
41
- /** The accessible sentence, translated by the caller. */
42
- title?: string;
43
- class?: string;
44
- }
30
+ // =========================
31
+ // TYPES
32
+ // =========================
33
+ interface Props {
34
+ /** The tool to link to: its name, accessible sentence and mark. */
35
+ tool: OpenInTool;
36
+ href: string;
37
+ variant?: OpenInVariant;
38
+ size?: OpenInSize;
39
+ /** Overrides the visible text. The accessible name is `title`, never this. */
40
+ label?: string;
41
+ /** The accessible sentence, translated by the caller. */
42
+ title?: string;
43
+ class?: string;
44
+ }
45
45
 
46
- // =========================
47
- // PROPS
48
- // =========================
49
- let {
50
- tool,
51
- href,
52
- variant = "chip",
53
- size = "default",
54
- label,
55
- title,
56
- class: className,
57
- }: Props = $props();
46
+ // =========================
47
+ // PROPS
48
+ // =========================
49
+ let {
50
+ tool,
51
+ href,
52
+ variant = "chip",
53
+ size = "default",
54
+ label,
55
+ title,
56
+ class: className,
57
+ }: Props = $props();
58
58
 
59
- // =========================
60
- // DERIVED
61
- // =========================
62
- let Icon = $derived(tool.icon);
63
- let iconSize = $derived(size === "sm" ? 12 : 14);
64
- let action = $derived(title ?? tool.action);
65
- let text = $derived(label ?? tool.name);
59
+ // =========================
60
+ // DERIVED
61
+ // =========================
62
+ let Icon = $derived(tool.icon);
63
+ let iconSize = $derived(size === "sm" ? 12 : 14);
64
+ let action = $derived(title ?? tool.action);
65
+ let text = $derived(label ?? tool.name);
66
66
  </script>
67
67
 
68
68
  <!-- =========================== -->
@@ -1,57 +1,57 @@
1
1
  <script lang="ts" generics="V extends string">
2
- // =========================
3
- // IMPORTS
4
- // =========================
5
- import { CaretDown } from "phosphor-svelte";
6
- import { Mark } from "../mark/index.js";
7
- import { cn } from "../../lib/utils.js";
8
- import Picker from "./picker.svelte";
9
- import { pickerTriggerClass } from "./trigger.js";
10
- import type { PickerOption } from "./types.js";
2
+ // =========================
3
+ // IMPORTS
4
+ // =========================
5
+ import { CaretDown } from "phosphor-svelte";
6
+ import { Mark } from "../mark/index.js";
7
+ import { cn } from "../../lib/utils.js";
8
+ import Picker from "./picker.svelte";
9
+ import { pickerTriggerClass } from "./trigger.js";
10
+ import type { PickerOption } from "./types.js";
11
11
 
12
- // =========================
13
- // TYPES
14
- // =========================
12
+ // =========================
13
+ // TYPES
14
+ // =========================
15
15
 
16
- /**
17
- * The picker for named things carrying a mark: a kit, a channel, a client. It
18
- * wraps `Picker` because the kit strip and the channel row wrote the same two
19
- * snippets.
20
- */
21
- interface Props {
22
- options: PickerOption<V>[];
23
- value: V | null;
24
- onSelect: (value: V) => void;
25
- ariaLabel: string;
26
- /** Said by the trigger when nothing in the list is the current value. */
27
- placeholder?: string;
28
- /** The search field's own prompt, on a list long enough to show one. */
29
- searchPlaceholder?: string;
30
- /** `circle` for a face or an avatar, `square` for a logo. */
31
- shape?: "square" | "circle";
32
- width?: "sm" | "default" | "lg";
33
- class?: string;
34
- };
16
+ /**
17
+ * The picker for named things carrying a mark: a kit, a channel, a client. It
18
+ * wraps `Picker` because the kit strip and the channel row wrote the same two
19
+ * snippets.
20
+ */
21
+ interface Props {
22
+ options: PickerOption<V>[];
23
+ value: V | null;
24
+ onSelect: (value: V) => void;
25
+ ariaLabel: string;
26
+ /** Said by the trigger when nothing in the list is the current value. */
27
+ placeholder?: string;
28
+ /** The search field's own prompt, on a list long enough to show one. */
29
+ searchPlaceholder?: string;
30
+ /** `circle` for a face or an avatar, `square` for a logo. */
31
+ shape?: "square" | "circle";
32
+ width?: "sm" | "default" | "lg";
33
+ class?: string;
34
+ }
35
35
 
36
- // =========================
37
- // PROPS
38
- // =========================
39
- let {
40
- options,
41
- value,
42
- onSelect,
43
- ariaLabel,
44
- placeholder = "Select",
45
- searchPlaceholder = "Search",
46
- shape = "square",
47
- width = "lg",
48
- class: className,
49
- }: Props = $props();
36
+ // =========================
37
+ // PROPS
38
+ // =========================
39
+ let {
40
+ options,
41
+ value,
42
+ onSelect,
43
+ ariaLabel,
44
+ placeholder = "Select",
45
+ searchPlaceholder = "Search",
46
+ shape = "square",
47
+ width = "lg",
48
+ class: className,
49
+ }: Props = $props();
50
50
 
51
- // =========================
52
- // DERIVED
53
- // =========================
54
- let selected = $derived(options.find((option) => option.value === value));
51
+ // =========================
52
+ // DERIVED
53
+ // =========================
54
+ let selected = $derived(options.find((option) => option.value === value));
55
55
  </script>
56
56
 
57
57
  <!-- =========================== -->
@@ -43,7 +43,7 @@
43
43
  /** `sm` fits a word, `default` a name, `lg` a name and a date. */
44
44
  width?: "sm" | "default" | "lg";
45
45
  disabled?: boolean;
46
- };
46
+ }
47
47
 
48
48
  let {
49
49
  options,
@@ -61,7 +61,7 @@
61
61
  open = $bindable(false),
62
62
  align = "start",
63
63
  width = "default",
64
- disabled = false
64
+ disabled = false,
65
65
  }: Props = $props();
66
66
 
67
67
  let resolved = $derived<PickerGroup<V>[]>(groups ?? [{ options: options ?? [] }]);
@@ -126,7 +126,9 @@
126
126
  {option.label}
127
127
  </span>
128
128
  {#if option.hint}
129
- <span class="text-muted-foreground shrink-0 text-xs tabular-nums">{option.hint}</span>
129
+ <span class="text-muted-foreground shrink-0 text-xs tabular-nums"
130
+ >{option.hint}</span
131
+ >
130
132
  {/if}
131
133
  </Command.Item>
132
134
  {/each}
@@ -7,7 +7,13 @@ function render(props: Record<string, unknown>) {
7
7
  document.body.appendChild(target);
8
8
  const app = mount(SectionHeader, { target, props: { title: "Lines", ...props } });
9
9
  flushSync();
10
- return { target, done: () => { void unmount(app); target.remove(); } };
10
+ return {
11
+ target,
12
+ done: () => {
13
+ void unmount(app);
14
+ target.remove();
15
+ },
16
+ };
11
17
  }
12
18
 
13
19
  describe("SectionHeader", () => {
@@ -1,26 +1,26 @@
1
1
  <script lang="ts">
2
- // =========================
3
- // IMPORTS
4
- // =========================
5
- import type { Snippet } from "svelte";
6
- import { cn } from "../../lib/utils.js";
7
- import type { PhosphorIcon } from "../../lib/icon-types.js";
2
+ // =========================
3
+ // IMPORTS
4
+ // =========================
5
+ import type { Snippet } from "svelte";
6
+ import { cn } from "../../lib/utils.js";
7
+ import type { PhosphorIcon } from "../../lib/icon-types.js";
8
8
 
9
- // =========================
10
- // TYPES
11
- // =========================
12
- interface Props {
13
- // The one label style for panel, rail group and sub-section headers. Retyped
14
- // copies drifted to a different tracking value.
15
- icon?: PhosphorIcon;
16
- children: Snippet;
17
- class?: string;
18
- };
9
+ // =========================
10
+ // TYPES
11
+ // =========================
12
+ interface Props {
13
+ // The one label style for panel, rail group and sub-section headers. Retyped
14
+ // copies drifted to a different tracking value.
15
+ icon?: PhosphorIcon;
16
+ children: Snippet;
17
+ class?: string;
18
+ }
19
19
 
20
- // =========================
21
- // PROPS
22
- // =========================
23
- let { icon: Icon, children, class: className }: Props = $props();
20
+ // =========================
21
+ // PROPS
22
+ // =========================
23
+ let { icon: Icon, children, class: className }: Props = $props();
24
24
  </script>
25
25
 
26
26
  <!-- =========================== -->