@heyramzi/ui 2.11.1 → 2.11.2

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 (266) hide show
  1. package/dist/agents/helpers.js +38 -38
  2. package/dist/agents/page-state.js +49 -50
  3. package/dist/agents/vendor/color.js +146 -127
  4. package/dist/agents/vendor/draw.js +617 -508
  5. package/dist/agents/vendor/engine.js +698 -599
  6. package/dist/agents/vendor/mesh.js +653 -683
  7. package/dist/agents/vendor/plastic.js +3913 -3112
  8. package/dist/agents/vendor/presets.js +163 -164
  9. package/dist/agents/vendor/shapes.js +21 -20
  10. package/dist/agents/vendor/ticker.js +41 -42
  11. package/dist/agents/vendor/types.js +1 -0
  12. package/dist/agents/vendor/wear.js +1421 -1448
  13. package/dist/ai/confirmation/confirmation-context.svelte.js +6 -6
  14. package/dist/ai/confirmation/index.js +3 -1
  15. package/dist/ai/index.js +33 -0
  16. package/dist/ai/prompt-input/index.js +3 -1
  17. package/dist/ai/reasoning/index.js +3 -1
  18. package/dist/ai/reasoning/reasoning-context.svelte.js +6 -6
  19. package/dist/ai/suggestion/index.js +3 -1
  20. package/dist/ai/typing-dots/index.js +3 -1
  21. package/dist/animations/text-swap.js +24 -24
  22. package/dist/brand/index.js +54 -48
  23. package/dist/canvas/card/resize.js +5 -3
  24. package/dist/canvas/edges/edge-path.js +255 -242
  25. package/dist/canvas/editor/context-menu.js +39 -36
  26. package/dist/canvas/editor/dispatch.svelte.js +154 -151
  27. package/dist/canvas/editor/editor-context.js +7 -2
  28. package/dist/canvas/editor/editor-mode.js +1 -0
  29. package/dist/canvas/editor/frame.js +73 -76
  30. package/dist/canvas/editor/hand-context.js +5 -2
  31. package/dist/canvas/editor/history-core.js +163 -191
  32. package/dist/canvas/editor/keymap.js +95 -169
  33. package/dist/canvas/editor/layout-actions.js +143 -144
  34. package/dist/canvas/editor/lock.js +52 -51
  35. package/dist/canvas/editor/rebase.js +217 -240
  36. package/dist/canvas/editor/style.js +132 -137
  37. package/dist/canvas/editor/text-field-context.js +7 -2
  38. package/dist/canvas/editor/z-order.js +65 -70
  39. package/dist/canvas/headless/alignment.js +22 -16
  40. package/dist/canvas/headless/break-apart-find.js +286 -279
  41. package/dist/canvas/headless/break-apart-pieces.js +62 -58
  42. package/dist/canvas/headless/break-apart-plan.js +299 -325
  43. package/dist/canvas/headless/break-apart-style.js +75 -70
  44. package/dist/canvas/headless/break-apart.js +188 -181
  45. package/dist/canvas/headless/canvas-cleanup.js +78 -58
  46. package/dist/canvas/headless/edge-anchors.js +115 -116
  47. package/dist/canvas/headless/edge-memo.js +24 -22
  48. package/dist/canvas/headless/edge-serialization.js +17 -27
  49. package/dist/canvas/headless/figure-geometry.js +232 -264
  50. package/dist/canvas/headless/fit-viewport.js +84 -67
  51. package/dist/canvas/headless/grid.js +88 -86
  52. package/dist/canvas/headless/icon-node.js +44 -36
  53. package/dist/canvas/headless/index.js +1 -0
  54. package/dist/canvas/headless/linkify.js +17 -19
  55. package/dist/canvas/headless/pen-marks.js +101 -95
  56. package/dist/canvas/headless/sketch.js +231 -209
  57. package/dist/canvas/headless/snap-guides.js +99 -83
  58. package/dist/canvas/headless/svg-figure.js +133 -117
  59. package/dist/canvas/headless/table-layout.js +146 -107
  60. package/dist/canvas/index.js +2 -0
  61. package/dist/canvas/lod/lod-mode.svelte.js +20 -18
  62. package/dist/canvas/lod/render-all.svelte.js +36 -39
  63. package/dist/canvas/ops/arrange.js +78 -71
  64. package/dist/canvas/ops/ops.js +260 -255
  65. package/dist/canvas/pen/colors.js +37 -35
  66. package/dist/canvas/pen/eraser.js +28 -27
  67. package/dist/canvas/pen/geometry.js +120 -130
  68. package/dist/canvas/pen/index.js +1 -0
  69. package/dist/canvas/pen/ops.js +11 -11
  70. package/dist/canvas/pen/pen-session.js +150 -159
  71. package/dist/canvas/pen/plugin.js +107 -104
  72. package/dist/canvas/pen/shapes.js +73 -68
  73. package/dist/canvas/pen/stroke-path.js +32 -30
  74. package/dist/canvas/pen/types.js +21 -21
  75. package/dist/canvas/pen/ui.js +10 -8
  76. package/dist/canvas/plugin.js +46 -46
  77. package/dist/canvas/screen/glyphs.js +12 -11
  78. package/dist/canvas/screen/labels.js +22 -22
  79. package/dist/canvas/screen/parts.js +98 -111
  80. package/dist/canvas/screen/plugin.js +47 -56
  81. package/dist/canvas/screen/types.js +30 -35
  82. package/dist/canvas/screen/ui.js +7 -7
  83. package/dist/canvas/test-utils.js +14 -14
  84. package/dist/canvas/types.js +1 -0
  85. package/dist/canvas/ui/forward-wheel.js +24 -25
  86. package/dist/canvas/ui/icons.js +64 -131
  87. package/dist/canvas/ui/place-panel.js +58 -49
  88. package/dist/canvas/ui/shortcut-tip.js +14 -12
  89. package/dist/canvas/ui/tools.js +300 -385
  90. package/dist/charts/dashboard/chart.js +4 -0
  91. package/dist/charts/dashboard/data-table.js +11 -0
  92. package/dist/charts/dashboard/windows.js +8 -3
  93. package/dist/charts/edge-fade.js +10 -5
  94. package/dist/charts/hover-band.js +16 -11
  95. package/dist/charts/index.js +0 -1
  96. package/dist/charts/motion.js +11 -7
  97. package/dist/charts/primitives/chart-utils.js +12 -12
  98. package/dist/components/copy/clipboard.js +32 -32
  99. package/dist/components/copy/copied.svelte.js +31 -23
  100. package/dist/components/data-table/data-table.js +39 -39
  101. package/dist/components/docs/index.js +4 -0
  102. package/dist/components/docs/scroll-spy.svelte.js +73 -68
  103. package/dist/components/list-page/filter-section.js +4 -1
  104. package/dist/components/list-page/index.js +2 -0
  105. package/dist/components/list-page/list-table.js +7 -2
  106. package/dist/components/list-page/queue-rail.js +14 -0
  107. package/dist/components/list-page/section-host.js +4 -2
  108. package/dist/components/list-page/step.js +4 -3
  109. package/dist/components/list-page/types.js +1 -0
  110. package/dist/components/picker/trigger.js +48 -30
  111. package/dist/components/picker/types.js +1 -0
  112. package/dist/components/segmented/collapse.js +38 -27
  113. package/dist/components/segmented/index.js +8 -0
  114. package/dist/components/segmented/segmented.js +67 -42
  115. package/dist/components/star-rating-input/index.js +3 -1
  116. package/dist/components/table-view/types.js +1 -0
  117. package/dist/components/tags-input/tags.js +81 -69
  118. package/dist/components/theme/index.js +4 -0
  119. package/dist/components/toolbar/index.js +4 -0
  120. package/dist/components/toolbar/toolbar-trigger.js +14 -1
  121. package/dist/editor/anchors.js +17 -13
  122. package/dist/editor/block-id.js +52 -51
  123. package/dist/editor/block-ops.js +108 -80
  124. package/dist/editor/doc-blocks.js +155 -166
  125. package/dist/editor/extensions.js +139 -180
  126. package/dist/editor/index.js +4 -0
  127. package/dist/editor/markdown-test-helpers.js +4 -2
  128. package/dist/editor/markdown.js +420 -408
  129. package/dist/editor/serializer.js +204 -200
  130. package/dist/editor/slash-items.js +89 -101
  131. package/dist/editor/youtube-url.js +25 -20
  132. package/dist/effects/animated-beam/path-calculator.svelte.js +43 -38
  133. package/dist/effects/animated-beam/types.js +1 -0
  134. package/dist/effects/border-beam/css.js +92 -78
  135. package/dist/effects/border-beam/presets.js +1705 -1720
  136. package/dist/effects/border-beam/register-properties.js +43 -33
  137. package/dist/effects/border-beam/types.js +1 -0
  138. package/dist/effects/image-comparison/compare.js +3 -2
  139. package/dist/effects/image-reveal/types.js +1 -0
  140. package/dist/effects/magnetic/magnetic.js +58 -52
  141. package/dist/effects/reveal/observe.js +50 -40
  142. package/dist/effects/reveal/types.js +1 -0
  143. package/dist/effects/shader-gradient/color.js +36 -29
  144. package/dist/effects/shader-gradient/renderer.js +384 -295
  145. package/dist/effects/shader-gradient/shaders.js +31 -0
  146. package/dist/effects/shader-gradient/types.js +1 -0
  147. package/dist/icons/apple-symbol-exports.js +99 -124
  148. package/dist/icons/sf-symbols.js +357 -461
  149. package/dist/icons/trades.js +43 -28
  150. package/dist/inbox/index.js +1 -0
  151. package/dist/inbox/logic.js +126 -122
  152. package/dist/inbox/types.js +43 -43
  153. package/dist/lib/arrive.js +19 -12
  154. package/dist/lib/icon-types.js +1 -0
  155. package/dist/lib/initials.js +16 -10
  156. package/dist/lib/layout.js +5 -0
  157. package/dist/lib/panel.js +13 -0
  158. package/dist/lib/result.js +22 -22
  159. package/dist/lib/sliding-pill.js +59 -44
  160. package/dist/lib/theme-transition.js +43 -43
  161. package/dist/lib/tone.js +31 -24
  162. package/dist/lib/utils.js +3 -1
  163. package/dist/onboarding/define-tours.js +24 -23
  164. package/dist/onboarding/onboarding.svelte.js +16 -12
  165. package/dist/onboarding/pick.js +10 -6
  166. package/dist/onboarding/stores.js +40 -41
  167. package/dist/onboarding/wait.js +24 -23
  168. package/dist/panel/side-panel-types.js +1 -0
  169. package/dist/record/demo-data.js +459 -486
  170. package/dist/record/fields.js +129 -131
  171. package/dist/record/format.js +70 -82
  172. package/dist/record/gutter.js +1 -0
  173. package/dist/record/kinds.js +95 -105
  174. package/dist/record/logic.js +238 -219
  175. package/dist/record/types.js +49 -48
  176. package/dist/shadcn/accordion/index.js +3 -1
  177. package/dist/shadcn/alert/index.js +3 -1
  178. package/dist/shadcn/alert-dialog/index.js +3 -1
  179. package/dist/shadcn/attachment/index.js +3 -1
  180. package/dist/shadcn/avatar/index.js +3 -1
  181. package/dist/shadcn/breadcrumb/index.js +3 -1
  182. package/dist/shadcn/bubble/index.js +3 -1
  183. package/dist/shadcn/button/index.js +3 -1
  184. package/dist/shadcn/calendar/index.js +3 -1
  185. package/dist/shadcn/card/index.js +3 -1
  186. package/dist/shadcn/checkbox/index.js +3 -1
  187. package/dist/shadcn/code-block/index.js +3 -1
  188. package/dist/shadcn/collapsible/index.js +3 -1
  189. package/dist/shadcn/command/index.js +4 -1
  190. package/dist/shadcn/context-menu/index.js +3 -1
  191. package/dist/shadcn/dialog/index.js +3 -1
  192. package/dist/shadcn/dropdown-menu/menu-item.js +40 -20
  193. package/dist/shadcn/empty/index.js +3 -1
  194. package/dist/shadcn/field/index.js +3 -1
  195. package/dist/shadcn/hooks/highlighter.js +77 -75
  196. package/dist/shadcn/hooks/is-mobile.svelte.js +3 -3
  197. package/dist/shadcn/hooks/use-highlighted-code.svelte.js +62 -62
  198. package/dist/shadcn/input/index.js +3 -1
  199. package/dist/shadcn/kbd/index.js +3 -1
  200. package/dist/shadcn/label/index.js +3 -1
  201. package/dist/shadcn/marker/index.js +3 -1
  202. package/dist/shadcn/message/index.js +3 -1
  203. package/dist/shadcn/message-scroller/index.js +3 -1
  204. package/dist/shadcn/popover/index.js +3 -1
  205. package/dist/shadcn/progress/index.js +3 -1
  206. package/dist/shadcn/progress/tone.js +8 -7
  207. package/dist/shadcn/radio-group/index.js +3 -1
  208. package/dist/shadcn/scroll-area/index.js +3 -1
  209. package/dist/shadcn/select/index.js +3 -1
  210. package/dist/shadcn/separator/index.js +3 -1
  211. package/dist/shadcn/sheet/index.js +3 -1
  212. package/dist/shadcn/sidebar/context.svelte.js +42 -28
  213. package/dist/shadcn/sidebar/index.js +3 -1
  214. package/dist/shadcn/skeleton/index.js +3 -1
  215. package/dist/shadcn/slider/index.js +3 -1
  216. package/dist/shadcn/switch/index.js +3 -1
  217. package/dist/shadcn/table/index.js +3 -1
  218. package/dist/shadcn/tabs/index.js +3 -1
  219. package/dist/shadcn/textarea/index.js +3 -1
  220. package/dist/shadcn/toggle/index.js +3 -1
  221. package/dist/shadcn/toggle-group/index.js +3 -1
  222. package/dist/shadcn/tooltip/context.js +7 -2
  223. package/dist/shadcn/tooltip/index.js +3 -1
  224. package/dist/shadcn/trace/index.js +3 -1
  225. package/dist/slides/bridges.js +65 -59
  226. package/dist/slides/deck-controller.svelte.js +210 -207
  227. package/dist/slides/export/capture.js +66 -71
  228. package/dist/slides/export/ffmpeg.js +76 -72
  229. package/dist/slides/export/index.js +3 -0
  230. package/dist/slides/export/launch.js +9 -6
  231. package/dist/slides/export/pdf.js +60 -54
  232. package/dist/slides/export/types.js +1 -0
  233. package/dist/slides/labels.js +24 -24
  234. package/dist/slides/layout.js +39 -41
  235. package/dist/slides/model.js +9 -7
  236. package/dist/slides/navigation.js +78 -73
  237. package/dist/slides/types.js +2 -2
  238. package/dist/status/define-statuses.js +18 -14
  239. package/dist/status/status-types.js +1 -0
  240. package/dist/test-setup.js +24 -20
  241. package/dist/thread/logic.js +73 -77
  242. package/dist/thread/types.js +21 -21
  243. package/dist/work/board-order.js +94 -90
  244. package/dist/work/dates.js +16 -9
  245. package/dist/work/detail/detail-types.js +18 -18
  246. package/dist/work/docs/edited.js +32 -29
  247. package/dist/work/docs/index.js +4 -0
  248. package/dist/work/docs/labels.js +34 -34
  249. package/dist/work/docs/menu.js +113 -106
  250. package/dist/work/docs/outline.js +39 -29
  251. package/dist/work/gantt/logic.js +211 -235
  252. package/dist/work/inbox/inbox-logic.js +71 -75
  253. package/dist/work/inbox/inbox-statuses.js +75 -72
  254. package/dist/work/inbox/inbox-types.js +1 -0
  255. package/dist/work/kanban-drag.js +27 -22
  256. package/dist/work/kanban-types.js +1 -0
  257. package/dist/work/presets/sales.js +36 -32
  258. package/dist/work/reorder.js +9 -8
  259. package/dist/work/task-types.js +1 -0
  260. package/dist/work/time/duration.js +51 -46
  261. package/dist/work/time/time-types.js +23 -23
  262. package/dist/work/use-kanban-dnd.svelte.js +126 -125
  263. package/package.json +3 -1
  264. package/src/components/list-page/master-detail.svelte +3 -1
  265. package/src/components/list-page/rail-row.svelte +4 -4
  266. package/src/editor/markdown.ts +30 -35
