@kolkrabbi/kol-component 0.101.0 → 0.102.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.102.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",
|
package/src/index.js
CHANGED
|
@@ -137,7 +137,7 @@ export { default as LoaderOverlay } from './utilities/LoaderOverlay.jsx'
|
|
|
137
137
|
export { default as MediaLibrary, MediaLibraryProvider, useMediaLibrary, MediaPicker, MediaBrowser } from './organisms/MediaLibrary.jsx'
|
|
138
138
|
export { default as MediaTileGallery } from './organisms/MediaTileGallery.jsx'
|
|
139
139
|
export { default as MediaViewer } from './organisms/MediaViewer.jsx'
|
|
140
|
-
export { default as SettingsPanel, SettingsRow, SettingsSwitch, SettingsChoice, SettingsChipRow, SettingsFooter } from './organisms/SettingsPanel.jsx'
|
|
140
|
+
export { default as SettingsPanel, SettingsSection, SettingsRow, SettingsSwitch, SettingsChoice, SettingsChipRow, SettingsFooter } from './organisms/SettingsPanel.jsx'
|
|
141
141
|
export { default as SectionNewsletter } from './organisms/SectionNewsletter.jsx'
|
|
142
142
|
export { default as NewsletterBand } from './organisms/NewsletterBand.jsx'
|
|
143
143
|
export { default as ColumnBrowser } from './organisms/ColumnBrowser.jsx'
|
|
@@ -107,7 +107,10 @@ export default function ContentCollection({
|
|
|
107
107
|
gridTemplateColumns: colsCls
|
|
108
108
|
? undefined
|
|
109
109
|
: form === 'list'
|
|
110
|
-
|
|
110
|
+
/* minmax(0, 1fr), never a bare 1fr (= minmax(auto, 1fr)): a truncated
|
|
111
|
+
* nowrap line handed its min-content width to the track and a /work row
|
|
112
|
+
* measured 3586px in a 1232px wall (CollectionItemMinWidth, 2026-08-27) */
|
|
113
|
+
? (listMin ? `repeat(auto-fill, minmax(${listMin}, 1fr))` : 'minmax(0, 1fr)')
|
|
111
114
|
: `repeat(auto-fill, minmax(${min}, 1fr))`,
|
|
112
115
|
gap: g,
|
|
113
116
|
}}
|
|
@@ -116,7 +119,10 @@ export default function ContentCollection({
|
|
|
116
119
|
child == null ? null : (
|
|
117
120
|
<li
|
|
118
121
|
key={child.key ?? i}
|
|
119
|
-
|
|
122
|
+
/* min-w-0 on every item: a grid item's min-width is auto by default,
|
|
123
|
+
* and auto = min-content, which is exactly what a truncated line must
|
|
124
|
+
* not get to claim */
|
|
125
|
+
className={`min-w-0 ${animate ? 'kol-collection-item' : ''}`.trim()}
|
|
120
126
|
style={animate ? { animationDelay: `${i * 40}ms` } : undefined}
|
|
121
127
|
>
|
|
122
128
|
{child}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import Button from '../atoms/Button.jsx'
|
|
2
|
-
import
|
|
2
|
+
import Dropdown from '../molecules/Dropdown.jsx'
|
|
3
|
+
import SectionLabel from '../atoms/SectionLabel.jsx'
|
|
3
4
|
import ToggleSwitch from '../atoms/ToggleSwitch.jsx'
|
|
4
5
|
import ShellDrawer from '../molecules/ShellDrawer.jsx'
|
|
5
6
|
import FullscreenOverlay from '../utilities/FullscreenOverlay.jsx'
|
|
@@ -21,7 +22,7 @@ import FullscreenOverlay from '../utilities/FullscreenOverlay.jsx'
|
|
|
21
22
|
* where the DS already owned one.
|
|
22
23
|
*
|
|
23
24
|
* The CONTROLS are the DS controls, not the source's word-buttons: a switch
|
|
24
|
-
* row is `ToggleSwitch`, a choice row is `
|
|
25
|
+
* row is `ToggleSwitch`, a choice row is a `Dropdown` (2026-08-27) — the source's
|
|
25
26
|
* segmented variant was flagged by the user as the thing to fix here, not to
|
|
26
27
|
* copy. Sections are the DS `Section` (pass `divided` on every one and the
|
|
27
28
|
* hairline lands between siblings on its own).
|
|
@@ -129,11 +130,26 @@ export function SettingsSwitch({ on = false, onChange, disabled = false, disable
|
|
|
129
130
|
)
|
|
130
131
|
}
|
|
131
132
|
|
|
132
|
-
/**
|
|
133
|
-
*
|
|
134
|
-
|
|
133
|
+
/** SettingsSection — a section of the panel: the estate's section label (the DS
|
|
134
|
+
* `SectionLabel`, sm — SettingsPanelEyebrowAndDropdowns, user 2026-08-27: "it's
|
|
135
|
+
* literally SECTION LABEL, SUPER COMMON PATTERN") over its rows.
|
|
136
|
+
* @param {string} label · @param {boolean} divided a hairline above (between sections) */
|
|
137
|
+
export function SettingsSection({ label, divided = false, children, className = '' }) {
|
|
138
|
+
return (
|
|
139
|
+
<div className={`flex flex-col gap-3 ${divided ? 'kol-section--divided' : ''} ${className}`.replace(/\s+/g, ' ').trim()}>
|
|
140
|
+
{label && <SectionLabel text={label} size="sm" />}
|
|
141
|
+
{children}
|
|
142
|
+
</div>
|
|
143
|
+
)
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
/** SettingsChoice — the row's one-of-N control: the DS Dropdown, sm · primary
|
|
147
|
+
* (SettingsPanelEyebrowAndDropdowns — user: "put the toggles inside a dropdown,
|
|
148
|
+
* because it's super messy like it is"). Options are values or `{ value, label }`;
|
|
149
|
+
* width is the call site's (`className="w-40"`). */
|
|
150
|
+
export function SettingsChoice({ options = [], value, onChange, ariaLabel, className = '' }) {
|
|
135
151
|
const opts = options.map((o) => (o != null && typeof o === 'object' ? o : { value: o, label: String(o) }))
|
|
136
|
-
return <
|
|
152
|
+
return <Dropdown size="sm" variant="primary" value={value} onChange={onChange} options={opts} className={className} aria-label={ariaLabel} />
|
|
137
153
|
}
|
|
138
154
|
|
|
139
155
|
/* THE CONTROL CHIP (SettingsPanelCompliance, user 2026-08-27: "WROOOONG" on the
|
|
@@ -146,15 +162,26 @@ export const chipCls = (on) => `${CHIP_CLS} ${on ? 'kol-control--filled' : 'text
|
|
|
146
162
|
|
|
147
163
|
/**
|
|
148
164
|
* SettingsChipRow — a wrap of toggle chips with optional counts (an
|
|
149
|
-
* allow-list: every chip sets a default, never a gate).
|
|
165
|
+
* allow-list: every chip sets a default, never a gate). `allChip` puts an
|
|
166
|
+
* "all" chip first — the same control chip, filled when every option is on
|
|
167
|
+
* (SettingsPanelEyebrowAndDropdowns — user: "Show all in ghost mode? makes no
|
|
168
|
+
* sense"); `onAll(nextAllOn)` fires when it is clicked.
|
|
150
169
|
* @param {Array} options [{ value, label, count? }]
|
|
151
170
|
* @param {Array|Set} selected the values that are on
|
|
152
171
|
* @param {Function} onToggle (value) => void
|
|
172
|
+
* @param {boolean|string} allChip render the "all" chip (a string = its label)
|
|
173
|
+
* @param {Function} onAll (nextAllOn: boolean) => void
|
|
153
174
|
*/
|
|
154
|
-
export function SettingsChipRow({ options = [], selected = [], onToggle }) {
|
|
175
|
+
export function SettingsChipRow({ options = [], selected = [], onToggle, allChip = false, onAll }) {
|
|
155
176
|
const on = selected instanceof Set ? selected : new Set(selected)
|
|
177
|
+
const allOn = options.length > 0 && options.every((o) => on.has(o.value))
|
|
156
178
|
return (
|
|
157
179
|
<div className="flex flex-wrap gap-1">
|
|
180
|
+
{allChip && (
|
|
181
|
+
<button type="button" aria-pressed={allOn} onClick={() => onAll?.(!allOn)} className={chipCls(allOn)}>
|
|
182
|
+
{typeof allChip === 'string' ? allChip : 'all'}
|
|
183
|
+
</button>
|
|
184
|
+
)}
|
|
158
185
|
{options.map((o) => (
|
|
159
186
|
<button
|
|
160
187
|
key={String(o.value)}
|