@umriss-ui/schedule 0.1.8 → 0.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.
- package/CHANGELOG.md +110 -0
- package/README.md +52 -26
- package/dist/index.d.ts +203 -146
- package/dist/schedule.css +1 -1
- package/dist/schedule.js +1353 -942
- package/docs/llms-full.md +6304 -0
- package/package.json +8 -7
package/CHANGELOG.md
CHANGED
|
@@ -15,6 +15,116 @@ moves from here under the rule above.
|
|
|
15
15
|
|
|
16
16
|
---
|
|
17
17
|
|
|
18
|
+
## 0.3.0 – Dependencies and blocked time (Sep. 2026)
|
|
19
|
+
|
|
20
|
+
Needs `@umriss-ui/core` 0.11 and `@umriss-ui/charts` 0.8: it reads the renamed wording keys, the new ones for blocked time, and the charts' working-time functions; the peer ranges move to `^0.11.0` and `^0.8.0`.
|
|
21
|
+
|
|
22
|
+
### Added
|
|
23
|
+
|
|
24
|
+
- **Blocked time per lane.** `<BlockedTimes data={…} />` takes a list of
|
|
25
|
+
`BlockedTime` — `{ id, lane, from, to, label? }`, plain data keyed by lane
|
|
26
|
+
like a subtask — for leave, maintenance and any other time a lane is not
|
|
27
|
+
available. It is drawn hatched behind all the work on the lane, in forced
|
|
28
|
+
colours too, wherever the layer is declared.
|
|
29
|
+
- **A finding: a subtask in blocked time.** `inBlockedTime(subtasks, blocked)`
|
|
30
|
+
returns every subtask that covers blocked time on its lane (lead-in and
|
|
31
|
+
lead-out included) as `InBlockedTime` — `{ subtask, blocked, lane, from, to }`.
|
|
32
|
+
`findings()` takes the blocked time as an optional third argument, and
|
|
33
|
+
`Findings` has the field `inBlockedTime`. The schedule marks the covered time
|
|
34
|
+
like an overlap; the tooltip and the keys' readout name it ("In blocked time
|
|
35
|
+
(Leave)"), and the plot's description counts it where there is any.
|
|
36
|
+
`ScheduleTooltipTarget` of kind `"subtask"` carries `blocked`, the blocked
|
|
37
|
+
times the subtask covers.
|
|
38
|
+
- **Blocked time is part of where a subtask may go.** A drag — inside the plot
|
|
39
|
+
or from outside — does not put work into blocked time it did not already
|
|
40
|
+
cover: the ghost stays where it was allowed, the cursor says no, a line ties
|
|
41
|
+
the ghost to the pointer, and its label says "Blocked time" (`data-blocked`
|
|
42
|
+
on the ghost label). Alt with an arrow key steps over blocked time instead of
|
|
43
|
+
into it; Alt+Shift does not stretch into it. Work the data already put there
|
|
44
|
+
is never locked in.
|
|
45
|
+
- A demo page, *Blocked time*.
|
|
46
|
+
|
|
47
|
+
### Changed
|
|
48
|
+
|
|
49
|
+
- **Neutral names for the schedule's terms** (ADR-0035). The schedule is for
|
|
50
|
+
any plan of work on lanes, and its names said "plant": a transport is now a
|
|
51
|
+
**dependency** with a **lag**, setup and teardown are **lead-in** and
|
|
52
|
+
**lead-out**, and a late transport is a **violated dependency** — with every
|
|
53
|
+
name built on them. One hard cut, no deprecated aliases. What the terms do is
|
|
54
|
+
unchanged: a dependency still joins two subtasks of one task, from an end to
|
|
55
|
+
a start, and its anchors decide whether it is violated. `]`/`[` and `t`/Shift+T
|
|
56
|
+
still walk along it. The tooltip, the ghost, the readout and the summary say
|
|
57
|
+
"Lead-in", "Lead-out", "Dependency" and "Violated dependency" (German
|
|
58
|
+
"Vorlauf", "Nachlauf", "Abhängigkeit", "Abhängigkeit verletzt").
|
|
59
|
+
|
|
60
|
+
| Before | Now |
|
|
61
|
+
|---|---|
|
|
62
|
+
| `Subtask.setup` | `Subtask.leadIn` |
|
|
63
|
+
| `Subtask.teardown` | `Subtask.leadOut` |
|
|
64
|
+
| `PlaceIntent.setup`, `.teardown` | `PlaceIntent.leadIn`, `.leadOut` |
|
|
65
|
+
| `PlacingItem.setup`, `.teardown` | `PlacingItem.leadIn`, `.leadOut` |
|
|
66
|
+
| `SetupIntent` (`kind: "setup"`, field `setup`) | `LeadInIntent` (`kind: "leadIn"`, field `leadIn`) |
|
|
67
|
+
| `TeardownIntent` (`kind: "teardown"`, field `teardown`) | `LeadOutIntent` (`kind: "leadOut"`, field `leadOut`) |
|
|
68
|
+
| `"setup"`, `"teardown"` in `intents` | `"leadIn"`, `"leadOut"` |
|
|
69
|
+
| `Transport` | `Dependency` |
|
|
70
|
+
| `Transport.duration` | `Dependency.lag` |
|
|
71
|
+
| `leaves: "teardown"` (the default) | `leaves: "leadOut"` |
|
|
72
|
+
| `arrives: "setup"` (the default) | `arrives: "leadIn"` |
|
|
73
|
+
| `TransportRoute`, `TransportAttachment`, `TransportEnds` | `DependencyRoute`, `DependencyAttachment`, `DependencyEnds` |
|
|
74
|
+
| `<Transports>`, `TransportsProps` | `<Dependencies>`, `DependenciesProps` |
|
|
75
|
+
| `LateTransport` (field `transport`) | `ViolatedDependency` (field `dependency`) |
|
|
76
|
+
| `lateTransports()` | `violatedDependencies()` |
|
|
77
|
+
| `Findings.lateTransports` | `Findings.violatedDependencies` |
|
|
78
|
+
| `ScheduleTooltipTarget`: `kind: "transport"`, `transport`, `late`; `lateTransports` | `kind: "dependency"`, `dependency`, `violated`; `violatedDependencies` |
|
|
79
|
+
| `ScheduleHit`: `kind: "transport"`, `transport`; `part: "setup" \| "teardown"` | `kind: "dependency"`, `dependency`; `part: "leadIn" \| "leadOut"` |
|
|
80
|
+
| ghost `data-findings` value `late-transport` | `violated-dependency` |
|
|
81
|
+
| grip `data-grip` values `setup`, `teardown` | `leadIn`, `leadOut` |
|
|
82
|
+
|
|
83
|
+
---
|
|
84
|
+
|
|
85
|
+
## 0.2.0 – By keyboard and screen reader (Sep. 2026)
|
|
86
|
+
|
|
87
|
+
Needs `@umriss-ui/core` 0.10 and `@umriss-ui/charts` 0.7: it reads the schedule's wording keys; the peer ranges move to `^0.10.0` and `^0.7.0`.
|
|
88
|
+
|
|
89
|
+
### Added
|
|
90
|
+
|
|
91
|
+
- **The Windows contrast mode** (`forced-colors: active`, forced-colors 03).
|
|
92
|
+
The browser forces the page around the plot and none of its pixels, so the
|
|
93
|
+
plot paints itself in the system colours, as the charts do: the work in the
|
|
94
|
+
text colour, lines in `GrayText`, and the selection colour kept for the
|
|
95
|
+
**Active subtask** alone, as an outline around its bar. Overlaps and late
|
|
96
|
+
transports are drawn in the text colour and dashed, the present in
|
|
97
|
+
`GrayText`. The frame, the tooltip, the grips and the ghost's label keep an
|
|
98
|
+
edge. Nothing changes outside forced colours.
|
|
99
|
+
- **`docs/llms-full.md`**, the package's documentation as one Markdown file for
|
|
100
|
+
a coding agent, in the npm package and pinned to its version: every demo page
|
|
101
|
+
with its import line, its examples' source, its props tables and why it is
|
|
102
|
+
built as it is, and the declaration of every other export. The same text
|
|
103
|
+
stands online as <https://romanhaendler.github.io/umriss-ui/schedule/llms-full.txt>,
|
|
104
|
+
with an index of the pages beside it (`llms.txt`).
|
|
105
|
+
- **The schedule by keyboard and screen reader** (schedule-a11y, ADR-0030's
|
|
106
|
+
pattern; ADR-0033 where it departs from it). The plot is one tab stop (`role="application"`, role description
|
|
107
|
+
"schedule", the schedule's `ariaLabel`) with an **Active subtask**: ←/→ walk
|
|
108
|
+
a lane in time order, ↑/↓ go to the nearest subtask on the lane above or
|
|
109
|
+
below (a folded group is one row), Home/End to the lane's first and last,
|
|
110
|
+
PageUp/PageDown by a tenth of the view. `]` or `t` follows a transport out
|
|
111
|
+
from its subtask and on to the next stop, `[` or Shift+T goes back - `t`
|
|
112
|
+
because a German keyboard reaches the brackets only with AltGr. The view
|
|
113
|
+
pans and scrolls to bring the active subtask into it. The active subtask is drawn and tooltipped
|
|
114
|
+
as the hover is; the pointer takes it over by moving, and keys walk on from
|
|
115
|
+
the pointer's.
|
|
116
|
+
- **Space and Enter select** the active subtask's task, reported through
|
|
117
|
+
`onSelectedTaskChange` as a click is.
|
|
118
|
+
- **Editing by key**: Alt+←/→ proposes a move by one step of the snap raster,
|
|
119
|
+
Alt+Shift+←/→ a new end - the same `move` and `stretch` intents a drag of that
|
|
120
|
+
length reports, and only where `intents` lists them.
|
|
121
|
+
- **What a screen reader hears**: once the keys rest (150 ms), a polite readout
|
|
122
|
+
of the lane, the task, the subtask, its day and times and every finding by
|
|
123
|
+
name; never after the pointer. The plot is described by a summary - lanes,
|
|
124
|
+
subtasks in view, the visible span, the plan's overlaps and late transports -
|
|
125
|
+
and the key help. New wording entries in `@umriss-ui/core`, English and
|
|
126
|
+
German: `scheduleRoleDescription`, `scheduleSummary`, `scheduleKeyHelp`.
|
|
127
|
+
|
|
18
128
|
## 0.1.8 – Core 0.9.0 (Sep. 2026)
|
|
19
129
|
|
|
20
130
|
Admits `@umriss-ui/core` 0.9, which only adds a token; the peer range moves to `^0.9.0`. Nothing else changes.
|
package/README.md
CHANGED
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
# @umriss-ui/schedule
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
across several
|
|
5
|
-
|
|
6
|
-
**
|
|
7
|
-
|
|
8
|
-
|
|
3
|
+
Work planned over time: **subtasks** on **lanes** — people, vehicles, rooms or
|
|
4
|
+
machines. One task runs across several lanes in a fixed order, each stop has a
|
|
5
|
+
main time with a lead-in before it and a lead-out after it, between the stops
|
|
6
|
+
lie **dependencies** with lags of their own, and a lane can be **blocked** for
|
|
7
|
+
leave or maintenance. The schedule draws all of it, marks what cannot work —
|
|
8
|
+
two subtasks on one lane at once, a dependency whose lag does not fit, work in
|
|
9
|
+
blocked time — and lets a planner move things by hand without ever changing
|
|
9
10
|
the plan underneath them.
|
|
10
11
|
|
|
11
12
|
## Install
|
|
@@ -17,30 +18,30 @@ pnpm add @umriss-ui/schedule @umriss-ui/core @umriss-ui/charts
|
|
|
17
18
|
Both `@umriss-ui/core` and `@umriss-ui/charts` are **peer dependencies**
|
|
18
19
|
(ADR-0022): the schedule takes its styling regime, provider, formats and
|
|
19
20
|
wording from core, and its time arithmetic — the affine scale, the time steps,
|
|
20
|
-
the
|
|
21
|
+
the working calendar, the canvas colour resolution — from charts. React 18 or
|
|
21
22
|
19 as a peer as well.
|
|
22
23
|
|
|
23
24
|
## The smallest schedule that runs
|
|
24
25
|
|
|
25
26
|
```tsx
|
|
26
|
-
import { Lane, Schedule, Subtasks,
|
|
27
|
-
import type { Subtask, Task,
|
|
27
|
+
import { Lane, Schedule, Subtasks, Dependencies } from "@umriss-ui/schedule";
|
|
28
|
+
import type { Subtask, Task, Dependency } from "@umriss-ui/schedule";
|
|
28
29
|
|
|
29
30
|
const at = (h: number, m = 0) => new Date(2026, 2, 17, h, m).getTime();
|
|
30
31
|
|
|
31
32
|
const tasks: Task[] = [{ id: "a-2041", color: "#2563eb" }];
|
|
32
33
|
const subtasks: Subtask[] = [
|
|
33
|
-
{ id: "cut", task: "a-2041", lane: "saw", from: at(6), to: at(7),
|
|
34
|
-
{ id: "mill", task: "a-2041", lane: "mill", from: at(8), to: at(10),
|
|
34
|
+
{ id: "cut", task: "a-2041", lane: "saw", from: at(6), to: at(7), leadOut: 10 * 60_000 },
|
|
35
|
+
{ id: "mill", task: "a-2041", lane: "mill", from: at(8), to: at(10), leadIn: 30 * 60_000 },
|
|
35
36
|
];
|
|
36
|
-
const
|
|
37
|
+
const dependencies: Dependency[] = [{ id: "move", from: "cut", to: "mill", lag: 15 * 60_000 }];
|
|
37
38
|
|
|
38
39
|
export function Plan() {
|
|
39
40
|
return (
|
|
40
41
|
<Schedule ariaLabel="Plan of Tuesday" initialDomain={[at(5), at(12)]}>
|
|
41
42
|
<Lane id="saw" label="Saw" />
|
|
42
43
|
<Lane id="mill" label="Mill" />
|
|
43
|
-
<
|
|
44
|
+
<Dependencies data={dependencies} />
|
|
44
45
|
<Subtasks data={subtasks} tasks={tasks} />
|
|
45
46
|
</Schedule>
|
|
46
47
|
);
|
|
@@ -51,7 +52,7 @@ export function Plan() {
|
|
|
51
52
|
|
|
52
53
|
The schedule draws the data it is given and changes none of it (ADR-0023). A
|
|
53
54
|
drag shows a **ghost** with the findings the drop would create, and ends in an
|
|
54
|
-
**intent** — move, lane, stretch,
|
|
55
|
+
**intent** — move, lane, stretch, lead-in, lead-out — reported to the caller:
|
|
55
56
|
|
|
56
57
|
```tsx
|
|
57
58
|
<Schedule
|
|
@@ -65,12 +66,12 @@ drag shows a **ghost** with the findings the drop would create, and ends in an
|
|
|
65
66
|
read-only. `canMoveTo(subtask, lane)` narrows it: a drag across a lane the
|
|
66
67
|
subtask may not go to leaves the ghost where it was allowed and shows a
|
|
67
68
|
refusal, and a refused drop reports nothing. A drag near the edge of the plot pans the plot along, and `snap`
|
|
68
|
-
takes the tick raster, a step, or a step with an offset -
|
|
69
|
+
takes the tick raster, a step, or a step with an offset - handovers at 06:00,
|
|
69
70
|
14:00 and 22:00 are eight hours offset by six.
|
|
70
71
|
|
|
71
72
|
Dependent subtasks never move by themselves: `ripple` computes the cascade for
|
|
72
|
-
the application to apply, or not, and `shiftTask` the moves of a whole
|
|
73
|
-
`findings`, `overlaps` and `
|
|
73
|
+
the application to apply, or not, and `shiftTask` the moves of a whole task.
|
|
74
|
+
`findings`, `overlaps` and `violatedDependencies` return what the schedule draws as
|
|
74
75
|
data.
|
|
75
76
|
|
|
76
77
|
Work that is not on the plan is dragged in from any list of the application,
|
|
@@ -84,7 +85,7 @@ subtask under the application's own id.
|
|
|
84
85
|
left out where nothing would be readable. `appearance` adds what a colour
|
|
85
86
|
cannot say - `"provisional"`, `"fixed"`, `"muted"`, `"open"` - and `progress`
|
|
86
87
|
draws the share that is done as a rail along the bar. `route`, `anchor` and
|
|
87
|
-
`ends` decide how a
|
|
88
|
+
`ends` decide how a dependency is drawn, per schedule or per dependency, without
|
|
88
89
|
touching what a finding says.
|
|
89
90
|
|
|
90
91
|
Each appearance owns exactly **one** property of the drawing, so several on one
|
|
@@ -92,12 +93,12 @@ bar stay several statements: `"provisional"` the fill (none at all, the surface
|
|
|
92
93
|
shows through), `"fixed"` the ends (a cap inside each), `"muted"` the
|
|
93
94
|
saturation (the task colour half mixed into the surface, at full height), and
|
|
94
95
|
`"open"` a fade at whichever edge of the view the bar passes. `progress` owns a
|
|
95
|
-
rail inside the main time. The faint, outlined fill belongs to a
|
|
96
|
-
|
|
96
|
+
rail inside the main time. The faint, outlined fill belongs to a lead-in and a
|
|
97
|
+
lead-out and to nothing else.
|
|
97
98
|
|
|
98
99
|
## Lanes that fold
|
|
99
100
|
|
|
100
|
-
`<LaneGroup>` puts
|
|
101
|
+
`<LaneGroup>` puts teams, depots or regions over the lanes, to any
|
|
101
102
|
depth. A group is structure and never a lane: nothing sits on it, no finding is
|
|
102
103
|
reported for it, and no intent names it (ADR-0025).
|
|
103
104
|
|
|
@@ -112,7 +113,7 @@ reported for it, and no intent names it (ADR-0025).
|
|
|
112
113
|
```
|
|
113
114
|
|
|
114
115
|
Folded, a group becomes one row showing a **miniature** — every lane in it as a
|
|
115
|
-
thin strip, the real work smaller.
|
|
116
|
+
thin strip, the real work smaller. Dependencies still arrive at the right strip,
|
|
116
117
|
findings are still marked, and a strip can still be hovered and selected:
|
|
117
118
|
folding costs a planner detail and never access. `collapsedGroups`,
|
|
118
119
|
`defaultCollapsedGroups` and `onCollapsedGroupsChange` put the state in the
|
|
@@ -120,8 +121,8 @@ application's hands; it is a view state, never an intent.
|
|
|
120
121
|
|
|
121
122
|
## Reading and moving
|
|
122
123
|
|
|
123
|
-
A tooltip on a hovered subtask or
|
|
124
|
-
and
|
|
124
|
+
A tooltip on a hovered subtask or dependency names the order, the times, lead-in
|
|
125
|
+
and lead-out and the findings; `tooltip` replaces its content or switches it
|
|
125
126
|
off. `now` draws the present across the lanes. The wheel over the schedule,
|
|
126
127
|
lane headers included, scrolls the lanes and releases the page at their end,
|
|
127
128
|
Ctrl or ⌘ and a pinch zoom, Shift pans; on a touch screen one finger pans and a
|
|
@@ -130,14 +131,39 @@ phone the plot keeps the larger part;
|
|
|
130
131
|
`onDomainChange` reports the visible span, and a ref handle turns a client
|
|
131
132
|
point into a time and a lane and back.
|
|
132
133
|
|
|
134
|
+
## Blocked time
|
|
135
|
+
|
|
136
|
+
`<BlockedTimes data={…} />` takes the time a lane is not available — leave,
|
|
137
|
+
maintenance — as plain data, `{ id, lane, from, to, label? }`. It is drawn
|
|
138
|
+
hatched behind the work; a subtask that covers some of it is a finding
|
|
139
|
+
(`inBlockedTime`, and the third argument of `findings`), and a drag does not
|
|
140
|
+
put work into it.
|
|
141
|
+
|
|
142
|
+
## Not yet
|
|
143
|
+
|
|
144
|
+
What the schedule does not do today, and waits for a caller who needs it (what
|
|
145
|
+
it never does stands in ADR-0032):
|
|
146
|
+
|
|
147
|
+
* **Milestones** — a point in time on a lane, drawn as a mark rather than a bar.
|
|
148
|
+
* **Stacked overlap** — overlapping subtasks packed into sub-lanes on request;
|
|
149
|
+
today an overlap is always drawn offset, as the finding it is.
|
|
150
|
+
* **Dependencies across tasks** — a dependency joins two subtasks of one task.
|
|
151
|
+
|
|
152
|
+
Done from this list: **blocked time** per lane.
|
|
153
|
+
|
|
133
154
|
## Where to read on
|
|
134
155
|
|
|
135
156
|
* The demo: <https://romanhaendler.github.io/umriss-ui/schedule/>, or locally
|
|
136
157
|
`pnpm dev:schedule` (port 4176). It is the documentation — every page shows
|
|
137
158
|
running examples with their source and the props table generated from `src/`.
|
|
138
159
|
* [`CHANGELOG.md`](CHANGELOG.md) — what changes for a caller.
|
|
139
|
-
*
|
|
140
|
-
|
|
160
|
+
* **For a coding agent**: `docs/llms-full.md` inside the installed package —
|
|
161
|
+
the demo as one Markdown file, pinned to the installed version: every page
|
|
162
|
+
with its examples' source, its props tables and why it is built as it is,
|
|
163
|
+
and the declaration of every other export. Online, for the latest version:
|
|
164
|
+
<https://romanhaendler.github.io/umriss-ui/schedule/llms.txt>.
|
|
165
|
+
* The vocabulary — **Task**, **Subtask**, **Lead-in**, **Lead-out**,
|
|
166
|
+
**Dependency**, **Violated dependency**, **Blocked time**, **Lane header**, **Lane group**,
|
|
141
167
|
**Miniature**, **Intent**, **Ghost** — stands in the workspace's
|
|
142
168
|
`CONTEXT.md`, section "The schedule".
|
|
143
169
|
* [`../../docs/design-language.md`](../../docs/design-language.md) — the design
|