@kolkrabbi/kol-framework 0.10.2 → 0.11.1
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/kol-framework.css +23 -1
- package/package.json +2 -2
- package/src/AppShell.jsx +1 -1
- package/src/ShellHeader.jsx +14 -3
- package/src/ThemeToggle.jsx +15 -3
- package/src/index.js +1 -1
package/kol-framework.css
CHANGED
|
@@ -31,8 +31,21 @@ body {
|
|
|
31
31
|
|
|
32
32
|
:root {
|
|
33
33
|
--kol-topnav-h: 0px;
|
|
34
|
-
|
|
34
|
+
/* 16rem — the rail width, one number (2026-07-31). It read 260 while every
|
|
35
|
+
grid track that had to line up with it read 256, so the shell header's
|
|
36
|
+
brand block sat 4 off the sidebar column it exists to align to. */
|
|
37
|
+
--kol-sidenav-w: 16rem;
|
|
35
38
|
--kol-sidenav-w-collapsed: 56px;
|
|
39
|
+
/* The workshop shell's RIGHT rail. EQUAL TO THE LEFT (user ruling
|
|
40
|
+
2026-08-01) — the two rails frame the same content and a lopsided frame is
|
|
41
|
+
a frame nobody drew on purpose; it read 14rem against the left's 16rem.
|
|
42
|
+
Kept as its own token rather than aliased: the right rail can be ruled
|
|
43
|
+
different later without touching the sidenav.
|
|
44
|
+
The track is RESERVED whether or not the rail has anything in it — a rail
|
|
45
|
+
that vanishes on a heading-less page re-flows main, so the same shell
|
|
46
|
+
renders at two widths. Distinct from --kol-toc-w further down, which is
|
|
47
|
+
the BRAND layout's rail: same concept, two shells, two numbers. */
|
|
48
|
+
--kol-shell-toc-w: 16rem;
|
|
36
49
|
--kol-container-max: 100%;
|
|
37
50
|
|
|
38
51
|
/* Opacity tokens (--kol-fg-*) + text-role tokens (--kol-text-*) live in
|
|
@@ -44,6 +57,15 @@ body {
|
|
|
44
57
|
Intentional: site chrome uses browser-ease for a softer feel. */
|
|
45
58
|
--kol-t-btn: background 200ms ease, color 200ms ease, border-color 200ms ease;
|
|
46
59
|
|
|
60
|
+
/* Shell CHROME inset (2026-07-31, user ruling: "24, it's what lives in
|
|
61
|
+
kolkrabbi") — a separate concern from the page ladder below, and
|
|
62
|
+
deliberately tighter: chrome is not page content. The shell header and the
|
|
63
|
+
shell content frame both read this, so they cannot disagree; before it,
|
|
64
|
+
the header carried bare Tailwind steps and the frame carried the page ramp.
|
|
65
|
+
FLAT, not stepped — one value at every width, on the user's word.
|
|
66
|
+
Do NOT reach for this on page containers — that is --kol-pad-section-x. */
|
|
67
|
+
--kol-pad-chrome-x: var(--kol-spacing-6);
|
|
68
|
+
|
|
47
69
|
/* Stepped page / section / band padding tokens.
|
|
48
70
|
Used by chrome (topnav, sidenav) and landing bands. Scaled at 768 / 1024
|
|
49
71
|
breakpoints so one set of rules covers mobile → desktop without clamp(). */
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@kolkrabbi/kol-framework",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.11.1",
|
|
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",
|
|
@@ -27,7 +27,7 @@
|
|
|
27
27
|
"app-shell"
|
|
28
28
|
],
|
|
29
29
|
"dependencies": {
|
|
30
|
-
"@kolkrabbi/kol-component": "0.
|
|
30
|
+
"@kolkrabbi/kol-component": "0.19.0",
|
|
31
31
|
"@kolkrabbi/kol-icons": "0.8.11"
|
|
32
32
|
},
|
|
33
33
|
"peerDependencies": {
|
package/src/AppShell.jsx
CHANGED
|
@@ -53,7 +53,7 @@ export default function AppShell({ navTree = [], getActivePage, header, footer,
|
|
|
53
53
|
</button>
|
|
54
54
|
|
|
55
55
|
<div
|
|
56
|
-
className="kol-sidenav-backdrop fixed inset-0 z-20
|
|
56
|
+
className="kol-sidenav-backdrop fixed inset-0 z-20 kol-overlay-scrim opacity-0 pointer-events-none transition-opacity duration-200 md:hidden"
|
|
57
57
|
onClick={() => setDrawerOpen(false)}
|
|
58
58
|
aria-hidden="true"
|
|
59
59
|
/>
|
package/src/ShellHeader.jsx
CHANGED
|
@@ -42,6 +42,13 @@ import ThemeToggle from './ThemeToggle.jsx'
|
|
|
42
42
|
* @param {string} className extra classes on the outer bar
|
|
43
43
|
*/
|
|
44
44
|
|
|
45
|
+
/* ONE header-action glyph size (user 2026-08-01: "icon in navbar is small and
|
|
46
|
+
* wrong"). The row mixed sizes: the ThemeToggle draws its solo glyph at 24 on
|
|
47
|
+
* the `lg` rung while search, GitHub and the hamburger sat at 18 — four
|
|
48
|
+
* controls, two scales, in a row eight inches wide. Named once here so a new
|
|
49
|
+
* control cannot pick its own. */
|
|
50
|
+
export const HEADER_ICON = 24
|
|
51
|
+
|
|
45
52
|
const iconBtnCls =
|
|
46
53
|
'flex h-9 w-9 items-center justify-center rounded p-0 bg-transparent border-0 cursor-pointer transition-colors hover:bg-fg-08 hover:text-emphasis'
|
|
47
54
|
|
|
@@ -66,7 +73,11 @@ export default function ShellHeader({
|
|
|
66
73
|
<header className={`kol-shell-header sticky top-0 z-50 shrink-0 bg-surface-primary ${className}`.trim()}>
|
|
67
74
|
{/* Row 1: brand block + controls */}
|
|
68
75
|
<div className="border-b border-fg-08">
|
|
69
|
-
|
|
76
|
+
{/* Chrome inset from --kol-pad-chrome-x, not Tailwind steps
|
|
77
|
+
* (2026-07-31): the header sat on its own improvised steps while the
|
|
78
|
+
* shell content frame sat on the page ramp, so the sidebar hung right
|
|
79
|
+
* of the wordmark above it. One token, both surfaces. */}
|
|
80
|
+
<div className="w-full py-4" style={{ paddingInline: 'var(--kol-pad-chrome-x)' }}>
|
|
70
81
|
<div className="flex items-center justify-between">
|
|
71
82
|
{/* kol-shell-header-brand reserves the nav-column width at lg+ so
|
|
72
83
|
* the Row-2 tabs align to the shell grid. */}
|
|
@@ -93,7 +104,7 @@ export default function ShellHeader({
|
|
|
93
104
|
onClick={onMenuClick}
|
|
94
105
|
aria-label="Open navigation menu"
|
|
95
106
|
>
|
|
96
|
-
<Icon name="hamburger" size={
|
|
107
|
+
<Icon name="hamburger" size={HEADER_ICON} />
|
|
97
108
|
</button>
|
|
98
109
|
</Tooltip>
|
|
99
110
|
)}
|
|
@@ -105,7 +116,7 @@ export default function ShellHeader({
|
|
|
105
116
|
{/* Row 2: section tabs + inline search + rail toggles */}
|
|
106
117
|
{hasTabRow && (
|
|
107
118
|
<div className="border-b border-fg-08">
|
|
108
|
-
<div className="w-full
|
|
119
|
+
<div className="w-full" style={{ paddingInline: 'var(--kol-pad-chrome-x)' }}>
|
|
109
120
|
<div className="kol-shell-header-tabs">
|
|
110
121
|
<nav className="flex flex-1 gap-6" aria-label="Sections">
|
|
111
122
|
{nav.map((item) => {
|
package/src/ThemeToggle.jsx
CHANGED
|
@@ -43,7 +43,8 @@ import { useTheme } from './theme.js'
|
|
|
43
43
|
* no consumer shifts a pixel; migrate at your own pace:
|
|
44
44
|
* icon → button + fill none + label off
|
|
45
45
|
* hop → button + fill subtle + fullWidth (old: chrome pinned md)
|
|
46
|
-
* hop-bare → flush + fullWidth
|
|
46
|
+
* hop-bare → flush + fullWidth. Horizontal pad stays 24px (sidenav gutter);
|
|
47
|
+
* vertical pad, type and glyph honour `size` since 2026-07-30.
|
|
47
48
|
*
|
|
48
49
|
* Theme state lives in useTheme (./theme.js); this component is only the
|
|
49
50
|
* glyph-roll UI on top of it.
|
|
@@ -145,13 +146,24 @@ export default function ThemeToggle({
|
|
|
145
146
|
}
|
|
146
147
|
if (variant === 'hop' || variant === 'hop-bare') {
|
|
147
148
|
const bare = variant === 'hop-bare'
|
|
149
|
+
/* hop-bare HONOURS `size` (user ruling 2026-07-30). It used to hardcode
|
|
150
|
+
* kol-mono-14 while its glyph still tracked `size`, so size="lg" produced a
|
|
151
|
+
* 24px glyph beside 14px text — and it took the SOLO glyph ladder despite
|
|
152
|
+
* carrying a label, against the glyph law in this docstring.
|
|
153
|
+
*
|
|
154
|
+
* One container across all three rungs: same bare full-width row, only the
|
|
155
|
+
* vertical pad, the type and the glyph move (4/6/8 · 12/14/16 · 14/16/18).
|
|
156
|
+
* The 24px horizontal gutter is FIXED at every size — it aligns the row with
|
|
157
|
+
* the sidenav's own pl-6, which is the whole reason this alias exists.
|
|
158
|
+
* `hop` stays pinned to md: its docstring promises old chrome verbatim. */
|
|
159
|
+
const barePadY = size === 'sm' ? 'py-1' : size === 'lg' ? 'py-2' : 'py-1.5'
|
|
148
160
|
const chromeCls = bare
|
|
149
|
-
?
|
|
161
|
+
? `w-full inline-flex items-center justify-start gap-2 ${barePadY} px-6 ${mono} bg-transparent text-emphasis`
|
|
150
162
|
: 'kol-theme-toggle kol-theme-toggle-subtle kol-btn-md kol-mono-14 w-full justify-start gap-2'
|
|
151
163
|
return (
|
|
152
164
|
<button {...shared} className={`${chromeCls} ${className}`.trim()}>
|
|
153
165
|
<span className="inline-flex items-center justify-center shrink-0" aria-hidden="true">
|
|
154
|
-
{iconSwap(glyphSolo)}
|
|
166
|
+
{iconSwap(bare ? glyphWithText : glyphSolo)}
|
|
155
167
|
</span>
|
|
156
168
|
<span className="kol-sidenav-hop-label flex-1 min-w-0 text-left">
|
|
157
169
|
{MODE_LABEL[shown]}
|
package/src/index.js
CHANGED
|
@@ -10,7 +10,7 @@
|
|
|
10
10
|
export { default as AppShell } from './AppShell.jsx'
|
|
11
11
|
export { ShellTocContext, ShellTocCollapsedContext } from './AppShell.jsx'
|
|
12
12
|
export { default as SideNav } from './SideNav.jsx'
|
|
13
|
-
export { default as ShellHeader } from './ShellHeader.jsx'
|
|
13
|
+
export { default as ShellHeader, HEADER_ICON } from './ShellHeader.jsx'
|
|
14
14
|
export { default as ThemeToggle } from './ThemeToggle.jsx'
|
|
15
15
|
export { useTheme, applyTheme, getInitialTheme, THEME_STORAGE_KEY } from './theme.js'
|
|
16
16
|
export { default as Layout } from './Layout.jsx'
|