@kolkrabbi/kol-component 0.11.0 → 0.12.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.11.0",
3
+ "version": "0.12.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",
@@ -23,7 +23,7 @@
23
23
  "dependencies": {
24
24
  "@floating-ui/react": "^0.27.19",
25
25
  "embla-carousel-react": "^8.6.0",
26
- "@kolkrabbi/kol-icons": "0.7.0"
26
+ "@kolkrabbi/kol-icons": "0.7.1"
27
27
  },
28
28
  "peerDependencies": {
29
29
  "react": "^18.3.0 || ^19.0.0",
@@ -5,22 +5,26 @@ export default function SectionLabel({
5
5
  size = 'md',
6
6
  className = ''
7
7
  }) {
8
- // Size variants: sm (16px), md (20px), lg (32px)
8
+ // Size variants: sm (16px), md (20px), lg (32px).
9
+ // Migrated off the deleted legacy kol-label-* family (2026-07-15): current
10
+ // helper/heading classes, no text-transform — labels render as authored.
11
+ // (lg's old 'kol-heading-md' was a ghost class defined nowhere — rendered
12
+ // 16px default; kol-sans-heading-03 is the real 32px scale.)
9
13
  const sizeConfig = {
10
14
  sm: {
11
15
  height: 'h-4',
12
16
  iconSize: 16,
13
- textClass: 'kol-label-compact-md'
17
+ textClass: 'kol-helper-14'
14
18
  },
15
19
  md: {
16
20
  height: 'h-5',
17
21
  iconSize: 24,
18
- textClass: 'kol-label-compact-lg'
22
+ textClass: 'kol-helper-20'
19
23
  },
20
24
  lg: {
21
25
  height: 'h-8',
22
26
  iconSize: 40,
23
- textClass: 'kol-heading-md'
27
+ textClass: 'kol-sans-heading-03'
24
28
  }
25
29
  }
26
30
 
package/src/index.js CHANGED
@@ -104,6 +104,7 @@ export { default as ErrorBoundary } from './organisms/ErrorBoundary.jsx'
104
104
  export { default as FeatureSplit } from './organisms/FeatureSplit.jsx'
105
105
  export { default as FeaturedCarousel } from './organisms/FeaturedCarousel.jsx'
106
106
  export { default as FeaturesCardSection } from './organisms/FeaturesCardSection.jsx'
107
+ export { default as FoundryCTA } from './organisms/FoundryCTA.jsx'
107
108
  export { default as FullBleedHero } from './organisms/FullBleedHero.jsx'
108
109
  export { default as LoaderOverlay } from './organisms/LoaderOverlay.jsx'
109
110
  export { default as MediaTileGallery } from './organisms/MediaTileGallery.jsx'
@@ -1,4 +1,4 @@
1
- import { useEffect, useMemo, useState } from 'react'
1
+ import { useEffect, useId, useMemo, useState } from 'react'
2
2
  import Input from '../atoms/Input.jsx'
3
3
 
4
4
  /**
@@ -46,6 +46,10 @@ const Slider = ({
46
46
  displayWidth = 6,
47
47
  fontSize,
48
48
  }) => {
49
+ /* Label ↔ input pairing — the <label> is a sibling of the range input, so
50
+ * without an htmlFor/id pair the visible label confers no accessible name. */
51
+ const sliderId = useId()
52
+
49
53
  const handleChange = (e) => {
50
54
  if (onChange) {
51
55
  onChange(Number(e.target.value))
@@ -96,6 +100,7 @@ const Slider = ({
96
100
  <div className={`control-slider gap-3 shadow-none ${className}`}>
97
101
  {label && (
98
102
  <label
103
+ htmlFor={sliderId}
99
104
  className={`kol-helper-12 whitespace-nowrap shrink-0 w-fit ${disabled ? 'opacity-50' : ''}`}
100
105
  style={fontSize ? { fontSize } : undefined}
101
106
  >
@@ -103,6 +108,7 @@ const Slider = ({
103
108
  </label>
104
109
  )}
105
110
  <input
111
+ id={sliderId}
106
112
  type="range"
107
113
  min={min}
108
114
  max={max}
@@ -183,7 +183,8 @@ export default function FeaturedCarousel({
183
183
  >
184
184
  {showHeader && (
185
185
  <div className="mb-6 flex items-center gap-4">
186
- <span className="kol-label-mono-xs text-auto">{sectionLabel}</span>
186
+ {/* migrated off the deleted legacy kol-label-* family — label renders as authored */}
187
+ <span className="kol-helper-12 text-auto">{sectionLabel}</span>
187
188
  <span className="kol-mono-12 text-fg-64">{selectedIndex + 1} / {items.length}</span>
188
189
  </div>
189
190
  )}
@@ -0,0 +1,65 @@
1
+ import Button from '../atoms/Button.jsx'
2
+
3
+ /* taxonomy-ok: nests component's Button */
4
+
5
+ /**
6
+ * FoundryCTA — the simple centered tier of the CTA-band family: a centered
7
+ * column with a short rule line, a heading, a mono description, and one or
8
+ * more Button actions. CtaGlobal is the editorial two-column closer of the
9
+ * same family; this is the quiet mid-page tier (foundry pages, prints grid).
10
+ *
11
+ * Presentational — copy arrives as props and renders verbatim (no
12
+ * text-transform; author strings in their final case). Actions with an
13
+ * `href` render Button's anchor form; pass `onNavigate` for SPA routing —
14
+ * same `(href, event)` seam contract as WorkListItem — or omit it for plain
15
+ * anchors (external links, mailto:).
16
+ *
17
+ * @param {ReactNode} heading band heading (kol-sans-heading-02)
18
+ * @param {ReactNode} description supporting line (kol-mono-14, dimmed)
19
+ * @param {Object|Array} action one {href, label, variant?, target?, rel?} or an array;
20
+ * variant 'secondary' renders Button's outline treatment,
21
+ * anything else the primary fill
22
+ * @param {Function} onNavigate (href, event) => void — SPA-nav seam for internal links
23
+ * @param {string} className extra classes on the section
24
+ */
25
+ export default function FoundryCTA({
26
+ heading,
27
+ description,
28
+ action,
29
+ onNavigate,
30
+ className = '',
31
+ }) {
32
+ const actions = (Array.isArray(action) ? action : [action]).filter(Boolean)
33
+
34
+ return (
35
+ <section className={`w-full py-24 ${className}`.trim()}>
36
+ <div className="max-w-[900px] mx-auto text-center space-y-8">
37
+ <div className="w-32 h-px bg-fg-24 mx-auto" />
38
+
39
+ {heading && <h2 className="kol-sans-heading-02 text-auto">{heading}</h2>}
40
+
41
+ {description && (
42
+ <p className="kol-mono-14 text-fg-64 max-w-[600px] mx-auto">{description}</p>
43
+ )}
44
+
45
+ {actions.length > 0 && (
46
+ <div className={`pt-4 ${actions.length > 1 ? 'flex flex-col sm:flex-row gap-4 justify-center' : ''}`.trim()}>
47
+ {actions.map((act, i) => (
48
+ <Button
49
+ key={i}
50
+ variant={act.variant === 'secondary' ? 'outline' : 'primary'}
51
+ size="md"
52
+ href={act.href}
53
+ target={act.target}
54
+ rel={act.rel}
55
+ onClick={onNavigate ? (e) => onNavigate(act.href, e) : undefined}
56
+ >
57
+ {act.label}
58
+ </Button>
59
+ ))}
60
+ </div>
61
+ )}
62
+ </div>
63
+ </section>
64
+ )
65
+ }