@kolkrabbi/kol-component 0.91.0 → 0.91.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.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@kolkrabbi/kol-component",
3
- "version": "0.91.0",
3
+ "version": "0.91.1",
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",
@@ -69,7 +69,8 @@ const RAMP = {
69
69
  * 2026-08-27): ListingCard size="hero"'s text, read off Stack — kicker in
70
70
  * the helper-16 voice, title on display-03 (Stack's ruled hero title),
71
71
  * body mono-14. One emphasis (the title), everything else meta/body. */
72
- hero: { kicker: 'kol-helper-16 text-meta', title: 'kol-sans-display-03 text-emphasis kol-content-title-dim', body: 'kol-mono-14 text-body', date: 'kol-mono-12 text-meta', size: 'kol-mono-12 text-meta', tags: 'flex flex-wrap gap-2' },
72
+ /* UPPERCASE title, clamped 2, body clamped 2 the shipped Stack hero, carried through (user 2026-08-27: "UPPERCASE THE FUCKING TITLE") */
73
+ hero: { kicker: 'kol-helper-16 text-meta', title: 'kol-sans-display-03 text-emphasis uppercase line-clamp-2 kol-content-title-dim', body: 'kol-mono-14 text-body line-clamp-2', date: 'kol-mono-12 text-meta', size: 'kol-mono-12 text-meta', tags: 'flex flex-wrap gap-2' },
73
74
  },
74
75
  work: {
75
76
  /* INVERSE ink — the card's plate is the drawer, `surface-inverse`. Leaving
@@ -22,6 +22,9 @@ import IconFrame from '../atoms/IconFrame.jsx'
22
22
  * @param {Function} props.renderItem — (filteredItems, viewMode, layout) => ReactNode
23
23
  * @param {Array} props.viewModeOptions — optional view mode options for the view strip
24
24
  * @param {string} props.defaultViewMode — default view mode (falls back to the FIRST option)
25
+ * @param {string} props.layout — controlled LIST/GRID value (kol-r2b2 2026-08-27: a consumer that persists
26
+ * layout per bucket needs the strip's value back; `defaultLayout` alone kept it internal)
27
+ * @param {Function} props.onLayoutChange — (layout) => void, fires on every strip click
25
28
  * @param {Function} props.onFilterChange — optional callback when filters change
26
29
  * @param {Array} props.mutuallyExclusiveFilters — filter keys that should be mutually exclusive
27
30
  * @param {Array} props.customFilterKeys — filter keys handled by renderItem, not by ContentFilters
@@ -60,6 +63,8 @@ const ContentFilters = ({
60
63
  defaultViewMode,
61
64
  layoutOptions,
62
65
  defaultLayout,
66
+ layout: layoutProp,
67
+ onLayoutChange,
63
68
  /* WHERE the LIST/GRID strip sits — the two arrangements kol-monitor and
64
69
  * kol-website each settled on, made interchangeable (user ruling 2026-08-15).
65
70
  *
@@ -115,7 +120,13 @@ const ContentFilters = ({
115
120
  const [isExpanded, setIsExpanded] = useState(false)
116
121
  const [internalViewMode, setInternalViewMode] = useState(defaultViewMode ?? viewModeOptions?.[0]?.value)
117
122
  const viewMode = viewModeProp !== undefined ? viewModeProp : internalViewMode
118
- const [layout, setLayout] = useState(defaultLayout ?? layoutOptions?.[0]?.value ?? 'grid')
123
+ /* Controlled when `layout` is passed, internal otherwise the same pair viewMode uses. */
124
+ const [internalLayout, setInternalLayout] = useState(defaultLayout ?? layoutOptions?.[0]?.value ?? 'grid')
125
+ const layout = layoutProp !== undefined ? layoutProp : internalLayout
126
+ const setLayout = (next) => {
127
+ setInternalLayout(next)
128
+ onLayoutChange?.(next)
129
+ }
119
130
  const [searchOpen, setSearchOpen] = useState(false)
120
131
  const [searchText, setSearchText] = useState('')
121
132