@kolkrabbi/kol-component 0.145.0 → 0.146.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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@kolkrabbi/kol-component",
3
- "version": "0.145.0",
3
+ "version": "0.146.0",
4
4
  "description": "KOL design-system components — atoms through organisms, emitting canonical kol-* classes. Pairs with @kolkrabbi/kol-theme for styling.",
5
5
  "license": "MIT",
6
6
  "type": "module",
@@ -10,8 +10,10 @@ import ContentText from './ContentText.jsx'
10
10
  * thumb; article rides a 120px 16:9 thumb; work a framed 64px row; typeface a
11
11
  * framed no-thumb block.
12
12
  *
13
- * @param {string} variant file | catalog | print | article | work | typeface
14
- * (`default` is an alias of `file`)
13
+ * @param {string} variant file | catalog | print | article | work | typeface | roster
14
+ * (`default` is an alias of `file`). `roster` is the pickable
15
+ * row: filled tile, no border or divider, a FIXED 56px height the
16
+ * content fills, a 40px square thumb and two truncated lines.
15
17
  * @param {ReactNode} media thumb content (omit → placeholder)
16
18
  * @param {number|'fill'} thumb thumb edge px — overrides the ruled default; 0 hides; `'fill'` = a square
17
19
  * the height of the row's content, whatever the rung (WorkListingRowsAndFilters)
@@ -61,6 +63,23 @@ const BOX = {
61
63
  * transparent → fg-08 on hover ("0 → 16 is a big jump"). No md step: the rows
62
64
  * were approved at their base values. */
63
65
  showcase: { thumb: 'fill', ratio: '1 / 1', pad: S4, gap: S4, frame: 'transparent', frameHover: 'var(--kol-fg-08)', bg: 'var(--kol-surface-secondary)', minH: 168, align: 'items-stretch', thumbRadius: 'var(--kol-radius-xs)', thumbBorder: false },
66
+ /* ROSTER — a PICKABLE row (ContentRowRosterVariant, kol-chess 2026-08-31):
67
+ * filled tile, no border, no divider, fixed height, square thumb, two
68
+ * truncated lines that FILL the row rather than setting it.
69
+ *
70
+ * `file` is the nearest part and a different object: a bare ruled line with a
71
+ * 48px thumb, a divider, and no hover wash by the 2026-08-29 ruling — right
72
+ * for a file listing, wrong for a grid of things you choose between. These
73
+ * are targets, so they take a hover.
74
+ *
75
+ * THE FIXED HEIGHT IS THE POINT. Every other row in this family follows its
76
+ * content, and on a pick grid that reads as broken: the filer measured 34 →
77
+ * 40 → 50 → 58 across four passes, and ONE long meta line was enough to push
78
+ * a tile out of line with its neighbours. `height`, not `minH` — the content
79
+ * fills the row and cannot move it. */
80
+ roster: { thumb: 40, ratio: '1 / 1', pad: S2, gap: S2, height: 56, align: 'items-stretch',
81
+ bg: 'var(--kol-surface-secondary)', hover: 'var(--kol-fg-04)',
82
+ thumbBg: 'var(--kol-fg-04)', thumbBorder: false },
64
83
  /* typeface's row is a COLUMN, not a line: a header (name/styles left,
65
84
  * classification/year right) with a full-width specimen band under it. The
66
85
  * shipped item is `flex-col gap-6`, and forcing it into the horizontal
@@ -148,6 +167,10 @@ export default function ContentRow({
148
167
  * taller row carried `--kol-row-min-h: 224px !important`. */
149
168
  '--kol-row-min-h': minHeight != null ? `${minHeight}px` : box.minH != null ? `${box.minH}px` : undefined,
150
169
  '--kol-row-min-h-md': box.minHMd != null ? `${box.minHMd}px` : undefined,
170
+ /* A FIXED rung, not a floor — `roster` only. `minHeight` still overrides it,
171
+ * so a consumer that wants a taller pick row gets one; what it cannot get is
172
+ * a row whose height drifts with its own copy. */
173
+ '--kol-row-h': box.height != null ? `${minHeight ?? box.height}px` : undefined,
151
174
  /* `fill` = the rung minus the vertical padding — a definite number, not a
152
175
  * stretch (a min-height row has no definite cross size, so a stretched
153
176
  * aspect-ratio square resolved to the image's intrinsic width).
@@ -211,7 +234,11 @@ export default function ContentRow({
211
234
  </ContentMedia>
212
235
  </div>
213
236
  )}
214
- <ContentText variant={variant} form="row" className="flex-1" {...text} />
237
+ {/* THE 2px IS DELIBERATE and the one off-grid value in `roster` (the filer
238
+ * ruled it on screen): the two lines stack to 34 inside a 40 content box,
239
+ * and pushing them fully apart puts the ascenders hard against the thumb's
240
+ * top and bottom edges. It is the ROW's ruling, so the row passes it. */}
241
+ <ContentText variant={variant} form="row" className={`flex-1 ${box.height != null ? 'py-[2px]' : ''}`.trim()} {...text} />
215
242
  {/* `specs` rides the trailing edge on EVERY variant — year · material ·
216
243
  * edition is a content difference, not a geometry one, and minting a
217
244
  * seventh page-named box for it is the exact mistake §1 of the ticket is
@@ -234,7 +261,7 @@ export default function ContentRow({
234
261
  )
235
262
 
236
263
  const common = {
237
- className: `kol-row group flex ${box.column ? 'flex-col' : ''} ${box.align} ${box.divider ? 'kol-row--divided' : ''} ${box.frame ? 'rounded-[var(--kol-radius-sm)] border' : ''} ${interactive ? 'cursor-pointer select-none' : ''} ${interactive && box.hover ? 'kol-content-hover' : ''} ${interactive && box.frameHover ? 'kol-content-hover-frame' : ''} ${className}`.trim(),
264
+ className: `kol-row group flex ${box.column ? 'flex-col' : ''} ${box.align} ${box.height != null ? 'kol-row--fixed' : ''} ${box.divider ? 'kol-row--divided' : ''} ${box.frame ? 'rounded-[var(--kol-radius-sm)] border' : ''} ${interactive ? 'cursor-pointer select-none' : ''} ${interactive && box.hover ? 'kol-content-hover' : ''} ${interactive && box.frameHover ? 'kol-content-hover-frame' : ''} ${className}`.trim(),
238
265
  style: vars,
239
266
  }
240
267
 
@@ -91,6 +91,15 @@ const RAMP = {
91
91
  * ink, the year kol-mono-12 fg-64. Body unchanged (the site passes its face). */
92
92
  row: { title: 'kol-mono-14 uppercase text-emphasis truncate', body: 'kol-sans-heading-03 leading-tight text-emphasis truncate', meta: 'kol-mono-14 text-emphasis', date: 'kol-mono-12 text-fg-64', tags: 'flex flex-wrap items-center gap-1.5' },
93
93
  },