@@ -1,128 +1,129 @@
1
1
  import { boardOrderAt } from "./board-order.js";
2
+ /**
3
+ * A board's drag state and handlers, on native HTML5 drag so a card can leave the board for
4
+ * any drop target a caller wired up.
5
+ */
2
6
  export function createKanbanDnd(config) {
3
- let draggedId = $state(null);
4
- let dragOver = $state(null);
5
- function readDraggedId(e) {
6
- const raw = e.dataTransfer?.getData("text/plain");
7
- if (!raw) return null;
8
- try {
9
- const parsed = JSON.parse(raw);
10
- return parsed.id ?? null;
11
- } catch {
12
- return null;
13
- }
14
- }
15
- function onDragStart(e, id) {
16
- if (e.dataTransfer) {
17
- e.dataTransfer.effectAllowed = "move";
18
- e.dataTransfer.setData("text/plain", JSON.stringify({
19
- id
20
- }));
21
- }
22
- requestAnimationFrame(()=>{
23
- draggedId = id;
24
- });
25
- }
26
- function onItemDragOver(e, columnId, overId, nextId) {
27
- if (config.isDroppable && !config.isDroppable(columnId)) return;
28
- e.preventDefault();
29
- e.stopPropagation();
30
- if (e.dataTransfer) e.dataTransfer.dropEffect = "move";
31
- const rect = e.currentTarget.getBoundingClientRect();
32
- const insertAfter = e.clientY > rect.top + rect.height / 2;
33
- const targetOverId = insertAfter ? nextId : overId;
34
- if (targetOverId === draggedId) return;
35
- if (dragOver?.columnId === columnId && dragOver.overId === targetOverId) return;
36
- dragOver = {
37
- columnId,
38
- overId: targetOverId
39
- };
40
- }
41
- function onColumnDragOver(e, columnId) {
42
- if (config.isDroppable && !config.isDroppable(columnId)) return;
43
- e.preventDefault();
44
- if (e.dataTransfer) e.dataTransfer.dropEffect = "move";
45
- if (dragOver?.columnId !== columnId || dragOver.overId !== null) {
46
- dragOver = {
47
- columnId,
48
- overId: null
49
- };
50
- }
51
- }
52
- function onDragLeave(e) {
53
- if (!e.currentTarget.contains(e.relatedTarget)) {
54
- dragOver = null;
55
- }
56
- }
57
- function clearDragOver() {
58
- dragOver = null;
59
- }
60
- function resetDrag() {
61
- draggedId = null;
62
- dragOver = null;
63
- }
64
- function manualInsertIndex(column, overId, columnId) {
65
- const overIndex = overId ? column.findIndex((item)=>config.getId(item) === overId) : -1;
66
- if (overIndex !== -1) return overIndex;
67
- return config.dropAtTop?.(columnId) ? 0 : column.length;
68
- }
69
- function onDrop(e, targetColumnId) {
70
- e.preventDefault();
71
- if (config.isDroppable && !config.isDroppable(targetColumnId)) return;
72
- const overId = dragOver?.overId ?? null;
73
- dragOver = null;
74
- draggedId = null;
75
- const id = readDraggedId(e);
76
- const item = id ? config.items().find((entry)=>config.getId(entry) === id) : undefined;
77
- if (!item) return;
78
- const movedId = config.getId(item);
79
- if (config.getSortKey() !== "manual") {
80
- if (config.getColumn(item) !== targetColumnId) {
81
- void config.onMove(movedId, {
82
- columnId: targetColumnId
83
- });
84
- }
85
- return;
86
- }
87
- const column = config.getColumnItems(targetColumnId).filter((entry)=>config.getId(entry) !== movedId);
88
- const index = manualInsertIndex(column, overId, targetColumnId);
89
- const before = column[index - 1];
90
- const after = column[index];
91
- const orderOf = config.boardOrder;
92
- void config.onMove(movedId, {
93
- columnId: targetColumnId,
94
- ...orderOf ? {
95
- boardOrder: boardOrderAt(column, index, orderOf)
96
- } : {},
97
- beforeId: before === undefined ? null : config.getId(before),
98
- afterId: after === undefined ? null : config.getId(after)
99
- });
100
- }
101
- return {
102
- get draggedId () {
103
- return draggedId;
104
- },
105
- get dragOver () {
106
- return dragOver;
107
- },
108
- set dragOver (value){
109
- dragOver = value;
110
- },
111
- onDragStart,
112
- onItemDragOver,
113
- onColumnDragOver,
114
- onDragLeave,
115
- onDrop,
116
- clearDragOver,
117
- resetDrag,
118
- isDragSource (id) {
119
- return draggedId === id;
120
- },
121
- showIndicatorBefore (columnId, itemId) {
122
- return dragOver?.columnId === columnId && dragOver.overId === itemId && draggedId !== null;
123
- },
124
- showIndicatorEnd (columnId) {
125
- return dragOver?.columnId === columnId && dragOver.overId === null && draggedId !== null;
126
- }
127
- };
7
+ let draggedId = $state(null);
8
+ let dragOver = $state(null);
9
+ function readDraggedId(e) {
10
+ const raw = e.dataTransfer?.getData("text/plain");
11
+ if (!raw) return null;
12
+ try {
13
+ const parsed = JSON.parse(raw);
14
+ return parsed.id ?? null;
15
+ } catch {
16
+ return null;
17
+ }
18
+ }
19
+ function onDragStart(e, id) {
20
+ if (e.dataTransfer) {
21
+ e.dataTransfer.effectAllowed = "move";
22
+ e.dataTransfer.setData("text/plain", JSON.stringify({ id }));
23
+ }
24
+ // Defer: marking the source during the dragstart event makes some browsers
25
+ // snapshot the faded state instead of the card.
26
+ requestAnimationFrame(() => {
27
+ draggedId = id;
28
+ });
29
+ }
30
+ function onItemDragOver(e, columnId, overId, nextId) {
31
+ if (config.isDroppable && !config.isDroppable(columnId)) return;
32
+ e.preventDefault();
33
+ e.stopPropagation();
34
+ if (e.dataTransfer) e.dataTransfer.dropEffect = "move";
35
+ const rect = e.currentTarget.getBoundingClientRect();
36
+ const insertAfter = e.clientY > rect.top + rect.height / 2;
37
+ const targetOverId = insertAfter ? nextId : overId;
38
+ if (targetOverId === draggedId) return;
39
+ if (dragOver?.columnId === columnId && dragOver.overId === targetOverId) return;
40
+ dragOver = {
41
+ columnId,
42
+ overId: targetOverId
43
+ };
44
+ }
45
+ function onColumnDragOver(e, columnId) {
46
+ if (config.isDroppable && !config.isDroppable(columnId)) return;
47
+ e.preventDefault();
48
+ if (e.dataTransfer) e.dataTransfer.dropEffect = "move";
49
+ if (dragOver?.columnId !== columnId || dragOver.overId !== null) {
50
+ dragOver = {
51
+ columnId,
52
+ overId: null
53
+ };
54
+ }
55
+ }
56
+ function onDragLeave(e) {
57
+ if (!e.currentTarget.contains(e.relatedTarget)) {
58
+ dragOver = null;
59
+ }
60
+ }
61
+ function clearDragOver() {
62
+ dragOver = null;
63
+ }
64
+ function resetDrag() {
65
+ draggedId = null;
66
+ dragOver = null;
67
+ }
68
+ /** Where a manual drop lands: on the hovered card, else the top or the end. */
69
+ function manualInsertIndex(column, overId, columnId) {
70
+ const overIndex = overId ? column.findIndex((item) => config.getId(item) === overId) : -1;
71
+ if (overIndex !== -1) return overIndex;
72
+ return config.dropAtTop?.(columnId) ? 0 : column.length;
73
+ }
74
+ function onDrop(e, targetColumnId) {
75
+ e.preventDefault();
76
+ if (config.isDroppable && !config.isDroppable(targetColumnId)) return;
77
+ const overId = dragOver?.overId ?? null;
78
+ dragOver = null;
79
+ draggedId = null;
80
+ const id = readDraggedId(e);
81
+ const item = id ? config.items().find((entry) => config.getId(entry) === id) : undefined;
82
+ if (!item) return;
83
+ const movedId = config.getId(item);
84
+ if (config.getSortKey() !== "manual") {
85
+ if (config.getColumn(item) !== targetColumnId) {
86
+ void config.onMove(movedId, { columnId: targetColumnId });
87
+ }
88
+ return;
89
+ }
90
+ const column = config.getColumnItems(targetColumnId).filter((entry) => config.getId(entry) !== movedId);
91
+ const index = manualInsertIndex(column, overId, targetColumnId);
92
+ const before = column[index - 1];
93
+ const after = column[index];
94
+ const orderOf = config.boardOrder;
95
+ void config.onMove(movedId, {
96
+ columnId: targetColumnId,
97
+ ...orderOf ? { boardOrder: boardOrderAt(column, index, orderOf) } : {},
98
+ beforeId: before === undefined ? null : config.getId(before),
99
+ afterId: after === undefined ? null : config.getId(after)
100
+ });
101
+ }
102
+ return {
103
+ get draggedId() {
104
+ return draggedId;
105
+ },
106
+ get dragOver() {
107
+ return dragOver;
108
+ },
109
+ set dragOver(value) {
110
+ dragOver = value;
111
+ },
112
+ onDragStart,
113
+ onItemDragOver,
114
+ onColumnDragOver,
115
+ onDragLeave,
116
+ onDrop,
117
+ clearDragOver,
118
+ resetDrag,
119
+ isDragSource(id) {
120
+ return draggedId === id;
121
+ },
122
+ showIndicatorBefore(columnId, itemId) {
123
+ return dragOver?.columnId === columnId && dragOver.overId === itemId && draggedId !== null;
124
+ },
125
+ showIndicatorEnd(columnId) {
126
+ return dragOver?.columnId === columnId && dragOver.overId === null && draggedId !== null;
127
+ }
128
+ };
128
129
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@heyramzi/ui",
3
- "version": "2.11.1",
3
+ "version": "2.11.2",
4
4
  "description": "Svelte 5 UI for apps: primitives, effects and animations, plus work (tasks and docs), charts, slides, an editor, onboarding and a canvas as subpaths.",
5
5
  "homepage": "https://ui.heyramzi.com",
6
6
  "license": "MIT",
@@ -145,6 +145,8 @@
145
145
  "default": "./src/animations/index.css"
146
146
  },
