@kolkrabbi/kol-component 0.168.0 → 0.170.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.170.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",
|
|
@@ -38,6 +38,7 @@ const FOCUSABLE =
|
|
|
38
38
|
* @param {number|string} height panel height (px number or CSS length); omit for a content-sized sheet — `bottom` only
|
|
39
39
|
* @param {ReactNode} header header-row content beside the close button (replaces the source's baked-in wordmark)
|
|
40
40
|
* @param {boolean} backdrop render the dimming scrim (default true); false = panel alone, no darken/blur, close via × / Esc
|
|
41
|
+
* @param {'xs'|'sm'|'md'|'lg'} closeSize the close control's rung (default 'sm' — match the controls in the panel)
|
|
41
42
|
* @param {ReactNode} children scrollable panel body
|
|
42
43
|
* @param {string} className extra classes on the panel
|
|
43
44
|
*/
|
|
@@ -50,6 +51,14 @@ export default function ShellDrawer({
|
|
|
50
51
|
header,
|
|
51
52
|
closeSide = 'end',
|
|
52
53
|
backdrop = true,
|
|
54
|
+
/* THE CLOSE SITS ON THE ROW'S RUNG (user 2026-09-03, on the settings drawer:
|
|
55
|
+
* *"does this button follow the size ladder?"*). It was pinned `md` (32) while
|
|
56
|
+
* every control in the panel below it — the switches, the dropdowns, the reset
|
|
57
|
+
* frame — is `sm` (26), so the one control that is not a setting was the
|
|
58
|
+
* largest thing on the surface. A size is a height and a row is one height;
|
|
59
|
+
* `sm` is the default because a drawer header sits over its own controls.
|
|
60
|
+
* Named `closeSize`, not `size` — `size` is already the panel's own box. */
|
|
61
|
+
closeSize = 'sm',
|
|
53
62
|
children,
|
|
54
63
|
className = '',
|
|
55
64
|
/* SettingsPanelApproved (2026-08-27): the settings drawer has neither */
|
|
@@ -207,7 +216,7 @@ export default function ShellDrawer({
|
|
|
207
216
|
{closeSide !== 'start' && (
|
|
208
217
|
<Button
|
|
209
218
|
variant="nav"
|
|
210
|
-
size=
|
|
219
|
+
size={closeSize}
|
|
211
220
|
iconOnly="x"
|
|
212
221
|
onClick={onClose}
|
|
213
222
|
aria-label="Close"
|
|
@@ -329,10 +329,18 @@ export function MediaLibraryBrowse({
|
|
|
329
329
|
const crumbs = prefix ? prefix.replace(/\/$/, '').split('/') : []
|
|
330
330
|
|
|
331
331
|
/* the virtual root — one browser for the whole client: root row = the title,
|
|
332
|
-
* its children the buckets, stepping into one IS the bucket switch
|
|
332
|
+
* its children the buckets, stepping into one IS the bucket switch.
|
|
333
|
+
*
|
|
334
|
+
* ONE BUCKET GETS NO BUCKET LEVEL (one-bucket-consumer, kol-client-olina
|
|
335
|
+
* 2026-09-03): with a single bucket the second column was a row that named
|
|
336
|
+
* the only thing it could name, under a root that named the app — two levels
|
|
337
|
+
* to reach a folder. The virtual root collapses to the empty string, which
|
|
338
|
+
* makes every `slice(VROOT.length)` below a no-op and leaves column 0 as the
|
|
339
|
+
* bucket's own folders. Multi-bucket browse is untouched. */
|
|
340
|
+
const single = buckets.length <= 1
|
|
333
341
|
const ROOT = title
|
|
334
342
|
const label = bucketMeta.label || 'bucket'
|
|
335
|
-
const VROOT = `${ROOT}/${label}/`
|
|
343
|
+
const VROOT = single ? '' : `${ROOT}/${label}/`
|
|
336
344
|
const treeFolders = (level) => (folderTree?.[bucketMeta.id]?.folders ?? [])
|
|
337
345
|
.filter((p) => p.startsWith(level) && p.length > level.length && !p.slice(level.length, -1).includes('/'))
|
|
338
346
|
.map((p) => p.slice(level.length))
|
|
@@ -412,8 +420,10 @@ export function MediaLibraryBrowse({
|
|
|
412
420
|
columnWidths={settings.columnWidths}
|
|
413
421
|
onColumnResize={(i, px) => setSettings({ ...settings, columnWidths: { ...(settings.columnWidths ?? {}), [i]: px } })}
|
|
414
422
|
objects={objects.filter((o) => !isSystemFile(o.key)).map((o) => ({ ...o, key: `${VROOT}${o.key}` }))}
|
|
415
|
-
prefix={appRoot ? `${ROOT}/` : `${VROOT}${prefix}`}
|
|
423
|
+
prefix={single ? prefix : (appRoot ? `${ROOT}/` : `${VROOT}${prefix}`)}
|
|
416
424
|
onPrefix={(v) => {
|
|
425
|
+
/* single: the browser's path IS the bucket path, no segment to strip */
|
|
426
|
+
if (single) { setAppRoot(false); setPrefix(v); return }
|
|
417
427
|
const [, seg, ...rest] = v.split('/')
|
|
418
428
|
const target = buckets.find((b) => b.label === seg)
|
|
419
429
|
if (!target && buckets.length) { setAppRoot(true); setPickedFile(null); setPrefix(''); return }
|
|
@@ -435,8 +445,10 @@ export function MediaLibraryBrowse({
|
|
|
435
445
|
return <KindPreview o={real} urlOf={(x) => mediaUrl(x.key)} poster={poster ? mediaUrl(poster) : undefined} kindOf={kindOf} kindLabel={KIND_LABEL} />
|
|
436
446
|
}}
|
|
437
447
|
partition={(objs, level) => {
|
|
438
|
-
if (
|
|
439
|
-
|
|
448
|
+
if (!single) {
|
|
449
|
+
if (level === '') return { folders: [`${ROOT}/`], files: [] }
|
|
450
|
+
if (level === `${ROOT}/`) return { folders: (buckets.length ? buckets : [bucketMeta]).map((b) => `${b.label || 'bucket'}/`), files: [] }
|
|
451
|
+
}
|
|
440
452
|
const live = partition(objs, level)
|
|
441
453
|
const baked = treeFolders(level.slice(VROOT.length))
|
|
442
454
|
return { folders: [...new Set([...baked, ...live.folders])].sort(), files: live.files }
|
|
@@ -6,8 +6,11 @@ import Button from '../atoms/Button.jsx'
|
|
|
6
6
|
* wears. Owns dismissal (Escape, backdrop, close button), scroll lock and
|
|
7
7
|
* stacking; the consumer supplies the panel.
|
|
8
8
|
*
|
|
9
|
-
* The close control is the DS `Button` (
|
|
10
|
-
*
|
|
9
|
+
* The close control is the DS `Button` (icon-only, the `x` glyph) — the estate's
|
|
10
|
+
* ONE close idiom, and therefore ONE SIZE: `sm` (26), matching `ShellDrawer`'s
|
|
11
|
+
* (2026-09-03). It took Button's `md` default while the drawer's went to `sm`,
|
|
12
|
+
* which is two sizes for one idiom — the thing the single-idiom ruling exists to
|
|
13
|
+
* stop. It was a hand-rolled <button> printing a
|
|
11
14
|
* literal `×` TEXT CHARACTER until 2026-08-01: no icon, no states, and a
|
|
12
15
|
* typographic multiplication sign standing in for a glyph the icon set has
|
|
13
16
|
* always shipped.
|
|
@@ -69,10 +72,11 @@ export default function FullscreenOverlay({ open, onClose, closeButton = true, c
|
|
|
69
72
|
* user ruling): the estate's close X is the drawer trigger's bare
|
|
70
73
|
* `nav` glyph — the boxed outline treatment was a second design one
|
|
71
74
|
* tap away from the first, and had he kept a box it would have worn
|
|
72
|
-
* `primary`, never `outline`. Same variant
|
|
73
|
-
* the
|
|
75
|
+
* `primary`, never `outline`. Same variant as the trigger; the SQUARE
|
|
76
|
+
* is `sm` since 2026-09-03, one size for the one idiom. */
|
|
74
77
|
<Button
|
|
75
78
|
variant="nav"
|
|
79
|
+
size="sm"
|
|
76
80
|
iconOnly="x"
|
|
77
81
|
className="kol-overlay-close"
|
|
78
82
|
onClick={onClose}
|