@the-portland-company/shell 0.11.1 → 0.11.3
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/CHANGELOG.md +33 -0
- package/dist/chrome.css +20 -0
- package/dist/chunk-VTGRJ4HV.js +25 -0
- package/dist/chunk-VTGRJ4HV.js.map +1 -0
- package/dist/index.cjs +2 -2
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +2 -9
- package/dist/index.d.ts +2 -9
- package/dist/index.js +3 -19
- package/dist/index.js.map +1 -1
- package/dist/native.cjs +39 -4
- package/dist/native.cjs.map +1 -1
- package/dist/native.d.cts +7 -0
- package/dist/native.d.ts +7 -0
- package/dist/native.js +22 -6
- package/dist/native.js.map +1 -1
- package/dist/topbarIconSlot-FunwEKO9.d.cts +10 -0
- package/dist/topbarIconSlot-FunwEKO9.d.ts +10 -0
- package/package.json +20 -8
package/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,36 @@
|
|
|
1
|
+
## 0.11.3 — 2026-07-20
|
|
2
|
+
|
|
3
|
+
### Fixed (native — token contract + client boundary)
|
|
4
|
+
|
|
5
|
+
- **Native chrome now has a real semantic token layer.** The `./native`
|
|
6
|
+
components (NavTopBar / NavSidebar / NavTabStrip / NavAppShell) reference
|
|
7
|
+
`--background`, `--foreground`, `--muted`, `--panel`, `--panel-elevated`,
|
|
8
|
+
`--line`, `--shadow-soft` directly as `var(--x)`, but chrome.css never defined
|
|
9
|
+
them for light mode and only emitted `--foreground`/`--muted`/`--background`
|
|
10
|
+
inside `.dark` as ShadCN **HSL channel triplets** (`210 40% 98%`) meant for
|
|
11
|
+
`hsl(var(--x))` — invalid when used as a full color, so out-of-the-box the
|
|
12
|
+
native chrome had no surface/border and broken text. `gen:tokens` now emits
|
|
13
|
+
these seven names as **full colors in both `:root` (light, aliased to the
|
|
14
|
+
canonical `--topbar-*`/`--surface-*`/`--sidebar-border`/`--shadow-lg` tokens)
|
|
15
|
+
and `.dark` (from the Specs `darkMode.*` values wrapped in `hsl()`)**. Note
|
|
16
|
+
`--muted` maps to muted-*foreground* because native uses it as secondary text.
|
|
17
|
+
Apps consuming `./native` no longer need an app-side var bridge in globals.css.
|
|
18
|
+
- **`"use client"` is now emitted on `dist/native.{js,cjs}`** (prepended
|
|
19
|
+
post-build, since esbuild strips a source/banner directive). Next.js App
|
|
20
|
+
Router apps can import the native chrome into Server Components without a
|
|
21
|
+
manual client-boundary wrapper. Ignored (harmless) by Vite/Chakra consumers.
|
|
22
|
+
|
|
23
|
+
## 0.11.2 — 2026-07-20
|
|
24
|
+
|
|
25
|
+
### Added (native — per-slot Brand glyphs)
|
|
26
|
+
|
|
27
|
+
- **`NavTopBarAction` gains an optional `slot`** so the native top-bar action
|
|
28
|
+
icons source their glyph by name from `--topbar-icon-<slot>` (Brand API),
|
|
29
|
+
matching the Chakra `<TopBarIcon>`; button size/color/hover and the cluster
|
|
30
|
+
gap now resolve the universal `--topbar-icon-*` tokens with the previous
|
|
31
|
+
literals as fallbacks. Shared slot contract extracted to
|
|
32
|
+
`src/lib/topbarIconSlot.ts` (framework-agnostic, no Chakra import).
|
|
33
|
+
|
|
1
34
|
## 0.11.1 — 2026-07-20
|
|
2
35
|
|
|
3
36
|
### Fixed (packaging — native install)
|
package/dist/chrome.css
CHANGED
|
@@ -240,6 +240,19 @@
|
|
|
240
240
|
--mode-input-border-color: #E63946;
|
|
241
241
|
--mode-input-hover-border-color: #C42E3A;
|
|
242
242
|
--mode-input-focus-shadow-color: #E63946;
|
|
243
|
+
|
|
244
|
+
/* Native chrome semantic layer — shell-owned aliases over the
|
|
245
|
+
canonical tokens above, consumed by the ./native export
|
|
246
|
+
(NavTopBar / NavSidebar / NavTabStrip / NavAppShell). These are the
|
|
247
|
+
full-color names those components reference directly as var(--x);
|
|
248
|
+
the .dark block overrides them with dark values. */
|
|
249
|
+
--background: var(--surface-1);
|
|
250
|
+
--foreground: var(--topbar-title-color);
|
|
251
|
+
--muted: var(--topbar-breadcrumb-color);
|
|
252
|
+
--panel: var(--topbar-bg);
|
|
253
|
+
--panel-elevated: var(--surface-1);
|
|
254
|
+
--line: var(--sidebar-border);
|
|
255
|
+
--shadow-soft: var(--shadow-lg);
|
|
243
256
|
}
|
|
244
257
|
.dark {
|
|
245
258
|
--background: 222.2 84% 4.9%;
|
|
@@ -261,4 +274,11 @@
|
|
|
261
274
|
--border: 217.2 32.6% 17.5%;
|
|
262
275
|
--input: 217.2 32.6% 17.5%;
|
|
263
276
|
--ring: 212.7 26.8% 83.9%;
|
|
277
|
+
--background: hsl(222.2 84% 4.9%);
|
|
278
|
+
--foreground: hsl(210 40% 98%);
|
|
279
|
+
--muted: hsl(215 20.2% 65.1%);
|
|
280
|
+
--panel: hsl(222.2 84% 4.9%);
|
|
281
|
+
--panel-elevated: hsl(217.2 32.6% 17.5%);
|
|
282
|
+
--line: hsl(217.2 32.6% 17.5%);
|
|
283
|
+
--shadow-soft: 0 4px 16px rgba(0, 0, 0, 0.5);
|
|
264
284
|
}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { useState, useEffect } from 'react';
|
|
2
|
+
|
|
3
|
+
// src/lib/topbarIconSlot.ts
|
|
4
|
+
function useTopBarIconSlotGlyph(slot) {
|
|
5
|
+
const [name, setName] = useState(null);
|
|
6
|
+
useEffect(() => {
|
|
7
|
+
if (typeof window === "undefined") return;
|
|
8
|
+
const read = () => {
|
|
9
|
+
const raw = window.getComputedStyle(document.documentElement).getPropertyValue(`--topbar-icon-${slot}`).trim().replace(/^['"]|['"]$/g, "");
|
|
10
|
+
setName(raw.length > 0 ? raw : null);
|
|
11
|
+
};
|
|
12
|
+
read();
|
|
13
|
+
const observer = new MutationObserver(read);
|
|
14
|
+
observer.observe(document.head, { childList: true, subtree: true });
|
|
15
|
+
return () => observer.disconnect();
|
|
16
|
+
}, [slot]);
|
|
17
|
+
return name;
|
|
18
|
+
}
|
|
19
|
+
function brandIconSrc(name, basePath = "/brand/icons/") {
|
|
20
|
+
return `${basePath}${name}.svg`;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
export { brandIconSrc, useTopBarIconSlotGlyph };
|
|
24
|
+
//# sourceMappingURL=chunk-VTGRJ4HV.js.map
|
|
25
|
+
//# sourceMappingURL=chunk-VTGRJ4HV.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/lib/topbarIconSlot.ts"],"names":[],"mappings":";;;AA6BO,SAAS,uBAAuB,IAAA,EAAqC;AAC1E,EAAA,MAAM,CAAC,IAAA,EAAM,OAAO,CAAA,GAAI,SAAwB,IAAI,CAAA;AAEpD,EAAA,SAAA,CAAU,MAAM;AACd,IAAA,IAAI,OAAO,WAAW,WAAA,EAAa;AAEnC,IAAA,MAAM,OAAO,MAAM;AACjB,MAAA,MAAM,GAAA,GAAM,MAAA,CACT,gBAAA,CAAiB,QAAA,CAAS,eAAe,CAAA,CACzC,gBAAA,CAAiB,CAAA,cAAA,EAAiB,IAAI,EAAE,CAAA,CACxC,IAAA,EAAK,CAEL,OAAA,CAAQ,gBAAgB,EAAE,CAAA;AAC7B,MAAA,OAAA,CAAQ,GAAA,CAAI,MAAA,GAAS,CAAA,GAAI,GAAA,GAAM,IAAI,CAAA;AAAA,IACrC,CAAA;AAEA,IAAA,IAAA,EAAK;AAEL,IAAA,MAAM,QAAA,GAAW,IAAI,gBAAA,CAAiB,IAAI,CAAA;AAC1C,IAAA,QAAA,CAAS,OAAA,CAAQ,SAAS,IAAA,EAAM,EAAE,WAAW,IAAA,EAAM,OAAA,EAAS,MAAM,CAAA;AAClE,IAAA,OAAO,MAAM,SAAS,UAAA,EAAW;AAAA,EACnC,CAAA,EAAG,CAAC,IAAI,CAAC,CAAA;AAET,EAAA,OAAO,IAAA;AACT;AAGO,SAAS,YAAA,CAAa,IAAA,EAAc,QAAA,GAAW,eAAA,EAAiB;AACrE,EAAA,OAAO,CAAA,EAAG,QAAQ,CAAA,EAAG,IAAI,CAAA,IAAA,CAAA;AAC3B","file":"chunk-VTGRJ4HV.js","sourcesContent":["import { useEffect, useState } from 'react'\n\n/**\n * The six canonical top-bar action slots (Reference/Global-Rules v9 → top-bar\n * icons). Each slot's GLYPH is unique and comes from the Brand API\n * `topbarIcons.items.*` tokens, exposed as `--topbar-icon-<slot>` CSS vars\n * whose value is the brand-icon NAME. Every OTHER property — size, gap, color,\n * hover, selected — is universal across all six slots.\n */\nexport type TopBarIconSlot =\n | 'comms-fuel'\n | 'apps'\n | 'notifications'\n | 'alerts'\n | 'support'\n | 'dark-mode'\n\n/**\n * Reads the glyph NAME for a slot from its `--topbar-icon-<slot>` CSS var.\n *\n * Runs in an effect because the Brand stylesheet is appended to <head> at\n * runtime (Global Rules forbids baking it into the build), so the var is not\n * resolvable during SSR or the first synchronous render. The MutationObserver\n * re-reads once the stylesheet lands so the glyph upgrades from the caller's\n * fallback without a reload.\n *\n * Returns null when the slot has no Brand glyph — callers render their own\n * fallback icon in that case.\n */\nexport function useTopBarIconSlotGlyph(slot: TopBarIconSlot): string | null {\n const [name, setName] = useState<string | null>(null)\n\n useEffect(() => {\n if (typeof window === 'undefined') return\n\n const read = () => {\n const raw = window\n .getComputedStyle(document.documentElement)\n .getPropertyValue(`--topbar-icon-${slot}`)\n .trim()\n // Brand may emit the name quoted (e.g. \"bell\"); strip the quotes.\n .replace(/^['\"]|['\"]$/g, '')\n setName(raw.length > 0 ? raw : null)\n }\n\n read()\n\n const observer = new MutationObserver(read)\n observer.observe(document.head, { childList: true, subtree: true })\n return () => observer.disconnect()\n }, [slot])\n\n return name\n}\n\n/** Path to a brand-icon SVG in the consuming app's public dir. */\nexport function brandIconSrc(name: string, basePath = '/brand/icons/') {\n return `${basePath}${name}.svg`\n}\n"]}
|
package/dist/index.cjs
CHANGED
|
@@ -2655,7 +2655,7 @@ function AppLayout({
|
|
|
2655
2655
|
overlaySlot
|
|
2656
2656
|
] });
|
|
2657
2657
|
}
|
|
2658
|
-
function
|
|
2658
|
+
function useTopBarIconSlotGlyph(slot) {
|
|
2659
2659
|
const [name, setName] = react$1.useState(null);
|
|
2660
2660
|
react$1.useEffect(() => {
|
|
2661
2661
|
if (typeof window === "undefined") return;
|
|
@@ -2672,7 +2672,7 @@ function useSlotGlyphName(slot) {
|
|
|
2672
2672
|
}
|
|
2673
2673
|
var TopBarIcon = react$1.forwardRef(
|
|
2674
2674
|
function TopBarIcon2({ slot, fallbackIcon, isSelected, ...rest }, ref) {
|
|
2675
|
-
const glyphName =
|
|
2675
|
+
const glyphName = useTopBarIconSlotGlyph(slot);
|
|
2676
2676
|
const icon = glyphName ? /* @__PURE__ */ jsxRuntime.jsx(
|
|
2677
2677
|
BrandIcon,
|
|
2678
2678
|
{
|