@kolkrabbi/kol-framework 0.34.0 → 0.36.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 +3 -3
- package/src/ThemeToggle.jsx +9 -5
- package/src/useDragResize.js +18 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@kolkrabbi/kol-framework",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.36.0",
|
|
4
4
|
"description": "KOL app shell — sidenav, layout, theme toggle, footer, heroes + brand color layer. SideNav takes nav data as props so the tree stays app-local.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"type": "module",
|
|
@@ -20,8 +20,8 @@
|
|
|
20
20
|
"react-router-dom": "^6.0.0 || ^7.0.0"
|
|
21
21
|
},
|
|
22
22
|
"devDependencies": {
|
|
23
|
-
"@kolkrabbi/kol-
|
|
24
|
-
"@kolkrabbi/kol-
|
|
23
|
+
"@kolkrabbi/kol-component": "^0.142.0",
|
|
24
|
+
"@kolkrabbi/kol-icons": "^0.25.0"
|
|
25
25
|
},
|
|
26
26
|
"files": [
|
|
27
27
|
"src",
|
package/src/ThemeToggle.jsx
CHANGED
|
@@ -84,9 +84,13 @@ export default function ThemeToggle({
|
|
|
84
84
|
label = true,
|
|
85
85
|
iconRight = false,
|
|
86
86
|
fullWidth = false,
|
|
87
|
+
/* `tone="sunken"` (ControlToneSunken, kol-website 2026-08-28): the control set's dark well + fg-96
|
|
88
|
+
* ink, so the toggle beside a sunken Dropdown matches it; `inverse` aliased. Rules in kol-theme. */
|
|
89
|
+
tone = 'default',
|
|
87
90
|
className = '',
|
|
88
91
|
}) {
|
|
89
92
|
const { theme, mode, cycle, clear } = useTheme()
|
|
93
|
+
const extra = `${tone === 'sunken' || tone === 'inverse' ? 'kol-tone-sunken' : ''} ${className}`.trim()
|
|
90
94
|
|
|
91
95
|
/* Label and slot follow the RESOLVED theme, not the stored choice: when the
|
|
92
96
|
* page is unset, what the user is looking at is the OS's answer, and the
|
|
@@ -149,7 +153,7 @@ export default function ThemeToggle({
|
|
|
149
153
|
/* ── DEPRECATED aliases — old chrome verbatim (0.6.x) ── */
|
|
150
154
|
if (variant === 'icon') {
|
|
151
155
|
return (
|
|
152
|
-
<button {...shared} className={`kol-theme-toggle kol-theme-toggle-none kol-btn-${size} kol-btn-icon ${
|
|
156
|
+
<button {...shared} className={`kol-theme-toggle kol-theme-toggle-none kol-btn-${size} kol-btn-icon ${extra}`.trim()}>
|
|
153
157
|
{iconSwap(glyphSolo)}
|
|
154
158
|
</button>
|
|
155
159
|
)
|
|
@@ -171,7 +175,7 @@ export default function ThemeToggle({
|
|
|
171
175
|
? `w-full inline-flex items-center justify-start gap-2 ${barePadY} px-6 ${mono} bg-transparent text-emphasis`
|
|
172
176
|
: 'kol-theme-toggle kol-theme-toggle-subtle kol-btn-md kol-mono-14 w-full justify-start gap-2'
|
|
173
177
|
return (
|
|
174
|
-
<button {...shared} className={`${chromeCls} ${
|
|
178
|
+
<button {...shared} className={`${chromeCls} ${extra}`.trim()}>
|
|
175
179
|
<span className="inline-flex items-center justify-center shrink-0" aria-hidden="true">
|
|
176
180
|
{iconSwap(bare ? glyphWithText : glyphSolo)}
|
|
177
181
|
</span>
|
|
@@ -187,7 +191,7 @@ export default function ThemeToggle({
|
|
|
187
191
|
|
|
188
192
|
if (variant === 'flush') {
|
|
189
193
|
const glyph = label ? glyphWithText : glyphSolo
|
|
190
|
-
const cls = `kol-theme-toggle kol-theme-toggle-flush gap-2 ${mono} ${width} ${
|
|
194
|
+
const cls = `kol-theme-toggle kol-theme-toggle-flush gap-2 ${mono} ${width} ${extra}`
|
|
191
195
|
return (
|
|
192
196
|
<button {...shared} className={cls.replace(/\s+/g, ' ').trim()}>
|
|
193
197
|
{!iconRight && iconSwap(glyph)}
|
|
@@ -204,13 +208,13 @@ export default function ThemeToggle({
|
|
|
204
208
|
if (!label) {
|
|
205
209
|
// icon-only pins the square box per rung — geometry condition, not a variant
|
|
206
210
|
return (
|
|
207
|
-
<button {...shared} className={`kol-theme-toggle ${fillCls} kol-btn-${size} kol-btn-icon ${width} ${
|
|
211
|
+
<button {...shared} className={`kol-theme-toggle ${fillCls} kol-btn-${size} kol-btn-icon ${width} ${extra}`.replace(/\s+/g, ' ').trim()}>
|
|
208
212
|
{iconSwap(glyphSolo)}
|
|
209
213
|
</button>
|
|
210
214
|
)
|
|
211
215
|
}
|
|
212
216
|
return (
|
|
213
|
-
<button {...shared} className={`kol-theme-toggle ${fillCls} kol-btn-${size} ${mono} gap-2 ${width} ${
|
|
217
|
+
<button {...shared} className={`kol-theme-toggle ${fillCls} kol-btn-${size} ${mono} gap-2 ${width} ${extra}`.replace(/\s+/g, ' ').trim()}>
|
|
214
218
|
{!iconRight && iconSwap(glyphWithText)}
|
|
215
219
|
<span className={fullWidth ? 'flex-1 min-w-0 text-left' : ''}>{MODE_LABEL[next]}</span>
|
|
216
220
|
{iconRight && iconSwap(glyphWithText)}
|
package/src/useDragResize.js
CHANGED
|
@@ -1,4 +1,12 @@
|
|
|
1
1
|
import { useEffect, useMemo, useRef, useState } from 'react'
|
|
2
|
+
/* THE SAME GRAB AS THE SHELL RAIL (OneGrabGestureBothRails, kol-fxr 2026-08-30 —
|
|
3
|
+
* user: *"why dont we use the grab animation and other sidenav settings to be
|
|
4
|
+
* consistent?"*). fxr's /labs shows both rails at once and only the left one
|
|
5
|
+
* woke as the cursor neared it, because each package had built the gesture
|
|
6
|
+
* itself. The hook lives in kol-component, the one package both can reach —
|
|
7
|
+
* kol-shell dropped its framework peer in 0.16.0, so neither could import the
|
|
8
|
+
* other's. */
|
|
9
|
+
import { useGrabEdge } from '@kolkrabbi/kol-component'
|
|
2
10
|
|
|
3
11
|
/* Grab-edge resize + collapse for SideNav — THE single control since 0.17.0
|
|
4
12
|
* (user build order 2026-08-09, completing the SideNavGrabResize brief: the
|
|
@@ -102,6 +110,11 @@ export default function useDragResize(ref, options = {}) {
|
|
|
102
110
|
const dir = side === 'right' ? -1 : 1
|
|
103
111
|
const names = useMemo(() => buildNames(token), [token])
|
|
104
112
|
|
|
113
|
+
/* the handle's own ref, so the shared gesture can find it. Returned in
|
|
114
|
+
* `grabProps`, so a consumer already spreading those gets the wake, the
|
|
115
|
+
* travel and the dwell with no change. */
|
|
116
|
+
const grabRef = useRef(null)
|
|
117
|
+
useGrabEdge(grabRef)
|
|
105
118
|
const drag = useRef(null) // { startX, startW, snapPx, maxPx, moved } during a drag
|
|
106
119
|
const defaultPx = useRef(null)
|
|
107
120
|
const collapsedPx = useRef(null)
|
|
@@ -249,6 +262,11 @@ export default function useDragResize(ref, options = {}) {
|
|
|
249
262
|
collapsed,
|
|
250
263
|
toggleCollapsed,
|
|
251
264
|
grabProps: {
|
|
265
|
+
ref: grabRef,
|
|
266
|
+
/* the pill is drawn by `.kol-rail-grab` (kol-animation.css) — the hook
|
|
267
|
+
* only supplies `is-near` and `--kol-rail-grab-y`. A consumer's own
|
|
268
|
+
* className, spread after this, still wins. */
|
|
269
|
+
className: 'kol-rail-grab',
|
|
252
270
|
role: 'separator',
|
|
253
271
|
'aria-orientation': 'vertical',
|
|
254
272
|
'aria-label': 'Resize navigation',
|