@kolkrabbi/kol-framework 0.6.0 → 0.6.2

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 CHANGED
@@ -17,21 +17,11 @@ html,
17
17
  body {
18
18
  background: var(--kol-surface-primary);
19
19
  color: var(--kol-surface-on-primary);
20
-
21
- /* Editor-style app — selection is mostly meaningless on chrome. Default
22
- * to non-selectable; opt back in for prose, tables, inputs, code below. */
23
- -webkit-user-select: none;
24
- user-select: none;
25
20
  }
26
21
 
27
- /* Allowlist — surfaces where reading / copying matters. */
28
- input, textarea, [contenteditable="true"],
29
- .kol-prose, .kol-prose *,
30
- .kol-table, .kol-table *,
31
- code, pre {
32
- -webkit-user-select: text;
33
- user-select: text;
34
- }
22
+ /* The global user-select:none gate + allowlist was REMOVED 2026-07-29 (user
23
+ * law, brand-app ruling): text is selectable everywhere — copyability beats
24
+ * chrome purity. */
35
25
 
36
26
  /* Selection highlight uses brand-primary so it reads on-brand when it appears. */
37
27
  ::selection {
@@ -87,7 +77,10 @@ code, pre {
87
77
 
88
78
  @media (min-width: 1280px) { :root { --kol-container-max: 1600px; } }
89
79
 
90
- :root[data-sidenav="collapsed"] { --kol-sidenav-w: var(--kol-sidenav-w-collapsed); }
80
+ /* :root[data-sidenav="collapsed"] removed 2026-07-29 — the manual collapse
81
+ * feature died with the editor's exit (brand ruling); the responsive rail
82
+ * below 1024px is the surviving narrow mode. --kol-sidenav-w-collapsed stays:
83
+ * the rail still uses it. */
91
84
 
92
85
  /* ───── Brand doc layout (sidebar + content) ─────
93
86
  The grid lives in CSS for its dynamic --kol-sidenav-w + transition. */
@@ -103,7 +96,6 @@ code, pre {
103
96
  User's localStorage expand preference is overridden while viewport is narrow;
104
97
  restored once they cross back over the threshold. */
105
98
  .kol-brand-layout { grid-template-columns: var(--kol-sidenav-w-collapsed) minmax(0, 1fr); }
106
- .kol-sidenav-toggle { display: none; }
107
99
  .kol-sidenav-hops { padding: 0 0 16px; margin-bottom: 16px; }
108
100
  .kol-sidenav-hop { padding: 8px 0; justify-content: center; gap: 0; }
109
101
  .kol-sidenav-hop-label { display: none; }
@@ -134,30 +126,9 @@ code, pre {
134
126
  }
135
127
 
136
128
  /* SideNav primitives (.kol-sidenav-hop, -hop-icon, -hop-label, -link,
137
- * -group) promoted to kol-components-atoms.css 2026-04-30. The .is-collapsed
138
- * responsive cascade rules below stay here — they're page-grid concerns,
139
- * not component chrome. */
140
-
141
- /* ───── SideNav collapsed (rail mode) — overrides inlined hop padding/gap ───── */
142
-
143
- .kol-sidenav.is-collapsed .kol-sidenav-hops {
144
- padding: 0 0 16px;
145
- margin-bottom: 16px;
146
- }
147
-
148
- .kol-sidenav.is-collapsed .kol-sidenav-hop {
149
- padding: 8px 0;
150
- justify-content: center;
151
- gap: 0;
152
- }
153
-
154
- .kol-sidenav.is-collapsed .kol-sidenav-hop-label {
155
- display: none;
156
- }
157
-
158
- .kol-sidenav.is-collapsed .kol-sidenav-body {
159
- display: none;
160
- }
129
+ * -group) promoted to kol-components-atoms.css 2026-04-30. The manual
130
+ * collapse (.is-collapsed rail mode) was removed 2026-07-29 with the
131
+ * editor's exit — the ≤1024px responsive rail above is the survivor. */
161
132
 
162
133
  /* ───── Page scaffold ───── */
163
134
 
@@ -807,13 +778,9 @@ code, pre {
807
778
  }
808
779
 
809
780
  /* SideNav collapsibleSections chrome — inert unless that mode renders.
810
- Rail (collapsed) + forced rail (≤1024px) hide count/toggle with the labels;
811
- the open ≤767px drawer restores them, mirroring -hop-label. */
812
- .kol-sidenav.is-collapsed .kol-sidenav-hop-count,
813
- .kol-sidenav.is-collapsed .kol-sidenav-section-toggle {
814
- display: none;
815
- }
816
-
781
+ The forced rail (≤1024px) hides count/toggle with the labels; the open
782
+ ≤767px drawer restores them, mirroring -hop-label. (Manual .is-collapsed
783
+ removed 2026-07-29.) */
817
784
  @media (max-width: 1024px) {
818
785
  .kol-sidenav-hop-count,
819
786
  .kol-sidenav-section-toggle {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@kolkrabbi/kol-framework",
3
- "version": "0.6.0",
3
+ "version": "0.6.2",
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",
@@ -28,7 +28,7 @@
28
28
  ],
29
29
  "dependencies": {
30
30
  "@kolkrabbi/kol-component": "0.12.19",
31
- "@kolkrabbi/kol-icons": "0.8.8"
31
+ "@kolkrabbi/kol-icons": "0.8.10"
32
32
  },
33
33
  "peerDependencies": {
34
34
  "react": "^18.3.0 || ^19.0.0",
@@ -1,5 +1,5 @@
1
1
  import { Icon } from '@kolkrabbi/kol-icons'
2
- import { SearchInput } from '@kolkrabbi/kol-component'
2
+ import { SearchInput, Tooltip } from '@kolkrabbi/kol-component'
3
3
  import ThemeToggle from './ThemeToggle.jsx'
4
4
 
5
5
  /**
@@ -21,6 +21,11 @@ import ThemeToggle from './ThemeToggle.jsx'
21
21
  * Tab-strip chrome (mono type, active underline, hidden scrollbar, wide-
22
22
  * viewport bumps) lives in kol-framework.css under kol-shell-header-*.
23
23
  *
24
+ * Every icon-only control is Tooltip-wrapped and aria-labelled, the bar is a
25
+ * real `<header>` landmark, and the theme toggle steps up a rung at lg+ —
26
+ * folded in from the kol-website workshop fork (2026-07-30), which existed
27
+ * only to add these. Consumers get ONE header; the fork is retired.
28
+ *
24
29
  * @param {ReactNode} brand Row-1 left slot — logo/wordmark + link, consumer-supplied
25
30
  * @param {Array} nav section tabs: [{ label, href, icon? }]
26
31
  * @param {Function} isActive (href) => boolean — marks the active tab
@@ -58,7 +63,7 @@ export default function ShellHeader({
58
63
  const hasTabRow = nav.length > 0 || Boolean(search) || Boolean(onNavToggle) || Boolean(onTocToggle)
59
64
 
60
65
  return (
61
- <div className={`kol-shell-header sticky top-0 z-50 shrink-0 bg-surface-primary ${className}`.trim()}>
66
+ <header className={`kol-shell-header sticky top-0 z-50 shrink-0 bg-surface-primary ${className}`.trim()}>
62
67
  {/* Row 1: brand block + controls */}
63
68
  <div className="border-b border-fg-08">
64
69
  <div className="w-full px-4 py-4 md:px-5 lg:px-6">
@@ -70,16 +75,25 @@ export default function ShellHeader({
70
75
  </div>
71
76
  <div className="flex shrink-0 items-center gap-1">
72
77
  {actions}
73
- {showThemeToggle && <ThemeToggle />}
78
+ {showThemeToggle && (
79
+ <Tooltip label="Toggle theme">
80
+ {/* one rung up at lg+ — the bar has room, and the toggle is
81
+ * the most-used control in the row */}
82
+ <span className="hidden lg:inline-flex"><ThemeToggle size="lg" /></span>
83
+ <span className="lg:hidden"><ThemeToggle /></span>
84
+ </Tooltip>
85
+ )}
74
86
  {onMenuClick && (
75
- <button
76
- type="button"
77
- className={`${iconBtnCls} text-fg-64`}
78
- onClick={onMenuClick}
79
- aria-label="Open navigation menu"
80
- >
81
- <Icon name="hamburger" size={18} />
82
- </button>
87
+ <Tooltip label="Open navigation menu">
88
+ <button
89
+ type="button"
90
+ className={`${iconBtnCls} text-fg-64`}
91
+ onClick={onMenuClick}
92
+ aria-label="Open navigation menu"
93
+ >
94
+ <Icon name="hamburger" size={18} />
95
+ </button>
96
+ </Tooltip>
83
97
  )}
84
98
  </div>
85
99
  </div>
@@ -98,7 +112,7 @@ export default function ShellHeader({
98
112
  <a
99
113
  key={item.href ?? item.label}
100
114
  href={item.href}
101
- className="kol-shell-header-tab"
115
+ className="kol-shell-header-tab kol-mono-14"
102
116
  aria-current={active ? 'page' : undefined}
103
117
  onClick={onNavigate ? (event) => onNavigate(event, item) : undefined}
104
118
  >
@@ -111,30 +125,37 @@ export default function ShellHeader({
111
125
  {search && (
112
126
  <SearchInput
113
127
  className="shrink-0 self-center"
128
+ aria-label="Search"
114
129
  {...(search === true ? {} : search)}
115
130
  />
116
131
  )}
117
132
  {(onNavToggle || onTocToggle) && (
118
133
  <div className="hidden lg:flex items-center gap-1 pb-2">
119
134
  {onNavToggle && (
120
- <button
121
- type="button"
122
- className={`${iconBtnCls} ${navCollapsed ? 'text-fg-32' : 'text-fg-64'}`}
123
- onClick={onNavToggle}
124
- aria-label="Toggle navigation sidebar"
125
- >
126
- <Icon name="panel-left" size={18} />
127
- </button>
135
+ <Tooltip label="Toggle navigation sidebar">
136
+ <button
137
+ type="button"
138
+ className={`${iconBtnCls} ${navCollapsed ? 'text-fg-32' : 'text-fg-64'}`}
139
+ onClick={onNavToggle}
140
+ aria-label="Toggle navigation sidebar"
141
+ aria-pressed={!navCollapsed}
142
+ >
143
+ <Icon name="panel-left" size={18} />
144
+ </button>
145
+ </Tooltip>
128
146
  )}
129
147
  {onTocToggle && (
130
- <button
131
- type="button"
132
- className={`${iconBtnCls} ${tocCollapsed ? 'text-fg-32' : 'text-fg-64'}`}
133
- onClick={onTocToggle}
134
- aria-label="Toggle table of contents sidebar"
135
- >
136
- <Icon name="panel-right" size={18} />
137
- </button>
148
+ <Tooltip label="Toggle table of contents sidebar">
149
+ <button
150
+ type="button"
151
+ className={`${iconBtnCls} ${tocCollapsed ? 'text-fg-32' : 'text-fg-64'}`}
152
+ onClick={onTocToggle}
153
+ aria-label="Toggle table of contents sidebar"
154
+ aria-pressed={!tocCollapsed}
155
+ >
156
+ <Icon name="panel-right" size={18} />
157
+ </button>
158
+ </Tooltip>
138
159
  )}
139
160
  </div>
140
161
  )}
@@ -142,6 +163,6 @@ export default function ShellHeader({
142
163
  </div>
143
164
  </div>
144
165
  )}
145
- </div>
166
+ </header>
146
167
  )
147
168
  }