@umriss-ui/schedule 0.3.6 → 0.3.8

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/docs/llms-full.md CHANGED
@@ -1,4 +1,4 @@
1
- # @umriss-ui/schedule 0.3.6
1
+ # @umriss-ui/schedule 0.3.8
2
2
 
3
3
  > React Gantt-style schedule for data-dense applications - work on lanes over time, with dependencies, blocked time, findings and controlled editing.
4
4
 
@@ -214,6 +214,9 @@ const WINDOW_CLOSES = new Map(
214
214
  TOURS.flatMap((tour) => tour.stops.map((stop) => [stop.id, stop.window[1] + DAY] as const)),
215
215
  );
216
216
 
217
+ /* A plate is one word, and so is its tie to the type: a lane header that
218
+ takes two lines must not tear "FP 377" from its "K". */
219
+ const plate = (text: string) => text.replaceAll(" ", "\u00a0");
217
220
  const plateOf = (vehicle: string) => VEHICLES.find((one) => one.id === vehicle)?.plate ?? vehicle;
218
221
  const driverOf = (driver: string) => DRIVERS.find((one) => one.id === driver)?.name ?? driver;
219
222
 
@@ -254,7 +257,7 @@ export default function TourPlan() {
254
257
  {DEPOTS.map((depot) => (
255
258
  <LaneGroup key={depot.id} id={depot.id} label={depot.name}>
256
259
  {VEHICLES.filter((one) => one.depot === depot.id).map((vehicle) => (
257
- <Lane key={vehicle.id} id={vehicle.id} label={`${vehicle.plate} · ${vehicle.type}`} />
260
+ <Lane key={vehicle.id} id={vehicle.id} label={`${plate(vehicle.plate)}\u00a0· ${vehicle.type}`} />
258
261
  ))}
259
262
  </LaneGroup>
260
263
  ))}
@@ -847,7 +850,7 @@ export default function LaneHeaders() {
847
850
  <Lane
848
851
  id="v1"
849
852
  label={
850
- <Stack direction="row" gap={2} align="center">
853
+ <Stack direction="row" gap={1} align="center">
851
854
  <Text size="sm">Van</Text>
852
855
  <Text size="xs" tone="muted" mono>
853
856
  FP 214 K
@@ -858,7 +861,7 @@ export default function LaneHeaders() {
858
861
  <Lane
859
862
  id="v2"
860
863
  label={
861
- <Stack direction="row" gap={2} align="center">
864
+ <Stack direction="row" gap={1} align="center" wrap>
862
865
  <Text size="sm">E-van</Text>
863
866
  <Text size="xs" tone="muted" mono>
864
867
  FP 377 K
@@ -980,7 +983,7 @@ const WORK: Subtask[] = [
980
983
 
981
984
  export default function AGroup() {
982
985
  return (
983
- <Schedule ariaLabel="Two developers in a team, a designer and a tester outside it" initialDomain={[at(6), at(15)]} height={240}>
986
+ <Schedule ariaLabel="Two developers in a team, a designer and a tester outside it" initialDomain={[at(6), at(15)]} height={240} headerWidth={200}>
984
987
  <LaneGroup id="developers" label="Developers">
985
988
  <Lane id="arjun" label="Arjun Mehta" />
986
989
  <Lane id="chloe" label="Chloe Durand" />
@@ -1003,6 +1006,10 @@ import type { Subtask, Task } from "@umriss-ui/schedule";
1003
1006
 
1004
1007
  const at = (hours: number, minutes = 0) => new Date(2026, 2, 17, hours, minutes).getTime();
1005
1008
 
1009
+ /* A plate is one word: a lane header that takes two lines must not tear it
1010
+ apart ("FP 214" / "K"). */
1011
+ const plate = (text: string) => text.replaceAll(" ", "\u00a0");
1012
+
1006
1013
  const TOURS: Task[] = [
1007
1014
  { id: "t-01", name: "T-01 Harbour", color: "light-dark(#2563eb, #6b9bff)" },
1008
1015
  { id: "t-03", name: "T-03 Old Town", color: "light-dark(#c2410c, #f08a52)" },
@@ -1021,13 +1028,13 @@ export default function Nesting() {
1021
1028
  <Schedule ariaLabel="North depot with its vans and a truck, and a van from Riverside" initialDomain={[at(6), at(15)]} height={330} headerWidth={200}>
1022
1029
  <LaneGroup id="north" label="North depot">
1023
1030
  <LaneGroup id="vans" label="Vans">
1024
- <Lane id="fp-214" label="Van FP 214 K" />
1025
- <Lane id="fp-377" label="E-van FP 377 K" />
1026
- <Lane id="fp-290" label="Van FP 290 E" />
1031
+ <Lane id="fp-214" label={`Van ${plate("FP 214 K")}`} />
1032
+ <Lane id="fp-377" label={`E-van ${plate("FP 377 K")}`} />
1033
+ <Lane id="fp-290" label={`Van ${plate("FP 290 E")}`} />
1027
1034
  </LaneGroup>
1028
- <Lane id="fp-118" label="Truck FP 118 R" />
1035
+ <Lane id="fp-118" label={`Truck ${plate("FP 118 R")}`} />
1029
1036
  </LaneGroup>
1030
- <Lane id="fp-402" label="Van FP 402 R" />
1037
+ <Lane id="fp-402" label={`Van ${plate("FP 402 R")}`} />
1031
1038
  <Subtasks data={LEGS} tasks={TOURS} />
1032
1039
  </Schedule>
1033
1040
  );
@@ -1115,6 +1122,10 @@ import type { Subtask, Task, Dependency } from "@umriss-ui/schedule";
1115
1122
  folded or not. */
1116
1123
 
1117
1124
  const at = (hours: number, minutes = 0) => new Date(2026, 2, 17, hours, minutes).getTime();
1125
+
1126
+ /* A plate is one word: a lane header that takes two lines must not tear it
1127
+ apart ("FP 214" / "K"). */
1128
+ const plate = (text: string) => text.replaceAll(" ", "\u00a0");
1118
1129
  const min = (n: number) => n * 60_000;
1119
1130
 
1120
1131
  const TOURS: Task[] = [
@@ -1160,12 +1171,12 @@ export default function TheMiniature() {
1160
1171
  setLast(`${intent.subtask}: ${intent.kind}`);
1161
1172
  }}
1162
1173
  >
1163
- <Lane id="truck" label="Truck FP 118 R" />
1174
+ <Lane id="truck" label={`Truck ${plate("FP 118 R")}`} />
1164
1175
  <LaneGroup id="north" label="North depot">
1165
- <Lane id="van-1" label="Van FP 214 K" />
1166
- <Lane id="van-2" label="E-van FP 377 K" />
1176
+ <Lane id="van-1" label={`Van ${plate("FP 214 K")}`} />
1177
+ <Lane id="van-2" label={`E-van ${plate("FP 377 K")}`} />
1167
1178
  </LaneGroup>
1168
- <Lane id="van-3" label="Van FP 402 R" />
1179
+ <Lane id="van-3" label={`Van ${plate("FP 402 R")}`} />
1169
1180
  <Dependencies data={HANDOVERS} />
1170
1181
  <Subtasks data={legs} tasks={TOURS} />
1171
1182
  </Schedule>
@@ -3222,7 +3233,7 @@ Set `tooltip={false}` when a panel of your own shows the item under the pointer,
3222
3233
 
3223
3234
  ```tsx
3224
3235
  import { useState } from "react";
3225
- import { Badge, Card, Stack, Text } from "@umriss-ui/core";
3236
+ import { Badge, Card, CardBody, Stack, Text } from "@umriss-ui/core";
3226
3237
  import { Lane, Schedule, Subtasks } from "@umriss-ui/schedule";
3227
3238
  import type { ScheduleInteraction } from "@umriss-ui/schedule";
3228
3239
  import { PEOPLE, PROJECTS, WORK } from "./planning";
@@ -3257,24 +3268,26 @@ export default function DetailPanelInstead() {
3257
3268
  <Subtasks data={WEB_WORK} tasks={PROJECTS} />
3258
3269
  </Schedule>
3259
3270
  <Card data-detail-panel>
3260
- {item === null ? (
3261
- <Text size="sm" tone="secondary">
3262
- Rest the pointer on a work item to see its details.
3263
- </Text>
3264
- ) : (
3265
- <Stack gap={1}>
3266
- <Stack direction="row" gap={2} align="center">
3267
- <Text size="sm" weight="semibold">
3268
- {item.name}
3271
+ <CardBody>
3272
+ {item === null ? (
3273
+ <Text size="sm" tone="secondary">
3274
+ Rest the pointer on a work item to see its details.
3275
+ </Text>
3276
+ ) : (
3277
+ <Stack gap={1}>
3278
+ <Stack direction="row" gap={2} align="center">
3279
+ <Text size="sm" weight="semibold">
3280
+ {item.name}
3281
+ </Text>
3282
+ <Badge tone={item.status === "done" ? "success" : "neutral"}>{item.status}</Badge>
3283
+ </Stack>
3284
+ <Text size="xs" tone="secondary">
3285
+ {PROJECTS.find((project) => project.id === item.task)?.name} · {PEOPLE.find((person) => person.id === item.lane)?.name} ·{" "}
3286
+ {item.estimate} h estimated
3269
3287
  </Text>
3270
- <Badge tone={item.status === "done" ? "success" : "neutral"}>{item.status}</Badge>
3271
3288
  </Stack>
3272
- <Text size="xs" tone="secondary">
3273
- {PROJECTS.find((project) => project.id === item.task)?.name} · {PEOPLE.find((person) => person.id === item.lane)?.name} ·{" "}
3274
- {item.estimate} h estimated
3275
- </Text>
3276
- </Stack>
3277
- )}
3289
+ )}
3290
+ </CardBody>
3278
3291
  </Card>
3279
3292
  </Stack>
3280
3293
  );
@@ -3532,7 +3545,7 @@ export default function PlaceAMark() {
3532
3545
  <Stack gap={2}>
3533
3546
  <div ref={host} style={{ position: "relative", height: 12 }}>
3534
3547
  {pin !== null && (
3535
- <Text size="xs" tone="muted" style={{ position: "absolute", top: -4, left: pin, transform: "translateX(-50%)" }} data-pin>
3548
+ <Text size="xs" tone="muted" style={{ position: "absolute", top: -4, left: pin, transform: "translateX(-50%)", whiteSpace: "nowrap" }} data-pin>
3536
3549
  Same-day cut-off
3537
3550
  </Text>
3538
3551
  )}
@@ -4115,7 +4128,7 @@ export default function DragFromTheBacklog() {
4115
4128
 
4116
4129
  return (
4117
4130
  <Stack gap={3}>
4118
- <Stack direction="row" gap={2}>
4131
+ <Stack direction="row" gap={2} wrap>
4119
4132
  {BACKLOG.map((entry) => (
4120
4133
  <Card key={entry.item}>
4121
4134
  <div
@@ -4127,7 +4140,7 @@ export default function DragFromTheBacklog() {
4127
4140
  setPlacing(entry);
4128
4141
  }}
4129
4142
  onDragEnd={() => setPlacing(null)}
4130
- style={{ cursor: "grab" }}
4143
+ style={{ cursor: "grab", padding: "var(--u-space-2) var(--u-space-3)" }}
4131
4144
  >
4132
4145
  <Text size="sm">{entry.label}</Text>
4133
4146
  </div>
@@ -4190,6 +4203,10 @@ import type { Intent, Subtask, Task } from "@umriss-ui/schedule";
4190
4203
 
4191
4204
  const at = (hours: number, minutes = 0) => new Date(2026, 2, 17, hours, minutes).getTime();
4192
4205
 
4206
+ /* A plate is one word: a lane header that takes two lines must not tear it
4207
+ apart ("FP 214" / "K"). */
4208
+ const plate = (text: string) => text.replaceAll(" ", "\u00a0");
4209
+
4193
4210
  const GOODS: Task[] = [
4194
4211
  { id: "dry", name: "Dry goods", color: "light-dark(#2563eb, #6b9bff)" },
4195
4212
  { id: "chilled", name: "Chilled goods", color: "light-dark(#c2410c, #f08a52)" },
@@ -4228,9 +4245,9 @@ export default function LanesThatFit() {
4228
4245
  canMoveTo={mayGo}
4229
4246
  onIntent={onIntent}
4230
4247
  >
4231
- <Lane id="cool-1" label="Cooled van FP 377 K" />
4232
- <Lane id="cool-2" label="Cooled van FP 455 R" />
4233
- <Lane id="dry" label="Van FP 214 K" />
4248
+ <Lane id="cool-1" label={`Cooled van ${plate("FP 377 K")}`} />
4249
+ <Lane id="cool-2" label={`Cooled van ${plate("FP 455 R")}`} />
4250
+ <Lane id="dry" label={`Van ${plate("FP 214 K")}`} />
4234
4251
  <Subtasks data={work} tasks={GOODS} />
4235
4252
  </Schedule>
4236
4253
  <Text size="sm" mono tone="secondary" data-last-move>
@@ -4253,6 +4270,10 @@ import type { Intent, PlacingItem, Subtask, Task } from "@umriss-ui/schedule";
4253
4270
 
4254
4271
  const at = (hours: number, minutes = 0) => new Date(2026, 2, 17, hours, minutes).getTime();
4255
4272
 
4273
+ /* A plate is one word: a lane header that takes two lines must not tear it
4274
+ apart ("FP 214" / "K"). */
4275
+ const plate = (text: string) => text.replaceAll(" ", "\u00a0");
4276
+
4256
4277
  const GOODS: Task[] = [
4257
4278
  { id: "dry", name: "Dry goods", color: "light-dark(#2563eb, #6b9bff)" },
4258
4279
  { id: "chilled", name: "Chilled goods", color: "light-dark(#c2410c, #f08a52)" },
@@ -4297,7 +4318,7 @@ export default function DraggedIn() {
4297
4318
  setPlacing(WAITING);
4298
4319
  }}
4299
4320
  onDragEnd={() => setPlacing(null)}
4300
- style={{ cursor: "grab" }}
4321
+ style={{ cursor: "grab", padding: "var(--u-space-2) var(--u-space-3)" }}
4301
4322
  >
4302
4323
  <Text size="sm">{WAITING.label}</Text>
4303
4324
  </div>
@@ -4311,9 +4332,9 @@ export default function DraggedIn() {
4311
4332
  canMoveTo={mayGo}
4312
4333
  onIntent={onIntent}
4313
4334
  >
4314
- <Lane id="cool-1" label="Cooled van FP 377 K" />
4315
- <Lane id="cool-2" label="Cooled van FP 455 R" />
4316
- <Lane id="dry" label="Van FP 214 K" />
4335
+ <Lane id="cool-1" label={`Cooled van ${plate("FP 377 K")}`} />
4336
+ <Lane id="cool-2" label={`Cooled van ${plate("FP 455 R")}`} />
4337
+ <Lane id="dry" label={`Van ${plate("FP 214 K")}`} />
4317
4338
  <Subtasks data={work} tasks={GOODS} />
4318
4339
  </Schedule>
4319
4340
  <Text size="sm" mono tone="secondary" data-last-place>
@@ -5485,7 +5506,7 @@ export interface AlertType {
5485
5506
 
5486
5507
  export const ALERT_TYPES: readonly AlertType[] = [
5487
5508
  { id: "checkout-latency", label: "Checkout · p95 latency above 300 ms", priority: "high" },
5488
- { id: "checkout-errors", label: "Checkout · error rate above 2 %", priority: "high" },
5509
+ { id: "checkout-errors", label: "Checkout · error rate above 2\u00a0%", priority: "high" },
5489
5510
  { id: "webhooks-queue", label: "Webhooks · queue older than 5 min", priority: "medium" },
5490
5511
  { id: "search-latency", label: "Search · p95 latency above 250 ms", priority: "medium" },
5491
5512
  { id: "images-disk", label: "Image service · disk 85 % full", priority: "low" },
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@umriss-ui/schedule",
3
- "version": "0.3.6",
3
+ "version": "0.3.8",
4
4
  "description": "React Gantt-style schedule for data-dense applications - work on lanes over time, with dependencies, blocked time, findings and controlled editing.",
5
5
  "license": "MIT",
6
6
  "author": "Roman Händler",
@@ -50,8 +50,8 @@
50
50
  "peerDependencies": {
51
51
  "react": ">=18",
52
52
  "react-dom": ">=18",
53
- "@umriss-ui/charts": "^0.8.1",
54
- "@umriss-ui/core": "^0.15.0"
53
+ "@umriss-ui/core": "^0.17.0",
54
+ "@umriss-ui/charts": "^0.8.2"
55
55
  },
56
56
  "devDependencies": {
57
57
  "@fontsource/geist-mono": "^5.3.0",
@@ -65,9 +65,9 @@
65
65
  "typescript": "^5.6.3",
66
66
  "vite": "^6.0.0",
67
67
  "vite-plugin-dts": "^4.3.0",
68
- "@umriss-ui/charts": "0.8.1",
69
- "@umriss-ui/core": "0.15.0",
70
- "@umriss-ui/demo": "0.0.0"
68
+ "@umriss-ui/demo": "0.0.0",
69
+ "@umriss-ui/charts": "0.8.2",
70
+ "@umriss-ui/core": "0.17.0"
71
71
  },
72
72
  "scripts": {
73
73
  "props": "node --disable-warning=ExperimentalWarning --experimental-strip-types demo/props.ts",