@kolkrabbi/kol-component 0.28.1 → 0.30.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.30.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",
|
|
@@ -24,7 +24,7 @@
|
|
|
24
24
|
"@floating-ui/react": "^0.27.19",
|
|
25
25
|
"embla-carousel-react": "^8.6.0",
|
|
26
26
|
"react-syntax-highlighter": "^16.1.1",
|
|
27
|
-
"@kolkrabbi/kol-icons": "0.
|
|
27
|
+
"@kolkrabbi/kol-icons": "0.11.1"
|
|
28
28
|
},
|
|
29
29
|
"peerDependencies": {
|
|
30
30
|
"framer-motion": "^12.0.0",
|
package/src/atoms/Popover.jsx
CHANGED
|
@@ -68,11 +68,15 @@ export function usePopover({
|
|
|
68
68
|
middleware.push(
|
|
69
69
|
sizeMw({
|
|
70
70
|
apply({ rects, elements }) {
|
|
71
|
-
/*
|
|
72
|
-
*
|
|
73
|
-
*
|
|
71
|
+
/* FLOOR again, not exact (2026-08-09 evening, user: "if you have
|
|
72
|
+
* to truncate 'centered' then its too narrow" — overrides the
|
|
73
|
+
* morning's exact-width reading of the one-piece ruling for the
|
|
74
|
+
* narrow case). The panel is never NARROWER than the trigger, and
|
|
75
|
+
* grows when its rows carry chrome the trigger doesn't (the
|
|
76
|
+
* selected row's check). Sole consumer is Dropdown. */
|
|
74
77
|
Object.assign(elements.floating.style, {
|
|
75
|
-
|
|
78
|
+
minWidth: `${rects.reference.width}px`,
|
|
79
|
+
width: '',
|
|
76
80
|
})
|
|
77
81
|
},
|
|
78
82
|
})
|
|
@@ -61,12 +61,15 @@ export function StatusChip({ value, options = [], onChange, size = 'sm' }) {
|
|
|
61
61
|
>
|
|
62
62
|
{activeOpt?.label ?? value}
|
|
63
63
|
{interactive && (
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
64
|
+
/* plain inline-flex wrapper — Icon's own element can render
|
|
65
|
+
* inline-block and ride the baseline (the misaligned caret,
|
|
66
|
+
* 2026-08-09); the flex span centres it against the label. */
|
|
67
|
+
<span
|
|
68
|
+
className={`inline-flex shrink-0 transition-transform duration-150${open ? ' rotate-180' : ''}`}
|
|
68
69
|
aria-hidden="true"
|
|
69
|
-
|
|
70
|
+
>
|
|
71
|
+
<Icon name="chevron-down" size={INDICATOR[size] ?? INDICATOR.sm} />
|
|
72
|
+
</span>
|
|
70
73
|
)}
|
|
71
74
|
</Tag>
|
|
72
75
|
)
|
|
@@ -168,7 +171,9 @@ export default function FieldRow({
|
|
|
168
171
|
) : empty
|
|
169
172
|
} else if (type === 'file') {
|
|
170
173
|
control = value ? (
|
|
171
|
-
|
|
174
|
+
/* kol-tag--data: a filename renders VERBATIM — the chip uppercase is
|
|
175
|
+
* for label strings, and transforming data misquotes it (2026-08-09). */
|
|
176
|
+
<Tag variant="secondary" size="sm" hash={false} className="kol-tag--data" onRemove={onChange ? () => onChange(null) : undefined}>
|
|
172
177
|
{value.name ?? value}
|
|
173
178
|
</Tag>
|
|
174
179
|
) : empty
|
|
@@ -7,9 +7,31 @@ import ToggleCheckbox from '../atoms/ToggleCheckbox'
|
|
|
7
7
|
import ShellDrawer from '../molecules/ShellDrawer'
|
|
8
8
|
import Dropdown from '../molecules/Dropdown'
|
|
9
9
|
import FieldRow, { StatusChip } from '../molecules/FieldRow'
|
|
10
|
+
import { Tooltip } from '../atoms/Popover'
|
|
10
11
|
import Table from './Table'
|
|
11
12
|
import MediaLibrary from './MediaLibrary'
|
|
12
13
|
|
|
14
|
+
/* TOOLBAR ICONS ARE BARE GLYPHS (user ruling 2026-08-09, verbatim: "did I
|
|
15
|
+
* ask for a button?? … the only thing that should hover is full opacity and
|
|
16
|
+
* popover"): no Button chrome, no fill, no box — body ink at rest, emphasis
|
|
17
|
+
* on hover, a Tooltip as the name. */
|
|
18
|
+
const ToolbarIcon = ({ name, label, onClick, active = false, triggerClassName }) => (
|
|
19
|
+
<Tooltip label={label} placement="bottom" triggerClassName={triggerClassName}>
|
|
20
|
+
<button
|
|
21
|
+
type="button"
|
|
22
|
+
aria-label={label}
|
|
23
|
+
aria-pressed={active}
|
|
24
|
+
onClick={onClick}
|
|
25
|
+
/* PRESSED gets the box (user ruling, reference frame 2026-08-09): a
|
|
26
|
+
* snug rounded fill hugging the glyph — "container relative to the
|
|
27
|
+
* icon, and only when pressed". Rest is bare; hover is ink only. */
|
|
28
|
+
className={`inline-flex cursor-pointer rounded-sm border-0 p-1 transition-colors duration-150 ${active ? 'bg-fg-08 text-emphasis' : 'bg-transparent text-body hover:text-emphasis'}`}
|
|
29
|
+
>
|
|
30
|
+
<Icon name={name} size={16} />
|
|
31
|
+
</button>
|
|
32
|
+
</Tooltip>
|
|
33
|
+
)
|
|
34
|
+
|
|
13
35
|
/**
|
|
14
36
|
* RecordManager — full-screen CMS record surface (lobby: RecordManager,
|
|
15
37
|
* reference: Framer CMS). A reorderable record table plus a slide-over detail
|
|
@@ -61,9 +83,14 @@ export default function RecordManager({
|
|
|
61
83
|
onOverflow,
|
|
62
84
|
mediaClient,
|
|
63
85
|
reorderLabel = (n) => `Reorder row ${n}`,
|
|
86
|
+
/* pressed states for the toolbar's sort/filter controls — the consumer owns
|
|
87
|
+
* those panels, so it tells the toolbar which control is open */
|
|
88
|
+
sortActive = false,
|
|
89
|
+
filterActive = false,
|
|
64
90
|
className = '',
|
|
65
91
|
}) {
|
|
66
92
|
const wrapRef = useRef(null)
|
|
93
|
+
const [searchOpen, setSearchOpen] = useState(false)
|
|
67
94
|
const dragRef = useRef(null)
|
|
68
95
|
const [drag, setDrag] = useState(null) // { from, over, x, y } during a drag
|
|
69
96
|
const [active, setActive] = useState(null)
|
|
@@ -193,7 +220,7 @@ export default function RecordManager({
|
|
|
193
220
|
className="cursor-grab touch-none bg-transparent border-0 p-0 text-meta hover:text-emphasis"
|
|
194
221
|
onPointerDown={(e) => startDrag(e, i)}
|
|
195
222
|
>
|
|
196
|
-
<Icon name="
|
|
223
|
+
<Icon name="drag-handle" size={14} />
|
|
197
224
|
</button>
|
|
198
225
|
)
|
|
199
226
|
},
|
|
@@ -233,23 +260,28 @@ export default function RecordManager({
|
|
|
233
260
|
return (
|
|
234
261
|
<div ref={wrapRef} className={`flex flex-col min-w-0 ${className}`}>
|
|
235
262
|
{hasToolbar && (
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
{
|
|
240
|
-
{
|
|
263
|
+
/* the reference cluster (user screenshots 2026-08-09): bare + · ↑↓ ·
|
|
264
|
+
* ≡ · 🔍, search expanding into a COMPACT field on press, … far right */
|
|
265
|
+
<div className="flex items-center gap-2 pb-3">
|
|
266
|
+
{onAdd && <ToolbarIcon name="plus" label="Add" onClick={onAdd} />}
|
|
267
|
+
{onSortToggle && <ToolbarIcon name="arrows-vertical" label="Sort" active={sortActive} onClick={onSortToggle} />}
|
|
268
|
+
{onFilterToggle && <ToolbarIcon name="filter-lines" label="Filter" active={filterActive} onClick={onFilterToggle} />}
|
|
269
|
+
{onQueryChange && (searchOpen || query ? (
|
|
241
270
|
<SearchInput
|
|
271
|
+
autoFocus
|
|
272
|
+
size="sm"
|
|
273
|
+
className="w-56"
|
|
242
274
|
value={query ?? ''}
|
|
243
275
|
onChange={(e) => onQueryChange(e?.target ? e.target.value : e)}
|
|
244
276
|
placeholder={searchPlaceholder}
|
|
245
|
-
|
|
246
|
-
|
|
277
|
+
onClear={() => { onQueryChange(''); setSearchOpen(false) }}
|
|
278
|
+
onBlur={() => { if (!query) setSearchOpen(false) }}
|
|
247
279
|
/>
|
|
248
|
-
)
|
|
249
|
-
|
|
250
|
-
|
|
280
|
+
) : (
|
|
281
|
+
<ToolbarIcon name="search" label="Search" onClick={() => setSearchOpen(true)} />
|
|
282
|
+
))}
|
|
251
283
|
{onOverflow && (
|
|
252
|
-
<
|
|
284
|
+
<ToolbarIcon name="more" label="More" triggerClassName="ml-auto" onClick={() => onOverflow(null)} />
|
|
253
285
|
)}
|
|
254
286
|
</div>
|
|
255
287
|
)}
|
|
@@ -286,10 +318,10 @@ export default function RecordManager({
|
|
|
286
318
|
header={
|
|
287
319
|
<div className="flex items-center gap-2 min-w-0">
|
|
288
320
|
{onOverflow && (
|
|
289
|
-
<
|
|
321
|
+
<ToolbarIcon name="more" label="More" onClick={() => onOverflow(record)} />
|
|
290
322
|
)}
|
|
291
323
|
{onPreview && (
|
|
292
|
-
<
|
|
324
|
+
<ToolbarIcon name="play" label="Preview" onClick={() => onPreview(record)} />
|
|
293
325
|
)}
|
|
294
326
|
{saveState != null && <span className="kol-helper-10 text-meta ml-auto truncate">{saveState}</span>}
|
|
295
327
|
{onPublish && (
|