@kolkrabbi/kol-shell 0.41.0 → 0.43.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 CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@kolkrabbi/kol-shell",
3
- "version": "0.41.0",
3
+ "version": "0.43.0",
4
4
  "private": false,
5
5
  "description": "KOL application shell — fixed 48px NavRail + AppShell layout root, PageShell/PageHeader scaffolds, ContentFilters catalog organism, GridCard, SettingsScaffold, WalkthroughPanel, ShortcutsOverlay. App chrome (kol-framework owns site chrome). Nav items, content, shortcuts and settings are consumer-injected. Sits above @kolkrabbi/kol-{theme,component,framework}.",
6
6
  "license": "MIT",
@@ -14,16 +14,16 @@
14
14
  "peerDependencies": {
15
15
  "@kolkrabbi/kol-component": ">=0.174.0",
16
16
  "@kolkrabbi/kol-icons": ">=0.16.0",
17
- "@kolkrabbi/kol-theme": ">=0.84.0",
17
+ "@kolkrabbi/kol-theme": ">=0.135.0",
18
18
  "gsap": "^3.13.0",
19
19
  "react": "^18.3.0 || ^19.0.0",
20
20
  "react-dom": "^18.3.0 || ^19.0.0"
21
21
  },
22
22
  "devDependencies": {
23
- "@kolkrabbi/kol-component": "^0.174.0",
24
- "@kolkrabbi/kol-framework": "^0.37.0",
23
+ "@kolkrabbi/kol-component": "^0.176.0",
24
+ "@kolkrabbi/kol-framework": "^0.41.0",
25
25
  "@kolkrabbi/kol-icons": "^0.25.0",
26
- "@kolkrabbi/kol-theme": "^0.132.1"
26
+ "@kolkrabbi/kol-theme": "^0.135.0"
27
27
  },
28
28
  "files": [
29
29
  "src",
@@ -18,7 +18,7 @@ import WalkthroughPanel from './WalkthroughPanel.jsx'
18
18
  *
19
19
  * Semantics are the consumer's: what RECENT / SAVED mean, what an item is,
20
20
  * what a click does. `toCard(item, { view, layout })` → `{ key, title, detail,
21
- * media, actions, onClick, href, onNavigate, expanded, expandedContent, fit }` is
21
+ * media, actions, onClick, href, onNavigate, expanded, expandedContent, fit, ratio }` is
22
22
  * the whole contract — `expanded` / `expandedContent` reach `ContentCard catalog`'s
23
23
  * 2×2 cell (ShellHomeSystemMonitorGaps, kol-monitor 2026-08-27) — and the page
24
24
  * HIDES the cell's three neighbours itself (CatalogPageMonitorParity: the
@@ -27,7 +27,10 @@ import WalkthroughPanel from './WalkthroughPanel.jsx'
27
27
  * instead of reflowing around the expanded card); `fit` (`cover` default | `natural` | `compact`) is the
28
28
  * card's media fit, PER CARD because one catalog mixes photographs (cover) and
29
29
  * diagrams (natural) — CatalogPageCardFit, kol-monitor: a rack preview wider
30
- * than the card lost its left rail to `cover`. Anything `ContentFilters` takes that the page has no
30
+ * than the card lost its left rail to `cover`; `ratio` (catalogpage-card-ratio, kol-client-olina
31
+ * 2026-09-03) is the card's aspect, PER CARD for the same reason — one page renders the same artwork
32
+ * at 1:1, 4:5 and 9:16 side by side, and a deck is a 16:9 stage — unset falling through to the
33
+ * variant's A4, so nothing existing moves. Anything `ContentFilters` takes that the page has no
31
34
  * prop for goes through `filtersProps` — `mutuallyExclusiveFilters` was the gap.
32
35
  *
33
36
  * @param {Object} header PageHeader props — `{ title, subtitle, size, voice, eyebrow }`
@@ -42,6 +45,9 @@ import WalkthroughPanel from './WalkthroughPanel.jsx'
42
45
  * @param {string} defaultLayout 'grid' (default) | 'list'
43
46
  * @param {{steps: Array, open: boolean, iconComponent?: ElementType}} walkthrough the panel over the catalog
44
47
  * @param {ReactNode} actions the bottom row's buttons
48
+ * @param {'bleed'|'capped'} width the page's TIER, forwarded to PageShell (two-page-scaffolds-one-job, 2026-09-03):
49
+ * `bleed` (default) fills the window — the app tier; `capped` centres on the
50
+ * framework container — the site tier, so a brand book adopting this page keeps its geometry
45
51
  * @param {ElementType} iconComponent icon renderer seam for ContentFilters
46
52
  * @param {boolean} showCountOnlyWhenFiltering (default true)
47
53
  * @param {Object} filtersProps spread onto ContentFilters last — e.g. `{ mutuallyExclusiveFilters: ['category', 'u_label'] }`
@@ -67,6 +73,7 @@ function computeHiddenSet(items, expandedIdx) {
67
73
 
68
74
  export default function CatalogPage({
69
75
  header,
76
+ width = 'bleed',
70
77
  items = [],
71
78
  toCard,
72
79
  filtersTitle,
@@ -89,7 +96,7 @@ export default function CatalogPage({
89
96
  }) {
90
97
  const open = walkthrough?.open === true
91
98
  return (
92
- <PageShell className={className} style={{ overflow: 'hidden', ...style }}>
99
+ <PageShell width={width} className={className} style={{ overflow: 'hidden', ...style }}>
93
100
  {header && <PageHeader {...header} />}
94
101
  <div style={{ flex: 1, position: 'relative' }}>
95
102
  {open && <WalkthroughPanel steps={walkthrough.steps} iconComponent={walkthrough.iconComponent} />}
@@ -131,7 +138,7 @@ export default function CatalogPage({
131
138
  const key = c.key ?? item.key ?? item.id ?? item.name ?? i
132
139
  return layout === 'list'
133
140
  ? <ContentRow key={key} variant="catalog" title={c.title} detail={c.detail} actions={c.actions} onClick={c.onClick} href={c.href} onNavigate={c.onNavigate} />
134
- : <ContentCard key={key} variant="catalog" fit={c.fit ?? 'cover'} title={c.title} detail={c.detail} media={c.media} actions={c.actions} onClick={c.onClick} href={c.href} onNavigate={c.onNavigate} expanded={c.expanded} expandedContent={c.expandedContent} />
141
+ : <ContentCard key={key} variant="catalog" fit={c.fit ?? 'cover'} ratio={c.ratio} title={c.title} detail={c.detail} media={c.media} actions={c.actions} onClick={c.onClick} href={c.href} onNavigate={c.onNavigate} expanded={c.expanded} expandedContent={c.expandedContent} />
135
142
  })}
136
143
  </div>
137
144
  )
package/src/PageShell.jsx CHANGED
@@ -6,8 +6,19 @@
6
6
  * `mode="fixed"`: height 100vh, overflow hidden — pair with a `flex:1
