@charcuterie/ui 4.10.2 → 4.11.1

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.
@@ -48,6 +48,13 @@ export type LaneTimelineProps = {
48
48
  * `2026-04-06` to `2026-04-12`, which is seven columns, not eight.
49
49
  */
50
50
  range: TimelineSpan;
51
+ /**
52
+ * The narrowest a day column may be before a bar's title wraps
53
+ * onto up to three lines instead of clipping to one, as a
54
+ * multiple of the timeline's **own font size**. Default 6. In em
55
+ * for the reason `minColumnSize` is.
56
+ */
57
+ wrapColumnSize?: number;
51
58
  };
52
59
  /**
53
60
  * One horizontal lane per group, across a date axis, with anything
@@ -128,5 +135,5 @@ export type LaneTimelineProps = {
128
135
  * can drag is a write operation, which is a different component with
129
136
  * a different decision behind it.
130
137
  */
131
- export declare const LaneTimeline: ({ className, emptyState, headingLevel, label, lanes, locale, maxRowCount, minColumnSize, range, }: LaneTimelineProps) => ReactNode;
138
+ export declare const LaneTimeline: ({ className, emptyState, headingLevel, label, lanes, locale, maxRowCount, minColumnSize, range, wrapColumnSize, }: LaneTimelineProps) => ReactNode;
132
139
  //# sourceMappingURL=LaneTimeline.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"LaneTimeline.d.ts","sourceRoot":"","sources":["../../src/LaneTimeline/LaneTimeline.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAA;AAKtC,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,wBAAwB,CAAA;AAE1D,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,2BAA2B,CAAA;AA+C7D,MAAM,MAAM,iBAAiB,GAAG;IAC9B,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB;;;;;OAKG;IACH,UAAU,CAAC,EAAE,SAAS,CAAA;IACtB;;;;;;OAMG;IACH,YAAY,CAAC,EAAE,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,CAAA;IAC5B,mEAAmE;IACnE,KAAK,EAAE,MAAM,CAAA;IACb,KAAK,EAAE,SAAS,YAAY,EAAE,CAAA;IAC9B;;;;;OAKG;IACH,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,mDAAmD;IACnD,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB;;;;;;;;;;OAUG;IACH,aAAa,CAAC,EAAE,MAAM,CAAA;IACtB;;;;OAIG;IACH,KAAK,EAAE,YAAY,CAAA;CACpB,CAAA;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8EG;AACH,eAAO,MAAM,YAAY,GAAI,mGAU1B,iBAAiB,KAAG,SA4LtB,CAAA"}
