@kolkrabbi/kol-component 0.82.0 → 0.83.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.
|
|
3
|
+
"version": "0.83.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,6 +1,7 @@
|
|
|
1
1
|
import SectionCardItem from '../molecules/SectionCardItem.jsx'
|
|
2
2
|
import SectionText, { HEADLINE_ROLE } from '../molecules/SectionText.jsx'
|
|
3
3
|
import useSectionTheme from '../hooks/useSectionTheme.js'
|
|
4
|
+
import { minHeightClass } from './sectionHeights.js'
|
|
4
5
|
|
|
5
6
|
/**
|
|
6
7
|
* SectionCards — the "N-up feature cards" band: a `SectionText` header over a
|
|
@@ -18,6 +19,8 @@ import useSectionTheme from '../hooks/useSectionTheme.js'
|
|
|
18
19
|
* `inverse` = the paired theme of the nearest live one, following the toggle;
|
|
19
20
|
* `light` / `dark` pinned; omit to inherit. Stamps `data-theme` on the root and
|
|
20
21
|
* paints its surface — every token inside resolves to the other theme's.
|
|
22
|
+
* @param {'full'|'80'|'60'|string} [height='60'] min-height on the family's ladder — full = 100dvh,
|
|
23
|
+
* 80 = 70svh / 80vh, 60 = 50svh / 60vh (default); content stays vertically centred inside it
|
|
21
24
|
* @param {{title, icon, visual, description, href, backgroundColor, imageAspectRatio}[]} features
|
|
22
25
|
* @param {ReactNode} label · headline · body the header (heading-03 + mono lede by default)
|
|
23
26
|
* @param {ReactNode} actions centred action row under the cards
|
|
@@ -29,6 +32,7 @@ import useSectionTheme from '../hooks/useSectionTheme.js'
|
|
|
29
32
|
*/
|
|
30
33
|
export default function SectionCards({
|
|
31
34
|
theme,
|
|
35
|
+
height = '60',
|
|
32
36
|
features = [],
|
|
33
37
|
label,
|
|
34
38
|
headline,
|
|
@@ -53,7 +57,7 @@ export default function SectionCards({
|
|
|
53
57
|
}) {
|
|
54
58
|
const [themeRef, themeStamp] = useSectionTheme(theme)
|
|
55
59
|
return (
|
|
56
|
-
<section ref={themeRef} data-theme={themeStamp} className={`w-full ${theme ? 'bg-surface-primary' : ''} ${sectionClassName}`.replace(/\s+/g, ' ').trim()}>
|
|
60
|
+
<section ref={themeRef} data-theme={themeStamp} className={`w-full flex flex-col justify-center ${minHeightClass(height)} ${theme ? 'bg-surface-primary' : ''} ${sectionClassName}`.replace(/\s+/g, ' ').trim()}>
|
|
57
61
|
<div className={wrapperClassName}>
|
|
58
62
|
{(label || headline || body) && (
|
|
59
63
|
<SectionText
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import Button from '../atoms/Button.jsx'
|
|
2
2
|
import SectionText from '../molecules/SectionText.jsx'
|
|
3
|
+
import { minHeightClass } from './sectionHeights.js'
|
|
3
4
|
|
|
4
5
|
/**
|
|
5
6
|
* SectionCta — the editorial two-column contact/CTA band: a large display
|
|
@@ -14,6 +15,8 @@ import SectionText from '../molecules/SectionText.jsx'
|
|
|
14
15
|
* heading, a mono line and Buttons, centred — which was `FoundryCTA`, a second
|
|
15
16
|
* way to render SectionText. FoundryCTA is its deprecated alias.
|
|
16
17
|
*
|
|
18
|
+
* @param {'full'|'80'|'60'|string} [height='60'] min-height on the family's ladder — full = 100dvh,
|
|
19
|
+
* 80 = 70svh / 80vh, 60 = 50svh / 60vh (default); content stays vertically centred inside it
|
|
17
20
|
* @param {'editorial'|'centered'} variant
|
|
18
21
|
* @param {ReactNode} headline · body · actions centered: the SectionText slots
|
|
19
22
|
* @param {ReactNode} eyebrow left-column display wordmark (kol-sans-display-01)
|
|
@@ -26,6 +29,7 @@ import SectionText from '../molecules/SectionText.jsx'
|
|
|
26
29
|
*/
|
|
27
30
|
export default function SectionCta({
|
|
28
31
|
variant = 'editorial',
|
|
32
|
+
height = '60',
|
|
29
33
|
headline,
|
|
30
34
|
body,
|
|
31
35
|
actions,
|
|
@@ -41,8 +45,8 @@ export default function SectionCta({
|
|
|
41
45
|
}) {
|
|
42
46
|
if (variant === 'centered') {
|
|
43
47
|
return (
|
|
44
|
-
<section className={`w-full py-24 ${className}`.trim()}>
|
|
45
|
-
<div className="max-w-[var(--kol-container-max,var(--kol-content-shell,1800px))] mx-auto">
|
|
48
|
+
<section className={`w-full flex flex-col justify-center py-24 ${minHeightClass(height)} ${className}`.replace(/\s+/g, ' ').trim()}>
|
|
49
|
+
<div className="w-full max-w-[var(--kol-container-max,var(--kol-content-shell,1800px))] mx-auto">
|
|
46
50
|
<div className="w-32 h-px bg-fg-24 mx-auto mb-8" />
|
|
47
51
|
<SectionText
|
|
48
52
|
align="center"
|
|
@@ -68,7 +72,7 @@ export default function SectionCta({
|
|
|
68
72
|
...(email ? [{ label: contactLabel, value: email, href: `mailto:${email}` }] : []),
|
|
69
73
|
]
|
|
70
74
|
return (
|
|
71
|
-
<section className={`w-full bg-auto ${className}`.trim()}>
|
|
75
|
+
<section className={`w-full bg-auto flex flex-col justify-center ${minHeightClass(height)} ${className}`.replace(/\s+/g, ' ').trim()}>
|
|
72
76
|
{/* the family's ONE cap — the shell's --kol-container-max ladder (user
|
|
73
77
|
* ruling 2026-08-26; the 1600 SectionCtaEditorial asked for was a third
|
|
74
78
|
* number beside split's 1200 and cards' 1400) — the surface stays full
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { useState } from 'react'
|
|
2
2
|
import { Accordion, AccordionPanel } from '../molecules/Accordion.jsx'
|
|
3
3
|
import SectionText from '../molecules/SectionText.jsx'
|
|
4
|
+
import { minHeightClass } from './sectionHeights.js'
|
|
4
5
|
|
|
5
6
|
/**
|
|
6
7
|
* SectionFaq — a `SectionText` header over an `Accordion` of question /
|
|
@@ -10,6 +11,8 @@ import SectionText from '../molecules/SectionText.jsx'
|
|
|
10
11
|
*
|
|
11
12
|
* @param {ReactNode} label · headline · body · actions the header (SectionText)
|
|
12
13
|
* @param {string} [headlineSize='heading-02']
|
|
14
|
+
* @param {'full'|'80'|'60'|string} [height='60'] min-height on the family's ladder — full = 100dvh,
|
|
15
|
+
* 80 = 70svh / 80vh, 60 = 50svh / 60vh (default); content stays vertically centred inside it
|
|
13
16
|
* @param {{ q: ReactNode, a: ReactNode, meta?: ReactNode }[]} items
|
|
14
17
|
* @param {boolean} [singleOpen=false] opening one panel closes the others
|
|
15
18
|
* @param {number} [defaultOpen] index open on mount (singleOpen) — omit for all closed
|
|
@@ -24,6 +27,7 @@ export default function SectionFaq({
|
|
|
24
27
|
items = [],
|
|
25
28
|
singleOpen = false,
|
|
26
29
|
defaultOpen,
|
|
30
|
+
height = '60',
|
|
27
31
|
slotClass,
|
|
28
32
|
slotStyle,
|
|
29
33
|
className = '',
|
|
@@ -33,8 +37,8 @@ export default function SectionFaq({
|
|
|
33
37
|
}) {
|
|
34
38
|
const [open, setOpen] = useState(defaultOpen ?? null)
|
|
35
39
|
return (
|
|
36
|
-
<section className={`kol-section-faq w-full px-5 py-16 md:px-8 md:py-24 lg:px-14 ${className}`.trim()}>
|
|
37
|
-
<div className="max-w-[var(--kol-container-max,var(--kol-content-shell,1800px))] mx-auto">
|
|
40
|
+
<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()}>
|
|
41
|
+
<div className="w-full max-w-[var(--kol-container-max,var(--kol-content-shell,1800px))] mx-auto">
|
|
38
42
|
<div className={innerClassName}>
|
|
39
43
|
{(label || headline || body || actions) && (
|
|
40
44
|
<SectionText label={label} headline={headline} headlineSize={headlineSize} body={body} actions={actions} slotClass={slotClass} slotStyle={slotStyle} />
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import SectionText from '../molecules/SectionText.jsx'
|
|
2
2
|
import useSectionTheme from '../hooks/useSectionTheme.js'
|
|
3
|
+
import { minHeightClass } from './sectionHeights.js'
|
|
3
4
|
|
|
4
5
|
/**
|
|
5
6
|
* SectionSplit — the media-and-text split section, on `SectionText` (the
|
|
@@ -46,16 +47,6 @@ import useSectionTheme from '../hooks/useSectionTheme.js'
|
|
|
46
47
|
* @param {object} slotClass · slotStyle per-slot class / style on the text block (reveal seam)
|
|
47
48
|
* @param {string} className · innerClassName · columnClassName layout seams
|
|
48
49
|
*/
|
|
49
|
-
/* The family's height ladder, as MIN-height — content may still grow, the two
|
|
50
|
-
* columns stay centred (SectionSplitHeight, kol-website 2026-08-27: "we need
|
|
51
|
-
* to set some sizes"). Same three names as SectionHero's presets, literal
|
|
52
|
-
* strings (the SPLIT_HEIGHTS lesson — a class built at runtime is not a
|
|
53
|
-
* class); anything else passes through as a class string. */
|
|
54
|
-
const MIN_HEIGHTS = {
|
|
55
|
-
full: 'min-h-dvh',
|
|
56
|
-
80: 'min-h-[70svh] md:min-h-[80vh]',
|
|
57
|
-
60: 'min-h-[50svh] md:min-h-[60vh]',
|
|
58
|
-
}
|
|
59
50
|
|
|
60
51
|
export default function SectionSplit({
|
|
61
52
|
theme,
|
|
@@ -95,7 +86,7 @@ export default function SectionSplit({
|
|
|
95
86
|
<section
|
|
96
87
|
ref={themeRef}
|
|
97
88
|
data-theme={themeStamp}
|
|
98
|
-
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 ${
|
|
89
|
+
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 ${minHeightClass(height)} ${bleed} ${className}`.replace(/\s+/g, ' ').trim()}
|
|
99
90
|
style={sectionStyle}
|
|
100
91
|
>
|
|
101
92
|
{/* ONE cap for the whole section family (user ruling 2026-08-26): the shell's
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
/* The section family's height ladder, as MIN-height — content may still grow,
|
|
2
|
+
* the content stays vertically centred inside it (SectionSplitHeight →
|
|
3
|
+
* SectionHeightLadder, kol-website 2026-08-27: "we need to set some sizes").
|
|
4
|
+
* Same three names as SectionHero's presets; literal strings — a class built
|
|
5
|
+
* at runtime is not a class (the SPLIT_HEIGHTS lesson). Anything else passes
|
|
6
|
+
* through as a class string. */
|
|
7
|
+
export const MIN_HEIGHTS = {
|
|
8
|
+
full: 'min-h-dvh',
|
|
9
|
+
80: 'min-h-[70svh] md:min-h-[80vh]',
|
|
10
|
+
60: 'min-h-[50svh] md:min-h-[60vh]',
|
|
11
|
+
}
|
|
12
|
+
export const minHeightClass = (height) => MIN_HEIGHTS[height] || height
|