hazo_ui 6.3.1 → 6.5.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.
- package/CHANGE_LOG.md +85 -0
- package/README.md +42 -0
- package/dist/index.cjs +371 -73
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +83 -4
- package/dist/index.d.ts +83 -4
- package/dist/index.js +372 -74
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
package/CHANGE_LOG.md
CHANGED
|
@@ -5,6 +5,91 @@ All notable changes to this project will be documented in this file.
|
|
|
5
5
|
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
|
6
6
|
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
7
7
|
|
|
8
|
+
## v6.5.0 (2026-08-02)
|
|
9
|
+
|
|
10
|
+
### Added — swimlanes for `HazoUiKanban`
|
|
11
|
+
|
|
12
|
+
A board can now declare `lanes`, rendering one full-width row per lane —
|
|
13
|
+
a wide lane heading, then that lane's own copy of the whole column grid. Where
|
|
14
|
+
`sections` (v6.4.0) group *within* a column, lanes group *across* all of them,
|
|
15
|
+
so the second axis can be the row axis instead of the inner one.
|
|
16
|
+
|
|
17
|
+
- `HazoUiKanbanProps.lanes?: KanbanLane[]` — `{ key, title, accepts?,
|
|
18
|
+
collapseWhenEmpty? }`. Cards are placed by the new `KanbanItem.laneKey`.
|
|
19
|
+
Omit `lanes` and nothing changes: existing boards render exactly as before.
|
|
20
|
+
- `KanbanMoveEvent` gained `fromLane`/`toLane`; `KanbanReorderEvent` gained
|
|
21
|
+
`laneKey`. Move-vs-reorder is now decided on all three axes — same column,
|
|
22
|
+
section *and* lane is a reorder; changing any one is a move.
|
|
23
|
+
- **A lane heading is the lane-only drop target.** It carries a lane but no
|
|
24
|
+
column, read as "change the lane, keep the card's column" — the mirror of a
|
|
25
|
+
sectioned column's head ("change the column, keep the section").
|
|
26
|
+
- `collapseWhenEmpty` renders a lane with no cards as a thin full-width dashed
|
|
27
|
+
strip, which is what makes "declare every lane" affordable for a long
|
|
28
|
+
vocabulary. A card whose `laneKey` matches no declared lane renders in an
|
|
29
|
+
unlabelled trailing lane rather than disappearing.
|
|
30
|
+
- The optimistic overlay tracks the destination lane too, so a cross-lane drop
|
|
31
|
+
moves immediately instead of snapping back until the consumer's async commit
|
|
32
|
+
lands.
|
|
33
|
+
|
|
34
|
+
### Fixed — drops landed in the wrong column on tall or scrolled boards
|
|
35
|
+
|
|
36
|
+
Two long-standing defects in drop resolution, both of which lanes made
|
|
37
|
+
impossible to miss:
|
|
38
|
+
|
|
39
|
+
- **Collision detection is now pointer-first** (`pointerWithin`, falling back
|
|
40
|
+
to `rectIntersection`, then `closestCorners`). `closestCorners` alone
|
|
41
|
+
averages the distance to all four corners, so a column stretched tall by a
|
|
42
|
+
neighbour's card stack scored *worse* than a short, far-away column — a drop
|
|
43
|
+
well inside the right column could resolve to a different one entirely.
|
|
44
|
+
Keyboard drags have no pointer and take the same fallbacks as before.
|
|
45
|
+
- **Droppable ids are scoped per layout tree.** The mobile tab strip and the
|
|
46
|
+
desktop grid both always render (CSS hides one), so every column previously
|
|
47
|
+
registered twice under one id. dnd-kit keys its registry by id, so one node
|
|
48
|
+
won and collisions were measured against the CSS-hidden copy's 0×0 rect.
|
|
49
|
+
Ids now carry the tree ("m"/"d") and, on a laned board, the lane.
|
|
50
|
+
|
|
51
|
+
## v6.4.0 (2026-08-01)
|
|
52
|
+
|
|
53
|
+
### Added — in-column sections for `HazoUiKanban`
|
|
54
|
+
|
|
55
|
+
A kanban column can now declare `sections`, splitting its body into
|
|
56
|
+
separator-headed bands so a board can group on two axes at once (e.g. status
|
|
57
|
+
across, tag down) without a mode toggle between them.
|
|
58
|
+
|
|
59
|
+
- `KanbanColumn.sections?: KanbanSection[]` — `{ key, title, accepts?,
|
|
60
|
+
collapseWhenEmpty? }`. Cards are placed by the new
|
|
61
|
+
`KanbanItem.sectionKey`. Omit `sections` and nothing changes: existing
|
|
62
|
+
boards render exactly as before.
|
|
63
|
+
- Each band is its own droppable, so a single drop expresses both column and
|
|
64
|
+
section. `KanbanMoveEvent` gained `fromSection`/`toSection`, and
|
|
65
|
+
`KanbanReorderEvent` gained `sectionKey`.
|
|
66
|
+
- Move-vs-reorder is now decided on both axes — same column *and* same
|
|
67
|
+
section is a reorder; changing either is a move. Unsectioned boards have
|
|
68
|
+
`undefined` on both sides, so this collapses to the previous behaviour.
|
|
69
|
+
- On a sectioned column the **header becomes a droppable** carrying the
|
|
70
|
+
column but no section — the status-only drop target ("move column, keep
|
|
71
|
+
section"). Required, not cosmetic: section bands cover the column body and
|
|
72
|
+
win every `closestCorners` contest, so without it a sectioned column has no
|
|
73
|
+
reachable spot that isn't a band. Unsectioned columns keep an inert header.
|
|
74
|
+
- `collapseWhenEmpty` renders a section with no cards as a thin dashed drop
|
|
75
|
+
strip at the foot of the column. This is what makes "declare every section
|
|
76
|
+
in every column" practical for a long vocabulary: every section stays a
|
|
77
|
+
drop target without filling the column with empty headers.
|
|
78
|
+
- The optimistic overlay tracks the destination section too, so a
|
|
79
|
+
same-column cross-section drop moves immediately rather than snapping back
|
|
80
|
+
until the consumer's async commit lands.
|
|
81
|
+
- Dropping on a column's own padding leaves the card's section alone; a card
|
|
82
|
+
whose `sectionKey` matches no declared section renders in an unlabelled
|
|
83
|
+
trailing group rather than disappearing.
|
|
84
|
+
|
|
85
|
+
New styling hooks (no new CSS variables): `cls_hazo_kanban_section`,
|
|
86
|
+
`_section_head`, `_section_title`, `_section_rule`, `_section_count`,
|
|
87
|
+
`_section_body`, `_section_empty`, `_section_over`, `_section_strips`,
|
|
88
|
+
`cls_hazo_kanban_column_head_over`,
|
|
89
|
+
`_section_strip`, `_section_strip_over`, `_section_unmatched`.
|
|
90
|
+
|
|
91
|
+
Demo: test-app `/kanban` §10.
|
|
92
|
+
|
|
8
93
|
## v6.3.1 (2026-07-29)
|
|
9
94
|
|
|
10
95
|
### Fixed — test-app builds again
|
package/README.md
CHANGED
|
@@ -3677,6 +3677,48 @@ function Actions({ initial }) {
|
|
|
3677
3677
|
event carries `revert()` — call it when your API request fails and the
|
|
3678
3678
|
overlay snaps back to whatever `items` says.
|
|
3679
3679
|
|
|
3680
|
+
### Grouping: sections (v6.4.0) and swimlanes (v6.5.0)
|
|
3681
|
+
|
|
3682
|
+
A board can group on a second axis, either *inside* each column or *across*
|
|
3683
|
+
all of them. Both are opt-in; omit them and the board is a plain column grid.
|
|
3684
|
+
|
|
3685
|
+
```tsx
|
|
3686
|
+
// Sections: separator-headed bands inside each column, keyed by item.sectionKey
|
|
3687
|
+
<HazoUiKanban
|
|
3688
|
+
columns={COLUMNS.map(col => ({
|
|
3689
|
+
...col,
|
|
3690
|
+
sections: TAGS.map(t => ({ key: t, title: t, collapseWhenEmpty: true })),
|
|
3691
|
+
}))}
|
|
3692
|
+
items={items.map(it => ({ ...it, sectionKey: it.tag }))}
|
|
3693
|
+
onMove={(e) => save(e.itemId, { column: e.toColumn, tag: e.toSection })}
|
|
3694
|
+
renderCard={renderCard}
|
|
3695
|
+
/>
|
|
3696
|
+
|
|
3697
|
+
// Swimlanes: one full-width row per lane, each with its own column grid,
|
|
3698
|
+
// keyed by item.laneKey
|
|
3699
|
+
<HazoUiKanban
|
|
3700
|
+
columns={COLUMNS}
|
|
3701
|
+
lanes={TAGS.map(t => ({ key: t, title: t, collapseWhenEmpty: true }))}
|
|
3702
|
+
items={items.map(it => ({ ...it, laneKey: it.tag }))}
|
|
3703
|
+
onMove={(e) => save(e.itemId, { column: e.toColumn, tag: e.toLane })}
|
|
3704
|
+
renderCard={renderCard}
|
|
3705
|
+
/>
|
|
3706
|
+
```
|
|
3707
|
+
|
|
3708
|
+
| | Sections | Lanes |
|
|
3709
|
+
|---|---|---|
|
|
3710
|
+
| Declared on | `KanbanColumn.sections` | `HazoUiKanbanProps.lanes` |
|
|
3711
|
+
| Card placed by | `KanbanItem.sectionKey` | `KanbanItem.laneKey` |
|
|
3712
|
+
| Renders as | bands stacked inside one column | full-width rows, each with the whole column grid |
|
|
3713
|
+
| Move event carries | `fromSection`/`toSection` | `fromLane`/`toLane` |
|
|
3714
|
+
| "Keep the other axis" drop target | the column head | the lane heading |
|
|
3715
|
+
| `collapseWhenEmpty` | thin drop strip at the column's foot | full-width drop strip |
|
|
3716
|
+
|
|
3717
|
+
A drop expresses both axes at once, so one gesture can change status and tag
|
|
3718
|
+
together. `accepts(item)` on a column, section or lane rejects a drop into it.
|
|
3719
|
+
Cards whose key matches nothing declared render in an unlabelled trailing
|
|
3720
|
+
group (sections) or lane row (lanes) rather than disappearing.
|
|
3721
|
+
|
|
3680
3722
|
### Theming (CSS custom properties)
|
|
3681
3723
|
|
|
3682
3724
|
| Variable | Default | Purpose |
|