@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,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
  <!-- =========================== -->