@kolkrabbi/kol-component 0.115.0 → 0.117.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.115.0",
3
+ "version": "0.117.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",
@@ -8,6 +8,8 @@ import { glyphSize } from '../hooks/glyphLadders.js'
8
8
  * variant="outline" — bordered, transparent bg — THE secondary
9
9
  * treatment (2026-07-08 chrome law: one
10
10
  * secondary, always subordinate to filled)
11
+ * tone="inverse" — the dark chip (`fg-absolute-24`) for a washed plane
12
+ * (ControlToneInverse, 2026-08-27); same prop on ViewToggle · Dropdown
11
13
  * variant="ghost" — legacy alias, resolves to outline
12
14
  * variant="property" — the Figma property field (PropertyField,
13
15
  * 2026-08-12): filled chrome, dim `affordance`
@@ -50,6 +52,7 @@ export default function Input({
50
52
  value,
51
53
  onChange,
52
54
  variant = 'filled',
55
+ tone = 'default',
53
56
  size = 'md',
54
57
  chars,
55
58
  prefix,
@@ -86,6 +89,8 @@ export default function Input({
86
89
  `kol-control-${size}`,
87
90
  SIZE_TYPE[size],
88
91
  'cursor-text',
92
+ /* the dark chip on a washed plane (ControlToneInverse, kol-website 2026-08-27) */
93
+ tone === 'inverse' && 'kol-tone-inverse',
89
94
  isProperty && 'w-full',
90
95
  className,
91
96
  ].filter(Boolean).join(' ')
@@ -18,6 +18,15 @@ import { Icon } from '@kolkrabbi/kol-icons'
18
18
  * icon cut for variant="icon" ('stroke' default; 'solid' reads better at
19
19
  * 14px). For `variant="single"`, the FIRST option in `options` is the "off"
20
20
  * value; the SECOND is "on".
21
+ *
22
+ * `tone="inverse"` (ControlToneInverse, kol-website 2026-08-27 — user: "a
23
+ * flipped version of this color scheme, where the darker is background and grey
24
+ * is the active … it would fit better on the light grey"): on a washed plane
25
+ * (`pageWash`, `fg-04`) the default grey well reads as a second plate, so the
26
+ * icon variant's two values swap — the well takes the dark chip
27
+ * (`fg-absolute-24`), the active chip a lighter grey (`surface-tertiary` —
28
+ * user: "the active grey can be lighter"), the inactive hover a lighter wash. Theme rules on `.kol-tone-inverse`
29
+ * (kol-theme ≥0.78.0); the same prop on `Dropdown` and `Input`.
21
30
  */
22
31
  const ViewToggle = ({
23
32
  size = 'sm',
@@ -25,6 +34,7 @@ const ViewToggle = ({
25
34
  onViewChange,
26
35
  variant = 'text',
27
36
  iconVariant = 'stroke',
37
+ tone = 'default',
28
38
  options = [
29
39
  { value: 'grid', label: 'Grid view', icon: 'grid' },
30
40
  { value: 'list', label: 'List view', icon: 'view-list' }
@@ -60,7 +70,7 @@ const ViewToggle = ({
60
70
  }
61
71
 
62
72
  const containerClasses = isIconVariant
63
- ? `inline-flex items-center gap-1 p-1 bg-surface-secondary rounded ${className}`
73
+ ? `kol-view-toggle inline-flex items-center gap-1 p-1 bg-surface-secondary rounded ${tone === 'inverse' ? 'kol-tone-inverse' : ''} ${className}`.replace(/\s+/g, ' ').trim()
64
74
  : `flex gap-2 ${className}`
65
75
 
66
76
  const buttonClasses = (isActive) => {
@@ -16,6 +16,9 @@ import { indicatorSize } from '../hooks/glyphLadders.js'
16
16
  * same fill (one piece: no border, no gap, hairline divider inside)
17
17
  * variant="grey" — oq-12 filled trigger (opaque per the fill
18
18
  * law); panel continues it
19
+ * tone="inverse" — the dark chip (`fg-absolute-24`) for a washed
20
+ * plane, the panel continuing it (ControlToneInverse,
21
+ * kol-website 2026-08-27); same prop on ViewToggle · Input
19
22
  * variant="outline" — bordered trigger; open panel carries the
20
23
  * same border, trigger's bottom edge acts as the divider
21
24
  *
@@ -42,6 +45,7 @@ const Dropdown = ({
42
45
  onChange,
43
46
  size,
44
47
  variant = 'primary',
48
+ tone = 'default',
45
49
  defaultOpen = false,
46
50
  className = ''
47
51
  }) => {
@@ -98,6 +102,8 @@ const Dropdown = ({
98
102
  SIZE_TYPE[resolvedSize],
99
103
  'kol-dd-trigger',
100
104
  isOpen && 'kol-dd-trigger--open',
105
+ /* the dark chip on a washed plane; the panel continues it (ControlToneInverse, 2026-08-27) */
106
+ tone === 'inverse' && 'kol-tone-inverse',
101
107
  ].filter(Boolean).join(' ')
102
108
 
103
109
  return (
@@ -131,7 +137,7 @@ const Dropdown = ({
131
137
  popover={popover}
132
138
  panel={false}
133
139
  focus={false}
134
- className={`kol-dd-panel kol-dd-panel--${resolvedVariant}`}
140
+ className={`kol-dd-panel kol-dd-panel--${resolvedVariant} ${tone === 'inverse' ? 'kol-tone-inverse' : ''}`.trim()}
135
141
  >
136
142
  {(resolvedVariant === 'primary' || resolvedVariant === 'grey') && <div className="kol-dd-div" />}
137
143
 
@@ -34,6 +34,7 @@ import { glyphSize } from '../hooks/glyphLadders.js'
34
34
  * @param {Function} onFocus (event) => void — input focus
35
35
  * @param {string} size 'sm' | 'md' — kol-control size + matched mono type class
36
36
  * @param {string} variant 'filled' | 'ghost' | 'outline' — kol-control variant, same chrome as Input (ignored when bare/expanding)
37
+ * @param {string} tone 'default' | 'inverse' — the dark chip for a washed plane (ControlToneInverse, 2026-08-27); on the expanding pill it is the OPEN fill
37
38
  * @param {boolean} bare borderless inline field for overlay panels (full width, no shell chrome; keeps icon/clear/chip slots)
38
39
  * @param {boolean} expanding round icon-button pill that animates open into an inline field
39
40
  * @param {boolean} open (expanding) controlled open state; omit for internal state
@@ -76,6 +77,7 @@ export default function SearchInput({
76
77
  onFocus,
77
78
  size = 'md',
78
79
  variant = 'filled',
80
+ tone = 'default',
79
81
  bare = false,
80
82
  expanding = false,
81
83
  open,
@@ -154,7 +156,7 @@ export default function SearchInput({
154
156
  control: sm 28 · md 32 · lg 36 (hooks/glyphLadders.js). This was a
155
157
  hardcoded 36 — the LG square — so an expanding search sat beside a
156
158
  `kol-btn-md` filter button at two different sizes. */
157
- className={`kol-expand flex items-center rounded-full ${isOpen ? 'bg-fg-04' : ''} ${className}`.trim()}
159
+ className={`kol-expand flex items-center rounded-full ${isOpen ? (tone === 'inverse' ? 'kol-tone-inverse' : 'bg-fg-04') : ''} ${className}`.trim()}
158
160
  style={{ height: isOpen ? fieldH : square, width: isOpen ? expandedWidth : square }}
159
161
  >
160
162
  {/* THE GLYPH IS THE CLOSED STATE, and only that (user ruling
@@ -196,7 +198,7 @@ export default function SearchInput({
196
198
  const shellCls = [
197
199
  bare
198
200
  ? 'flex w-full gap-2.5 px-4 py-3'
199
- : `kol-control kol-control--${variant} kol-control-${size} gap-2`,
201
+ : `kol-control kol-control--${variant} kol-control-${size} gap-2${tone === 'inverse' ? ' kol-tone-inverse' : ''}`,
200
202
  'items-center cursor-text',
201
203
  SIZE_TYPE[size],
202
204
  className,
@@ -56,8 +56,11 @@ import IconFrame from '../atoms/IconFrame.jsx'
56
56
  * @param {string} props.stripActiveClassName — strip ink, selected (both strips)
57
57
  * @param {string} props.stripRestClassName — strip ink, unselected (both strips)
58
58
  * @param {string} props.countClassName — the "N of N" type/ink
59
+ * @param {string} props.tone — 'default' | 'inverse' — forwarded to the search field (ControlToneInverse,
60
+ * 2026-08-27): a page on a wash sets its header row's tone in one place
59
61
  */
60
62
  const ContentFilters = ({
63
+ tone = 'default',
61
64
  items,
62
65
  title,
63
66
  totalCount,
@@ -371,6 +374,7 @@ const ContentFilters = ({
371
374
  * shows while searching); SearchInput takes it controlled. */}
372
375
  <SearchInput
373
376
  expanding
377
+ tone={tone}
374
378
  open={searchOpen}
375
379
  onOpenChange={(next) => { setSearchOpen(next); if (!next) setSearchText('') }}
376
380
  value={searchText}
@@ -131,7 +131,7 @@ export default function ShellSearchOverlay({
131
131
  }
132
132
 
133
133
  return (
134
- <div className="fixed inset-0 z-[300] flex items-start justify-center pt-[20vh]">
134
+ <div className="fixed inset-0 flex items-start justify-center pt-[20vh]" style={{ zIndex: 'var(--kol-z-modal, 100)' }}>
135
135
  <div
136
136
  className="absolute inset-0 kol-overlay-scrim"
137
137
  onClick={onClose}