@kolkrabbi/kol-component 0.104.2 → 0.105.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.104.2",
3
+ "version": "0.105.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",
@@ -42,8 +42,9 @@ import IconFrame from '../atoms/IconFrame.jsx'
42
42
  * @param {boolean} props.titleUppercase — cases the title (default false)
43
43
  * @param {string} props.labelClassName — filter-group label type/ink (default `kol-eyebrow text-fg-96`)
44
44
  * @param {boolean} props.labelUppercase — cases the group label (default true)
45
- * groups: `{ label, key, values, stack?, className?, wrapClassName? }` — a short group (≤ 6 values) hugs its chips,
46
- * a long one flows; `stack` pins either way; `className` / `wrapClassName` are per-group seams
45
+ * groups: `{ label, key, values, stack?, className?, wrapClassName? }` — THE FIRST GROUP HUGS ITS CHIPS, EVERY
46
+ * GROUP AFTER IT FLOWS (user law 2026-08-27, by position, never by chip count); `stack` is the explicit
47
+ * override; `className` / `wrapClassName` are per-group seams
47
48
  * @param {string} props.tagVariant — filter chip variant ('primary' grey fill)
48
49
  * @param {string} props.tagSize — filter chip size
49
50
  * @param {string} props.tagActiveClassName — chip ink, selected
@@ -245,12 +246,15 @@ const ContentFilters = ({
245
246
  </div>
246
247
  ) : null
247
248
 
248
- const renderFilterGroup = (group) => {
249
- /* the FIRST group hugs its chips, the rest flow (the ruled shape/prints;
250
- * ContentFiltersEqualColumns was withdrawn 2026-08-27 same day: the "equal
251
- * columns" ask was a misread). A short group (≤ 6) hugs by default;
252
- * `stack` pins either way (kol-fxr passes `stack: i === 0`). */
253
- const stacked = group.stack ?? (group.values?.length ?? 0) <= 6
249
+ const renderFilterGroup = (group, index = 0) => {
250
+ /* THE LAW (user ruling 2026-08-27, said "for the 10th time"ContentFiltersFirstGroupHugs):
251
+ * THE FIRST FILTER GROUP HUGS ITS CHIPS — IT IS NARROW. EVERY GROUP AFTER IT
252
+ * FLOWS ACROSS THE REST OF THE ROW. By POSITION, never by chip count. The
253
+ * reference is kol-website /prints: CATEGORY hugs at the left, YEAR flows
254
+ * beside it. Not equal columns (0.104.1, a misread — reverted), not "short
255
+ * groups stack" (0.101, one page's ruling — reverted). `stack` stays the
256
+ * explicit override; kol-fxr pins `stack: i === 0`. */
257
+ const stacked = group.stack ?? index === 0
254
258
  return (
255
259
  <div key={group.key} className={`flex flex-col gap-3 ${stacked ? 'shrink-0' : 'min-w-0 flex-1'} ${group.className ?? ''}`.trim()}>
256
260
  {/* THE CATEGORY LABEL IS THE ACTIVE INK — `kol-helper-12` at `text-fg-96`,
@@ -444,7 +448,7 @@ const ContentFilters = ({
444
448
  <div className="flex items-start justify-between gap-16">
445
449
  <div className="flex min-w-0 flex-1 items-start gap-16">
446
450
  {leadingActions}
447
- {isExpanded && filterGroups.map((group) => renderFilterGroup(group))}
451
+ {isExpanded && filterGroups.map((group, i) => renderFilterGroup(group, i))}
448
452
  {isExpanded && activeFilters.size > 0 && (
449
453
  <button
450
454
  type="button"
@@ -18,7 +18,7 @@ import { minHeightClass } from './sectionHeights.js'
18
18
  *
19
19
  * @param {'full'|'80'|'60'|string} [height='60'] min-height on the family's ladder — full = 100dvh,
20
20
  * 80 = 70svh / 80vh, 60 = 50svh / 60vh (default), 40 = 35svh / 40vh; content stays vertically centred inside it
21
- * @param {'editorial'|'centered'} variant
21
+ * @param {'editorial'|'centered'|'connect'} variant `connect` = editorial with the contact copy as defaults (/ CONNECT · WORKING ON A PROJECT? · SEND A MESSAGE · CONTACT · hello@kolkrabbi.io), every prop still overridable
22
22
  * @param {ReactNode} headline · body · actions centered: the SectionText slots
23
23
  * @param {ReactNode} eyebrow left-column display wordmark (kol-sans-display-01)
24
24
  * @param {ReactNode} promptLabel prompt-row label
@@ -47,6 +47,17 @@ export default function SectionCta({
47
47
  slotStyle,
48
48
  className = '',
49
49
  }) {
50
+ /* `connect` (SectionCtaConnectVariant, kol-website 2026-08-27 — user: "it's stupid
51
+ * to make a prefix family that we opt out of at the first opportunity"): the
52
+ * editorial layout with the site's contact copy as defaults — every one still
53
+ * overridable by the props. Pages speak SectionCta directly; ConnectCta retires. */
54
+ if (variant === 'connect') {
55
+ eyebrow = eyebrow ?? '/ CONNECT'
56
+ promptLabel = promptLabel ?? 'WORKING ON A PROJECT?'
57
+ heading = heading ?? 'SEND A MESSAGE'
58
+ contactLabel = contactLabel ?? 'CONTACT'
59
+ email = email ?? 'hello@kolkrabbi.io'
60
+ }
50
61
  if (variant === 'centered') {
51
62
  return (
52
63
  <section className={`w-full flex flex-col justify-center py-24 ${surfaceClass(background, 'auto')} ${minHeightClass(height)} ${className}`.replace(/\s+/g, ' ').trim()}>