@the-portland-company/shell 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/CHANGELOG.md +47 -0
- package/dist/chrome.css +2 -2
- package/dist/index.cjs +57 -9
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +30 -2
- package/dist/index.d.ts +30 -2
- package/dist/index.js +60 -13
- package/dist/index.js.map +1 -1
- package/dist/native.cjs +99 -0
- package/dist/native.cjs.map +1 -1
- package/dist/native.d.cts +50 -2
- package/dist/native.d.ts +50 -2
- package/dist/native.js +99 -1
- package/dist/native.js.map +1 -1
- package/package.json +11 -3
package/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,50 @@
|
|
|
1
|
+
## 0.11.1 — 2026-07-20
|
|
2
|
+
|
|
3
|
+
### Fixed (packaging — native install)
|
|
4
|
+
|
|
5
|
+
- **Chakra-only peers are now `optional`** via `peerDependenciesMeta`
|
|
6
|
+
(`@chakra-ui/react`, `@emotion/react`, `@emotion/styled`,
|
|
7
|
+
`@supabase/supabase-js`, `react-icons`, `react-router-dom`). The `./native`
|
|
8
|
+
export imports none of them — only `react`/`react-dom` (still required) — so
|
|
9
|
+
the Next.js worker apps (Forms/Surveys/Polls) can `npm i
|
|
10
|
+
@the-portland-company/shell` without `ERESOLVE` and without
|
|
11
|
+
`--legacy-peer-deps`. The Chakra `.` export still expects these at runtime;
|
|
12
|
+
apps that use it already install them.
|
|
13
|
+
- **Relaxed the `@supabase/supabase-js` peer range** from `~2.95.3`
|
|
14
|
+
(`>=2.95.3 <2.96`) to `>=2.95.3 <3` so it no longer conflicts with apps on a
|
|
15
|
+
newer 2.x (e.g. surveys on `^2.106.2`).
|
|
16
|
+
|
|
17
|
+
## 0.11.0 — 2026-07-20
|
|
18
|
+
|
|
19
|
+
### Added (native — icon-only tab strip)
|
|
20
|
+
|
|
21
|
+
- **`NavTabStrip`** in the `./native` export: the standard icon-only secondary
|
|
22
|
+
navigation the Next.js worker apps (Forms / Surveys / Polls) render below the
|
|
23
|
+
top bar, promoted from each app's hand-rolled `.tabstrip`/`.tab-strip` markup
|
|
24
|
+
into the shell so they stop diverging. Icon-only tabs with `role="tablist"` /
|
|
25
|
+
`role="tab"`, `title` tooltips + `aria-label`; the **selected tab merges into
|
|
26
|
+
the content panel** (top/left/right border, no bottom border, shared
|
|
27
|
+
`--tab-content-bg`). All geometry is driven by the Brand `--tab-*` CSS vars
|
|
28
|
+
(`--tab-height`, `--tab-icon-size`, `--tab-radius`, `--tab-gap`,
|
|
29
|
+
`--tab-content-bg`, `--tab-unselected-opacity` [default `0.6`]) with literal
|
|
30
|
+
fallbacks. Items are `{ key, label, icon, href?, onSelect?, selected,
|
|
31
|
+
disabled?, disabledTitle? }`; `href` tabs render through the injectable
|
|
32
|
+
`linkComponent` (Next `<Link>`), no-`href` tabs render as `<button>`, and
|
|
33
|
+
`disabled` tabs render a dimmed non-interactive span (e.g. Surveys' Canvas /
|
|
34
|
+
Results before a survey is chosen). Pass `children` to render the merged
|
|
35
|
+
content panel, or omit to compose your own. No Chakra, no react-router.
|
|
36
|
+
- `NavLinkProps` widened with optional passthrough attributes
|
|
37
|
+
(`role`, `aria-selected`, `aria-label`, `title`, `style`) so one injected link
|
|
38
|
+
can back both a nav row and a routed tab.
|
|
39
|
+
- Tokens regenerated from Specs (`gen:tokens`, tokens v38).
|
|
40
|
+
|
|
41
|
+
## 0.10.3 — 2026-07-13
|
|
42
|
+
|
|
43
|
+
### Fixed (sidebar)
|
|
44
|
+
|
|
45
|
+
- **Sidebar width is driven by the `--sidebar-width` Brand token** (default
|
|
46
|
+
`240px`) so the Chakra `Sidebar` tracks the Brand API value.
|
|
47
|
+
|
|
1
48
|
## 0.10.2 — 2026-07-13
|
|
2
49
|
|
|
3
50
|
### Security (XSS) + UI
|
package/dist/chrome.css
CHANGED
|
@@ -135,7 +135,7 @@
|
|
|
135
135
|
--form-label-padding-x: 6px;
|
|
136
136
|
|
|
137
137
|
/* Tabs */
|
|
138
|
-
--tab-header-bg:
|
|
138
|
+
--tab-header-bg: transparent;
|
|
139
139
|
--tab-row-bg: #F0F4F8;
|
|
140
140
|
--tab-content-bg: #F8FAFC;
|
|
141
141
|
--tab-height: 44px;
|
|
@@ -145,7 +145,7 @@
|
|
|
145
145
|
--tab-radius: 12px;
|
|
146
146
|
|
|
147
147
|
/* Sidebar (nav chrome) */
|
|
148
|
-
--sidebar-width:
|
|
148
|
+
--sidebar-width: 240px;
|
|
149
149
|
--sidebar-bg: #FFFFFF;
|
|
150
150
|
--sidebar-border: #E2E8F0;
|
|
151
151
|
--sidebar-brand-logo-height: 40px;
|
package/dist/index.cjs
CHANGED
|
@@ -1521,19 +1521,19 @@ function Header({ onOpen, id }) {
|
|
|
1521
1521
|
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
1522
1522
|
react.HStack,
|
|
1523
1523
|
{
|
|
1524
|
-
spacing:
|
|
1524
|
+
spacing: "var(--topbar-icon-gap, 8px)",
|
|
1525
1525
|
mr: "15px",
|
|
1526
|
-
color: "
|
|
1526
|
+
color: "var(--topbar-icon-color, #4A5568)",
|
|
1527
1527
|
sx: {
|
|
1528
1528
|
'& button:not([role="menuitem"]):not([data-menu-item])': {
|
|
1529
|
-
width: "32px",
|
|
1530
|
-
height: "32px",
|
|
1531
|
-
minWidth: "32px",
|
|
1529
|
+
width: "var(--topbar-icon-button-size, 32px)",
|
|
1530
|
+
height: "var(--topbar-icon-button-size, 32px)",
|
|
1531
|
+
minWidth: "var(--topbar-icon-button-size, 32px)",
|
|
1532
1532
|
padding: 0
|
|
1533
1533
|
},
|
|
1534
|
-
'& button:not([role="menuitem"]):not([data-menu-item]) svg': {
|
|
1535
|
-
width: "20px",
|
|
1536
|
-
height: "20px"
|
|
1534
|
+
'& button:not([role="menuitem"]):not([data-menu-item]) svg, & button:not([role="menuitem"]):not([data-menu-item]) img': {
|
|
1535
|
+
width: "var(--topbar-icon-size, 20px)",
|
|
1536
|
+
height: "var(--topbar-icon-size, 20px)"
|
|
1537
1537
|
}
|
|
1538
1538
|
},
|
|
1539
1539
|
children: [
|
|
@@ -2488,7 +2488,7 @@ function Sidebar({ onClose, id }) {
|
|
|
2488
2488
|
bg: sidebarBg,
|
|
2489
2489
|
borderRight: "1px",
|
|
2490
2490
|
borderRightColor: sidebarBorderColor,
|
|
2491
|
-
w: { base: "full", md:
|
|
2491
|
+
w: { base: "full", md: "var(--sidebar-width, 240px)" },
|
|
2492
2492
|
pos: "fixed",
|
|
2493
2493
|
h: "100vh",
|
|
2494
2494
|
direction: "column",
|
|
@@ -2655,6 +2655,53 @@ function AppLayout({
|
|
|
2655
2655
|
overlaySlot
|
|
2656
2656
|
] });
|
|
2657
2657
|
}
|
|
2658
|
+
function useSlotGlyphName(slot) {
|
|
2659
|
+
const [name, setName] = react$1.useState(null);
|
|
2660
|
+
react$1.useEffect(() => {
|
|
2661
|
+
if (typeof window === "undefined") return;
|
|
2662
|
+
const read = () => {
|
|
2663
|
+
const raw = window.getComputedStyle(document.documentElement).getPropertyValue(`--topbar-icon-${slot}`).trim().replace(/^['"]|['"]$/g, "");
|
|
2664
|
+
setName(raw.length > 0 ? raw : null);
|
|
2665
|
+
};
|
|
2666
|
+
read();
|
|
2667
|
+
const observer = new MutationObserver(read);
|
|
2668
|
+
observer.observe(document.head, { childList: true, subtree: true });
|
|
2669
|
+
return () => observer.disconnect();
|
|
2670
|
+
}, [slot]);
|
|
2671
|
+
return name;
|
|
2672
|
+
}
|
|
2673
|
+
var TopBarIcon = react$1.forwardRef(
|
|
2674
|
+
function TopBarIcon2({ slot, fallbackIcon, isSelected, ...rest }, ref) {
|
|
2675
|
+
const glyphName = useSlotGlyphName(slot);
|
|
2676
|
+
const icon = glyphName ? /* @__PURE__ */ jsxRuntime.jsx(
|
|
2677
|
+
BrandIcon,
|
|
2678
|
+
{
|
|
2679
|
+
name: glyphName,
|
|
2680
|
+
style: {
|
|
2681
|
+
width: "var(--topbar-icon-size, 20px)",
|
|
2682
|
+
height: "var(--topbar-icon-size, 20px)"
|
|
2683
|
+
}
|
|
2684
|
+
}
|
|
2685
|
+
) : fallbackIcon;
|
|
2686
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
2687
|
+
react.IconButton,
|
|
2688
|
+
{
|
|
2689
|
+
ref,
|
|
2690
|
+
icon,
|
|
2691
|
+
variant: "ghost",
|
|
2692
|
+
minW: "var(--topbar-icon-button-size, 32px)",
|
|
2693
|
+
h: "var(--topbar-icon-button-size, 32px)",
|
|
2694
|
+
bg: isSelected ? "var(--topbar-icon-selected-bg, transparent)" : "transparent",
|
|
2695
|
+
color: isSelected ? "var(--topbar-icon-selected-color, var(--topbar-icon-color, #64748B))" : "var(--topbar-icon-color, #64748B)",
|
|
2696
|
+
_hover: {
|
|
2697
|
+
bg: "var(--topbar-icon-hover-bg, transparent)",
|
|
2698
|
+
color: "var(--topbar-icon-hover-color, var(--topbar-icon-color, #64748B))"
|
|
2699
|
+
},
|
|
2700
|
+
...rest
|
|
2701
|
+
}
|
|
2702
|
+
);
|
|
2703
|
+
}
|
|
2704
|
+
);
|
|
2658
2705
|
var SUPPORT_REQUEST_SUCCESS_MESSAGE = "Your support request was sent to Politogy leadership.";
|
|
2659
2706
|
function splitName(value) {
|
|
2660
2707
|
const trimmed = String(value ?? "").trim();
|
|
@@ -3055,6 +3102,7 @@ exports.ShellRoleContext = ShellRoleContext;
|
|
|
3055
3102
|
exports.ShellSupportProviderContext = ShellSupportProviderContext;
|
|
3056
3103
|
exports.Sidebar = Sidebar;
|
|
3057
3104
|
exports.SupportRequestButton = SupportRequestButton;
|
|
3105
|
+
exports.TopBarIcon = TopBarIcon;
|
|
3058
3106
|
exports.UserMenu = UserMenu;
|
|
3059
3107
|
exports.buildSpeculationRules = buildSpeculationRules;
|
|
3060
3108
|
exports.getOrganizationBadgeLetters = getOrganizationBadgeLetters;
|