147
147
  "./animations/text-swap": {
148
+ "svelte": "./src/animations/text-swap.ts",
149
+ "types": "./src/animations/text-swap.ts",
148
150
  "node": "./dist/animations/text-swap.js",
149
151
  "default": "./src/animations/text-swap.ts"
150
152
  },
@@ -132,7 +132,9 @@
132
132
  {backLabel}
133
133
  </Button>
134
134
  {/if}
135
- <div class={cn("min-h-0 min-w-0 flex-1", detailClass)}>
135
+ <!-- p-px: a card's edge is a 1px outer shadow, and every caller makes this a
136
+ scroller, which clipped the top edge of a card flush with it. -->
137
+ <div class={cn("min-h-0 min-w-0 flex-1 p-px", detailClass)}>
136
138
  {@render detail()}
137
139
  </div>
138
140
  </div>
@@ -103,9 +103,9 @@
103
103
  class={cn(
104
104
  "t-press flex w-full items-start gap-3 px-4 py-3 text-left any-pointer-coarse:py-3.5",
105
105
  "focus-visible:outline-none focus-visible:ring-3 focus-visible:ring-ring/50 focus-visible:ring-inset",
106
- // WHY: the hover actions sit over this corner, so the text stops short
107
- // of them rather than sliding underneath when a title is long.
108
- actions && "pr-24",
106
+ // Room for the actions only where they always show; a hover-only reserve
107
+ // cost every title 96px. The overlay below sits on its own surface instead.
108
+ actions && "any-pointer-coarse:pr-24",
109
109
  )}
