@kolkrabbi/kol-component 0.102.3 → 0.103.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 +1 -1
- package/src/organisms/SectionCards.jsx +5 -1
- package/src/organisms/SectionCta.jsx +6 -2
- package/src/organisms/SectionFaq.jsx +5 -1
- package/src/organisms/SectionHero.jsx +5 -1
- package/src/organisms/SectionNewsletter.jsx +5 -1
- package/src/organisms/SectionSplit.jsx +5 -1
- package/src/organisms/sectionSurface.js +17 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@kolkrabbi/kol-component",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.103.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",
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import SectionCardItem from '../molecules/SectionCardItem.jsx'
|
|
2
|
+
import { surfaceClass } from './sectionSurface.js'
|
|
2
3
|
import SectionText, { HEADLINE_ROLE } from '../molecules/SectionText.jsx'
|
|
3
4
|
import useSectionTheme from '../hooks/useSectionTheme.js'
|
|
4
5
|
import { minHeightClass } from './sectionHeights.js'
|
|
@@ -29,9 +30,12 @@ import { minHeightClass } from './sectionHeights.js'
|
|
|
29
30
|
* @param {object|Function} itemStyle inline style per card, or `(index) => style`
|
|
30
31
|
* @param {object} slotClass · slotStyle per-slot class / style on the header text
|
|
31
32
|
* @param {string} sectionClassName · wrapperClassName · cardsWrapperClassName · actionsClassName · headerClassName · headerTextWidthClass layout seams
|
|
33
|
+
* @param {'primary'|'secondary'|'tertiary'|'inverse'|'auto'|'none'|string} background the section's surface
|
|
34
|
+
* (SectionBackgroundProp, 2026-08-27) — a named surface, `none`, or a raw utility / token string; default = what it painted before
|
|
32
35
|
*/
|
|
33
36
|
export default function SectionCards({
|
|
34
37
|
theme,
|
|
38
|
+
background,
|
|
35
39
|
height = '60',
|
|
36
40
|
features = [],
|
|
37
41
|
eyebrow,
|
|
@@ -60,7 +64,7 @@ export default function SectionCards({
|
|
|
60
64
|
const eb = eyebrow ?? label
|
|
61
65
|
const [themeRef, themeStamp] = useSectionTheme(theme)
|
|
62
66
|
return (
|
|
63
|
-
<section ref={themeRef} data-theme={themeStamp} className={`w-full flex flex-col justify-center ${minHeightClass(height)} ${theme ? '
|
|
67
|
+
<section ref={themeRef} data-theme={themeStamp} className={`w-full flex flex-col justify-center ${minHeightClass(height)} ${surfaceClass(background, theme ? 'primary' : 'none')} ${sectionClassName}`.replace(/\s+/g, ' ').trim()}>
|
|
64
68
|
<div className={wrapperClassName}>
|
|
65
69
|
{(eb || headline || body) && (
|
|
66
70
|
<SectionText
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import Button from '../atoms/Button.jsx'
|
|
2
|
+
import { surfaceClass } from './sectionSurface.js'
|
|
2
3
|
import SectionText from '../molecules/SectionText.jsx'
|
|
3
4
|
import { minHeightClass } from './sectionHeights.js'
|
|
4
5
|
|
|
@@ -26,9 +27,12 @@ import { minHeightClass } from './sectionHeights.js'
|
|
|
26
27
|
* @param {string} email contact-row value + `mailto:` target; omit to drop the row
|
|
27
28
|
* @param {{label: ReactNode, value: ReactNode, href?: string}[]} secondaryRows extra rows between prompt and contact
|
|
28
29
|
* @param {string} className extra classes on the section
|
|
30
|
+
* @param {'primary'|'secondary'|'tertiary'|'inverse'|'auto'|'none'|string} background the section's surface
|
|
31
|
+
* (SectionBackgroundProp, 2026-08-27) — a named surface, `none`, or a raw utility / token string; default = what it painted before
|
|
29
32
|
*/
|
|
30
33
|
export default function SectionCta({
|
|
31
34
|
variant = 'editorial',
|
|
35
|
+
background,
|
|
32
36
|
height = '60',
|
|
33
37
|
headline,
|
|
34
38
|
body,
|
|
@@ -45,7 +49,7 @@ export default function SectionCta({
|
|
|
45
49
|
}) {
|
|
46
50
|
if (variant === 'centered') {
|
|
47
51
|
return (
|
|
48
|
-
<section className={`w-full flex flex-col justify-center py-24 ${minHeightClass(height)} ${className}`.replace(/\s+/g, ' ').trim()}>
|
|
52
|
+
<section className={`w-full flex flex-col justify-center py-24 ${surfaceClass(background, 'auto')} ${minHeightClass(height)} ${className}`.replace(/\s+/g, ' ').trim()}>
|
|
49
53
|
<div className="w-full max-w-[var(--kol-container-max,var(--kol-content-shell,1800px))] mx-auto">
|
|
50
54
|
<div className="w-32 h-px bg-fg-24 mx-auto mb-8" />
|
|
51
55
|
<SectionText
|
|
@@ -72,7 +76,7 @@ export default function SectionCta({
|
|
|
72
76
|
...(email ? [{ label: contactLabel, value: email, href: `mailto:${email}` }] : []),
|
|
73
77
|
]
|
|
74
78
|
return (
|
|
75
|
-
<section className={`w-full
|
|
79
|
+
<section className={`w-full ${surfaceClass(background, 'auto')} flex flex-col justify-center ${minHeightClass(height)} ${className}`.replace(/\s+/g, ' ').trim()}>
|
|
76
80
|
{/* the family's ONE cap — the shell's --kol-container-max ladder (user
|
|
77
81
|
* ruling 2026-08-26; the 1600 SectionCtaEditorial asked for was a third
|
|
78
82
|
* number beside split's 1200 and cards' 1400) — the surface stays full
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { useState } from 'react'
|
|
2
|
+
import { surfaceClass } from './sectionSurface.js'
|
|
2
3
|
import { Accordion, AccordionPanel } from '../molecules/Accordion.jsx'
|
|
3
4
|
import SectionText from '../molecules/SectionText.jsx'
|
|
4
5
|
import { minHeightClass } from './sectionHeights.js'
|
|
@@ -17,6 +18,8 @@ import { minHeightClass } from './sectionHeights.js'
|
|
|
17
18
|
* @param {boolean} [singleOpen=false] opening one panel closes the others
|
|
18
19
|
* @param {number} [defaultOpen] index open on mount (singleOpen) — omit for all closed
|
|
19
20
|
* @param {string} className · innerClassName layout seams
|
|
21
|
+
* @param {'primary'|'secondary'|'tertiary'|'inverse'|'auto'|'none'|string} background the section's surface
|
|
22
|
+
* (SectionBackgroundProp, 2026-08-27) — a named surface, `none`, or a raw utility / token string; default = what it painted before
|
|
20
23
|
*/
|
|
21
24
|
export default function SectionFaq({
|
|
22
25
|
eyebrow,
|
|
@@ -29,6 +32,7 @@ export default function SectionFaq({
|
|
|
29
32
|
singleOpen = false,
|
|
30
33
|
defaultOpen,
|
|
31
34
|
height = '60',
|
|
35
|
+
background,
|
|
32
36
|
slotClass,
|
|
33
37
|
slotStyle,
|
|
34
38
|
className = '',
|
|
@@ -40,7 +44,7 @@ export default function SectionFaq({
|
|
|
40
44
|
const eb = eyebrow ?? label
|
|
41
45
|
const [open, setOpen] = useState(defaultOpen ?? null)
|
|
42
46
|
return (
|
|
43
|
-
<section className={`kol-section-faq w-full flex flex-col justify-center px-5 py-16 md:px-8 md:py-24 lg:px-14 ${minHeightClass(height)} ${className}`.replace(/\s+/g, ' ').trim()}>
|
|
47
|
+
<section className={`kol-section-faq w-full flex flex-col justify-center px-5 py-16 md:px-8 md:py-24 lg:px-14 ${minHeightClass(height)} ${surfaceClass(background, 'none')} ${className}`.replace(/\s+/g, ' ').trim()}>
|
|
44
48
|
<div className="w-full max-w-[var(--kol-container-max,var(--kol-content-shell,1800px))] mx-auto">
|
|
45
49
|
<div className={innerClassName}>
|
|
46
50
|
{(eb || headline || body || actions) && (
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { isValidElement } from 'react'
|
|
2
|
+
import { surfaceClass } from './sectionSurface.js'
|
|
2
3
|
import HlsVideo from '../atoms/HlsVideo.jsx'
|
|
3
4
|
import Image from '../atoms/Image.jsx'
|
|
4
5
|
import OverlayGlassPanel from '../utilities/OverlayGlassPanel.jsx'
|
|
@@ -143,10 +144,13 @@ function MediaLayer({ media }) {
|
|
|
143
144
|
* split: 'left' | 'right' — the media side
|
|
144
145
|
* @param {boolean} fullBleed span the full viewport width (100vw breakout) — split
|
|
145
146
|
* @param {string} className extra classes on the section
|
|
147
|
+
* @param {'primary'|'secondary'|'tertiary'|'inverse'|'auto'|'none'|string} background the section's surface
|
|
148
|
+
* (SectionBackgroundProp, 2026-08-27) — a named surface, `none`, or a raw utility / token string; default = what it painted before
|
|
146
149
|
*/
|
|
147
150
|
export default function SectionHero({
|
|
148
151
|
variant = 'media',
|
|
149
152
|
theme,
|
|
153
|
+
background,
|
|
150
154
|
fullBleed = false,
|
|
151
155
|
media,
|
|
152
156
|
overlayOpacity = 0,
|
|
@@ -189,7 +193,7 @@ export default function SectionHero({
|
|
|
189
193
|
/* `label` = alias of `eyebrow` (2026-08-27) */
|
|
190
194
|
const eb = eyebrow ?? label
|
|
191
195
|
const [themeRef, themeStamp] = useSectionTheme(theme)
|
|
192
|
-
const themed = theme ? '
|
|
196
|
+
const themed = surfaceClass(background, theme ? 'primary' : 'none')
|
|
193
197
|
|
|
194
198
|
if (variant === 'split') {
|
|
195
199
|
const mediaFirst = align !== 'right'
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { useId, useState } from 'react'
|
|
2
|
+
import { surfaceClass } from './sectionSurface.js'
|
|
2
3
|
import Input from '../atoms/Input.jsx'
|
|
3
4
|
import Button from '../atoms/Button.jsx'
|
|
4
5
|
import SectionText from '../molecules/SectionText.jsx'
|
|
@@ -44,10 +45,13 @@ import { minHeightClass } from './sectionHeights.js'
|
|
|
44
45
|
* @param {string} inputId id override for the email input (default useId-generated)
|
|
45
46
|
* @param {object} slotClass · slotStyle per-slot class / style on the SectionText (reveal seam)
|
|
46
47
|
* @param {string} className extra classes on the section
|
|
48
|
+
* @param {'primary'|'secondary'|'tertiary'|'inverse'|'auto'|'none'|string} background the section's surface
|
|
49
|
+
* (SectionBackgroundProp, 2026-08-27) — a named surface, `none`, or a raw utility / token string; default = what it painted before
|
|
47
50
|
*/
|
|
48
51
|
export default function SectionNewsletter({
|
|
49
52
|
height = '60',
|
|
50
53
|
theme,
|
|
54
|
+
background,
|
|
51
55
|
eyebrow,
|
|
52
56
|
label,
|
|
53
57
|
headline,
|
|
@@ -99,7 +103,7 @@ export default function SectionNewsletter({
|
|
|
99
103
|
id={id}
|
|
100
104
|
ref={themeRef}
|
|
101
105
|
data-theme={themeStamp}
|
|
102
|
-
className={`kol-section-newsletter w-full flex flex-col justify-center py-24 ${theme ? '
|
|
106
|
+
className={`kol-section-newsletter w-full flex flex-col justify-center py-24 ${surfaceClass(background, theme ? 'primary' : 'none')} ${theme ? 'text-auto' : ''} ${minHeightClass(height)} ${className}`.replace(/\s+/g, ' ').trim()}
|
|
103
107
|
>
|
|
104
108
|
{/* the family's ONE cap — the shell's --kol-container-max ladder — and
|
|
105
109
|
* inside it the lede's MEASURE on a wrapper (SectionNewsletterForm,
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import SectionText from '../molecules/SectionText.jsx'
|
|
2
|
+
import { surfaceClass } from './sectionSurface.js'
|
|
2
3
|
import useSectionTheme from '../hooks/useSectionTheme.js'
|
|
3
4
|
import { minHeightClass } from './sectionHeights.js'
|
|
4
5
|
|
|
@@ -50,10 +51,13 @@ import { minHeightClass } from './sectionHeights.js'
|
|
|
50
51
|
* @param {boolean} fullBleed span the full viewport width
|
|
51
52
|
* @param {object} slotClass · slotStyle per-slot class / style on the text block (reveal seam)
|
|
52
53
|
* @param {string} className · innerClassName · columnClassName layout seams
|
|
54
|
+
* @param {'primary'|'secondary'|'tertiary'|'inverse'|'auto'|'none'|string} background the section's surface
|
|
55
|
+
* (SectionBackgroundProp, 2026-08-27) — a named surface, `none`, or a raw utility / token string; default = what it painted before
|
|
53
56
|
*/
|
|
54
57
|
|
|
55
58
|
export default function SectionSplit({
|
|
56
59
|
theme,
|
|
60
|
+
background,
|
|
57
61
|
eyebrow,
|
|
58
62
|
label,
|
|
59
63
|
headline,
|
|
@@ -93,7 +97,7 @@ export default function SectionSplit({
|
|
|
93
97
|
<section
|
|
94
98
|
ref={themeRef}
|
|
95
99
|
data-theme={themeStamp}
|
|
96
|
-
className={`kol-section-split flex flex-col justify-center px-5 py-16 md:px-8 md:py-24 lg:px-14 lg:py-32 [--kol-section-py:4rem] md:[--kol-section-py:6rem] lg:[--kol-section-py:8rem] ${minHeightClass(height)} ${bleed} ${className}`.replace(/\s+/g, ' ').trim()}
|
|
100
|
+
className={`kol-section-split flex flex-col justify-center px-5 py-16 md:px-8 md:py-24 lg:px-14 lg:py-32 [--kol-section-py:4rem] md:[--kol-section-py:6rem] lg:[--kol-section-py:8rem] ${minHeightClass(height)} ${surfaceClass(background, 'none')} ${bleed} ${className}`.replace(/\s+/g, ' ').trim()}
|
|
97
101
|
style={sectionStyle}
|
|
98
102
|
>
|
|
99
103
|
{/* ONE cap for the whole section family (user ruling 2026-08-26): the shell's
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
/* ONE surface prop across the section family (SectionBackgroundProp, kol-website
|
|
2
|
+
* 2026-08-27 — user: "ALL section family should pass bg as props"). A named
|
|
3
|
+
* surface, `none`, or a raw utility / token string for the odd case
|
|
4
|
+
* (`'bg-fg-absolute-16'`). Each section's default is what it painted before,
|
|
5
|
+
* so nothing moves on the bump. `theme` keeps scoping ink; this is the paint. */
|
|
6
|
+
export const SURFACES = {
|
|
7
|
+
primary: 'bg-surface-primary',
|
|
8
|
+
secondary: 'bg-surface-secondary',
|
|
9
|
+
tertiary: 'bg-surface-tertiary',
|
|
10
|
+
inverse: 'bg-surface-inverse',
|
|
11
|
+
auto: 'bg-auto',
|
|
12
|
+
none: '',
|
|
13
|
+
}
|
|
14
|
+
export const surfaceClass = (background, fallback = 'none') => {
|
|
15
|
+
const key = background ?? fallback
|
|
16
|
+
return key in SURFACES ? SURFACES[key] : key
|
|
17
|
+
}
|