1
+ {"version":3,"file":"LaneTimeline.d.ts","sourceRoot":"","sources":["../../src/LaneTimeline/LaneTimeline.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAA;AAKtC,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,wBAAwB,CAAA;AAE1D,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,2BAA2B,CAAA;AAkE7D,MAAM,MAAM,iBAAiB,GAAG;IAC9B,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB;;;;;OAKG;IACH,UAAU,CAAC,EAAE,SAAS,CAAA;IACtB;;;;;;OAMG;IACH,YAAY,CAAC,EAAE,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,CAAA;IAC5B,mEAAmE;IACnE,KAAK,EAAE,MAAM,CAAA;IACb,KAAK,EAAE,SAAS,YAAY,EAAE,CAAA;IAC9B;;;;;OAKG;IACH,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,mDAAmD;IACnD,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB;;;;;;;;;;OAUG;IACH,aAAa,CAAC,EAAE,MAAM,CAAA;IACtB;;;;OAIG;IACH,KAAK,EAAE,YAAY,CAAA;IACnB;;;;;OAKG;IACH,cAAc,CAAC,EAAE,MAAM,CAAA;CACxB,CAAA;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8EG;AACH,eAAO,MAAM,YAAY,GAAI,mHAW1B,iBAAiB,KAAG,SAoMtB,CAAA"}
@@ -3,7 +3,7 @@ import { getPlainDateFromDayNumber } from "../DatePicker/plainDate.js";
3
3
  import { EmptyState } from "../EmptyState/EmptyState.js";
4
4
  import { toClassName } from "../toClassName.js";
5
5
  import { LaneTimelineLane } from "./LaneTimelineLane.js";
6
- import { chooseAxisTickStep, formatAxisDate, getIsAxisReadable, toTimelineAxis, } from "./laneTimelineGeometry.js";
6
+ import { chooseAxisTickStep, chooseTitleLayout, formatAxisDate, getIsAxisReadable, toTimelineAxis, } from "./laneTimelineGeometry.js";
7
7
  import { useTrackMeasurements } from "./useTrackMeasurements.js";
8
8
  /**
9
9
  * Room one tick label needs, as a multiple of the timeline's own
@@ -40,6 +40,23 @@ const DEFAULT_MIN_COLUMN_SIZE = 1.75;
40
40
  * than drawn. Six is roughly a screen's worth of one lane.
41
41
  */
42
42
  const DEFAULT_MAX_ROW_COUNT = 6;
43
+ /**
44
+ * The narrowest a day column may be before a bar's title WRAPS
45
+ * rather than clips, in em.
46
+ *
47
+ * A one-line title with an ellipsis is right for a narrow column
48
+ * and wrong for a wide one, and the fold threshold above cannot
49
+ * tell the two apart: `minColumnSize` is where the axis stops
50
+ * being worth drawing, not where a title becomes readable. A
51
+ * seven-day week across a 64rem page gives every column 7em, and
52
+ * a single-day bar in it still printed `Regional Rob…` — the
53
+ * owner's verdict on that picture was *"I can't really read this
54
+ * text"*. Six em is about eight characters of the bar's own type,
55
+ * which is the narrowest box in which a wrapped word is a word and
56
+ * not a column of letters. A four-week range on the same page is
57
+ * under it and keeps the ellipsis.
58
+ */
59
+ const DEFAULT_WRAP_COLUMN_SIZE = 6;
43
60
  /**
44
61
  * One horizontal lane per group, across a date axis, with anything
45
62
  * that lasts more than a day drawn as a **bar**.
@@ -119,7 +136,7 @@ const DEFAULT_MAX_ROW_COUNT = 6;
119
136
  * can drag is a write operation, which is a different component with
120
137
  * a different decision behind it.
121
138
  */
122
- export const LaneTimeline = ({ className, emptyState, headingLevel = 3, label, lanes, locale, maxRowCount = DEFAULT_MAX_ROW_COUNT, minColumnSize = DEFAULT_MIN_COLUMN_SIZE, range, }) => {
139
+ export const LaneTimeline = ({ className, emptyState, headingLevel = 3, label, lanes, locale, maxRowCount = DEFAULT_MAX_ROW_COUNT, minColumnSize = DEFAULT_MIN_COLUMN_SIZE, range, wrapColumnSize = DEFAULT_WRAP_COLUMN_SIZE, }) => {
123
140
  const { fontSize, inlineSize, isMeasured, trackRef } = useTrackMeasurements();
124
141
  const axis = toTimelineAxis(range);
125
142
  const columnCount = axis?.columnCount ?? 0;
@@ -134,6 +151,12 @@ export const LaneTimeline = ({ className, emptyState, headingLevel = 3, label, l
134
151
  inlineSize,
135
152
  minTickInlineSize: TICK_LABEL_SIZE * fontSize,
136
153
  });
154
+ const titleLayout = chooseTitleLayout({
155
+ columnCount,
156
+ inlineSize,
157
+ isMeasured,
158
+ wrapColumnInlineSize: wrapColumnSize * fontSize,
159
+ });
137
160
  /*
138
161
  * An inline style, not a class. Tailwind scans source text for
139
162
  * complete class strings, so a `grid-cols-[repeat(${n},…)]` is
@@ -160,6 +183,6 @@ export const LaneTimeline = ({ className, emptyState, headingLevel = 3, label, l
160
183
  }, children: formatAxisDate({
161
184
  date: getPlainDateFromDayNumber(axis.startDay + index),
162
185
  locale,
163
- }) }, axis.startDay + index))) })] }), lanes.map((lane, position) => (_jsx(LaneTimelineLane, { axis: axis, columnTemplate: columnTemplate, headingLevel: headingLevel, lane: lane, locale: locale, maxRowCount: maxRowCount, position: position, shape: "axis", tickStep: tickStep }, lane.key)))] })) : (_jsxs(_Fragment, { children: [_jsx("p", { className: "pb-1 text-content-muted text-xs", children: rangeCaption }), lanes.map((lane, position) => (_jsx(LaneTimelineLane, { axis: axis, columnTemplate: columnTemplate, headingLevel: headingLevel, lane: lane, locale: locale, maxRowCount: maxRowCount, position: position, shape: "list", tickStep: tickStep }, lane.key)))] }))] }));
186
+ }) }, axis.startDay + index))) })] }), lanes.map((lane, position) => (_jsx(LaneTimelineLane, { axis: axis, columnTemplate: columnTemplate, headingLevel: headingLevel, lane: lane, locale: locale, maxRowCount: maxRowCount, position: position, shape: "axis", tickStep: tickStep, titleLayout: titleLayout }, lane.key)))] })) : (_jsxs(_Fragment, { children: [_jsx("p", { className: "pb-1 text-content-muted text-xs", children: rangeCaption }), lanes.map((lane, position) => (_jsx(LaneTimelineLane, { axis: axis, columnTemplate: columnTemplate, headingLevel: headingLevel, lane: lane, locale: locale, maxRowCount: maxRowCount, position: position, shape: "list", tickStep: tickStep }, lane.key)))] }))] }));
164
187
  };
165
188
  //# sourceMappingURL=LaneTimeline.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"LaneTimeline.js","sourceRoot":"","sources":["../../src/LaneTimeline/LaneTimeline.tsx"],"names":[],"mappings":";AAEA,OAAO,EAAE,yBAAyB,EAAE,MAAM,4BAA4B,CAAA;AACtE,OAAO,EAAE,UAAU,EAAE,MAAM,6BAA8B,CAAA;AACzD,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAA;AAE/C,OAAO,EAAE,gBAAgB,EAAE,MAAM,uBAAwB,CAAA;AAEzD,OAAO,EACL,kBAAkB,EAClB,cAAc,EACd,iBAAiB,EACjB,cAAc,GACf,MAAM,2BAA2B,CAAA;AAClC,OAAO,EAAE,oBAAoB,EAAE,MAAM,2BAA2B,CAAA;AAEhE;;;;;;;;;;GAUG;AACH,MAAM,eAAe,GAAG,GAAG,CAAA;AAE3B;;;;;;;;;;;;;;;;GAgBG;AACH,MAAM,uBAAuB,GAAG,IAAI,CAAA;AAEpC;;;GAGG;AACH,MAAM,qBAAqB,GAAG,CAAC,CAAA;AAmD/B;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8EG;AACH,MAAM,CAAC,MAAM,YAAY,GAAG,CAAC,EAC3B,SAAS,EACT,UAAU,EACV,YAAY,GAAG,CAAC,EAChB,KAAK,EACL,KAAK,EACL,MAAM,EACN,WAAW,GAAG,qBAAqB,EACnC,aAAa,GAAG,uBAAuB,EACvC,KAAK,GACa,EAAa,EAAE;IACjC,MAAM,EAAE,QAAQ,EAAE,UAAU,EAAE,UAAU,EAAE,QAAQ,EAAE,GAClD,oBAAoB,EAAE,CAAA;IAExB,MAAM,IAAI,GAAG,cAAc,CAAC,KAAK,CAAC,CAAA;IAElC,MAAM,WAAW,GAAG,IAAI,EAAE,WAAW,IAAI,CAAC,CAAA;IAE1C,MAAM,cAAc,GAAG,iBAAiB,CAAC;QACvC,WAAW;QACX,UAAU;QACV,UAAU;QACV,mBAAmB,EAAE,aAAa,GAAG,QAAQ;KAC9C,CAAC,CAAA;IAEF,MAAM,QAAQ,GAAG,kBAAkB,CAAC;QAClC,WAAW;QACX,UAAU;QACV,iBAAiB,EAAE,eAAe,GAAG,QAAQ;KAC9C,CAAC,CAAA;IAEF;;;;;;;OAOG;IACH,MAAM,cAAc,GAAG,UAAU,IAAI,CAAC,GAAG,CAAC,WAAW,EAAE,CAAC,CAAC,mBAAmB,CAAA;IAE5E,MAAM,YAAY,GAChB,IAAI;QACJ,GAAG,cAAc,CAAC;YAChB,IAAI,EAAE,yBAAyB,CAAC,IAAI,CAAC,QAAQ,CAAC;YAC9C,MAAM;SACP,CAAC,OAAO,cAAc,CAAC;YACtB,IAAI,EAAE,yBAAyB,CAAC,IAAI,CAAC,MAAM,CAAC;YAC5C,MAAM;SACP,CAAC,EAAE,CAAA;IAEN,OAAO,CACL,iCACc,KAAK,EACjB,SAAS,EAAE,WAAW,CACpB,0BAA0B,EAC1B,SAAS,CACV,aAgBD,8BACc,MAAM,EAClB,SAAS,EAAC,8DAA8D,aAExE,eAAO,EAEP,cAAK,SAAS,EAAC,KAAK,EAAC,GAAG,EAAE,QAAQ,GAAI,IAClC,EAEL,IAAI,KAAK,IAAI,CAAC,CAAC,CAAC,CACf,CAAC,UAAU,IAAI,CACb,KAAC,UAAU,IACT,WAAW,EAAC,0CAA0C,EACtD,OAAO,EAAC,iBAAiB,EACzB,YAAY,EAAE,YAAY,EAC1B,IAAI,EAAC,IAAI,GACT,CACH,CAAC,CACH,CAAC,CAAC,CAAC,KAAK,CAAC,MAAM,KAAK,CAAC,CAAC,CAAC,CAAC,CACvB,CAAC,UAAU,IAAI,CACb,KAAC,UAAU,IACT,WAAW,EAAC,8CAA8C,EAC1D,OAAO,EAAC,cAAc,EACtB,YAAY,EAAE,YAAY,EAC1B,IAAI,EAAC,IAAI,GACT,CACH,CAAC,CACH,CAAC,CAAC,CAAC,cAAc,CAAC,CAAC,CAAC,CACnB,8BACE,eAAK,SAAS,EAAC,6DAA6D,aAC1E,eACE,SAAS,EAAC,6CAA6C,EACvD,KAAK,EAAE,YAAY,IAAI,SAAS,YAE/B,YAAY,GACR,EAWP,6BACc,MAAM,EAClB,SAAS,EAAC,MAAM,EAChB,KAAK,EAAE;oCACL,mBAAmB,EAAE,cAAc;iCACpC,YAEA,KAAK,CAAC,IAAI,CACT,EAAE,MAAM,EAAE,WAAW,EAAE,EACvB,CAAC,OAAO,EAAE,KAAK,EAAE,EAAE,CAAC,KAAK,CAC1B;qCACE,MAAM,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,GAAG,QAAQ,KAAK,CAAC,CAAC;qCACzC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,CACd,eACE,SAAS,EAAC,6CAA6C,EAEvD,KAAK,EAAE;wCACL,UAAU,EAAE,GAAG,KAAK,GAAG,CAAC,WAAW,IAAI,CAAC,GAAG,CACzC,QAAQ,EACR,WAAW,GAAG,KAAK,CACpB,EAAE;qCACJ,YAEA,cAAc,CAAC;wCACd,IAAI,EAAE,yBAAyB,CAC7B,IAAI,CAAC,QAAQ,GAAG,KAAK,CACtB;wCACD,MAAM;qCACP,CAAC,IAbG,IAAI,CAAC,QAAQ,GAAG,KAAK,CAcrB,CACR,CAAC,GACA,IACF,EAEL,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,QAAQ,EAAE,EAAE,CAAC,CAC7B,KAAC,gBAAgB,IACf,IAAI,EAAE,IAAI,EACV,cAAc,EAAE,cAAc,EAC9B,YAAY,EAAE,YAAY,EAE1B,IAAI,EAAE,IAAI,EACV,MAAM,EAAE,MAAM,EACd,WAAW,EAAE,WAAW,EACxB,QAAQ,EAAE,QAAQ,EAClB,KAAK,EAAC,MAAM,EACZ,QAAQ,EAAE,QAAQ,IANb,IAAI,CAAC,GAAG,CAOb,CACH,CAAC,IACD,CACJ,CAAC,CAAC,CAAC,CACF,8BAOE,YAAG,SAAS,EAAC,iCAAiC,YAC3C,YAAY,GACX,EAEH,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,QAAQ,EAAE,EAAE,CAAC,CAC7B,KAAC,gBAAgB,IACf,IAAI,EAAE,IAAI,EACV,cAAc,EAAE,cAAc,EAC9B,YAAY,EAAE,YAAY,EAE1B,IAAI,EAAE,IAAI,EACV,MAAM,EAAE,MAAM,EACd,WAAW,EAAE,WAAW,EACxB,QAAQ,EAAE,QAAQ,EAClB,KAAK,EAAC,MAAM,EACZ,QAAQ,EAAE,QAAQ,IANb,IAAI,CAAC,GAAG,CAOb,CACH,CAAC,IACD,CACJ,IACO,CACX,CAAA;AACH,CAAC,CAAA"}
1
+ {"version":3,"file":"LaneTimeline.js","sourceRoot":"","sources":["../../src/LaneTimeline/LaneTimeline.tsx"],"names":[],"mappings":"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"}
@@ -1,6 +1,6 @@
1
1
  import type { CategoricalIndex } from "@charcuterie/tokens";
2
2
  import type { ReactNode } from "react";
3
- import type { TimelineSpan } from "./laneTimelineGeometry.ts";
3
+ import type { TimelineSpan, TimelineTitleLayout } from "./laneTimelineGeometry.ts";
4
4
  /**
5
5
  * Who owns the item's activation — nobody, a router, or a handler.
6
6
  *
@@ -59,6 +59,13 @@ export type LaneTimelineBarProps = {
59
59
  * text and no position to carry meaning.
60
60
  */
61
61
  shape: "bar" | "row";
62
+ /**
63
+ * For the `bar` shape only: `clip` prints the title on one line
64
+ * with an ellipsis, `wrap` lets it run onto up to three. The
65
+ * timeline chooses from the measured column width, so a bar
66
+ * never decides this for itself. Default `clip`.
67
+ */
68
+ titleLayout?: TimelineTitleLayout;
62
69
  };
63
70
  /**
64
71
  * One item, in either of the two shapes this component draws it in.
@@ -92,6 +99,6 @@ export type LaneTimelineBarProps = {
92
99
  * missing corner is not something anybody perceives without the
93
100
  * unclipped bar beside it to compare against.
94
101
  */
95
- export declare const LaneTimelineBar: ({ className, description, hasEarlierStart, hasLaterEnd, item, laneCategorical, shape, }: LaneTimelineBarProps) => ReactNode;
102
+ export declare const LaneTimelineBar: ({ className, description, hasEarlierStart, hasLaterEnd, item, laneCategorical, shape, titleLayout, }: LaneTimelineBarProps) => ReactNode;
96
103
  export {};
97
104
  //# sourceMappingURL=LaneTimelineBar.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"LaneTimelineBar.d.ts","sourceRoot":"","sources":["../../src/LaneTimeline/LaneTimelineBar.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,qBAAqB,CAAA;AAC3D,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAA;AAUtC,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,2BAA2B,CAAA;AAE7D;;;;;;;;GAQG;AACH,KAAK,kBAAkB,GACnB;IACE;;;;OAIG;IACH,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,QAAQ,CAAC,EAAE,KAAK,CAAA;CACjB,GACD;IACE,IAAI,CAAC,EAAE,KAAK,CAAA;IACZ,6DAA6D;IAC7D,QAAQ,CAAC,EAAE,MAAM,IAAI,CAAA;CACtB,CAAA;AAEL,MAAM,MAAM,YAAY,GAAG,YAAY,GAAG;IACxC;;;;;;;OAOG;IACH,WAAW,CAAC,EAAE,gBAAgB,CAAA;IAC9B,GAAG,EAAE,MAAM,CAAA;IACX;;;;;OAKG;IACH,KAAK,EAAE,MAAM,CAAA;CACd,GAAG,kBAAkB,CAAA;AAEtB,MAAM,MAAM,oBAAoB,GAAG;IACjC,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,IAAI,EAAE,YAAY,CAAA;IAClB,sDAAsD;IACtD,eAAe,EAAE,gBAAgB,CAAA;IACjC,iEAAiE;IACjE,WAAW,EAAE,MAAM,CAAA;IACnB,kEAAkE;IAClE,eAAe,EAAE,OAAO,CAAA;IACxB,0DAA0D;IAC1D,WAAW,EAAE,OAAO,CAAA;IACpB;;;;OAIG;IACH,KAAK,EAAE,KAAK,GAAG,KAAK,CAAA;CACrB,CAAA;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+BG;AACH,eAAO,MAAM,eAAe,GAAI,yFAQ7B,oBAAoB,KAAG,SAuHzB,CAAA"}
1
+ {"version":3,"file":"LaneTimelineBar.d.ts","sourceRoot":"","sources":["../../src/LaneTimeline/LaneTimelineBar.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,qBAAqB,CAAA;AAC3D,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAA;AAUtC,OAAO,KAAK,EACV,YAAY,EACZ,mBAAmB,EACpB,MAAM,2BAA2B,CAAA;AAElC;;;;;;;;GAQG;AACH,KAAK,kBAAkB,GACnB;IACE;;;;OAIG;IACH,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,QAAQ,CAAC,EAAE,KAAK,CAAA;CACjB,GACD;IACE,IAAI,CAAC,EAAE,KAAK,CAAA;IACZ,6DAA6D;IAC7D,QAAQ,CAAC,EAAE,MAAM,IAAI,CAAA;CACtB,CAAA;AAEL,MAAM,MAAM,YAAY,GAAG,YAAY,GAAG;IACxC;;;;;;;OAOG;IACH,WAAW,CAAC,EAAE,gBAAgB,CAAA;IAC9B,GAAG,EAAE,MAAM,CAAA;IACX;;;;;OAKG;IACH,KAAK,EAAE,MAAM,CAAA;CACd,GAAG,kBAAkB,CAAA;AAEtB,MAAM,MAAM,oBAAoB,GAAG;IACjC,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,IAAI,EAAE,YAAY,CAAA;IAClB,sDAAsD;IACtD,eAAe,EAAE,gBAAgB,CAAA;IACjC,iEAAiE;IACjE,WAAW,EAAE,MAAM,CAAA;IACnB,kEAAkE;IAClE,eAAe,EAAE,OAAO,CAAA;IACxB,0DAA0D;IAC1D,WAAW,EAAE,OAAO,CAAA;IACpB;;;;OAIG;IACH,KAAK,EAAE,KAAK,GAAG,KAAK,CAAA;IACpB;;;;;OAKG;IACH,WAAW,CAAC,EAAE,mBAAmB,CAAA;CAClC,CAAA;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+BG;AACH,eAAO,MAAM,eAAe,GAAI,sGAS7B,oBAAoB,KAAG,SAsJzB,CAAA"}
@@ -36,12 +36,14 @@ import { VisuallyHidden } from "../VisuallyHidden/VisuallyHidden.js";
36
36
  * missing corner is not something anybody perceives without the
37
37
  * unclipped bar beside it to compare against.
38
38
  */
39
- export const LaneTimelineBar = ({ className, description, hasEarlierStart, hasLaterEnd, item, laneCategorical, shape, }) => {
39
+ export const LaneTimelineBar = ({ className, description, hasEarlierStart, hasLaterEnd, item, laneCategorical, shape, titleLayout = "clip", }) => {
40
40
  const categorical = item.categorical ?? laneCategorical;
41
41
  const isInteractive = Boolean(item.href ?? item.onSelect);
42
- const content = (_jsxs(_Fragment, { children: [_jsx("span", { className: toClassName("min-w-0 flex-1", shape === "bar"
43
- ? "truncate"
44
- : "wrap-anywhere text-sm"), children: item.title }), shape === "row" ? (_jsx("span", { className: "text-content-muted text-xs", children: description })) : isInteractive ? null : (_jsx(VisuallyHidden, { children: description }))] }));
42
+ const content = (_jsxs(_Fragment, { children: [_jsx("span", { className: toClassName("min-w-0 flex-1 text-sm", shape === "row"
43
+ ? "wrap-anywhere hyphens-auto"
44
+ : titleLayout === "wrap"
45
+ ? "line-clamp-3 wrap-anywhere hyphens-auto"
46
+ : "truncate"), children: item.title }), shape === "row" ? (_jsx("span", { className: "text-content-muted text-xs", children: description })) : isInteractive ? null : (_jsx(VisuallyHidden, { children: description }))] }));
45
47
  /**
46
48
  * Only the bar shape gets one, and it carries the **title** as
47
49
  * well as the span. The Narrow View prints both already, and a
@@ -50,9 +52,14 @@ export const LaneTimelineBar = ({ className, description, hasEarlierStart, hasLa
50
52
  */
51
53
  const sentence = `${item.title}, ${description}`;
52
54
  const hoverText = shape === "bar" ? sentence : undefined;
53
- const shellClassName = toClassName("w-full min-w-0 border px-1.5 text-xs leading-tight", shape === "bar"
54
- ? "flex min-h-5 items-center rounded-sm"
55
- : "flex flex-col gap-0.5 rounded-md py-1", CATEGORICAL_APPEARANCE_CLASS[categorical].soft,
55
+ const shellClassName = toClassName("w-full min-w-0 border px-1.5 text-xs leading-tight",
56
+ // `h-full` so every bar in one packed row is the height of the
57
+ // tallest: a wrapped three-line title beside a one-line one
58
+ // would otherwise leave the shorter bar floating above the
59
+ // row's baseline.
60
+ shape === "bar"
61
+ ? "flex h-full min-h-5 items-center rounded-sm"
62
+ : "flex flex-col gap-0.5 rounded-md py-1", shape === "bar" && titleLayout === "wrap" && "py-0.5", CATEGORICAL_APPEARANCE_CLASS[categorical].soft,
56
63
  // A square edge where the item leaves the range. `rounded-*-none`
57
64
  // rather than a different component, so a clipped bar and a whole
58
65
  // one are the same box with one corner rule changed.
@@ -1 +1 @@
1
- {"version":3,"file":"LaneTimelineBar.js","sourceRoot":"","sources":["../../src/LaneTimeline/LaneTimelineBar.tsx"],"names":[],"mappings":";AAGA,OAAO,EACL,4BAA4B,EAC5B,uBAAuB,GACxB,MAAM,yBAAyB,CAAA;AAChC,OAAO,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAA;AACrD,OAAO,EAAE,YAAY,EAAE,MAAM,+BAAgC,CAAA;AAC7D,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAA;AAC/C,OAAO,EAAE,cAAc,EAAE,MAAM,qCAAsC,CAAA;AAmErE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+BG;AACH,MAAM,CAAC,MAAM,eAAe,GAAG,CAAC,EAC9B,SAAS,EACT,WAAW,EACX,eAAe,EACf,WAAW,EACX,IAAI,EACJ,eAAe,EACf,KAAK,GACgB,EAAa,EAAE;IACpC,MAAM,WAAW,GAAG,IAAI,CAAC,WAAW,IAAI,eAAe,CAAA;IAEvD,MAAM,aAAa,GAAG,OAAO,CAAC,IAAI,CAAC,IAAI,IAAI,IAAI,CAAC,QAAQ,CAAC,CAAA;IAEzD,MAAM,OAAO,GAAG,CACd,8BASE,eACE,SAAS,EAAE,WAAW,CACpB,gBAAgB,EAChB,KAAK,KAAK,KAAK;oBACb,CAAC,CAAC,UAAU;oBACZ,CAAC,CAAC,uBAAuB,CAC5B,YAEA,IAAI,CAAC,KAAK,GACN,EAsBN,KAAK,KAAK,KAAK,CAAC,CAAC,CAAC,CACjB,eAAM,SAAS,EAAC,4BAA4B,YACzC,WAAW,GACP,CACR,CAAC,CAAC,CAAC,aAAa,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CACzB,KAAC,cAAc,cAAE,WAAW,GAAkB,CAC/C,IACA,CACJ,CAAA;IAED;;;;;OAKG;IACH,MAAM,QAAQ,GAAG,GAAG,IAAI,CAAC,KAAK,KAAK,WAAW,EAAE,CAAA;IAEhD,MAAM,SAAS,GAAG,KAAK,KAAK,KAAK,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,SAAS,CAAA;IAExD,MAAM,cAAc,GAAG,WAAW,CAChC,oDAAoD,EACpD,KAAK,KAAK,KAAK;QACb,CAAC,CAAC,sCAAsC;QACxC,CAAC,CAAC,uCAAuC,EAC3C,4BAA4B,CAAC,WAAW,CAAC,CAAC,IAAI;IAC9C,kEAAkE;IAClE,kEAAkE;IAClE,qDAAqD;IACrD,eAAe,IAAI,KAAK,KAAK,KAAK,IAAI,gBAAgB,EACtD,WAAW,IAAI,KAAK,KAAK,KAAK,IAAI,gBAAgB,EAClD,aAAa,IAAI,gBAAgB,EACjC,aAAa;QACX,uBAAuB,CAAC,WAAW,CAAC,CAAC,IAAI,EAC3C,aAAa,IAAI,gBAAgB,EACjC,SAAS,CACV,CAAA;IAED,IAAI,IAAI,CAAC,IAAI,EAAE,CAAC;QACd,OAAO,CACL,KAAC,YAAY,kBACC,QAAQ,EACpB,SAAS,EAAE,cAAc,EACzB,IAAI,EAAE,IAAI,CAAC,IAAI,EACf,KAAK,EAAE,SAAS,YAEf,OAAO,GACK,CAChB,CAAA;IACH,CAAC;IAED,IAAI,IAAI,CAAC,QAAQ,EAAE,CAAC;QAClB,OAAO,CACL,+BACc,QAAQ,EACpB,SAAS,EAAE,WAAW,CACpB,cAAc,EACd,YAAY,CACb,EACD,OAAO,EAAE,IAAI,CAAC,QAAQ,EACtB,KAAK,EAAE,SAAS,EAChB,IAAI,EAAC,QAAQ,YAEZ,OAAO,GACD,CACV,CAAA;IACH,CAAC;IAED,OAAO,CACL,eAAM,SAAS,EAAE,cAAc,EAAE,KAAK,EAAE,SAAS,YAC9C,OAAO,GACH,CACR,CAAA;AACH,CAAC,CAAA"}
1
+ {"version":3,"file":"LaneTimelineBar.js","sourceRoot":"","sources":["../../src/LaneTimeline/LaneTimelineBar.tsx"],"names":[],"mappings":"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"}
@@ -1,7 +1,7 @@
1
1
  import type { CategoricalIndex } from "@charcuterie/tokens";
2
2
  import type { ReactNode } from "react";
3
3
  import type { TimelineItem } from "./LaneTimelineBar.tsx";
4
- import type { TimelineAxis } from "./laneTimelineGeometry.ts";
4
+ import type { TimelineAxis, TimelineTitleLayout } from "./laneTimelineGeometry.ts";
5
5
  export type TimelineLane = {
6
6
  /**
7
7
  * Which of the ten hues this lane wears, overriding the one its
@@ -47,6 +47,12 @@ export type LaneTimelineLaneProps = {
47
47
  shape: "axis" | "list";
48
48
  /** Draw a separator every this many columns. */
49
49
  tickStep: number;
50
+ /**
51
+ * Whether a bar's title clips to one line or wraps onto up to
52
+ * three. The parent measures the column and decides; the Narrow
53
+ * View ignores it, because a row always has room to wrap.
54
+ */
55
+ titleLayout?: TimelineTitleLayout;
50
56
  };
51
57
  /**
52
58
  * One lane: its name, how much it is carrying, and either a track of
@@ -80,5 +86,5 @@ export type LaneTimelineLaneProps = {
80
86
  * month grid, where every cell is the same size no matter what is
81
87
  * in it.
82
88
  */
83
- export declare const LaneTimelineLane: ({ axis, columnTemplate, headingLevel, lane, locale, maxRowCount, position, shape, tickStep, }: LaneTimelineLaneProps) => ReactNode;
89
+ export declare const LaneTimelineLane: ({ axis, columnTemplate, headingLevel, lane, locale, maxRowCount, position, shape, tickStep, titleLayout, }: LaneTimelineLaneProps) => ReactNode;
84
90
  //# sourceMappingURL=LaneTimelineLane.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"LaneTimelineLane.d.ts","sourceRoot":"","sources":["../../src/LaneTimeline/LaneTimelineLane.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,qBAAqB,CAAA;AAK3D,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAA;AAMtC,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,uBAAuB,CAAA;AAEzD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,2BAA2B,CAAA;AAM7D,MAAM,MAAM,YAAY,GAAG;IACzB;;;;;;;;;;OAUG;IACH,WAAW,CAAC,EAAE,gBAAgB,CAAA;IAC9B;;;;;OAKG;IACH,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,KAAK,EAAE,SAAS,YAAY,EAAE,CAAA;IAC9B,GAAG,EAAE,MAAM,CAAA;IACX;;;OAGG;IACH,KAAK,EAAE,MAAM,CAAA;CACd,CAAA;AAED,MAAM,MAAM,qBAAqB,GAAG;IAClC,IAAI,EAAE,YAAY,CAAA;IAClB,+DAA+D;IAC/D,cAAc,EAAE,MAAM,CAAA;IACtB,YAAY,EAAE,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,CAAA;IAC3B,IAAI,EAAE,YAAY,CAAA;IAClB,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,WAAW,EAAE,MAAM,CAAA;IACnB,4DAA4D;IAC5D,QAAQ,EAAE,MAAM,CAAA;IAChB;;;OAGG;IACH,KAAK,EAAE,MAAM,GAAG,MAAM,CAAA;IACtB,gDAAgD;IAChD,QAAQ,EAAE,MAAM,CAAA;CACjB,CAAA;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+BG;AACH,eAAO,MAAM,gBAAgB,GAAI,+FAU9B,qBAAqB,KAAG,SA6N1B,CAAA"}
1
+ {"version":3,"file":"LaneTimelineLane.d.ts","sourceRoot":"","sources":["../../src/LaneTimeline/LaneTimelineLane.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,qBAAqB,CAAA;AAK3D,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAA;AAMtC,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,uBAAuB,CAAA;AAEzD,OAAO,KAAK,EACV,YAAY,EACZ,mBAAmB,EACpB,MAAM,2BAA2B,CAAA;AAMlC,MAAM,MAAM,YAAY,GAAG;IACzB;;;;;;;;;;OAUG;IACH,WAAW,CAAC,EAAE,gBAAgB,CAAA;IAC9B;;;;;OAKG;IACH,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,KAAK,EAAE,SAAS,YAAY,EAAE,CAAA;IAC9B,GAAG,EAAE,MAAM,CAAA;IACX;;;OAGG;IACH,KAAK,EAAE,MAAM,CAAA;CACd,CAAA;AAED,MAAM,MAAM,qBAAqB,GAAG;IAClC,IAAI,EAAE,YAAY,CAAA;IAClB,+DAA+D;IAC/D,cAAc,EAAE,MAAM,CAAA;IACtB,YAAY,EAAE,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,CAAA;IAC3B,IAAI,EAAE,YAAY,CAAA;IAClB,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,WAAW,EAAE,MAAM,CAAA;IACnB,4DAA4D;IAC5D,QAAQ,EAAE,MAAM,CAAA;IAChB;;;OAGG;IACH,KAAK,EAAE,MAAM,GAAG,MAAM,CAAA;IACtB,gDAAgD;IAChD,QAAQ,EAAE,MAAM,CAAA;IAChB;;;;OAIG;IACH,WAAW,CAAC,EAAE,mBAAmB,CAAA;CAClC,CAAA;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+BG;AACH,eAAO,MAAM,gBAAgB,GAAI,4GAW9B,qBAAqB,KAAG,SA8N1B,CAAA"}
@@ -39,7 +39,7 @@ import { describeTimelineSpan, toPackedLane, } from "./laneTimelineGeometry.js";
39
39
  * month grid, where every cell is the same size no matter what is
40
40
  * in it.
41
41
  */
42
- export const LaneTimelineLane = ({ axis, columnTemplate, headingLevel, lane, locale, maxRowCount, position, shape, tickStep, }) => {
42
+ export const LaneTimelineLane = ({ axis, columnTemplate, headingLevel, lane, locale, maxRowCount, position, shape, tickStep, titleLayout = "clip", }) => {
43
43
  const headingId = useUniqueId();
44
44
  /*
45
45
  * Position, not `getCategoricalIndex(lane.key)`, and `ActionTiles`
@@ -104,6 +104,6 @@ export const LaneTimelineLane = ({ axis, columnTemplate, headingLevel, lane, loc
104
104
  locale,
105
105
  placement,
106
106
  span: item,
107
- }), hasEarlierStart: placement.hasEarlierStart, hasLaterEnd: placement.hasLaterEnd, item: item, shape: "bar" }) }, item.key)))) }), packed.hiddenCount > 0 ? (_jsx("p", { className: "pt-1 text-content-muted text-xs", children: `+ ${packed.hiddenCount} more overlapping in ${lane.label}` })) : null] })] }));
107
+ }), hasEarlierStart: placement.hasEarlierStart, hasLaterEnd: placement.hasLaterEnd, item: item, shape: "bar", titleLayout: titleLayout }) }, item.key)))) }), packed.hiddenCount > 0 ? (_jsx("p", { className: "pt-1 text-content-muted text-xs", children: `+ ${packed.hiddenCount} more overlapping in ${lane.label}` })) : null] })] }));
108
108
  };
109
109
  //# sourceMappingURL=LaneTimelineLane.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"LaneTimelineLane.js","sourceRoot":"","sources":["../../src/LaneTimeline/LaneTimelineLane.tsx"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"LaneTimelineLane.js","sourceRoot":"","sources":["../../src/LaneTimeline/LaneTimelineLane.tsx"],"names":[],"mappings":"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"}
@@ -221,6 +221,37 @@ export declare const getIsAxisReadable: ({ columnCount, inlineSize, isMeasured,
221
221
  isMeasured: boolean;
222
222
  minColumnInlineSize: number;
223
223
  }) => boolean;
224
+ /**
225
+ * How a bar prints its title: on one line with an ellipsis, or
226
+ * wrapped onto up to three.
227
+ *
228
+ * `clip` is the honest answer when a column is narrow — a wrapped
229
+ * title in 30px is three lines of two letters each, which is
230
+ * neither the word nor a shape. `wrap` is the honest answer when
231
+ * the column is wide, and it is the one the whole component was
232
+ * measured wanting: at seven columns across a 64rem page a single-
233
+ * day bar has 7em of room and was still printing `Regional Rob…`,
234
+ * because one line is one line however wide the box gets.
235
+ */
236
+ export type TimelineTitleLayout = "clip" | "wrap";
237
+ /**
238
+ * Wrap the titles only once a day column is wide enough for a word.
239
+ *
240
+ * Measured, for the same reason `getIsAxisReadable` is: the
241
+ * question is the width of ONE column, which is the box divided by
242
+ * a number that lives in the data. Before the first measurement it
243
+ * clips, because that is the layout with no vertical surprise in
244
+ * it — a server render that wrapped would move every lane on the
245
+ * client's first paint.
246
+ */
247
+ export declare const chooseTitleLayout: ({ columnCount, inlineSize, isMeasured, wrapColumnInlineSize, }: {
248
+ columnCount: number;
249
+ /** The measured inline size of the track, in CSS pixels. */
250
+ inlineSize: number;
251
+ isMeasured: boolean;
252
+ /** The narrowest column that wraps, in CSS pixels. */
253
+ wrapColumnInlineSize: number;
254
+ }) => TimelineTitleLayout;
224
255
  export declare const chooseAxisTickStep: ({ columnCount, inlineSize, minTickInlineSize, }: {
225
256
  columnCount: number;
226
257
  inlineSize: number;
@@ -1 +1 @@
1
- {"version":3,"file":"laneTimelineGeometry.d.ts","sourceRoot":"","sources":["../../src/LaneTimeline/laneTimelineGeometry.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AAEH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,4BAA4B,CAAA;AAO3D;;;;GAIG;AACH,MAAM,MAAM,YAAY,GAAG;IACzB,2CAA2C;IAC3C,GAAG,EAAE,MAAM,CAAA;IACX,6BAA6B;IAC7B,KAAK,EAAE,MAAM,CAAA;CACd,CAAA;AAED;;;;;;;;GAQG;AACH,MAAM,MAAM,YAAY,GAAG;IACzB,uDAAuD;IACvD,WAAW,EAAE,MAAM,CAAA;IACnB,MAAM,EAAE,MAAM,CAAA;IACd,QAAQ,EAAE,MAAM,CAAA;CACjB,CAAA;AAED,MAAM,MAAM,YAAY,GAAG;IACzB,iDAAiD;IACjD,WAAW,EAAE,MAAM,CAAA;IACnB;;;;;;;;;OASG;IACH,UAAU,EAAE,MAAM,CAAA;IAClB;;;;;OAKG;IACH,QAAQ,EAAE,MAAM,CAAA;IAChB,oDAAoD;IACpD,eAAe,EAAE,OAAO,CAAA;IACxB,4DAA4D;IAC5D,WAAW,EAAE,OAAO,CAAA;CACrB,CAAA;AAED,MAAM,MAAM,kBAAkB,CAAC,IAAI,IAAI;IACrC,IAAI,EAAE,IAAI,CAAA;IACV,SAAS,EAAE,YAAY,CAAA;CACxB,CAAA;AAED,MAAM,MAAM,UAAU,CAAC,IAAI,IAAI;IAC7B;;;;;;;;OAQG;IACH,WAAW,EAAE,MAAM,CAAA;IACnB;;;;;;;;;;;OAWG;IACH,YAAY,EAAE,MAAM,CAAA;IACpB,IAAI,EAAE,kBAAkB,CAAC,IAAI,CAAC,EAAE,EAAE,CAAA;CACnC,CAAA;AAQD;;;;;;;;;;;;;;GAcG;AACH,eAAO,MAAM,cAAc,GACzB,OAAO,YAAY,KAClB,IAAI,GAAG,YAgBT,CAAA;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AACH,eAAO,MAAM,cAAc,GAAI,iBAG5B;IACD,IAAI,EAAE,YAAY,CAAA;IAClB,IAAI,EAAE,YAAY,CAAA;CACnB,KAAG,IAAI,GAAG,YAgCV,CAAA;AAED;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,eAAO,MAAM,YAAY,GACvB,IAAI,SAAS,YAAY,GAAG;IAAE,GAAG,EAAE,MAAM,CAAA;CAAE,EAC3C,+BAIC;IACD,IAAI,EAAE,YAAY,CAAA;IAClB,KAAK,EAAE,SAAS,IAAI,EAAE,CAAA;IACtB;;;OAGG;IACH,WAAW,EAAE,MAAM,CAAA;CACpB,KAAG,UAAU,CAAC,IAAI,CAiDlB,CAAA;AAED;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,eAAO,MAAM,iBAAiB,GAAI,+DAK/B;IACD,WAAW,EAAE,MAAM,CAAA;IACnB,4DAA4D;IAC5D,UAAU,EAAE,MAAM,CAAA;IAClB,UAAU,EAAE,OAAO,CAAA;IACnB,mBAAmB,EAAE,MAAM,CAAA;CAC5B,KAAG,OAG6C,CAAA;AAejD,eAAO,MAAM,kBAAkB,GAAI,iDAIhC;IACD,WAAW,EAAE,MAAM,CAAA;IACnB,UAAU,EAAE,MAAM,CAAA;IAClB,gDAAgD;IAChD,iBAAiB,EAAE,MAAM,CAAA;CAC1B,KAAG,MAaH,CAAA;AAED;;;;;;;;;;;;;;;;;;;GAmBG;AACH,eAAO,MAAM,oBAAoB,GAAI,8BAIlC;IACD,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,SAAS,EAAE,YAAY,CAAA;IACvB,IAAI,EAAE,YAAY,CAAA;CACnB,KAAG,MA4BH,CAAA;AAED;;;;;;;;GAQG;AACH,eAAO,MAAM,cAAc,GAAI,mBAG5B;IACD,IAAI,EAAE,SAAS,CAAA;IACf,MAAM,CAAC,EAAE,MAAM,CAAA;CAChB,KAAG,MAMA,CAAA"}
1
+ {"version":3,"file":"laneTimelineGeometry.d.ts","sourceRoot":"","sources":["../../src/LaneTimeline/laneTimelineGeometry.ts"],"names":[],"mappings":"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"}
@@ -198,6 +198,21 @@ export const toPackedLane = ({ axis, items, maxRowCount, }) => {
198
198
  export const getIsAxisReadable = ({ columnCount, inlineSize, isMeasured, minColumnInlineSize, }) => !isMeasured ||
199
199
  columnCount <= 0 ||
200
200
  inlineSize / columnCount >= minColumnInlineSize;
201
+ /**
202
+ * Wrap the titles only once a day column is wide enough for a word.
203
+ *
204
+ * Measured, for the same reason `getIsAxisReadable` is: the
205
+ * question is the width of ONE column, which is the box divided by
206
+ * a number that lives in the data. Before the first measurement it
207
+ * clips, because that is the layout with no vertical surprise in
208
+ * it — a server render that wrapped would move every lane on the
209
+ * client's first paint.
210
+ */
211
+ export const chooseTitleLayout = ({ columnCount, inlineSize, isMeasured, wrapColumnInlineSize, }) => isMeasured &&
212
+ columnCount > 0 &&
213
+ inlineSize / columnCount >= wrapColumnInlineSize
214
+ ? "wrap"
215
+ : "clip";
201
216
  /**
202
217
  * Label every day, every week, or every four weeks.
203
218
  *
@@ -1 +1 @@
1
- {"version":3,"file":"laneTimelineGeometry.js","sourceRoot":"","sources":["../../src/LaneTimeline/laneTimelineGeometry.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"laneTimelineGeometry.js","sourceRoot":"","sources":["../../src/LaneTimeline/laneTimelineGeometry.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@charcuterie/ui",
3
- "version": "4.10.2",
3
+ "version": "4.11.1",
4
4
  "description": "The Charcuterie components. Tokens for look, @charcuterie/logic for state, ARIA that agents can actually drive.",
5
5
  "license": "MIT",
6
6
  "type": "module",
@@ -117,6 +117,20 @@ which measures 0 again, every frame.
117
117
  Which is why "has it been measured" is its own flag rather than `inlineSize > 0`: **zero is a
118
118
  real width here**, because the track is a `minmax(0, 1fr)` column beside a fixed label rail.
119
119
 
120
+ ## A title wraps when its column has room
121
+
122
+ A bar's title is words, and one line is one line however wide the box gets: a week across
123
+ a desktop page gives every day about 7em, and a single-day bar in it still printed
124
+ `Regional Rob…`. So the timeline measures the column and chooses. At or above
125
+ `wrapColumnSize` (default `6`, in em of the timeline's own type) a title wraps onto up to
126
+ three lines; below it, the title clips to one line with an ellipsis, because three lines
127
+ of two letters each is neither the word nor a shape. The full title is in the bar's
128
+ `title` attribute and its accessible name either way.
129
+
130
+ The threshold is the **column's** width, not the box's, which is why the same 64rem panel
131
+ wraps a week's titles and clips a month's. It is decided by the timeline, never by the
132
+ bar, so every bar in a range agrees.
133
+
120
134
  ## The labels thin; the type does not shrink
121
135
 
122
136
  Type that shrinks to fit is type somebody cannot read, and the density axis already owns font
@@ -252,6 +252,39 @@ test("the same width keeps its axis for a week and loses it for a month", async
252
252
  await expect(getBarCount("The month at 34rem")).toBe(0)
253
253
  })
254
254
 
255
+ /**
256
+ * A title is words, and one line is one line however wide the box
257
+ * gets. So a bar in a column the timeline measured as wide enough
258
+ * wraps onto more lines, and the same title in a narrow column clips
259
+ * to one — decided from the column, never from the bar, which is why
260
+ * one story wraps what the other clips.
261
+ */
262
+ test("a bar's title wraps in a wide column and clips in a narrow one", async () => {
263
+ const toLineCount = (element: HTMLElement) =>
264
+ element.getBoundingClientRect().height /
265
+ Number.parseFloat(getComputedStyle(element).lineHeight)
266
+
267
+ // Playground: seven columns across 64rem, so about 7em a day.
268
+ const { canvas: week } = await mountStory(Playground)
269
+
270
+ const wrapped = week.getByText("Mic locker inventory")
271
+
272
+ await expect(toLineCount(wrapped)).toBeGreaterThanOrEqual(
273
+ 1.8,
274
+ )
275
+
276
+ // LongRange: thirty columns across 72rem, so about 2em a day.
277
+ const { canvas: month } = await mountStory(LongRange)
278
+
279
+ const clipped = month.getByText("Mic locker inventory")
280
+
281
+ await expect(toLineCount(clipped)).toBeLessThan(1.5)
282
+
283
+ await expect(clipped.scrollWidth).toBeGreaterThan(
284
+ clipped.clientWidth,
285
+ )
286
+ })
287
+
255
288
  /**
256
289
  * Thinning the labels rather than shrinking the type, because type
257
290
  * that shrinks to fit is type somebody cannot read.
@@ -8,6 +8,7 @@ import { LaneTimelineLane } from "./LaneTimelineLane.tsx"
8
8
  import type { TimelineSpan } from "./laneTimelineGeometry.ts"
9
9
  import {
10
10
  chooseAxisTickStep,
11
+ chooseTitleLayout,
11
12
  formatAxisDate,
12
13
  getIsAxisReadable,
13
14
  toTimelineAxis,
@@ -52,6 +53,24 @@ const DEFAULT_MIN_COLUMN_SIZE = 1.75
52
53
  */
53
54
  const DEFAULT_MAX_ROW_COUNT = 6
54
55
 
56
+ /**
57
+ * The narrowest a day column may be before a bar's title WRAPS
58
+ * rather than clips, in em.
59
+ *
60
+ * A one-line title with an ellipsis is right for a narrow column
61
+ * and wrong for a wide one, and the fold threshold above cannot
62
+ * tell the two apart: `minColumnSize` is where the axis stops
63
+ * being worth drawing, not where a title becomes readable. A
64
+ * seven-day week across a 64rem page gives every column 7em, and
65
+ * a single-day bar in it still printed `Regional Rob…` — the
66
+ * owner's verdict on that picture was *"I can't really read this
67
+ * text"*. Six em is about eight characters of the bar's own type,
68
+ * which is the narrowest box in which a wrapped word is a word and
69
+ * not a column of letters. A four-week range on the same page is
70
+ * under it and keeps the ellipsis.
71
+ */
72
+ const DEFAULT_WRAP_COLUMN_SIZE = 6
73
+
55
74
  export type LaneTimelineProps = {
56
75
  className?: string
57
76
  /**
@@ -99,6 +118,13 @@ export type LaneTimelineProps = {
99
118
  * `2026-04-06` to `2026-04-12`, which is seven columns, not eight.
100
119
  */
101
120
  range: TimelineSpan
121
+ /**
122
+ * The narrowest a day column may be before a bar's title wraps
123
+ * onto up to three lines instead of clipping to one, as a
124
+ * multiple of the timeline's **own font size**. Default 6. In em
125
+ * for the reason `minColumnSize` is.
126
+ */
127
+ wrapColumnSize?: number
102
128
  }
103
129
 
104
130
  /**
@@ -190,6 +216,7 @@ export const LaneTimeline = ({
190
216
  maxRowCount = DEFAULT_MAX_ROW_COUNT,
191
217
  minColumnSize = DEFAULT_MIN_COLUMN_SIZE,
192
218
  range,
219
+ wrapColumnSize = DEFAULT_WRAP_COLUMN_SIZE,
193
220
  }: LaneTimelineProps): ReactNode => {
194
221
  const { fontSize, inlineSize, isMeasured, trackRef } =
195
222
  useTrackMeasurements()
@@ -211,6 +238,13 @@ export const LaneTimeline = ({
211
238
  minTickInlineSize: TICK_LABEL_SIZE * fontSize,
212
239
  })
213
240
 
241
+ const titleLayout = chooseTitleLayout({
242
+ columnCount,
243
+ inlineSize,
244
+ isMeasured,
245
+ wrapColumnInlineSize: wrapColumnSize * fontSize,
246
+ })
247
+
214
248
  /*
215
249
  * An inline style, not a class. Tailwind scans source text for
216
250
  * complete class strings, so a `grid-cols-[repeat(${n},…)]` is
@@ -345,6 +379,7 @@ export const LaneTimeline = ({
345
379
  position={position}
346
380
  shape="axis"
347
381
  tickStep={tickStep}
382
+ titleLayout={titleLayout}
348
383
  />
349
384
  ))}
350
385
  </>
@@ -9,7 +9,10 @@ import { FOCUS_RING_CLASS } from "../intentStyles.ts"
9
9
  import { UnstyledLink } from "../RouterLink/UnstyledLink.tsx"
10
10
  import { toClassName } from "../toClassName.ts"
11
11
  import { VisuallyHidden } from "../VisuallyHidden/VisuallyHidden.tsx"
12
- import type { TimelineSpan } from "./laneTimelineGeometry.ts"
12
+ import type {
13
+ TimelineSpan,
14
+ TimelineTitleLayout,
15
+ } from "./laneTimelineGeometry.ts"
13
16
 
14
17
  /**
15
18
  * Who owns the item's activation — nobody, a router, or a handler.
@@ -73,6 +76,13 @@ export type LaneTimelineBarProps = {
73
76
  * text and no position to carry meaning.
74
77
  */
75
78
  shape: "bar" | "row"
79
+ /**
80
+ * For the `bar` shape only: `clip` prints the title on one line
81
+ * with an ellipsis, `wrap` lets it run onto up to three. The
82
+ * timeline chooses from the measured column width, so a bar
83
+ * never decides this for itself. Default `clip`.
84
+ */
85
+ titleLayout?: TimelineTitleLayout
76
86
  }
77
87
 
78
88
  /**
@@ -115,6 +125,7 @@ export const LaneTimelineBar = ({
115
125
  item,
116
126
  laneCategorical,
117
127
  shape,
128
+ titleLayout = "clip",
118
129
  }: LaneTimelineBarProps): ReactNode => {
119
130
  const categorical = item.categorical ?? laneCategorical
120
131
 
@@ -123,19 +134,45 @@ export const LaneTimelineBar = ({
123
134
  const content = (
124
135
  <>
125
136
  {/*
126
- * `truncate` and a `min-w-0`, per the flex-overflow rule: the
127
- * title is the flex row's text child and a single unbreakable
128
- * word would otherwise become the bar's floor and push the
129
- * bar past its own grid column. The whole string is in the
130
- * `title` attribute and in the hidden sentence, so nothing is
131
- * lost to the ellipsis.
137
+ * A `min-w-0`, per the flex-overflow rule: the title is the
138
+ * flex row's text child and a single unbreakable word would
139
+ * otherwise become the bar's floor and push the bar past its
140
+ * own grid column.
141
+ *
142
+ * Then one of three treatments. A bar in a narrow column
143
+ * clips to one line with an ellipsis, because three lines
144
+ * of two letters each is neither the word nor a shape. A
145
+ * bar in a column the timeline measured as wide enough
146
+ * WRAPS, onto up to three lines — one line is one line
147
+ * however wide the box gets, and a week across a desktop
148
+ * was still printing `Regional Rob…` at 7em a column. The
149
+ * Narrow View's row wraps freely. The whole string is in the
150
+ * `title` attribute and in the hidden sentence either way,
151
+ * so nothing is lost to a clamp.
152
+ *
153
+ * `wrap-anywhere` on the wrapped shapes rather than
154
+ * `break-word`, for the reason `Main` gives: only `anywhere`
155
+ * also shrinks the min-content size, so a long word cannot
156
+ * push the bar out of its column.
157
+ *
158
+ * `hyphens-auto` in front of it, because a column just past
159
+ * the wrap threshold is narrower than one long word: at 5em a
160
+ * column, an eleven-letter word broke as `Optometris` / `t`
161
+ * on the first live fortnight. A browser with a hyphenation
162
+ * dictionary breaks it as `Optom-` / `etrist` instead; one
163
+ * without (a headless shell has none) falls through to
164
+ * `anywhere`, which still keeps the bar in its column. It
165
+ * needs a `lang` on an ancestor, which every app's `<html>`
166
+ * carries.
132
167
  */}
133
168
  <span
134
169
  className={toClassName(
135
- "min-w-0 flex-1",
136
- shape === "bar"
137
- ? "truncate"
138
- : "wrap-anywhere text-sm",
170
+ "min-w-0 flex-1 text-sm",
171
+ shape === "row"
172
+ ? "wrap-anywhere hyphens-auto"
173
+ : titleLayout === "wrap"
174
+ ? "line-clamp-3 wrap-anywhere hyphens-auto"
175
+ : "truncate",
139
176
  )}
140
177
  >
141
178
  {item.title}
@@ -183,9 +220,14 @@ export const LaneTimelineBar = ({
183
220
 
184
221
  const shellClassName = toClassName(
185
222
  "w-full min-w-0 border px-1.5 text-xs leading-tight",
223
+ // `h-full` so every bar in one packed row is the height of the
224
+ // tallest: a wrapped three-line title beside a one-line one
225
+ // would otherwise leave the shorter bar floating above the
226
+ // row's baseline.
186
227
  shape === "bar"
187
- ? "flex min-h-5 items-center rounded-sm"
228
+ ? "flex h-full min-h-5 items-center rounded-sm"
188
229
  : "flex flex-col gap-0.5 rounded-md py-1",
230
+ shape === "bar" && titleLayout === "wrap" && "py-0.5",
189
231
  CATEGORICAL_APPEARANCE_CLASS[categorical].soft,
190
232
  // A square edge where the item leaves the range. `rounded-*-none`
191
233
  // rather than a different component, so a clipped bar and a whole
@@ -12,7 +12,10 @@ import { TextLink } from "../TextLink/TextLink.tsx"
12
12
  import { toClassName } from "../toClassName.ts"
13
13
  import type { TimelineItem } from "./LaneTimelineBar.tsx"
14
14
  import { LaneTimelineBar } from "./LaneTimelineBar.tsx"
15
- import type { TimelineAxis } from "./laneTimelineGeometry.ts"
15
+ import type {
16
+ TimelineAxis,
17
+ TimelineTitleLayout,
18
+ } from "./laneTimelineGeometry.ts"
16
19
  import {
17
20
  describeTimelineSpan,
18
21
  toPackedLane,
@@ -64,6 +67,12 @@ export type LaneTimelineLaneProps = {
64
67
  shape: "axis" | "list"
65
68
  /** Draw a separator every this many columns. */
66
69
  tickStep: number
70
+ /**
71
+ * Whether a bar's title clips to one line or wraps onto up to
72
+ * three. The parent measures the column and decides; the Narrow
73
+ * View ignores it, because a row always has room to wrap.
74
+ */
75
+ titleLayout?: TimelineTitleLayout
67
76
  }
68
77
 
69
78
  /**
@@ -108,6 +117,7 @@ export const LaneTimelineLane = ({
108
117
  position,
109
118
  shape,
110
119
  tickStep,
120
+ titleLayout = "clip",
111
121
  }: LaneTimelineLaneProps): ReactNode => {
112
122
  const headingId = useUniqueId()
113
123
 
@@ -315,6 +325,7 @@ export const LaneTimelineLane = ({
315
325
  hasLaterEnd={placement.hasLaterEnd}
316
326
  item={item}
317
327
  shape="bar"
328
+ titleLayout={titleLayout}
318
329
  />
319
330
  </li>
320
331
  )),
@@ -17,6 +17,7 @@ import { expect, test } from "vitest"
17
17
 
18
18
  import {
19
19
  chooseAxisTickStep,
20
+ chooseTitleLayout,
20
21
  describeTimelineSpan,
21
22
  getIsAxisReadable,
22
23
  toBarPlacement,
@@ -427,3 +428,37 @@ test("a single day says the day and nothing about a span", () => {
427
428
  }),
428
429
  ).toBe("Wed 8 Apr")
429
430
  })
431
+
432
+ /**
433
+ * The wrap threshold is a column width, so the same box answers
434
+ * differently for a week and for a month — and before a measurement
435
+ * it clips, so a server render has no vertical surprise in it.
436
+ */
437
+ test("a title wraps only once a measured column is wide enough", () => {
438
+ expect(
439
+ chooseTitleLayout({
440
+ columnCount: 7,
441
+ inlineSize: 812,
442
+ isMeasured: true,
443
+ wrapColumnInlineSize: 96,
444
+ }),
445
+ ).toBe("wrap")
446
+
447
+ expect(
448
+ chooseTitleLayout({
449
+ columnCount: 30,
450
+ inlineSize: 812,
451
+ isMeasured: true,
452
+ wrapColumnInlineSize: 96,
453
+ }),
454
+ ).toBe("clip")
455
+
456
+ expect(
457
+ chooseTitleLayout({
458
+ columnCount: 7,
459
+ inlineSize: 0,
460
+ isMeasured: false,
461
+ wrapColumnInlineSize: 96,
462
+ }),
463
+ ).toBe("clip")
464
+ })
@@ -357,6 +357,49 @@ export const getIsAxisReadable = ({
357
357
  columnCount <= 0 ||
358
358
  inlineSize / columnCount >= minColumnInlineSize
359
359
 
360
+ /**
361
+ * How a bar prints its title: on one line with an ellipsis, or
362
+ * wrapped onto up to three.
363
+ *
364
+ * `clip` is the honest answer when a column is narrow — a wrapped
365
+ * title in 30px is three lines of two letters each, which is
366
+ * neither the word nor a shape. `wrap` is the honest answer when
367
+ * the column is wide, and it is the one the whole component was
368
+ * measured wanting: at seven columns across a 64rem page a single-
369
+ * day bar has 7em of room and was still printing `Regional Rob…`,
370
+ * because one line is one line however wide the box gets.
371
+ */
372
+ export type TimelineTitleLayout = "clip" | "wrap"
373
+
374
+ /**
375
+ * Wrap the titles only once a day column is wide enough for a word.
376
+ *
377
+ * Measured, for the same reason `getIsAxisReadable` is: the
378
+ * question is the width of ONE column, which is the box divided by
379
+ * a number that lives in the data. Before the first measurement it
380
+ * clips, because that is the layout with no vertical surprise in
381
+ * it — a server render that wrapped would move every lane on the
382
+ * client's first paint.
383
+ */
384
+ export const chooseTitleLayout = ({
385
+ columnCount,
386
+ inlineSize,
387
+ isMeasured,
388
+ wrapColumnInlineSize,
389
+ }: {
390
+ columnCount: number
391
+ /** The measured inline size of the track, in CSS pixels. */
392
+ inlineSize: number
393
+ isMeasured: boolean
394
+ /** The narrowest column that wraps, in CSS pixels. */
395
+ wrapColumnInlineSize: number
396
+ }): TimelineTitleLayout =>
397
+ isMeasured &&
398
+ columnCount > 0 &&
399
+ inlineSize / columnCount >= wrapColumnInlineSize
400
+ ? "wrap"
401
+ : "clip"
402
+
360
403
  /**
361
404
  * Label every day, every week, or every four weeks.
362
405
  *