@kolkrabbi/kol-component 0.326.0 → 0.327.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 +1 -1
- package/src/organisms/NavRail.jsx +32 -17
package/package.json
CHANGED
|
@@ -122,11 +122,21 @@ const openWidth = () => {
|
|
|
122
122
|
* are now — inside `GRAB.range`, the middle band of the edge, so it never rides
|
|
123
123
|
* up beside the logomark. One window listener, rAF-throttled. */
|
|
124
124
|
|
|
125
|
-
/* THE DRAG
|
|
126
|
-
*
|
|
127
|
-
*
|
|
128
|
-
*
|
|
129
|
-
*
|
|
125
|
+
/* THE DRAG HOLDS ITS WIDTH (RailDragHoldsWidth, kol-fxr 2026-10-31 — user: *"you should be able to drag it however
|
|
126
|
+
* you want, it will just get reset on rail click"*). Hold the pill and the width follows the pointer between CLOSED
|
|
127
|
+
* and MAX; release leaves it exactly there, no snap. A click (no travel past GRAB.slop) still snaps collapsed ⇄
|
|
128
|
+
* expanded — any width past CLOSED closes, CLOSED opens to the open width — so a click resets a custom width.
|
|
129
|
+
*
|
|
130
|
+
* THE LABEL THRESHOLD (LABELS): below it the rail is icons only — labels, chevrons and the mark's title hide (the
|
|
131
|
+
* `@max-[…]:hidden` container query on the rows, measured on the rail's content box = LABELS − its px-2 gutter), never
|
|
132
|
+
* a label clipped in a narrow strip. `onSnap` reports from the same threshold: crossings during a drag report live,
|
|
133
|
+
* a snap reports its target once at the start of the tween (as before) — the sub rows render only while it is true,
|
|
134
|
+
* because closed they would still take their height and push the rungs below them.
|
|
135
|
+
*
|
|
136
|
+
* ONE AXIS: the gesture reads `pos` and `size` only. A side rail reads x and width; a top rail (variant="top", not
|
|
137
|
+
* built) swaps them for y and height — nothing else in here assumes a side. */
|
|
138
|
+
const RAIL_MAX = 560
|
|
139
|
+
const RAIL_LABELS = 160
|
|
130
140
|
function useRailDrag(railRef, grabRef, onSnap, snapRef, enabled = true) {
|
|
131
141
|
useEffect(() => {
|
|
132
142
|
const strip = grabRef.current, rail = railRef.current, root = document.documentElement
|
|
@@ -137,11 +147,15 @@ function useRailDrag(railRef, grabRef, onSnap, snapRef, enabled = true) {
|
|
|
137
147
|
* exactly the inline token a consumer could not reach without `!important`. */
|
|
138
148
|
if (!enabled) return undefined
|
|
139
149
|
if (!strip || !rail) return undefined
|
|
150
|
+
const pos = (e) => e.clientX
|
|
151
|
+
const size = () => rail.offsetWidth
|
|
140
152
|
gsap.set(root, { [RAIL_W]: `${CLOSED}px` })
|
|
141
153
|
let drag = null
|
|
154
|
+
let labelled = false
|
|
155
|
+
const report = (w) => { const on = w >= RAIL_LABELS; if (on !== labelled) { labelled = on; onSnap(on) } }
|
|
142
156
|
const snapTo = (w) => {
|
|
143
157
|
gsap.to(root, { [RAIL_W]: `${w}px`, ...GRAB.snap, overwrite: 'auto' })
|
|
144
|
-
|
|
158
|
+
report(w)
|
|
145
159
|
}
|
|
146
160
|
/* the ONLY way out of this effect (RailSectionPressOpensRail, kol-fxr
|
|
147
161
|
* 2026-08-30). `snapTo` closes over the animation and the CLOSED/open
|
|
@@ -155,20 +169,21 @@ function useRailDrag(railRef, grabRef, onSnap, snapRef, enabled = true) {
|
|
|
155
169
|
const onDown = (e) => {
|
|
156
170
|
strip.setPointerCapture(e.pointerId)
|
|
157
171
|
gsap.killTweensOf(root)
|
|
158
|
-
drag = {
|
|
172
|
+
drag = { p: pos(e), w: size(), moved: false }
|
|
159
173
|
strip.classList.add('is-dragging')
|
|
160
174
|
}
|
|
161
175
|
const onMove = (e) => {
|
|
162
176
|
if (!drag) return
|
|
163
|
-
const
|
|
164
|
-
if (Math.abs(
|
|
165
|
-
|
|
177
|
+
const d = pos(e) - drag.p
|
|
178
|
+
if (Math.abs(d) > GRAB.slop) drag.moved = true
|
|
179
|
+
if (!drag.moved) return
|
|
180
|
+
const w = Math.min(Math.max(drag.w + d, CLOSED), RAIL_MAX)
|
|
181
|
+
root.style.setProperty(RAIL_W, `${w}px`)
|
|
182
|
+
report(w)
|
|
166
183
|
}
|
|
167
184
|
const onUp = () => {
|
|
168
185
|
if (!drag) return
|
|
169
|
-
|
|
170
|
-
const open = drag.open
|
|
171
|
-
snapTo(drag.moved ? (w > (CLOSED + open) / 2 ? open : CLOSED) : (drag.w > CLOSED ? CLOSED : open))
|
|
186
|
+
if (!drag.moved) snapTo(drag.w > CLOSED ? CLOSED : openWidth())
|
|
172
187
|
drag = null
|
|
173
188
|
strip.classList.remove('is-dragging')
|
|
174
189
|
}
|
|
@@ -250,13 +265,13 @@ function RailItem({ icon, path, to, label, sub, currentPath, onNavigate, iconCom
|
|
|
250
265
|
/>
|
|
251
266
|
</Tooltip>
|
|
252
267
|
<span
|
|
253
|
-
className={`${RAIL_ROW.label} text-oq-96 flex-1 min-w-0 truncate cursor-pointer`}
|
|
268
|
+
className={`${RAIL_ROW.label} text-oq-96 flex-1 min-w-0 truncate cursor-pointer @max-[144px]/rail:hidden`}
|
|
254
269
|
onClick={press}
|
|
255
270
|
>
|
|
256
271
|
{label}
|
|
257
272
|
</span>
|
|
258
273
|
{sub?.length > 0 && (
|
|
259
|
-
<Tooltip label={label} placement="right" triggerClassName="inline-flex shrink-0">
|
|
274
|
+
<Tooltip label={label} placement="right" triggerClassName="inline-flex shrink-0 @max-[144px]/rail:hidden">
|
|
260
275
|
<Button
|
|
261
276
|
iconOnly={onEnter ? 'chevron-right' : open ? 'chevron-down' : 'chevron-right'}
|
|
262
277
|
iconSize={16}
|
|
@@ -371,7 +386,7 @@ function AppRail({
|
|
|
371
386
|
* trigger travelling to mid-screen, never the navigation's side. The
|
|
372
387
|
* trigger is now pinned top-right in both states, so a left panel has
|
|
373
388
|
* nothing to collide with and the drawer opens where the rail lives. */
|
|
374
|
-
className="kol-shell-rail bg-surface-primary fixed inset-y-0 left-0 flex flex-col items-start pt-4 pb-4 px-2 gap-2 border-r border-fg-08"
|
|
389
|
+
className="@container/rail kol-shell-rail bg-surface-primary fixed inset-y-0 left-0 flex flex-col items-start pt-4 pb-4 px-2 gap-2 border-r border-fg-08"
|
|
375
390
|
/* A drawer takes its own width, NOT the live rail token — that token is
|
|
376
391
|
* zeroed in drawer mode so the content gets the whole viewport back. */
|
|
377
392
|
style={{ width: drawer ? 'var(--kol-shell-drawer-width, 240px)' : `var(${RAIL_W})` }}
|
|
@@ -413,7 +428,7 @@ function AppRail({
|
|
|
413
428
|
className="text-oq-96 cursor-pointer flex items-center gap-3 w-full overflow-hidden shrink-0 pt-1 mb-4"
|
|
414
429
|
>
|
|
415
430
|
<span className="w-8 flex justify-center shrink-0"><VectorLoader src={logomark.svgUrl} size={20} /></span>
|
|
416
|
-
<span className="kol-helper-12 uppercase flex-1 min-w-0 truncate">{logomark.title}</span>
|
|
431
|
+
<span className="kol-helper-12 uppercase flex-1 min-w-0 truncate @max-[144px]/rail:hidden">{logomark.title}</span>
|
|
417
432
|
</div>
|
|
418
433
|
</Tooltip>
|
|
419
434
|
)}
|