@kolkrabbi/kol-component 0.108.0 → 0.109.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.108.0",
3
+ "version": "0.109.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,13 +1,15 @@
1
1
  import { createContext, useContext, useEffect, useMemo, useState } from 'react'
2
2
  import { Icon } from '@kolkrabbi/kol-icons'
3
+ import ActionButton from '../atoms/ActionButton.jsx'
3
4
  import Button from '../atoms/Button.jsx'
4
5
  import Divider from '../atoms/Divider.jsx'
5
6
  import Input from '../atoms/Input.jsx'
6
7
  import SegmentedToggle from '../atoms/SegmentedToggle.jsx'
8
+ import SizeOrDownload from '../atoms/SizeOrDownload.jsx'
7
9
  import ViewToggle from '../atoms/ViewToggle.jsx'
8
10
  import FullscreenOverlay from '../utilities/FullscreenOverlay.jsx'
9
- import MediaCard from '../molecules/MediaCard.jsx'
10
- import MediaRow from '../molecules/MediaRow.jsx'
11
+ import ContentCard from '../molecules/ContentCard.jsx'
12
+ import ContentRow from '../molecules/ContentRow.jsx'
11
13
  import ContentFilters from './ContentFilters.jsx'
12
14
  import MediaViewer from './MediaViewer.jsx'
13
15
  import { SettingsChipRow, chipCls } from './SettingsPanel.jsx'
@@ -25,8 +27,12 @@ import { SettingsChipRow, chipCls } from './SettingsPanel.jsx'
25
27
  * Same contract as kol-dashboards / kol-chess / kol-content.
26
28
  *
27
29
  * COMPOSED, NOT BUILT. Every part is an existing DS member:
28
- * MediaCard — the grid tile (thumb · download chip · name · meta · actions)
29
- * MediaRow — the list row (thumb · name · date · size · actions)
30
+ * ContentCard — the grid tile, `variant="default"` (thumb · download in the
31
+ * frame corner · title · date · size-or-download · inline actions)
32
+ * ContentRow — the list row, `variant="default"` (thumb · title · date · size · actions)
33
+ * MediaCard / MediaRow retired 2026-08-26 (ContentSetRetirement);
34
+ * this was the DS's own last composition of them, swapped 2026-08-27
35
+ * onto kol-r2b2 FileList's ContentCard / ContentRow shape.
30
36
  * MediaViewer — the lightbox, via its `actions` slot
31
37
  * ContentFilters — the PICKER's chrome (search, kind filter, view toggle, N-of-M)
32
38
  * FullscreenOverlay — the picker's scrim, dismissal and close button
@@ -650,7 +656,7 @@ function Toolbar({ viewMode, onViewMode }) {
650
656
  * picker; `onPick` is the only difference between them. */
651
657
  function FilesBody({ files, viewMode, onOpen, onPick }) {
652
658
  const { mediaUrl, viewable, prefix, stats, more, pageSize, showMore } = useMediaLibrary()
653
- const [copied, copy] = useCopy()
659
+ const [, copy] = useCopy()
654
660
 
655
661
  if (files.length === 0) {
656
662
  return (
@@ -680,46 +686,60 @@ function FilesBody({ files, viewMode, onOpen, onPick }) {
680
686
  </div>
681
687
  )
682
688
  }
683
- const actionsFor = (row) => (
684
- <div className="flex items-center gap-2">
685
- {onPick && <Button size="sm" onClick={() => onPick(row)}>Use</Button>}
686
- <Button variant="secondary" size="sm" onClick={() => copy(urlFor(row))}>
687
- {copied === urlFor(row) ? 'Copied' : 'Copy URL'}
688
- </Button>
689
- <Button variant="ghost" size="sm" iconOnly="download" iconSize={14} href={urlFor(row)} aria-label={`Download ${row.displayKey}`} />
689
+ /* INLINE controls, never labelled Buttons (ContentSetRetirement, 2026-08-27):
690
+ * the card's `actions` float in the plate's corner beside the title, so a
691
+ * labelled Button there sits on the copy — kol-r2b2's column of
692
+ * `.kol-inline-control`s is the shape that fits. The card's download is the
693
+ * frame-corner `control` + the size slot (SizeOrDownload); the row keeps its
694
+ * glyph beside Copy. `Use` (picker only) is the same control wearing `plus`. */
695
+ const actionsFor = (row, form) => (
696
+ <div className={form === 'row' ? 'flex items-center gap-2' : 'flex h-full flex-col items-center justify-between'}>
697
+ {onPick && <ActionButton chrome="inline" size="sm" icon="plus" confirmIcon="check" label="Use" confirmLabel="Used" onAction={() => onPick(row)} />}
698
+ <ActionButton chrome="inline" size="sm" icon="copy" confirmIcon="check" label="Copy URL" confirmLabel="Copied" onAction={() => copy(urlFor(row))} />
699
+ {form === 'row' && (
700
+ <ActionButton chrome="inline" size="sm" icon="download" confirmIcon="check" label="Download" confirmLabel="Downloaded" href={urlFor(row)} />
701
+ )}
690
702
  </div>
691
703
  )
692
- const nameFor = (row) => <p className="kol-mono-12 text-body truncate" title={row.key}>{row.displayKey}</p>
693
- const date = (row) => (row.uploaded ? String(row.uploaded).slice(0, 10) : '')
704
+ /* the title voice is the family's ruled default (heading-04 card / heading-05
705
+ * row, truncated by ContentText); the full key rides as the tooltip, as before */
706
+ const nameFor = (row) => <span title={row.key}>{row.displayKey}</span>
707
+ const date = (row) => (row.uploaded ? String(row.uploaded).slice(0, 10) : undefined)
708
+ const size = (row) => formatSize(row.size) || undefined
694
709
 
695
710
  return (
696
711
  <>
697
712
  {viewMode === 'list' ? (
698
- <ul className="kol-media-list">
713
+ <div className="kol-media-list">
699
714
  {files.map((row) => (
700
- <MediaRow
715
+ <ContentRow
701
716
  key={row.key}
702
- thumb={thumbFor(row)}
703
- name={nameFor(row)}
717
+ variant="default"
718
+ media={thumbFor(row)}
719
+ title={nameFor(row)}
704
720
  date={date(row)}
705
- size={formatSize(row.size)}
706
- actions={actionsFor(row)}
721
+ size={size(row)}
722
+ actions={actionsFor(row, 'row')}
707
723
  />
708
724
  ))}
709
- </ul>
725
+ </div>
710
726
  ) : (
711
- <ul className="kol-media-grid">
727
+ <div className="kol-media-grid">
712
728
  {files.map((row) => (
713
- <MediaCard
729
+ <ContentCard
714
730
  key={row.key}
715
- thumb={thumbFor(row)}
716
- name={nameFor(row)}
717
- meta={`${formatSize(row.size)}${date(row) ? ` · ${date(row)}` : ''}`}
718
- downloadHref={urlFor(row)}
719
- actions={actionsFor(row)}
731
+ variant="default"
732
+ media={thumbFor(row)}
733
+ control={
734
+ <ActionButton chrome="media" icon="download" confirmIcon="check" label="Download" confirmLabel="Downloaded" href={urlFor(row)} />
735
+ }
736
+ title={nameFor(row)}
737
+ date={date(row)}
738
+ size={size(row) && <SizeOrDownload href={urlFor(row)}>{size(row)}</SizeOrDownload>}
739
+ actions={actionsFor(row, 'card')}
720
740
  />
721
741
  ))}
722
- </ul>
742
+ </div>
723
743
  )}
724
744
  {more > 0 && (
725
745
  <button