@lovett/ui 0.0.11 → 0.2.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/dist/chunk-RBYWGBQ2.js +2752 -0
- package/dist/chunk-RBYWGBQ2.js.map +1 -0
- package/dist/index.d.ts +5574 -57
- package/dist/index.js +21650 -11206
- package/dist/index.js.map +1 -1
- package/dist/rich-composer-impl-5NO443A6.js +1859 -0
- package/dist/rich-composer-impl-5NO443A6.js.map +1 -0
- package/dist/styles.css +1570 -0
- package/dist/tokens.css +112 -0
- package/package.json +8 -1
- package/src/__tests__/avatar.test.tsx +272 -0
- package/src/__tests__/bar-chart.test.tsx +809 -0
- package/src/__tests__/board.test.tsx +420 -0
- package/src/__tests__/chart-math.test.ts +922 -0
- package/src/__tests__/chart-series.test.ts +339 -0
- package/src/__tests__/code-block.test.tsx +134 -0
- package/src/__tests__/display-popover.test.tsx +195 -0
- package/src/__tests__/display-store.test.tsx +307 -0
- package/src/__tests__/donut-chart.test.tsx +397 -0
- package/src/__tests__/dropdown-menu.test.tsx +156 -2
- package/src/__tests__/filter-menu.test.tsx +175 -0
- package/src/__tests__/gauge-ring.test.tsx +233 -0
- package/src/__tests__/line-chart.test.tsx +612 -0
- package/src/__tests__/ranked-bars.test.tsx +343 -0
- package/src/__tests__/remark-underline.test.ts +194 -0
- package/src/__tests__/sortable.test.tsx +394 -0
- package/src/__tests__/sparkline.test.tsx +368 -0
- package/src/__tests__/stat-layer.test.tsx +271 -0
- package/src/__tests__/stat-strip.test.tsx +175 -0
- package/src/__tests__/status.test.tsx +293 -0
- package/src/__tests__/tabs.test.tsx +303 -0
- package/src/__tests__/token-shape.test.ts +132 -2
- package/src/avatar.tsx +352 -0
- package/src/bar-chart.tsx +1214 -0
- package/src/board.tsx +658 -0
- package/src/chart-frame.tsx +960 -0
- package/src/chart-legend.tsx +304 -0
- package/src/chart-tooltip.tsx +267 -0
- package/src/code-block.tsx +62 -8
- package/src/delta-chip.tsx +263 -0
- package/src/detail/__tests__/activity-pane.test.tsx +369 -0
- package/src/detail/__tests__/detail-chrome.test.tsx +134 -0
- package/src/detail/__tests__/detail-surface.test.tsx +529 -0
- package/src/detail/__tests__/field-row.test.tsx +357 -0
- package/src/detail/activity-pane.tsx +611 -0
- package/src/detail/calendar.tsx +355 -0
- package/src/detail/detail-divider.tsx +261 -0
- package/src/detail/detail-header.tsx +287 -0
- package/src/detail/detail-menu.tsx +254 -0
- package/src/detail/detail-surface.tsx +1110 -0
- package/src/detail/field-list.tsx +196 -0
- package/src/detail/field-row.tsx +1131 -0
- package/src/detail/index.ts +58 -0
- package/src/detail/segmented-choice.tsx +94 -0
- package/src/detail/types.ts +129 -0
- package/src/display-popover.tsx +487 -0
- package/src/display-store.tsx +301 -0
- package/src/donut-chart.tsx +988 -0
- package/src/dropdown-menu.tsx +290 -19
- package/src/filter-core/EXPORTS.md +85 -0
- package/src/filter-core/__tests__/columns.test.ts +159 -0
- package/src/filter-core/__tests__/faceting.test.ts +193 -0
- package/src/filter-core/__tests__/filter-fns.test.ts +519 -0
- package/src/filter-core/__tests__/operators.test.ts +235 -0
- package/src/filter-core/__tests__/state.test.ts +268 -0
- package/src/filter-core/__tests__/url.test.ts +350 -0
- package/src/filter-core/columns.ts +134 -0
- package/src/filter-core/date-utils.ts +38 -0
- package/src/filter-core/examples/task-filter-columns.ts +121 -0
- package/src/filter-core/faceting.ts +120 -0
- package/src/filter-core/filter-fns.ts +335 -0
- package/src/filter-core/index.ts +105 -0
- package/src/filter-core/operators.ts +433 -0
- package/src/filter-core/state.ts +280 -0
- package/src/filter-core/types.ts +247 -0
- package/src/filter-core/url.ts +261 -0
- package/src/filter-dropdown.tsx +12 -0
- package/src/filter-menu.tsx +649 -0
- package/src/floating-drawer.tsx +19 -1
- package/src/gauge-ring.tsx +435 -0
- package/src/hue.ts +52 -0
- package/src/index.ts +303 -0
- package/src/kbd.tsx +27 -4
- package/src/lib/chart.ts +866 -0
- package/src/lib/focus.ts +43 -1
- package/src/lib/layer-stack.ts +30 -3
- package/src/lib/remark-underline.ts +443 -0
- package/src/lib/series.ts +169 -0
- package/src/line-chart.tsx +1176 -0
- package/src/markdown.tsx +26 -7
- package/src/modal.tsx +42 -18
- package/src/progress-ledger.tsx +304 -0
- package/src/ranked-bars.tsx +386 -0
- package/src/segmented-pill.tsx +32 -9
- package/src/sortable.tsx +520 -1
- package/src/sparkline.tsx +416 -0
- package/src/stat-card.tsx +376 -0
- package/src/stat-strip.tsx +327 -0
- package/src/status.tsx +215 -0
- package/src/styles.css +1570 -0
- package/src/tabs.tsx +206 -25
- package/src/task-card.tsx +610 -0
- package/src/thread/__tests__/comment-body-hostile.test.tsx +331 -0
- package/src/thread/__tests__/comment-tree.test.ts +151 -0
- package/src/thread/__tests__/emoji.test.ts +187 -0
- package/src/thread/__tests__/fixtures/thread-fixture.ts +252 -0
- package/src/thread/__tests__/link-preview-source.test.ts +120 -0
- package/src/thread/__tests__/link-preview.test.tsx +600 -0
- package/src/thread/__tests__/markdown-format.test.ts +82 -0
- package/src/thread/__tests__/markdown-spec.test.ts +469 -0
- package/src/thread/__tests__/relative-time.test.ts +71 -0
- package/src/thread/__tests__/rich-composer.test.tsx +799 -0
- package/src/thread/__tests__/scroll-caret.test.ts +58 -0
- package/src/thread/__tests__/suggestion-list.test.tsx +648 -0
- package/src/thread/__tests__/thread-scroll-ownership.test.tsx +88 -0
- package/src/thread/__tests__/thread.test.tsx +742 -0
- package/src/thread/__tests__/use-attachments.test.tsx +679 -0
- package/src/thread/actions.tsx +196 -0
- package/src/thread/attachments.tsx +1071 -0
- package/src/thread/comment-body.tsx +148 -0
- package/src/thread/comment-tree.ts +182 -0
- package/src/thread/comment.tsx +967 -0
- package/src/thread/composer-footer.tsx +125 -0
- package/src/thread/composer.tsx +319 -0
- package/src/thread/emoji.ts +283 -0
- package/src/thread/index.ts +153 -0
- package/src/thread/link-preview.tsx +341 -0
- package/src/thread/markdown-format.ts +155 -0
- package/src/thread/markdown-spec.ts +754 -0
- package/src/thread/rail.tsx +372 -0
- package/src/thread/reactions.tsx +415 -0
- package/src/thread/relative-time.tsx +94 -0
- package/src/thread/rich-composer-impl.tsx +1601 -0
- package/src/thread/rich-composer.tsx +195 -0
- package/src/thread/scroll-caret.ts +37 -0
- package/src/thread/suggestion-list.tsx +182 -0
- package/src/thread/thread.tsx +718 -0
- package/src/thread/types.ts +232 -0
- package/src/thread/use-attachments.ts +598 -0
- package/src/thread/use-now.ts +73 -0
- package/src/thread/use-thread.ts +316 -0
- package/src/tokens.css +112 -0
|
@@ -0,0 +1,169 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* series.ts — the categorical chart palette, resolved by a frozen literal
|
|
3
|
+
* lookup and nothing else.
|
|
4
|
+
*
|
|
5
|
+
* Promoted in ADR-146 D8. Canonical home for the palette so `ChartLegend`,
|
|
6
|
+
* `ChartTooltip` and every chart primitive resolve a hue the same way.
|
|
7
|
+
* Re-exported from `chart-legend.tsx` for the barrel.
|
|
8
|
+
*
|
|
9
|
+
* CONSUMERS — measured 2026-09-06, real imports inside `@lovett/ui` (7):
|
|
10
|
+
* `chart-legend.tsx`, `chart-tooltip.tsx`, `line-chart.tsx`,
|
|
11
|
+
* `bar-chart.tsx`, `donut-chart.tsx`, `ranked-bars.tsx`, `sparkline.tsx`.
|
|
12
|
+
* `ChartFrame` does NOT import it — it renders chrome and takes an
|
|
13
|
+
* already-coloured legend node — so the earlier claim naming it was wrong.
|
|
14
|
+
*
|
|
15
|
+
* WHY A FROZEN ARRAY AND NOT A CONSTRUCTED NAME
|
|
16
|
+
* ----------------------------------------------
|
|
17
|
+
* `ENGINEERING-AXES.md:186` records the exact defect this shape exists to
|
|
18
|
+
* prevent. A constructed custom-property name (`--folder-${key}`) produced
|
|
19
|
+
* `--folder-folder-violet`, which is undefined, which makes the enclosing
|
|
20
|
+
* `rgb()` invalid, which the browser **silently discards**. Typecheck, lint,
|
|
21
|
+
* tests, build and the token gate were all green while white-on-white tiles
|
|
22
|
+
* shipped. There is no gate that reads source and can see it, because the
|
|
23
|
+
* source is syntactically perfect.
|
|
24
|
+
*
|
|
25
|
+
* So no primitive in this package ever composes `` `--series-${i}` ``. The
|
|
26
|
+
* mapping is the literal array below, the same shape as `metric-card.tsx`'s
|
|
27
|
+
* `TONE_COLOR`, and `__tests__/chart-series.test.ts` asserts — with a
|
|
28
|
+
* mutation proof that the guard fails in the failing direction — that every
|
|
29
|
+
* entry names a custom property that `tokens.css` actually declares.
|
|
30
|
+
*
|
|
31
|
+
* Token discipline: this module produces `rgb(var(--token))` strings only. It
|
|
32
|
+
* contains no colour literal, and every token it names is a **bare RGB
|
|
33
|
+
* triple** in `tokens.css`, so a call site may legally apply its own alpha —
|
|
34
|
+
* `rgb(var(--series-1) / 0.12)` for the area fill under a line. That is
|
|
35
|
+
* asserted too: a series token that grew a baked-in alpha would make every
|
|
36
|
+
* such call site invalid CSS.
|
|
37
|
+
*
|
|
38
|
+
* CALLERS PASS A SLOT INDEX, NEVER A COLOUR AND NEVER A TOKEN NAME.
|
|
39
|
+
*/
|
|
40
|
+
|
|
41
|
+
/**
|
|
42
|
+
* The eight categorical series colours, in ADR-146 D2's **measured** order —
|
|
43
|
+
* blue, green, violet, olive, pink, amber, teal, red.
|
|
44
|
+
*
|
|
45
|
+
* The order is load-bearing, not cosmetic:
|
|
46
|
+
*
|
|
47
|
+
* • **Blue is slot 1, not red.** Slot 1 is the single-series default, so a
|
|
48
|
+
* red slot 1 would paint every one-series chart in the product accent and
|
|
49
|
+
* destroy accent scarcity.
|
|
50
|
+
* • **Red is slot 8.** Red belongs to `--accent` and `--destructive`. It
|
|
51
|
+
* enters a chart only at eight series.
|
|
52
|
+
* • **Green (slot 2) and red (slot 8) sit far apart**, so a two-series
|
|
53
|
+
* chart never accidentally reads as pass/fail.
|
|
54
|
+
*
|
|
55
|
+
* Worst adjacent pair is ΔE 13.2 (deutan) / 21.0 (normal), identical in both
|
|
56
|
+
* themes — the palette is theme-independent by construction.
|
|
57
|
+
*/
|
|
58
|
+
export const SERIES = [
|
|
59
|
+
'rgb(var(--series-1))',
|
|
60
|
+
'rgb(var(--series-2))',
|
|
61
|
+
'rgb(var(--series-3))',
|
|
62
|
+
'rgb(var(--series-4))',
|
|
63
|
+
'rgb(var(--series-5))',
|
|
64
|
+
'rgb(var(--series-6))',
|
|
65
|
+
'rgb(var(--series-7))',
|
|
66
|
+
'rgb(var(--series-8))',
|
|
67
|
+
] as const
|
|
68
|
+
|
|
69
|
+
/**
|
|
70
|
+
* The all-pairs palette, capped at three (ADR-146 D2).
|
|
71
|
+
*
|
|
72
|
+
* Scatter, bubble, choropleth and small-multiples let any two marks touch, so
|
|
73
|
+
* they take the harder all-pairs colour-blindness test instead of the
|
|
74
|
+
* adjacent-pairs one. **Our eight hues cannot pass it — no ordering can.**
|
|
75
|
+
* These three (`--series-1` blue, `--series-6` amber, `--series-7` teal) do,
|
|
76
|
+
* at worst ΔE 14.8 in both modes.
|
|
77
|
+
*
|
|
78
|
+
* A scatter-family chart with more than three series folds the remainder into
|
|
79
|
+
* "Other" or facets into small multiples. It never generates a ninth hue.
|
|
80
|
+
*/
|
|
81
|
+
export const SERIES_SCATTER = [SERIES[0], SERIES[5], SERIES[6]] as const
|
|
82
|
+
|
|
83
|
+
/** How many slots the default palette has. */
|
|
84
|
+
export const SERIES_SLOT_COUNT = SERIES.length
|
|
85
|
+
|
|
86
|
+
/** How many slots the all-pairs (`scatter`) palette has. */
|
|
87
|
+
export const SCATTER_SLOT_COUNT = SERIES_SCATTER.length
|
|
88
|
+
|
|
89
|
+
/**
|
|
90
|
+
* A legal slot in the default palette.
|
|
91
|
+
*
|
|
92
|
+
* Typed as a union rather than `number` so an out-of-range slot is a **type
|
|
93
|
+
* error at the boundary** (ADR-146 D8) rather than a runtime `undefined` that
|
|
94
|
+
* becomes invalid CSS. Callers holding a plain `number` narrow with
|
|
95
|
+
* `isSeriesSlot` and decide explicitly what a ninth series does.
|
|
96
|
+
*/
|
|
97
|
+
export type SeriesSlot = 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7
|
|
98
|
+
|
|
99
|
+
/** A legal slot in the `scatter` palette. */
|
|
100
|
+
export type ScatterSlot = 0 | 1 | 2
|
|
101
|
+
|
|
102
|
+
/** Which palette a chart draws from. `scatter` is the all-pairs, 3-slot one. */
|
|
103
|
+
export type SeriesPalette = 'default' | 'scatter'
|
|
104
|
+
|
|
105
|
+
/** Narrow a plain number to a default-palette slot. */
|
|
106
|
+
export function isSeriesSlot(value: number): value is SeriesSlot {
|
|
107
|
+
return Number.isInteger(value) && value >= 0 && value < SERIES_SLOT_COUNT
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
/** Narrow a plain number to a `scatter`-palette slot. */
|
|
111
|
+
export function isScatterSlot(value: number): value is ScatterSlot {
|
|
112
|
+
return Number.isInteger(value) && value >= 0 && value < SCATTER_SLOT_COUNT
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
/** The default-palette colour for a slot. Total — the union type guarantees it. */
|
|
116
|
+
export function seriesColor(slot: SeriesSlot): string {
|
|
117
|
+
return SERIES[slot]
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
/** The `scatter`-palette colour for a slot. Total. */
|
|
121
|
+
export function scatterColor(slot: ScatterSlot): string {
|
|
122
|
+
return SERIES_SCATTER[slot]
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
/**
|
|
126
|
+
* The colour for `slot` in `palette`, or `undefined` when the slot is outside
|
|
127
|
+
* that palette's cap.
|
|
128
|
+
*
|
|
129
|
+
* `undefined` is the deliberate answer rather than a wrap-around or a clamp:
|
|
130
|
+
* ADR-146 D2 says a fourth scatter series folds into "Other", and silently
|
|
131
|
+
* reusing slot 1's blue for slot 4 would draw two different entities in one
|
|
132
|
+
* hue — a wrong chart that no gate can see. Consumers render the "Other"
|
|
133
|
+
* treatment (a neutral swatch) when this returns `undefined`.
|
|
134
|
+
*/
|
|
135
|
+
export function paletteColor(
|
|
136
|
+
palette: SeriesPalette,
|
|
137
|
+
slot: number,
|
|
138
|
+
): string | undefined {
|
|
139
|
+
if (palette === 'scatter') {
|
|
140
|
+
return isScatterSlot(slot) ? scatterColor(slot) : undefined
|
|
141
|
+
}
|
|
142
|
+
return isSeriesSlot(slot) ? seriesColor(slot) : undefined
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
/**
|
|
146
|
+
* A palette slot, or the explicit `'other'` fold.
|
|
147
|
+
*
|
|
148
|
+
* `'other'` is how a chart says "this mark is the remainder". ADR-146 D2 caps
|
|
149
|
+
* the palette at eight slots (three for `scatter`) and folds the rest rather
|
|
150
|
+
* than generating a ninth hue, so the fold has to be representable in the
|
|
151
|
+
* data — not improvised at render time.
|
|
152
|
+
*/
|
|
153
|
+
export type ChartSlot = SeriesSlot | 'other'
|
|
154
|
+
|
|
155
|
+
/** The neutral swatch for the `'other'` fold — a grey, never a hue. */
|
|
156
|
+
export const OTHER_SLOT_COLOR = 'rgb(var(--text-muted))'
|
|
157
|
+
|
|
158
|
+
/**
|
|
159
|
+
* The rendered colour for a `ChartSlot`. Total: anything the palette cannot
|
|
160
|
+
* legally colour — the `'other'` fold, or a slot past a palette's cap — comes
|
|
161
|
+
* back as the neutral swatch rather than wrapping onto a hue already in use.
|
|
162
|
+
*
|
|
163
|
+
* Shared by `ChartLegend` and `ChartTooltip` so a series cannot be one colour
|
|
164
|
+
* in the legend and another in the readout.
|
|
165
|
+
*/
|
|
166
|
+
export function slotColor(slot: ChartSlot, palette: SeriesPalette): string {
|
|
167
|
+
if (slot === 'other') return OTHER_SLOT_COLOR
|
|
168
|
+
return paletteColor(palette, slot) ?? OTHER_SLOT_COLOR
|
|
169
|
+
}
|