@kolkrabbi/kol-component 0.31.0 → 0.32.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.32.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.12.
|
|
27
|
+
"@kolkrabbi/kol-icons": "0.12.1"
|
|
28
28
|
},
|
|
29
29
|
"peerDependencies": {
|
|
30
30
|
"framer-motion": "^12.0.0",
|
package/src/atoms/Popover.jsx
CHANGED
|
@@ -74,9 +74,14 @@ export function usePopover({
|
|
|
74
74
|
* narrow case). The panel is never NARROWER than the trigger, and
|
|
75
75
|
* grows when its rows carry chrome the trigger doesn't (the
|
|
76
76
|
* selected row's check). Sole consumer is Dropdown. */
|
|
77
|
+
/* width: max-content is LOAD-BEARING — an abs-positioned float
|
|
78
|
+
* with auto width shrink-to-fits its available space, and the
|
|
79
|
+
* w-full rows inside then blew the panel to ~2× (the broken
|
|
80
|
+
* dropdown, 2026-08-09 evening). max-content sizes it to the
|
|
81
|
+
* widest row; minWidth keeps the trigger as the floor. */
|
|
77
82
|
Object.assign(elements.floating.style, {
|
|
78
83
|
minWidth: `${rects.reference.width}px`,
|
|
79
|
-
width: '',
|
|
84
|
+
width: 'max-content',
|
|
80
85
|
})
|
|
81
86
|
},
|
|
82
87
|
})
|
|
@@ -50,28 +50,29 @@ export function StatusChip({ value, options = [], onChange, size = 'sm' }) {
|
|
|
50
50
|
const norm = options.map((opt) => (typeof opt === 'object' ? opt : { value: opt, label: opt }))
|
|
51
51
|
const activeOpt = norm.find((o) => o.value === value)
|
|
52
52
|
const toneCls = activeOpt?.tone ? ` kol-status-chip--${activeOpt.tone}` : ''
|
|
53
|
+
/* BUILT ON THE COVER-FOCUS SPECS (user ruling 2026-08-09: "same component
|
|
54
|
+
* as cover focus"): the chip wears the Dropdown-sm trigger metrics — the
|
|
55
|
+
* kol-btn-sm box (py-1 px-3) and mono-12 type — as a pill with the tone
|
|
56
|
+
* tint. The caret is a direct child of the flex row, centred by
|
|
57
|
+
* items-center; it cannot sit off the label's middle. */
|
|
53
58
|
const chip = (interactive) => (
|
|
54
|
-
<
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
className={`kol-status-chip${toneCls}`}
|
|
59
|
+
<button
|
|
60
|
+
type="button"
|
|
61
|
+
disabled={!interactive || undefined}
|
|
62
|
+
aria-expanded={interactive ? open : undefined}
|
|
63
|
+
className={`kol-status-chip${toneCls} kol-mono-12 inline-flex items-center gap-1 rounded-full border-0 px-3 py-1 leading-none${interactive ? ' cursor-pointer' : ''}`}
|
|
60
64
|
onClick={interactive ? () => setOpen((o) => !o) : undefined}
|
|
61
65
|
>
|
|
62
66
|
{activeOpt?.label ?? value}
|
|
63
67
|
{interactive && (
|
|
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
68
|
<span
|
|
68
69
|
className={`inline-flex shrink-0 transition-transform duration-150${open ? ' rotate-180' : ''}`}
|
|
69
70
|
aria-hidden="true"
|
|
70
71
|
>
|
|
71
|
-
<Icon name="chevron-down" size={INDICATOR
|
|
72
|
+
<Icon name="chevron-down" size={INDICATOR.sm} />
|
|
72
73
|
</span>
|
|
73
74
|
)}
|
|
74
|
-
</
|
|
75
|
+
</button>
|
|
75
76
|
)
|
|
76
77
|
return (
|
|
77
78
|
<>
|
|
@@ -113,9 +114,9 @@ export function StatusChip({ value, options = [], onChange, size = 'sm' }) {
|
|
|
113
114
|
)
|
|
114
115
|
}
|
|
115
116
|
|
|
116
|
-
/* Media
|
|
117
|
-
*
|
|
118
|
-
const THUMB_CLS = 'h-
|
|
117
|
+
/* Media thumbnail — the reference panel's proportions (frame 39,
|
|
118
|
+
* 2026-08-09): a generous rounded tile, remove × inset at its corner. */
|
|
119
|
+
const THUMB_CLS = 'h-16 w-28 rounded-lg object-cover bg-fg-04'
|
|
119
120
|
|
|
120
121
|
export default function FieldRow({
|
|
121
122
|
label,
|
|
@@ -138,9 +139,9 @@ export default function FieldRow({
|
|
|
138
139
|
aria-label={label}
|
|
139
140
|
disabled={disabled}
|
|
140
141
|
onClick={onPick}
|
|
141
|
-
className="flex h-
|
|
142
|
+
className="flex h-16 w-28 cursor-pointer items-center justify-center rounded-lg border border-fg-16 bg-fg-02 text-body transition-colors duration-150 hover:text-emphasis"
|
|
142
143
|
>
|
|
143
|
-
<Icon name="plus" size={
|
|
144
|
+
<Icon name="plus" size={16} />
|
|
144
145
|
</button>
|
|
145
146
|
) : dash
|
|
146
147
|
const fileEmpty = onPick ? (
|
|
@@ -184,7 +185,7 @@ export default function FieldRow({
|
|
|
184
185
|
iconOnly="x"
|
|
185
186
|
iconSize={10}
|
|
186
187
|
aria-label={label}
|
|
187
|
-
className="absolute
|
|
188
|
+
className="absolute top-1 right-1 opacity-0 group-hover:opacity-100 focus-visible:opacity-100"
|
|
188
189
|
onClick={() => onChange(null)}
|
|
189
190
|
/>
|
|
190
191
|
)}
|
|
@@ -25,9 +25,11 @@ const ToolbarIcon = ({ name, label, onClick, active = false, triggerClassName })
|
|
|
25
25
|
/* PRESSED gets the box (user ruling, reference frame 2026-08-09): a
|
|
26
26
|
* snug rounded fill hugging the glyph — "container relative to the
|
|
27
27
|
* icon, and only when pressed". Rest is bare; hover is ink only. */
|
|
28
|
-
|
|
28
|
+
/* 20px glyph, half-step pad — "TOO SMALL, TOO MUCH PADDING" (user
|
|
29
|
+
* frames 2026-08-09): the reference icons nearly fill their box. */
|
|
30
|
+
className={`inline-flex cursor-pointer rounded-sm border-0 p-0.5 transition-colors duration-150 ${active ? 'bg-fg-08 text-emphasis' : 'bg-transparent text-body hover:text-emphasis'}`}
|
|
29
31
|
>
|
|
30
|
-
<Icon name={name} size={
|
|
32
|
+
<Icon name={name} size={20} />
|
|
31
33
|
</button>
|
|
32
34
|
</Tooltip>
|
|
33
35
|
)
|
|
@@ -155,10 +157,10 @@ export default function RecordManager({
|
|
|
155
157
|
<button
|
|
156
158
|
type="button"
|
|
157
159
|
aria-label="Toggle overlay"
|
|
158
|
-
className="shrink-0 inline-flex cursor-pointer rounded-
|
|
160
|
+
className="shrink-0 inline-flex cursor-pointer rounded-md border border-fg-16 bg-transparent p-1 text-body opacity-0 transition-opacity duration-150 group-hover:opacity-100 focus-visible:opacity-100 hover:text-emphasis"
|
|
159
161
|
onClick={() => openRecord(row)}
|
|
160
162
|
>
|
|
161
|
-
<Icon name="toggle-overlay" size={
|
|
163
|
+
<Icon name="toggle-overlay" size={18} />
|
|
162
164
|
</button>
|
|
163
165
|
</span>
|
|
164
166
|
),
|
|
@@ -289,6 +291,7 @@ export default function RecordManager({
|
|
|
289
291
|
columns={builtColumns}
|
|
290
292
|
rows={rows}
|
|
291
293
|
width="column"
|
|
294
|
+
compact
|
|
292
295
|
rowClassName={(row, i) =>
|
|
293
296
|
`group${drag && i === drag.from ? ' opacity-40' : ''}${
|
|
294
297
|
drag && i === drag.over && drag.over !== drag.from ? ' bg-fg-04' : ''
|
package/src/organisms/Table.jsx
CHANGED
|
@@ -33,7 +33,7 @@ const WIDTHS = {
|
|
|
33
33
|
column: '',
|
|
34
34
|
}
|
|
35
35
|
|
|
36
|
-
const Table = ({ caption, columns, rows, variant = 'default', className = '', width = 'panel', rowClassName }) => {
|
|
36
|
+
const Table = ({ caption, columns, rows, variant = 'default', className = '', width = 'panel', rowClassName, compact = false }) => {
|
|
37
37
|
const [sort, setSort] = useState({ key: null, dir: null })
|
|
38
38
|
|
|
39
39
|
const cycle = (key) =>
|
|
@@ -56,7 +56,9 @@ const Table = ({ caption, columns, rows, variant = 'default', className = '', wi
|
|
|
56
56
|
}, [rows, columns, sort])
|
|
57
57
|
|
|
58
58
|
const variantClass = variant === 'simple' ? 'kol-table--simple' : ''
|
|
59
|
-
|
|
59
|
+
/* compact — record-surface density (RecordManager, 2026-08-09): the default
|
|
60
|
+
* 12/16 cell box read as bloated rows against the reference table. */
|
|
61
|
+
const wrapperClass = ['kol-table-wrapper', variantClass, compact && 'kol-table--compact', WIDTHS[width] ?? WIDTHS.panel, className].filter(Boolean).join(' ')
|
|
60
62
|
return (
|
|
61
63
|
<div className={wrapperClass}>
|
|
62
64
|
<table className="kol-table">
|