94
+ /* ROSTER — a pickable row's two lines, both TRUNCATED (ContentRowRosterVariant,
95
+ * kol-chess 2026-08-31). Written out rather than derived from `showcase`: the
96
+ * name-keyed maps below (FILL, GAPS) cannot be reached by a spread, and a
97
+ * derive that misses one of them is the exact trap `showcaseCanvas` fell into
98
+ * twice. Two literals beat a derive. Row form only — kol-chess wants no card,
99
+ * and a card nobody asked for is a variant to keep in step for nothing. */
100
+ roster: {
101
+ row: { title: 'kol-mono-14 text-fg-96 truncate', meta: 'kol-mono-12 text-fg-48 truncate' },
102
+ },
94
103
  showcaseCanvas: {
95
104
  /* RULED ON SCREEN (TypefaceCardAndRow, kol-website 2026-08-27): name and
96
105
  * classification are FULL ink, the year steps to 64; the card's title is the
@@ -143,6 +152,8 @@ const ORDER = {
143
152
  * item, which had been flattened into title-left / date-right and lost the
144
153
  * styles line into a body slot below. */
145
154
  showcaseCanvas: { card: ['title', 'body'], row: [['between', ['stack', 'title', 'body'], ['stack', 'detail', 'date']]] },
155
+ /* two lines, pushed apart by the column's own justify-between (FILL) */
156
+ roster: { row: ['title', 'meta'] },
146
157
  }
147
158
 
148
159
  /* inner line gap per variant/form, read from the shipped boxes and spelled in
@@ -158,7 +169,7 @@ const ORDER = {
158
169
  * `self-stretch`, NOT `h-full` — the row carries `min-height`, never `height`,
159
170
  * so `height: 100%` resolves against an indefinite parent, computes to auto,
160
171
  * and shrink-wraps the column. Which is exactly what it did. */
161
- const FILL = { showcase: true }
172
+ const FILL = { showcase: true, roster: true }
162
173
 
163
174
  /* gap INSIDE a ['stack', …] block. Defaults to the tight 4px pair article
164
175
  * wants; work's header stack is the shipped gap-1 md:gap-2. */
@@ -173,6 +184,9 @@ const GAPS = {
173
184
  article: { card: 'var(--kol-spacing-3)', row: 'var(--kol-spacing-3)', hero: 'var(--kol-spacing-3)' },
174
185
  showcase: { card: 'var(--kol-spacing-2)', row: 'var(--kol-spacing-4)' },
175
186
  showcaseCanvas: { card: 'var(--kol-spacing-2)', row: 'var(--kol-spacing-6)' },
187
+ /* roster's lines are pushed apart by justify-between, so this is only a
188
+ * floor for the case where the row is given more height than 56. */
189
+ roster: { row: 'var(--kol-spacing-1)' },
176
190
  }
177
191
 
178
192
  /* `default` → `file` (user 2026-08-29) — kept working as an alias here too,