@kolkrabbi/kol-component 0.79.0 → 0.80.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.
|
|
3
|
+
"version": "0.80.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",
|
|
@@ -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'])
|
|
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
|
|
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
|
|
@@ -22,6 +22,20 @@ const HEIGHTS = {
|
|
|
22
22
|
md: 'h-[320px] md:h-[440px]',
|
|
23
23
|
}
|
|
24
24
|
|
|
25
|
+
/* The SPLIT variant's presets as LITERALS (SectionHeroSplitHeight, kol-website
|
|
26
|
+
* 2026-08-26). 0.76.0 rewrote HEIGHTS to min-h-* at runtime — a string no
|
|
27
|
+
* source file carries, so Tailwind's scanner never emitted it and every
|
|
28
|
+
* split preset was dead: the Studio hero rendered its text column's 175px.
|
|
29
|
+
* A class Tailwind cannot see is not a class. */
|
|
30
|
+
const SPLIT_HEIGHTS = {
|
|
31
|
+
full: 'min-h-dvh',
|
|
32
|
+
80: 'min-h-[70svh] md:min-h-[80vh]',
|
|
33
|
+
60: 'min-h-[50svh] md:min-h-[60vh]',
|
|
34
|
+
screen: 'min-h-dvh',
|
|
35
|
+
lg: 'min-h-dvh',
|
|
36
|
+
md: 'min-h-[50svh] md:min-h-[60vh]',
|
|
37
|
+
}
|
|
38
|
+
|
|
25
39
|
/**
|
|
26
40
|
* Background layer: a media descriptor becomes a cover-fit Image / HlsVideo /
|
|
27
41
|
* inert <video> (`.kol-full-bleed-hero-media` pins it absolute + object-cover
|
|
@@ -110,7 +124,8 @@ function MediaLayer({ media }) {
|
|
|
110
124
|
* @param {string} height 'full' | '80' | '60' (viewport tiers) · 'lg' | 'md' | 'screen' (aliases) · or a height class string
|
|
111
125
|
* @param {ReactNode} label · headline · body · actions the composed text (SectionText)
|
|
112
126
|
* @param {object} slotClass · slotStyle per-slot class / style, forwarded to SectionText (a consumer's reveal seam)
|
|
113
|
-
* @param {string}
|
|
127
|
+
* @param {string} headlineSize role; defaults per variant — media 'display-04', split 'heading-02'
|
|
128
|
+
* @param {string} gap SectionText's inner rhythm, forwarded as given (no hero default)
|
|
114
129
|
* @param {string} [panelMaxWidth='max-w-[440px]'] the glass panel's cap on the composed route
|
|
115
130
|
* @param {object} panelProps everything else on the glass panel (user ask 2026-08-26):
|
|
116
131
|
* `padding` ('px-6 py-8') · `maxWidth` · `surfaceOpacity`
|
|
@@ -146,7 +161,11 @@ export default function SectionHero({
|
|
|
146
161
|
height = 'lg',
|
|
147
162
|
label,
|
|
148
163
|
headline,
|
|
149
|
-
|
|
164
|
+
/* per-variant DEFAULT only — the hero has no say in the text's voice
|
|
165
|
+
* (SectionHeroNoOverrides, 2026-08-26): media 'display-04', split
|
|
166
|
+
* 'heading-02'; the consumer's value wins */
|
|
167
|
+
headlineSize,
|
|
168
|
+
gap,
|
|
150
169
|
body,
|
|
151
170
|
actions,
|
|
152
171
|
panelMaxWidth = 'max-w-[440px]',
|
|
@@ -167,20 +186,22 @@ export default function SectionHero({
|
|
|
167
186
|
? <ContentMedia ratio={null} radius={false} fit="cover" className="h-full">{media}</ContentMedia>
|
|
168
187
|
: <MediaLayer media={media} />
|
|
169
188
|
return (
|
|
170
|
-
<section className={`kol-section-hero-split grid grid-cols-1 md:grid-cols-2 ${
|
|
171
|
-
|
|
189
|
+
<section className={`kol-section-hero-split grid grid-cols-1 md:grid-cols-2 ${SPLIT_HEIGHTS[height] || height} ${bleed} ${className}`.replace(/\s+/g, ' ').trim()}>
|
|
190
|
+
{/* the half sizes itself off the grid row (`h-full min-h-0`) so an
|
|
191
|
+
* absolute media node — the descriptor's cover-fit img — fills it */}
|
|
192
|
+
<div className={`relative h-full min-h-[50vh] overflow-hidden md:min-h-0 ${mediaFirst ? '' : 'md:order-2'}`.trim()}>{mediaNode}</div>
|
|
172
193
|
<div className={`flex items-center justify-center p-10 ${mediaFirst ? '' : 'md:order-1'}`.trim()}>
|
|
194
|
+
{/* BARE — the molecule's own voice; `headlineCase="upper"` is the
|
|
195
|
+
* split hero's one trait, a role on SectionText (SectionHeroNoOverrides) */}
|
|
173
196
|
<SectionText
|
|
174
197
|
label={label}
|
|
175
198
|
headline={headline}
|
|
176
|
-
headlineSize={headlineSize
|
|
177
|
-
|
|
199
|
+
headlineSize={headlineSize ?? 'heading-02'}
|
|
200
|
+
headlineCase="upper"
|
|
178
201
|
body={body}
|
|
179
202
|
actions={actions}
|
|
180
203
|
align="center"
|
|
181
|
-
gap=
|
|
182
|
-
bodyClass="kol-sans-body-02 text-body"
|
|
183
|
-
actionsClass="flex flex-wrap gap-4 justify-center"
|
|
204
|
+
gap={gap}
|
|
184
205
|
className="max-w-[var(--kol-content-column)]"
|
|
185
206
|
slotClass={slotClass}
|
|
186
207
|
slotStyle={slotStyle}
|
|
@@ -231,18 +252,20 @@ export default function SectionHero({
|
|
|
231
252
|
}
|
|
232
253
|
|
|
233
254
|
const text = composed ? (
|
|
255
|
+
/* BARE (SectionHeroNoOverrides, user 2026-08-26: "you think the purpose
|
|
256
|
+
* of unifying components is to make OVERWRITES?") — the hero passes the
|
|
257
|
+
* slots and nothing about their voice. The old glass hero's gap-6 /
|
|
258
|
+
* body-02 / caps were pixel parity with a retired component, and parity
|
|
259
|
+
* with it is not the bar; one voice across the set is. `gap` is the
|
|
260
|
+
* consumer's if they want it. */
|
|
234
261
|
<SectionText
|
|
235
262
|
label={label}
|
|
236
263
|
headline={headline}
|
|
237
|
-
headlineSize={headlineSize}
|
|
264
|
+
headlineSize={headlineSize ?? 'display-04'}
|
|
238
265
|
body={body}
|
|
239
266
|
actions={actions}
|
|
240
267
|
align={align === 'center' ? 'center' : 'start'}
|
|
241
|
-
|
|
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' : ''}`}
|
|
268
|
+
gap={gap}
|
|
246
269
|
className={media == null ? `${panelMaxWidth} mx-auto` : ''}
|
|
247
270
|
slotClass={slotClass}
|
|
248
271
|
slotStyle={slotStyle}
|