110
110
  onclick={select}
111
111
  aria-current={selected ? "page" : undefined}
@@ -162,7 +162,7 @@
162
162
  <!-- WHY visible on a coarse pointer: there is no hover on a touchscreen, so
163
163
  the row's actions would be unreachable there. -->
164
164
  <div
165
- class="absolute right-2 top-2 hidden items-center gap-1 group-hover:flex group-focus-within:flex any-pointer-coarse:flex"
165
+ class="absolute right-2 top-2 hidden items-center gap-1 rounded-md bg-card shadow-btn group-hover:flex group-focus-within:flex any-pointer-coarse:flex"
166
166
  >
167
167
  {@render actions()}
168
168
  </div>
@@ -62,16 +62,14 @@ export function markdownToTiptap(md: string): TiptapDoc {
62
62
  function parseTokensToBlocks(tokens: Token[]): TiptapNode[] {
63
63
  const blocks: TiptapNode[] = [];
64
64
  let i = 0;
65
- while (i < tokens.length) {
66
- const parse = Object.hasOwn(BLOCK_PARSERS, tokens[i].type)
67
- ? BLOCK_PARSERS[tokens[i].type]
68
- : null;
65
+ for (let tok = tokens[i]; tok; tok = tokens[i]) {
66
+ const parse = Object.hasOwn(BLOCK_PARSERS, tok.type) ? BLOCK_PARSERS[tok.type] : null;
69
67
  // Unknown or unhandled tokens (html_block, etc.) are skipped.
70
68
  if (!parse) {
71
69
  i++;
72
70
  continue;
73
71
  }
74
- const { node, next } = parse(tokens, i);
72
+ const { node, next } = parse(tokens, i, tok);
75
73
  blocks.push(stampId(node));
76
74
  i = next;
77
75
  }
@@ -79,7 +77,7 @@ function parseTokensToBlocks(tokens: Token[]): TiptapNode[] {
79
77
  }
80
78
 
81
79
  type Parsed = { node: TiptapNode; next: number };
82
- type BlockParser = (tokens: Token[], i: number) => Parsed;
80
+ type BlockParser = (tokens: Token[], i: number, tok: Token) => Parsed;
83
81
 
84
82
  function inlineChildrenAt(tokens: Token[], i: number): Token[] {
85
83
  const inlineTok = tokens[i];
@@ -95,7 +93,8 @@ function orderedStart(tok: Token): number {
95
93
  function parseParagraph(tokens: Token[], i: number): Parsed {
96
94
  const children = inlineChildrenAt(tokens, i + 1);
97
95
  // A lone image with a YouTube src becomes a `youtube` block.
98
- const youtube = children.length === 1 ? imageTokenToYoutubeNode(children[0]) : null;
96
+ const [only, ...rest] = children;
97
+ const youtube = only && !rest.length ? imageTokenToYoutubeNode(only) : null;
99
98
  const node = youtube ?? {
100
99
  type: "paragraph",
101
100
  attrs: { id: null },
@@ -104,14 +103,13 @@ function parseParagraph(tokens: Token[], i: number): Parsed {
104
103
  return { node, next: i + 3 };
105
104
  }
106
105
 
107
- function parseHeading(tokens: Token[], i: number): Parsed {
108
- const level = headingLevel(tokens[i].markup);
106
+ function parseHeading(tokens: Token[], i: number, tok: Token): Parsed {
107
+ const level = headingLevel(tok.markup);
109
108
  const content = parseInlineChildren(inlineChildrenAt(tokens, i + 1));
110
109
  return { node: { type: "heading", attrs: { level, id: null }, content }, next: i + 3 };
111
110
  }
112
111
 
113
- function parseFence(tokens: Token[], i: number): Parsed {
114
- const tok = tokens[i];
112
+ function parseFence(_tokens: Token[], i: number, tok: Token): Parsed {
115
113
  const lang = tok.info.trim() || null;
116
114
  const code = tok.content.endsWith("\n") ? tok.content.slice(0, -1) : tok.content;
117
115
  const node = {
@@ -136,8 +134,8 @@ function parseBulletList(tokens: Token[], i: number): Parsed {
136
134
  return { node, next: next + 1 };
137
135
  }
138
136
 
139
- function parseOrderedList(tokens: Token[], i: number): Parsed {
140
- const start = orderedStart(tokens[i]);
137
+ function parseOrderedList(tokens: Token[], i: number, tok: Token): Parsed {
138
+ const start = orderedStart(tok);
141
139
  const { inner, next } = collectUntilClose(tokens, i + 1, "ordered_list");
142
140
  const node = { type: "orderedList", attrs: { id: null, start }, content: parseListItems(inner) };
143
141
  return { node, next: next + 1 };
@@ -163,21 +161,20 @@ function collectUntilClose(
163
161
  const openType = `${type}_open`;
164
162
  const closeType = `${type}_close`;
165
163
  let depth = 1;
166
- let i = start;
167
164
 
168
- while (i < tokens.length) {
169
- if (tokens[i].type === openType) depth++;
170
- else if (tokens[i].type === closeType) {
165
+ for (let i = start; i < tokens.length; i++) {
166
+ const type = tokens[i]?.type;
167
+ if (type === openType) depth++;
168
+ else if (type === closeType) {
171
169
  depth--;
172
170
  if (depth === 0) {
173
171
  return { inner: tokens.slice(start, i), next: i };
174
172
  }
175
173
  }
176
- i++;
177
174
  }
178
175
 
179
176
  // Unclosed block: return everything remaining.
180
- return { inner: tokens.slice(start), next: i };
177
+ return { inner: tokens.slice(start), next: tokens.length };
181
178
  }
182
179
 
183
180
  // Parse list_item_open ... list_item_close pairs into listItem nodes.
@@ -185,8 +182,8 @@ function parseListItems(tokens: Token[]): TiptapNode[] {
185
182
  const items: TiptapNode[] = [];
186
183
  let i = 0;
187
184
 
188
- while (i < tokens.length) {
189
- if (tokens[i].type === "list_item_open") {
185
+ for (let tok = tokens[i]; tok; tok = tokens[i]) {
186
+ if (tok.type === "list_item_open") {
190
187
  const { inner, next } = collectUntilClose(tokens, i + 1, "list_item");
191
188
  items.push(parseListItemContent(inner));
192
189
  i = next + 1;
@@ -204,8 +201,7 @@ function parseListItemContent(tokens: Token[]): TiptapNode {
204
201
  const content: TiptapNode[] = [];
205
202
  let i = 0;
206
203
 
207
- while (i < tokens.length) {
208
- const tok = tokens[i];
204
+ for (let tok = tokens[i]; tok; tok = tokens[i]) {
209
205
  if (tok.type === "paragraph_open") {
210
206
  content.push({
211
207
  type: "paragraph",
@@ -213,7 +209,8 @@ function parseListItemContent(tokens: Token[]): TiptapNode {
213
209
  });
214
210
  i += 3;
215
211
  } else if (tok.type === "bullet_list_open" || tok.type === "ordered_list_open") {
216
- const { node, next } = BLOCK_PARSERS[tok.type](tokens, i);
212
+ const parse = tok.type === "bullet_list_open" ? parseBulletList : parseOrderedList;
213
+ const { node, next } = parse(tokens, i, tok);
217
214
  content.push(stripId(node));
218
215
  i = next;
219
216
  } else {
@@ -294,12 +291,8 @@ const INLINE_HANDLERS: Record<string, InlineHandler> = {
294
291
  };
295
292
 
296
293
  function removeLastMark(stack: TiptapMark[], type: string): void {
297
- for (let i = stack.length - 1; i >= 0; i--) {
298
- if (stack[i].type === type) {
299
- stack.splice(i, 1);
300
- return;
301
- }
302
- }
294
+ const i = stack.findLastIndex((mark) => mark.type === type);
295
+ if (i >= 0) stack.splice(i, 1);
303
296
  }
304
297
 
305
298
  function headingLevel(markup: string): number {
@@ -406,12 +399,13 @@ function tableToMd(node: TiptapNode): string {
406
399
  .replace(/\|/g, "\\|"),
407
400
  ),
408
401
  );
409
- if (rows.length === 0) return "";
402
+ const [header, ...body] = rows;
403
+ if (!header) return "";
410
404
  const width = Math.max(...rows.map((row) => row.length));
411
405
  const line = (cells: string[]) =>
412
406
  `| ${Array.from({ length: width }, (_, i) => cells[i] ?? "").join(" | ")} |`;
413
407
  const rule = `| ${Array.from({ length: width }, () => "---").join(" | ")} |`;
414
- return [line(rows[0]), rule, ...rows.slice(1).map(line)].join("\n");
408
+ return [line(header), rule, ...body.map(line)].join("\n");
415
409
  }
416
410
 
417
411
  const MD_WRITERS: Record<string, MdWriter> = {
@@ -441,8 +435,8 @@ const MD_WRITERS: Record<string, MdWriter> = {
441
435
  };
442
436
 
443
437
  function nodeToMd(node: TiptapNode, listDepth: number): string {
444
- if (Object.hasOwn(MD_WRITERS, node.type)) return MD_WRITERS[node.type](node, listDepth);
445
- return childrenToMd(node, listDepth);
438
+ const write = Object.hasOwn(MD_WRITERS, node.type) ? MD_WRITERS[node.type] : null;
439
+ return write ? write(node, listDepth) : childrenToMd(node, listDepth);
446
440
  }
447
441
 
448
442
  function listItemToMd(item: TiptapNode, bullet: string, depth: number): string {
@@ -487,7 +481,8 @@ const MARK_WRAPS: Record<string, (text: string) => string> = {
487
481
  // A code span keeps its raw text verbatim and replaces whatever was wrapped before it.
488
482
  function applyMark(text: string, mark: TiptapMark, raw: string): string {
489
483
  if (mark.type === "code") return `\`${raw}\``;
490
- return Object.hasOwn(MARK_WRAPS, mark.type) ? MARK_WRAPS[mark.type](text) : text;
484
+ const wrap = Object.hasOwn(MARK_WRAPS, mark.type) ? MARK_WRAPS[mark.type] : null;
485
+ return wrap ? wrap(text) : text;
491
486
  }
492
487
 
493
488
  function inlineTextToMd(node: TiptapNode): string {