@kolkrabbi/kol-component 0.200.0 → 0.201.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.200.0",
3
+ "version": "0.201.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",
package/src/index.js CHANGED
@@ -158,6 +158,9 @@ export { default as MediaLibrary, MediaLibraryProvider, useMediaLibrary, MediaPi
158
158
  export { default as MediaTileGallery } from './organisms/MediaTileGallery.jsx'
159
159
  export { default as MediaViewer } from './organisms/MediaViewer.jsx'
160
160
  export { default as SettingsPanel, LabeledControlSection, SettingsRow, SettingsSwitch, SettingsChoice, SettingsMulti, SettingsChipRow, SettingsFooter } from './organisms/SettingsPanel.jsx'
161
+ /* the settings BODY as data — one call for the page, the drawer and a sheet
162
+ * (user 2026-09-03: "lets normalise a component they can grab") */
163
+ export { default as SettingsSections } from './organisms/SettingsSections.jsx'
161
164
  export { default as SectionNewsletter } from './organisms/SectionNewsletter.jsx'
162
165
  export { default as NewsletterBand } from './organisms/NewsletterBand.jsx'
163
166
  export { default as ColumnBrowser } from './organisms/ColumnBrowser.jsx'
@@ -0,0 +1,63 @@
1
+ import { LabeledControlSection, SettingsRow } from './SettingsPanel.jsx'
2
+
3
+ /**
4
+ * SettingsSections — settings rows AS DATA, rendered once.
5
+ *
6
+ * The one component a consumer grabs for a settings body (user, 2026-09-03:
7
+ * *"lets normalise a component they can grab"*). The estate had the PIECES —
8
+ * `LabeledControlSection` for the eyebrow-headed section, `SettingsRow` for the
9
+ * 160px label column — and every surface looped over them itself: kol-fxr's
10
+ * `AppSettingsSections`, the settings page, the drawer, the shortcuts sheet.
11
+ * Four hand-written loops over one anatomy is how the sheet ended up with a
12
+ * plain `text-fg-32` heading and `fg-96` combos while the page two clicks away
13
+ * had eyebrows and `fg-32`.
14
+ *
15
+ * THE SECTIONS ARE A VALUE, so one declaration feeds every frame that shows
16
+ * them — the page, the drawer over what you are looking at, and a sheet:
17
+ *
18
+ * const sections = [
19
+ * { label: 'Canvas', rows: [
20
+ * { label: 'Default aspect', render: () => <SettingsChoice … /> },
21
+ * { label: 'Autoplay', render: () => <SettingsSwitch … /> },
22
+ * ] },
23
+ * ]
24
+ *
25
+ * <SettingsPanel open={open} onClose={close}><SettingsSections sections={sections} /></SettingsPanel>
26
+ * <SettingsScaffold renderContent={() => <SettingsSections sections={visible} />} />
27
+ *
28
+ * A row is `{ label, render, align?, id? }` — `render` returns the control, so
29
+ * the CONTROL stays the consumer's and this owns only the anatomy. A row may
30
+ * also carry a plain `value` instead of `render` when the right cell is just
31
+ * text (a keyboard combo, a version string), which is what lets the shortcuts
32
+ * sheet and the settings page's shortcut block be the same call.
33
+ *
34
+ * `divided` puts the hairline above a section — pass it on EVERY section, the
35
+ * first included: the rule is `.kol-section--divided + .kol-section--divided`,
36
+ * so the first draws nothing and skipping it just costs the next its line.
37
+ *
38
+ * @param {Array<{label?: string, rows: Array<{label: ReactNode, render?: Function, value?: ReactNode, align?: string, labelWidth?: number|'auto', id?: string}>, rowGap?: number}>} sections - The settings body, in order
39
+ * @param {boolean} [divided=false] - Hairline above each section
40
+ * @param {number|'auto'} [labelWidth] - Default label column for every row — `'auto'` makes the label yield and the control hug, which is what a narrow column or a nowrap value needs
41
+ * @param {string} [align] - Default row alignment passed to `SettingsRow`
42
+ * @param {string} [className] - Extra classes on the wrapper
43
+ */
44
+ export default function SettingsSections({ sections = [], divided = false, labelWidth, align, className = '' }) {
45
+ return (
46
+ <div className={`kol-settings-sections flex flex-col gap-6 ${className}`.trim()}>
47
+ {sections.map((sec, i) => (
48
+ <LabeledControlSection key={sec.label ?? i} label={sec.label} divided={divided} rowGap={sec.rowGap}>
49
+ {sec.rows.map((row, j) => (
50
+ <SettingsRow
51
+ key={row.id ?? row.label ?? j}
52
+ label={row.label}
53
+ align={row.align ?? align}
54
+ labelWidth={row.labelWidth ?? labelWidth}
55
+ >
56
+ {row.render ? row.render() : row.value}
57
+ </SettingsRow>
58
+ ))}
59
+ </LabeledControlSection>
60
+ ))}
61
+ </div>
62
+ )
63
+ }