@kolkrabbi/kol-component 0.79.0 → 0.80.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.79.0",
3
+ "version": "0.80.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",
@@ -21,6 +21,9 @@
21
21
  * @param {ReactNode} headline the heading
22
22
  * @param {'pull'|'display-01'|'display-02'|'display-03'|'display-04'|'heading-01'|'heading-02'|'heading-03'|'heading-04'|'heading-05'} [headlineSize='heading-02']
23
23
  * @param {string} [headlineAs='h2'] element for the headline
24
+ * @param {'auto'|'upper'} [headlineCase='auto'] `upper` = the caps role (`.kol-section-text-caps`) —
25
+ * a title card; the split hero sets it (SectionHeroNoOverrides, 2026-08-26:
26
+ * a ROLE on the molecule, never a hero-side class)
24
27
  * @param {ReactNode} body lede / paragraph(s)
25
28
  * @param {ReactNode} actions row of Buttons / links / Tags
26
29
  * @param {'start'|'center'} [align='start'] text-align + item alignment
@@ -52,6 +55,7 @@ export default function SectionText({
52
55
  headline,
53
56
  headlineSize = 'heading-02',
54
57
  headlineAs: Headline = 'h2',
58
+ headlineCase = 'auto',
55
59
  headlineClass,
56
60
  body,
57
61
  actions,
@@ -76,7 +80,7 @@ export default function SectionText({
76
80
  {/* `kol-section-text-eyebrow` = uppercase by ROLE (kol-theme ≥0.55.0);
77
81
  * `labelClass` is the voice riding beside it */}
78
82
  {label && <span className={cls(`kol-section-text-eyebrow ${labelClass}`, 'label')} style={slotStyle.label}>{label}</span>}
79
- {headline && <Headline className={cls(headlineClass ?? (HEADLINE_ROLE[headlineSize] ?? HEADLINE_ROLE['heading-02']), 'headline')} style={slotStyle.headline}>{headline}</Headline>}
83
+ {headline && <Headline className={cls(`${headlineClass ?? (HEADLINE_ROLE[headlineSize] ?? HEADLINE_ROLE['heading-02'])}${headlineCase === 'upper' ? ' kol-section-text-caps' : ''}`, 'headline')} style={slotStyle.headline}>{headline}</Headline>}
80
84
  {body && (typeof body === 'string' ? <p className={cls(bodyClass, 'body')} style={slotStyle.body}>{body}</p> : <div className={cls(bodyClass, 'body')} style={slotStyle.body}>{body}</div>)}
81
85
  {children}
82
86
  {actions && <div className={cls(actionsClass, 'actions')} style={slotStyle.actions}>{actions}</div>}
@@ -4,7 +4,7 @@ import Image from '../atoms/Image.jsx'
4
4
  import OverlayGlassPanel from '../utilities/OverlayGlassPanel.jsx'
5
5
  import AssetPlaceholder from '../utilities/AssetPlaceholder.jsx'
6
6
  import ContentMedia from '../molecules/ContentMedia.jsx'
7
- import SectionText, { HEADLINE_ROLE } from '../molecules/SectionText.jsx'
7
+ import SectionText from '../molecules/SectionText.jsx'
8
8
  import FeaturedCarousel from './FeaturedCarousel.jsx'
9
9
 
10
10
  /* Height presets (SectionHeroRound2, user ruling 2026-08-26): three tiers in
@@ -110,7 +110,8 @@ function MediaLayer({ media }) {
110
110
  * @param {string} height 'full' | '80' | '60' (viewport tiers) · 'lg' | 'md' | 'screen' (aliases) · or a height class string
111
111
  * @param {ReactNode} label · headline · body · actions the composed text (SectionText)
112
112
  * @param {object} slotClass · slotStyle per-slot class / style, forwarded to SectionText (a consumer's reveal seam)
113
- * @param {string} [headlineSize='display-04']
113
+ * @param {string} headlineSize role; defaults per variant — media 'display-04', split 'heading-02'
114
+ * @param {string} gap SectionText's inner rhythm, forwarded as given (no hero default)
114
115
  * @param {string} [panelMaxWidth='max-w-[440px]'] the glass panel's cap on the composed route
115
116
  * @param {object} panelProps everything else on the glass panel (user ask 2026-08-26):
116
117
  * `padding` ('px-6 py-8') · `maxWidth` · `surfaceOpacity`
@@ -146,7 +147,11 @@ export default function SectionHero({
146
147
  height = 'lg',
147
148
  label,
148
149
  headline,
149
- headlineSize = 'display-04',
150
+ /* per-variant DEFAULT only — the hero has no say in the text's voice
151
+ * (SectionHeroNoOverrides, 2026-08-26): media 'display-04', split
152
+ * 'heading-02'; the consumer's value wins */
153
+ headlineSize,
154
+ gap,
150
155
  body,
151
156
  actions,
152
157
  panelMaxWidth = 'max-w-[440px]',
@@ -170,17 +175,17 @@ export default function SectionHero({
170
175
  <section className={`kol-section-hero-split grid grid-cols-1 md:grid-cols-2 ${(HEIGHTS[height === 'lg' ? 'full' : height] || height).replace(/\bh-/g, 'min-h-')} ${bleed} ${className}`.replace(/\s+/g, ' ').trim()}>
171
176
  <div className={`relative min-h-[50vh] overflow-hidden md:min-h-0 ${mediaFirst ? '' : 'md:order-2'}`.trim()}>{mediaNode}</div>
172
177
  <div className={`flex items-center justify-center p-10 ${mediaFirst ? '' : 'md:order-1'}`.trim()}>
178
+ {/* BARE — the molecule's own voice; `headlineCase="upper"` is the
179
+ * split hero's one trait, a role on SectionText (SectionHeroNoOverrides) */}
173
180
  <SectionText
174
181
  label={label}
175
182
  headline={headline}
176
- headlineSize={headlineSize === 'display-04' ? 'heading-02' : headlineSize}
177
- headlineClass={`${HEADLINE_ROLE[headlineSize === 'display-04' ? 'heading-02' : headlineSize] ?? HEADLINE_ROLE['heading-02']} kol-section-text-caps`}
183
+ headlineSize={headlineSize ?? 'heading-02'}
184
+ headlineCase="upper"
178
185
  body={body}
179
186
  actions={actions}
180
187
  align="center"
181
- gap="gap-6"
182
- bodyClass="kol-sans-body-02 text-body"
183
- actionsClass="flex flex-wrap gap-4 justify-center"
188
+ gap={gap}
184
189
  className="max-w-[var(--kol-content-column)]"
185
190
  slotClass={slotClass}
186
191
  slotStyle={slotStyle}
@@ -231,18 +236,20 @@ export default function SectionHero({
231
236
  }
232
237
 
233
238
  const text = composed ? (
239
+ /* BARE (SectionHeroNoOverrides, user 2026-08-26: "you think the purpose
240
+ * of unifying components is to make OVERWRITES?") — the hero passes the
241
+ * slots and nothing about their voice. The old glass hero's gap-6 /
242
+ * body-02 / caps were pixel parity with a retired component, and parity
243
+ * with it is not the bar; one voice across the set is. `gap` is the
244
+ * consumer's if they want it. */
234
245
  <SectionText
235
246
  label={label}
236
247
  headline={headline}
237
- headlineSize={headlineSize}
248
+ headlineSize={headlineSize ?? 'display-04'}
238
249
  body={body}
239
250
  actions={actions}
240
251
  align={align === 'center' ? 'center' : 'start'}
241
- /* gap-6 — the rhythm every hand-built OverlayGlassPanel hero ran on,
242
- * so the composed route lands on the same pixels */
243
- gap="gap-6"
244
- bodyClass="kol-sans-body-02 text-body"
245
- actionsClass={`flex flex-wrap gap-4${align === 'center' ? ' justify-center' : ''}`}
252
+ gap={gap}
246
253
  className={media == null ? `${panelMaxWidth} mx-auto` : ''}
247
254
  slotClass={slotClass}
248
255
  slotStyle={slotStyle}