@kolkrabbi/kol-framework 0.5.10 → 0.5.12

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-framework",
3
- "version": "0.5.10",
3
+ "version": "0.5.12",
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.6"
31
+ "@kolkrabbi/kol-icons": "0.8.8"
32
32
  },
33
33
  "peerDependencies": {
34
34
  "react": "^18.3.0 || ^19.0.0",
@@ -9,6 +9,11 @@ import { useTheme } from './theme.js'
9
9
  * → 14/16/18px glyph, square box + quiet states from the
10
10
  * .kol-btn-nav chrome (theme ≥0.11.4), so the toggle sits flush
11
11
  * with sibling navigation buttons in a bar.
12
+ * button — a REAL ladder button (2026-07-29, user-ordered): glyph + label
13
+ * inside plain `.kol-btn .kol-btn-primary .kol-btn-{size}` with
14
+ * the rung's mono type and pairing-law glyph (16/20/24) — no
15
+ * width/justify overrides, so it measures exactly like any
16
+ * other kol-btn on the rung.
12
17
  * hop — full-width labeled Button-primary-styled sidenav row
13
18
  * (bg-fg-04, on-primary text). For sidenav rows where it pairs
14
19
  * with other Button-primary "hop" entries.
@@ -19,9 +24,10 @@ import { useTheme } from './theme.js'
19
24
  * Theme state lives in useTheme (./theme.js) — the exported machinery
20
25
  * (initial-state resolution, saved-choice re-stamp, system-follow, cross-
21
26
  * instance sync). This component is only the icon-swap UI on top of it.
22
- * The icon-swap animation slides a doubled `mode-toggle-01` (v1 set)
23
- * horizontally — the split-circle glyph makes the slide itself read as
24
- * the flip (same-icon slide, per design).
27
+ * The icon-swap slides a doubled `mode-toggle-01` (v1 set) horizontally
28
+ * while both glyphs spin 180° in the same clock — the split-circle rolls
29
+ * forward (>>) on dark→light and rolls back (<<) on light→dark (the
30
+ * original roll behavior, restored 2026-07-29).
25
31
  */
26
32
  export default function ThemeToggle({ variant = 'icon', size = 'md', className = '' }) {
27
33
  const { isDark, toggle } = useTheme()
@@ -29,6 +35,12 @@ export default function ThemeToggle({ variant = 'icon', size = 'md', className =
29
35
  const next = isDark ? 'light' : 'dark'
30
36
  const handleToggle = toggle
31
37
 
38
+ /* The roll: the strip slides one glyph-width while each glyph spins 180° in
39
+ * the same clock — dark→light rolls forward (>>), light→dark rolls back (<<). */
40
+ const glyphSpin = {
41
+ transform: isDark ? 'rotate(0deg)' : 'rotate(180deg)',
42
+ lineHeight: 0,
43
+ }
32
44
  const iconSwap = (size) => (
33
45
  <span
34
46
  className="relative inline-block overflow-hidden"
@@ -39,12 +51,32 @@ export default function ThemeToggle({ variant = 'icon', size = 'md', className =
39
51
  className="flex transition-transform duration-500 ease-in-out"
40
52
  style={{ width: size * 2, transform: isDark ? 'translateX(0)' : `translateX(-${size}px)` }}
41
53
  >
42
- <Icon name="mode-toggle-01" size={size} />
43
- <Icon name="mode-toggle-01" size={size} />
54
+ <span className="inline-flex transition-transform duration-500 ease-in-out" style={glyphSpin}>
55
+ <Icon name="mode-toggle-01" size={size} />
56
+ </span>
57
+ <span className="inline-flex transition-transform duration-500 ease-in-out" style={glyphSpin}>
58
+ <Icon name="mode-toggle-01" size={size} />
59
+ </span>
44
60
  </span>
45
61
  </span>
46
62
  )
47
63
 
64
+ if (variant === 'button') {
65
+ const mono = size === 'sm' ? 'kol-mono-12' : size === 'lg' ? 'kol-mono-16' : 'kol-mono-14'
66
+ const glyph = size === 'sm' ? 16 : size === 'lg' ? 24 : 20
67
+ return (
68
+ <button
69
+ type="button"
70
+ onClick={handleToggle}
71
+ aria-label={`Switch to ${next} mode`}
72
+ className={`kol-btn kol-btn-primary kol-btn-${size} ${mono} gap-2 ${className}`.trim()}
73
+ >
74
+ {iconSwap(glyph)}
75
+ <span>{isDark ? 'Dark mode' : 'Light mode'}</span>
76
+ </button>
77
+ )
78
+ }
79
+
48
80
  if (variant === 'hop' || variant === 'hop-bare') {
49
81
  const bare = variant === 'hop-bare'
50
82
  const chromeCls = bare