7
7
  * overflow:auto` body (the settings idiom; SettingsScaffold does this).
8
8
  *
9
- * Gutter is `--kol-shell-page-pad` (kol-theme). `PageBleed` breaks it for
10
- * full-width embeds (monitor's rack bleed).
9
+ * Gutter is `--kol-shell-page-pad` (kol-theme) since theme 0.135.0 an alias
10
+ * of `--kol-pad-section-x`, the ONE page-content ladder every `.kol-page`
11
+ * wears (two-page-scaffolds-one-job, kol-client-olina 2026-09-03: two ladders
12
+ * for one job agreed only at 48). `PageBleed` breaks it for full-width embeds
13
+ * (monitor's rack bleed).
14
+ *
15
+ * THE GEOMETRY IS A CLASS — `.kol-shell-page` (+ `--fixed`, `--capped`), in
16
+ * kol-components-shell.css — so a consumer has a selector to reach; inline is
17
+ * the `style` prop only. `width` is the TIER: `bleed` (default) fills the
18
+ * window, the app tier; `capped` takes the framework container ladder and
19
+ * centres, the site tier — the one real difference between this and a
20
+ * `.kol-page`, and a prop so a site adopting the shipped catalog page does
21
+ * not silently get app geometry.
11
22
  *
12
23
  * `scrollbar-gutter: stable` on both modes (PageShellScrollbarGutter,
13
24
  * kol-monitor 2026-08-28 — user: "Create is the odd one out"). A page's content
@@ -39,40 +50,31 @@
39
50
  * `AppShell pageWash`, a transparent wash over the shell's primary back —
40
51
  * the lightness steps up and the structure stays visible, which an opaque
41
52
  * surface swap would hide. The ink stays `text-auto` (surface-on-primary).
53
+ * ONE OWNER PER PIXEL (2026-09-03): the variable means what is LEFT to paint.
54
+ * kol-shell's `AppShell` hands the wash down for this to paint; kol-framework's
55
+ * `PageLayout` paints it on its own plane and hands down `transparent`, so a
56
+ * PageShell inside it does not paint it again (it used to — two 0.02 layers).
57
+ *
58
+ * @param {'scroll'|'fixed'} mode scroll (default) | fixed — see above
59
+ * @param {'bleed'|'capped'} width bleed (default, the app tier) | capped (the site tier — `--kol-container-max`, centred)
60
+ * @param {string} className
61
+ * @param {object} style inline — the one thing that stays inline
42
62
  */
43
- export default function PageShell({ mode = 'scroll', className = '', style, children }) {
44
- const modeStyle =
45
- mode === 'fixed'
46
- ? { height: '100vh', overflow: 'hidden' }
47
- : { minHeight: '100vh' }
63
+ export default function PageShell({ mode = 'scroll', width = 'bleed', className = '', style, children }) {
48
64
  return (
49
65
  <div
50
- className={`text-auto ${className}`.trim()}
51
- style={{
52
- background: 'var(--kol-shell-page-wash, var(--kol-surface-primary))',
53
- padding: 'var(--kol-shell-page-pad)',
54
- scrollbarGutter: 'stable',
55
- display: 'flex',
56
- flexDirection: 'column',
57
- ...modeStyle,
58
- ...style,
59
- }}
66
+ className={`kol-shell-page${mode === 'fixed' ? ' kol-shell-page--fixed' : ''}${width === 'capped' ? ' kol-shell-page--capped' : ''} text-auto ${className}`.trim()}
67
+ style={style}
60
68
  >
61
69
  {children}
62
70
  </div>
63
71
  )
64
72
  }
65
73
 
66
- /** Full-bleed slot — cancels PageShell's horizontal gutter. */
74
+ /** Full-bleed slot — cancels PageShell's horizontal gutter (`.kol-shell-page-bleed`). */
67
75
  export function PageBleed({ style, children }) {
68
76
  return (
69
- <div
70
- style={{
71
- marginLeft: 'calc(var(--kol-shell-page-pad) * -1)',
72
- marginRight: 'calc(var(--kol-shell-page-pad) * -1)',
73
- ...style,
74
- }}
75
- >
77
+ <div className="kol-shell-page-bleed" style={style}>
76
78
  {children}
77
79
  </div>
78
80
  )