gridsmith-ui 0.6.4 → 0.6.5
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/README.md +6 -0
- package/dist/index.d.ts +13 -8
- package/dist/index.js +95 -51
- package/dist/index.js.map +1 -1
- package/dist/roots.css +41 -0
- package/dist/tokens.css +52 -0
- package/dist-static/tokens.css +52 -0
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -122,6 +122,12 @@ Wrap your app in `<IconProvider>` to select a pack:
|
|
|
122
122
|
</IconProvider>
|
|
123
123
|
```
|
|
124
124
|
|
|
125
|
+
## Troubleshooting
|
|
126
|
+
|
|
127
|
+
- **Import errors after installing a package while `vite` is running** — restart with `npm run dev -- --force` (or delete `node_modules/.vite`); Vite's dependency cache otherwise serves the pre-install module graph.
|
|
128
|
+
- **Components render unstyled** — add `@source "../node_modules/gridsmith-ui/dist/*.js"` to your CSS entry point *after* every `@import`. Tailwind v4 needs it to scan the compiled components, and rejects an `@import` that follows it.
|
|
129
|
+
- **`IconProvider` is not exported** — upgrade to a current `gridsmith-ui`; the provider ships from the `gridsmith-ui/icons` entry point.
|
|
130
|
+
|
|
125
131
|
## Peer Dependencies
|
|
126
132
|
|
|
127
133
|
| Package | Required |
|
package/dist/index.d.ts
CHANGED
|
@@ -873,7 +873,6 @@ interface LinkProps extends AnchorHTMLAttributes<HTMLAnchorElement> {
|
|
|
873
873
|
*/
|
|
874
874
|
declare const Link: react.ForwardRefExoticComponent<LinkProps & react.RefAttributes<HTMLAnchorElement>>;
|
|
875
875
|
|
|
876
|
-
type TabsVariant = "underline" | "pill";
|
|
877
876
|
type TabsOverflow = "scroll" | "hidden" | "truncate";
|
|
878
877
|
interface Tab {
|
|
879
878
|
id: string;
|
|
@@ -894,7 +893,6 @@ interface TabsArrayProps {
|
|
|
894
893
|
orientation?: "horizontal" | "vertical" | "responsive";
|
|
895
894
|
/** Below md, tabs either side-scroll (default) or collapse to a Dropdown. "responsive" implies "dropdown". */
|
|
896
895
|
mobile?: "scroll" | "dropdown";
|
|
897
|
-
variant?: TabsVariant;
|
|
898
896
|
fullWidth?: boolean;
|
|
899
897
|
overflow?: TabsOverflow;
|
|
900
898
|
className?: string;
|
|
@@ -904,7 +902,6 @@ interface TabsCompoundProps {
|
|
|
904
902
|
activeTab: string;
|
|
905
903
|
onTabChange: (id: string) => void;
|
|
906
904
|
orientation?: "horizontal" | "vertical";
|
|
907
|
-
variant?: TabsVariant;
|
|
908
905
|
fullWidth?: boolean;
|
|
909
906
|
overflow?: TabsOverflow;
|
|
910
907
|
className?: string;
|
|
@@ -1163,7 +1160,8 @@ interface DockProps {
|
|
|
1163
1160
|
}
|
|
1164
1161
|
declare function Dock({ items, magnification, baseSize, className, }: DockProps): react_jsx_runtime.JSX.Element;
|
|
1165
1162
|
|
|
1166
|
-
|
|
1163
|
+
/** `tint` (soft accent fill), `underline`, `minimal`, `pill` (solid accent fill). `default` is the deprecated pre-20.8 name for `tint`. */
|
|
1164
|
+
type NavbarType = "tint" | "underline" | "minimal" | "pill" | "default";
|
|
1167
1165
|
type NavbarAlign = "left" | "center" | "right";
|
|
1168
1166
|
type NavbarVariant = "default" | "transparent" | "compact" | "elevated" | "blurred";
|
|
1169
1167
|
type NavbarSize = "sm" | "md" | "lg";
|
|
@@ -1175,7 +1173,7 @@ interface NavbarProps {
|
|
|
1175
1173
|
actions?: ReactNode;
|
|
1176
1174
|
userMenu?: ReactNode;
|
|
1177
1175
|
variant?: NavbarVariant;
|
|
1178
|
-
/** Visual style type:
|
|
1176
|
+
/** Visual style type: tint (ghost-button nav items with a soft accent fill), underline (tab-style with bottom indicator), minimal (transparent, borderless, text-only), pill (solid accent fill with on-primary text). This is a theme decision (navigation.headerType) — NavItem reads it from context. */
|
|
1179
1177
|
type?: NavbarType;
|
|
1180
1178
|
/** Horizontal alignment of nav links: left (default), center (viewport-centered), right (before actions) */
|
|
1181
1179
|
align?: NavbarAlign;
|
|
@@ -1191,7 +1189,13 @@ interface NavbarProps {
|
|
|
1191
1189
|
}
|
|
1192
1190
|
declare const Navbar: react.ForwardRefExoticComponent<NavbarProps & react.RefAttributes<HTMLElement>>;
|
|
1193
1191
|
|
|
1194
|
-
|
|
1192
|
+
/**
|
|
1193
|
+
* Navbar active style. `tint` is the soft accent fill (the pre-20.8 `default`),
|
|
1194
|
+
* `underline` the bottom indicator, `minimal` a text-only change, `pill` a solid
|
|
1195
|
+
* accent fill with on-primary text. `default` is accepted as a deprecated alias
|
|
1196
|
+
* for `tint` for one release.
|
|
1197
|
+
*/
|
|
1198
|
+
type NavItemType = "tint" | "underline" | "minimal" | "pill" | "default";
|
|
1195
1199
|
interface NavItemProps {
|
|
1196
1200
|
label: string;
|
|
1197
1201
|
icon?: IconName;
|
|
@@ -1219,14 +1223,15 @@ interface NavMenuProps {
|
|
|
1219
1223
|
items: NavMenuItem[];
|
|
1220
1224
|
/** Whether any child route is currently active (highlights the trigger) */
|
|
1221
1225
|
active?: boolean;
|
|
1222
|
-
/** Matches the parent Navbar type for consistent styling */
|
|
1226
|
+
/** Matches the parent Navbar type for consistent styling (`default` is the deprecated name for `tint`) */
|
|
1223
1227
|
type?: NavbarType;
|
|
1224
1228
|
onItemClick?: (item: NavMenuItem) => void;
|
|
1225
1229
|
className?: string;
|
|
1226
1230
|
}
|
|
1227
1231
|
declare function NavMenu({ label, items, active, type, onItemClick, className, }: NavMenuProps): react_jsx_runtime.JSX.Element;
|
|
1228
1232
|
|
|
1229
|
-
|
|
1233
|
+
/** Mirrors NavbarType. `default` is the deprecated pre-20.8 name for `tint`. */
|
|
1234
|
+
type MobileHeaderMenuType = "tint" | "underline" | "minimal" | "pill" | "default";
|
|
1230
1235
|
interface MobileHeaderMenuItemData {
|
|
1231
1236
|
label: string;
|
|
1232
1237
|
icon?: IconName;
|
package/dist/index.js
CHANGED
|
@@ -6846,7 +6846,9 @@ function TreeNodeRow({
|
|
|
6846
6846
|
className: cn(
|
|
6847
6847
|
"flex items-center gap-ds-2 py-ds-1.5 px-ds-2 rounded-[var(--ds-radius-md)] cursor-pointer transition-colors",
|
|
6848
6848
|
"focus-visible:outline-none focus-visible:shadow-[var(--ds-shadow-focus)]",
|
|
6849
|
-
|
|
6849
|
+
// Active style comes from the theme's --ds-tree-* tokens (rail / tint;
|
|
6850
|
+
// pill degrades to tint). The rail is drawn on the selected row only.
|
|
6851
|
+
isSelected ? "bg-[var(--ds-tree-active-bg)] text-[var(--ds-tree-active-text)] font-medium border-l-[length:var(--ds-tree-active-rail)] border-[var(--ds-accent-primary)]" : "text-[var(--ds-text-primary)] hover:bg-[var(--ds-tab-hover-bg)] hover:text-[var(--ds-text-primary)]",
|
|
6850
6852
|
node.disabled && "opacity-disabled pointer-events-none"
|
|
6851
6853
|
),
|
|
6852
6854
|
style: { paddingLeft: `calc(var(--ds-space-5) * ${depth} + var(--ds-space-2))` },
|
|
@@ -6873,7 +6875,7 @@ function TreeNodeRow({
|
|
|
6873
6875
|
{
|
|
6874
6876
|
name: "chevron-right",
|
|
6875
6877
|
size: 14,
|
|
6876
|
-
className: cn("text-[var(--ds-text-muted)] transition-transform", isExpanded && "rotate-90")
|
|
6878
|
+
className: cn(isSelected ? "text-[var(--ds-tree-active-muted)]" : "text-[var(--ds-text-muted)]", "transition-transform", isExpanded && "rotate-90")
|
|
6877
6879
|
}
|
|
6878
6880
|
)
|
|
6879
6881
|
}
|
|
@@ -6888,7 +6890,7 @@ function TreeNodeRow({
|
|
|
6888
6890
|
}
|
|
6889
6891
|
}
|
|
6890
6892
|
),
|
|
6891
|
-
node.icon && /* @__PURE__ */ jsx(Icon, { name: node.icon, size: 16, className: cn("shrink-0", isSelected ? "text-[var(--ds-
|
|
6893
|
+
node.icon && /* @__PURE__ */ jsx(Icon, { name: node.icon, size: 16, className: cn("shrink-0", isSelected ? "text-[var(--ds-tree-active-text)]" : "text-[var(--ds-text-muted)]") }),
|
|
6892
6894
|
/* @__PURE__ */ jsx(TruncLabel2, { children: node.label })
|
|
6893
6895
|
]
|
|
6894
6896
|
}
|
|
@@ -7376,6 +7378,19 @@ function useTabsCtx() {
|
|
|
7376
7378
|
if (!ctx) throw new Error("Tabs.List / Tabs.Trigger / Tabs.Content must be used inside <Tabs>");
|
|
7377
7379
|
return ctx;
|
|
7378
7380
|
}
|
|
7381
|
+
function trackClasses(orientation) {
|
|
7382
|
+
if (orientation === "vertical") {
|
|
7383
|
+
return cn(
|
|
7384
|
+
"flex flex-col gap-ds-0.5 min-w-[var(--ds-tab-rail-width)]",
|
|
7385
|
+
"border-r-[length:var(--ds-nav-v-track-border)] border-[var(--ds-border-default)]",
|
|
7386
|
+
"pr-[var(--ds-nav-v-track-padding)]"
|
|
7387
|
+
);
|
|
7388
|
+
}
|
|
7389
|
+
return cn(
|
|
7390
|
+
"flex gap-[var(--ds-nav-h-track-gap)]",
|
|
7391
|
+
"border-b-[length:var(--ds-nav-h-track-border)] border-[var(--ds-border-default)]"
|
|
7392
|
+
);
|
|
7393
|
+
}
|
|
7379
7394
|
function getTabsFromDOM(el) {
|
|
7380
7395
|
const tablist = el.closest('[role="tablist"]');
|
|
7381
7396
|
if (!tablist) return [];
|
|
@@ -7423,7 +7438,6 @@ function TabButton({
|
|
|
7423
7438
|
icon,
|
|
7424
7439
|
disabled,
|
|
7425
7440
|
orientation,
|
|
7426
|
-
variant,
|
|
7427
7441
|
activeTab,
|
|
7428
7442
|
onTabChange,
|
|
7429
7443
|
fullWidth,
|
|
@@ -7436,10 +7450,11 @@ function TabButton({
|
|
|
7436
7450
|
const isActive = activeTab === id;
|
|
7437
7451
|
const tabId = `ds-tab-${id}`;
|
|
7438
7452
|
const panelId = hasPanel === false ? void 0 : `ds-tabpanel-${id}`;
|
|
7453
|
+
const badgeBg = orientation === "vertical" ? "bg-[var(--ds-nav-v-badge-bg)]" : "bg-[var(--ds-nav-h-badge-bg)]";
|
|
7439
7454
|
const countBadge = count !== void 0 ? /* @__PURE__ */ jsx("span", { className: cn(
|
|
7440
7455
|
orientation === "vertical" ? "ml-ds-2" : "",
|
|
7441
7456
|
"px-ds-1.5 py-ds-0.5 text-xs rounded-[var(--ds-radius-sm)]",
|
|
7442
|
-
|
|
7457
|
+
isActive ? cn(badgeBg, "text-[var(--ds-text-on-primary)]") : "bg-[var(--ds-bg-emphasis)] text-[var(--ds-text-muted)]"
|
|
7443
7458
|
), children: count }) : null;
|
|
7444
7459
|
if (orientation === "vertical") {
|
|
7445
7460
|
const btn2 = /* @__PURE__ */ jsxs(
|
|
@@ -7456,10 +7471,12 @@ function TabButton({
|
|
|
7456
7471
|
className: cn(
|
|
7457
7472
|
"flex items-center justify-between px-ds-3 py-ds-2 text-sm font-medium text-left",
|
|
7458
7473
|
disabled ? "cursor-not-allowed opacity-disabled" : "cursor-pointer",
|
|
7459
|
-
"rounded-[var(--ds-radius
|
|
7474
|
+
"rounded-[var(--ds-nav-v-item-radius)]",
|
|
7460
7475
|
"transition-colors duration-[var(--ds-transition-speed)]",
|
|
7461
7476
|
"focus-visible:outline-none focus-visible:shadow-[var(--ds-shadow-focus)]",
|
|
7462
|
-
|
|
7477
|
+
// The rail is drawn on the active item only (today's behaviour; a
|
|
7478
|
+
// transparent placeholder on every item is a future layout tweak).
|
|
7479
|
+
isActive ? "bg-[var(--ds-nav-v-active-bg)] text-[var(--ds-nav-v-active-text)] border-l-[length:var(--ds-nav-v-active-rail)] border-[var(--ds-accent-primary)]" : "text-[var(--ds-text-secondary)] hover:text-[var(--ds-text-primary)] hover:bg-[var(--ds-tab-hover-bg)]",
|
|
7463
7480
|
className
|
|
7464
7481
|
),
|
|
7465
7482
|
children: [
|
|
@@ -7492,13 +7509,11 @@ function TabButton({
|
|
|
7492
7509
|
"focus-visible:outline-none focus-visible:shadow-[var(--ds-shadow-focus)]",
|
|
7493
7510
|
fullWidth && "flex-1",
|
|
7494
7511
|
truncate && "flex-1 min-w-0 flex items-center",
|
|
7495
|
-
|
|
7496
|
-
|
|
7497
|
-
isActive ? "bg-[var(--ds-accent-primary)] text-[var(--ds-text-on-primary)]" : "text-[var(--ds-text-secondary)] hover:text-[var(--ds-text-primary)] hover:bg-[var(--ds-tab-hover-bg)]"
|
|
7498
|
-
) : isActive ? "text-[var(--ds-text-primary)] border-b-[length:var(--ds-border-width)] border-[var(--ds-accent-primary)]" : "text-[var(--ds-text-muted)] hover:text-[var(--ds-text-primary)]",
|
|
7512
|
+
"rounded-[var(--ds-nav-h-item-radius)]",
|
|
7513
|
+
isActive ? "bg-[var(--ds-nav-h-active-bg)] text-[var(--ds-nav-h-active-text)] border-[var(--ds-accent-primary)]" : "text-[var(--ds-nav-h-inactive-text)] hover:text-[var(--ds-text-primary)] hover:bg-[var(--ds-nav-h-hover-bg)]",
|
|
7499
7514
|
className
|
|
7500
7515
|
),
|
|
7501
|
-
style:
|
|
7516
|
+
style: isActive ? { borderBottomWidth: "var(--ds-nav-h-indicator)", marginBottom: "calc(var(--ds-nav-h-track-border) * -1)" } : void 0,
|
|
7502
7517
|
children: truncate ? /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
7503
7518
|
icon && /* @__PURE__ */ jsx(Icon, { name: icon, size: 16, className: "shrink-0" }),
|
|
7504
7519
|
/* @__PURE__ */ jsx("span", { ref: truncRef, className: "truncate min-w-0 flex-1", children: label }),
|
|
@@ -7514,18 +7529,14 @@ function TabButton({
|
|
|
7514
7529
|
return btn;
|
|
7515
7530
|
}
|
|
7516
7531
|
function TabsList({ children, className }) {
|
|
7517
|
-
const { orientation,
|
|
7532
|
+
const { orientation, fullWidth, overflow } = useTabsCtx();
|
|
7518
7533
|
if (orientation === "vertical") {
|
|
7519
7534
|
return /* @__PURE__ */ jsx(
|
|
7520
7535
|
"div",
|
|
7521
7536
|
{
|
|
7522
7537
|
role: "tablist",
|
|
7523
7538
|
"aria-orientation": "vertical",
|
|
7524
|
-
className: cn(
|
|
7525
|
-
"flex flex-col gap-ds-0.5 min-w-[var(--ds-tab-rail-width)]",
|
|
7526
|
-
variant === "underline" && "border-r-[length:var(--ds-border-width)] border-[var(--ds-border-default)] pr-ds-1",
|
|
7527
|
-
className
|
|
7528
|
-
),
|
|
7539
|
+
className: cn(trackClasses("vertical"), className),
|
|
7529
7540
|
children
|
|
7530
7541
|
}
|
|
7531
7542
|
);
|
|
@@ -7535,10 +7546,9 @@ function TabsList({ children, className }) {
|
|
|
7535
7546
|
{
|
|
7536
7547
|
role: "tablist",
|
|
7537
7548
|
className: cn(
|
|
7538
|
-
"
|
|
7549
|
+
trackClasses("horizontal"),
|
|
7550
|
+
"max-w-full",
|
|
7539
7551
|
overflow === "hidden" ? "overflow-hidden" : overflow === "truncate" ? "overflow-hidden" : "overflow-x-auto overflow-y-hidden",
|
|
7540
|
-
variant === "underline" && "border-b-[length:var(--ds-border-width)] border-[var(--ds-border-default)]",
|
|
7541
|
-
variant === "pill" && "gap-ds-1 p-ds-0.5 bg-[var(--ds-bg-muted)] rounded-[var(--ds-radius-lg)]",
|
|
7542
7552
|
fullWidth && "w-full",
|
|
7543
7553
|
className
|
|
7544
7554
|
),
|
|
@@ -7547,7 +7557,7 @@ function TabsList({ children, className }) {
|
|
|
7547
7557
|
);
|
|
7548
7558
|
}
|
|
7549
7559
|
function TabsTrigger({ value, children, count, icon, disabled, truncate, className }) {
|
|
7550
|
-
const { activeTab, onTabChange, orientation,
|
|
7560
|
+
const { activeTab, onTabChange, orientation, fullWidth, overflow } = useTabsCtx();
|
|
7551
7561
|
return /* @__PURE__ */ jsx(
|
|
7552
7562
|
TabButton,
|
|
7553
7563
|
{
|
|
@@ -7558,7 +7568,6 @@ function TabsTrigger({ value, children, count, icon, disabled, truncate, classNa
|
|
|
7558
7568
|
disabled,
|
|
7559
7569
|
truncate: overflow === "truncate" || truncate,
|
|
7560
7570
|
orientation,
|
|
7561
|
-
variant,
|
|
7562
7571
|
activeTab,
|
|
7563
7572
|
onTabChange,
|
|
7564
7573
|
fullWidth,
|
|
@@ -7587,7 +7596,6 @@ function TabsRoot(props) {
|
|
|
7587
7596
|
activeTab,
|
|
7588
7597
|
onTabChange,
|
|
7589
7598
|
orientation = "horizontal",
|
|
7590
|
-
variant = "underline",
|
|
7591
7599
|
fullWidth = false,
|
|
7592
7600
|
overflow = "scroll",
|
|
7593
7601
|
className
|
|
@@ -7614,11 +7622,7 @@ function TabsRoot(props) {
|
|
|
7614
7622
|
{
|
|
7615
7623
|
role: "tablist",
|
|
7616
7624
|
"aria-orientation": "vertical",
|
|
7617
|
-
className: cn(
|
|
7618
|
-
"flex flex-col gap-ds-0.5 min-w-[var(--ds-tab-rail-width)]",
|
|
7619
|
-
variant === "underline" && "border-r-[length:var(--ds-border-width)] border-[var(--ds-border-default)] pr-ds-1",
|
|
7620
|
-
className
|
|
7621
|
-
),
|
|
7625
|
+
className: cn(trackClasses("vertical"), className),
|
|
7622
7626
|
children: tabs.map((tab, i) => /* @__PURE__ */ jsxs(Fragment$1, { children: [
|
|
7623
7627
|
tab.group && tab.group !== tabs[i - 1]?.group && /* @__PURE__ */ jsx(
|
|
7624
7628
|
"span",
|
|
@@ -7631,7 +7635,7 @@ function TabsRoot(props) {
|
|
|
7631
7635
|
children: tab.group
|
|
7632
7636
|
}
|
|
7633
7637
|
),
|
|
7634
|
-
/* @__PURE__ */ jsx(TabButton, { hasPanel: false, ...tab, orientation: effectiveOrientation,
|
|
7638
|
+
/* @__PURE__ */ jsx(TabButton, { hasPanel: false, ...tab, orientation: effectiveOrientation, activeTab, onTabChange, fullWidth, onKeyDown: (e) => handleTabKeyDown(e, tab.id, () => tabs, effectiveOrientation, onTabChange) })
|
|
7635
7639
|
] }, tab.id))
|
|
7636
7640
|
}
|
|
7637
7641
|
);
|
|
@@ -7642,18 +7646,16 @@ function TabsRoot(props) {
|
|
|
7642
7646
|
{
|
|
7643
7647
|
role: "tablist",
|
|
7644
7648
|
className: cn(
|
|
7645
|
-
"
|
|
7649
|
+
trackClasses("horizontal"),
|
|
7646
7650
|
effectiveOverflow === "scroll" ? "overflow-x-auto overflow-y-hidden" : "overflow-hidden",
|
|
7647
|
-
variant === "underline" && "border-b-[length:var(--ds-border-width)] border-[var(--ds-border-default)]",
|
|
7648
|
-
variant === "pill" && "gap-ds-1 p-ds-0.5 bg-[var(--ds-bg-muted)] rounded-[var(--ds-radius-lg)]",
|
|
7649
7651
|
fullWidth && "w-full",
|
|
7650
7652
|
className
|
|
7651
7653
|
),
|
|
7652
|
-
children: tabs.map((tab) => /* @__PURE__ */ jsx(TabButton, { hasPanel: false, ...tab, orientation: effectiveOrientation,
|
|
7654
|
+
children: tabs.map((tab) => /* @__PURE__ */ jsx(TabButton, { hasPanel: false, ...tab, orientation: effectiveOrientation, activeTab, onTabChange, fullWidth, onKeyDown: (e) => handleTabKeyDown(e, tab.id, () => tabs, effectiveOrientation, onTabChange) }, tab.id))
|
|
7653
7655
|
}
|
|
7654
7656
|
);
|
|
7655
7657
|
}
|
|
7656
|
-
return /* @__PURE__ */ jsx(TabsContext.Provider, { value: { activeTab, onTabChange, orientation: effectiveOrientation,
|
|
7658
|
+
return /* @__PURE__ */ jsx(TabsContext.Provider, { value: { activeTab, onTabChange, orientation: effectiveOrientation, fullWidth, overflow }, children: /* @__PURE__ */ jsx("div", { className, children: props.children }) });
|
|
7657
7659
|
}
|
|
7658
7660
|
var Tabs = Object.assign(TabsRoot, {
|
|
7659
7661
|
List: TabsList,
|
|
@@ -8567,7 +8569,7 @@ function CompactFlyout({
|
|
|
8567
8569
|
},
|
|
8568
8570
|
className: cn(
|
|
8569
8571
|
"flex items-center gap-ds-2 px-ds-2 py-ds-1.5 text-xs rounded-[var(--ds-radius-sm)] transition-colors cursor-pointer",
|
|
8570
|
-
child.active ? "bg-sidebar-
|
|
8572
|
+
child.active ? "bg-[var(--ds-sidebar-active-bg)] text-[var(--ds-sidebar-active-accent)] font-medium" : "text-[var(--ds-sidebar-text-secondary)] hover:bg-[var(--ds-sidebar-item-hover)] hover:text-[var(--ds-sidebar-text)]"
|
|
8571
8573
|
),
|
|
8572
8574
|
children: [
|
|
8573
8575
|
child.icon && /* @__PURE__ */ jsx(Icon, { name: child.icon, size: 14 }),
|
|
@@ -8673,7 +8675,10 @@ function SidebarNav({
|
|
|
8673
8675
|
"flex items-center gap-ds-2 transition-colors cursor-pointer",
|
|
8674
8676
|
isRoot ? cn(rootPy, rootText, isMinimal ? "rounded-[var(--ds-radius-full)]" : "rounded-[var(--ds-radius-md)]") : cn(childPy, "text-xs rounded-[var(--ds-radius-sm)]"),
|
|
8675
8677
|
isRoot ? collapsed ? "justify-center px-0" : "px-ds-3" : "px-ds-2",
|
|
8676
|
-
|
|
8678
|
+
// Active style comes from the theme's --ds-sidebar-active-* tokens
|
|
8679
|
+
// (rail / tint / pill). The rail token is 0px for minimal sidebars,
|
|
8680
|
+
// so the transparent placeholder on inactive roots is harmless there.
|
|
8681
|
+
item.active ? isRoot ? "bg-[var(--ds-sidebar-active-bg)] text-[var(--ds-sidebar-active-text)] font-medium border-l-[length:var(--ds-sidebar-active-rail)] border-[var(--ds-sidebar-active-accent)]" : "bg-[var(--ds-sidebar-active-bg)] text-[var(--ds-sidebar-active-accent)] font-medium" : isRoot ? "text-[var(--ds-sidebar-text-secondary)] hover:bg-[var(--ds-sidebar-item-hover)] hover:text-[var(--ds-sidebar-text)] border-l-[length:var(--ds-sidebar-active-rail)] border-transparent" : "text-[var(--ds-sidebar-text-muted)] hover:bg-[var(--ds-sidebar-item-hover)] hover:text-[var(--ds-sidebar-text)]"
|
|
8677
8682
|
),
|
|
8678
8683
|
children: [
|
|
8679
8684
|
item.icon && /* @__PURE__ */ jsx(
|
|
@@ -8681,7 +8686,7 @@ function SidebarNav({
|
|
|
8681
8686
|
{
|
|
8682
8687
|
name: item.icon,
|
|
8683
8688
|
size: isRoot ? rootIconSize : childIconSize,
|
|
8684
|
-
className: cn("shrink-0", item.active && "text-[var(--ds-sidebar-accent)]")
|
|
8689
|
+
className: cn("shrink-0", item.active && "text-[var(--ds-sidebar-active-accent)]")
|
|
8685
8690
|
}
|
|
8686
8691
|
),
|
|
8687
8692
|
!collapsed && /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
@@ -8753,7 +8758,10 @@ function SidebarNav({
|
|
|
8753
8758
|
"flex items-center gap-ds-2 w-full text-left transition-colors cursor-pointer",
|
|
8754
8759
|
isRoot ? cn(rootPy, rootText, isMinimal ? "rounded-[var(--ds-radius-full)]" : "rounded-[var(--ds-radius-md)]") : cn(childPy, "text-xs rounded-[var(--ds-radius-sm)]"),
|
|
8755
8760
|
isRoot ? collapsed ? "justify-center px-0" : "px-ds-3" : "px-ds-2",
|
|
8756
|
-
|
|
8761
|
+
// This row has no fill, so its label, icon and chevron keep the plain
|
|
8762
|
+
// sidebar tokens: --ds-sidebar-active-accent is on-primary white under
|
|
8763
|
+
// `pill` and would vanish here. Only filled elements read the active set.
|
|
8764
|
+
item.active || childActive ? isRoot ? "text-[var(--ds-sidebar-text)] font-medium border-l-[length:var(--ds-sidebar-active-rail)] border-transparent" : "text-[var(--ds-sidebar-text)] font-medium" : isRoot ? "text-[var(--ds-sidebar-text-secondary)] hover:bg-[var(--ds-sidebar-item-hover)] hover:text-[var(--ds-sidebar-text)] border-l-[length:var(--ds-sidebar-active-rail)] border-transparent" : "text-[var(--ds-sidebar-text-muted)] hover:bg-[var(--ds-sidebar-item-hover)] hover:text-[var(--ds-sidebar-text)]"
|
|
8757
8765
|
),
|
|
8758
8766
|
children: [
|
|
8759
8767
|
item.icon && /* @__PURE__ */ jsx(
|
|
@@ -8944,7 +8952,9 @@ function CompactNavItem({
|
|
|
8944
8952
|
"aria-expanded": hasChildren ? mobile ? expanded : isOpen : void 0,
|
|
8945
8953
|
className: cn(
|
|
8946
8954
|
"relative flex flex-col items-center justify-center gap-[3px] w-full py-ds-3 px-ds-1 rounded-[var(--ds-radius-md)] transition-colors cursor-pointer",
|
|
8947
|
-
|
|
8955
|
+
// Compact tiles have no edge to stroke: they read the fill and text
|
|
8956
|
+
// tokens only, never --ds-sidebar-active-rail.
|
|
8957
|
+
item.active || childActive ? "bg-[var(--ds-sidebar-active-bg)] text-[var(--ds-sidebar-active-accent)]" : "text-[var(--ds-sidebar-text-secondary)] hover:bg-[var(--ds-sidebar-item-hover)] hover:text-[var(--ds-sidebar-text)]"
|
|
8948
8958
|
),
|
|
8949
8959
|
children: [
|
|
8950
8960
|
item.icon && /* @__PURE__ */ jsx(
|
|
@@ -8952,7 +8962,7 @@ function CompactNavItem({
|
|
|
8952
8962
|
{
|
|
8953
8963
|
name: item.icon,
|
|
8954
8964
|
size: 20,
|
|
8955
|
-
className: cn((item.active || childActive) && "text-[var(--ds-sidebar-accent)]")
|
|
8965
|
+
className: cn((item.active || childActive) && "text-[var(--ds-sidebar-active-accent)]")
|
|
8956
8966
|
}
|
|
8957
8967
|
),
|
|
8958
8968
|
/* @__PURE__ */ jsx(TruncLabel3, { className: "text-[clamp(9px,var(--ds-font-size-2xs),12px)] leading-tight max-w-full", side: "right", container: portalContainer ?? void 0, children: item.label }),
|
|
@@ -8963,7 +8973,7 @@ function CompactNavItem({
|
|
|
8963
8973
|
size: 10,
|
|
8964
8974
|
className: cn(
|
|
8965
8975
|
"absolute right-1 top-1/2 -translate-y-1/2 transition-transform",
|
|
8966
|
-
item.active || childActive ? "text-[var(--ds-sidebar-accent)]" : "text-[var(--ds-sidebar-text-muted)]",
|
|
8976
|
+
item.active || childActive ? "text-[var(--ds-sidebar-active-accent)]" : "text-[var(--ds-sidebar-text-muted)]",
|
|
8967
8977
|
expanded && "rotate-180"
|
|
8968
8978
|
)
|
|
8969
8979
|
}
|
|
@@ -8990,7 +9000,7 @@ function CompactNavItem({
|
|
|
8990
9000
|
onClick: () => onItemClick?.(child, ci),
|
|
8991
9001
|
className: cn(
|
|
8992
9002
|
"flex items-center gap-ds-2 px-ds-3 py-ds-1.5 text-[length:var(--ds-font-size-xs)] rounded-[var(--ds-radius-sm)] transition-colors cursor-pointer w-full",
|
|
8993
|
-
child.active ? "bg-sidebar-
|
|
9003
|
+
child.active ? "bg-[var(--ds-sidebar-active-bg)] text-[var(--ds-sidebar-active-accent)] font-medium" : "text-[var(--ds-sidebar-text-muted)] hover:bg-[var(--ds-sidebar-item-hover)] hover:text-[var(--ds-sidebar-text)]"
|
|
8994
9004
|
),
|
|
8995
9005
|
children: [
|
|
8996
9006
|
child.icon && /* @__PURE__ */ jsx(Icon, { name: child.icon, size: 14, className: "shrink-0" }),
|
|
@@ -10385,10 +10395,13 @@ var AppShell = forwardRef(function AppShell2({
|
|
|
10385
10395
|
}
|
|
10386
10396
|
);
|
|
10387
10397
|
});
|
|
10388
|
-
|
|
10398
|
+
function resolveNavItemType(type) {
|
|
10399
|
+
return type === "default" ? "tint" : type;
|
|
10400
|
+
}
|
|
10401
|
+
var NavbarTypeContext = createContext("tint");
|
|
10389
10402
|
var NavItem = forwardRef(function NavItem2({ label, icon, active = false, href, onClick, type: typeProp, className, children }, ref) {
|
|
10390
10403
|
const contextType = useContext(NavbarTypeContext);
|
|
10391
|
-
const type = typeProp ?? contextType;
|
|
10404
|
+
const type = resolveNavItemType(typeProp ?? contextType);
|
|
10392
10405
|
const baseClasses = cn(
|
|
10393
10406
|
"inline-flex items-center gap-ds-2 cursor-pointer select-none",
|
|
10394
10407
|
"transition-colors duration-[var(--ds-transition-speed)] ease-[var(--ds-transition-ease)]",
|
|
@@ -10420,6 +10433,11 @@ var NavItem = forwardRef(function NavItem2({ label, icon, active = false, href,
|
|
|
10420
10433
|
});
|
|
10421
10434
|
function getTypeClasses(type, active) {
|
|
10422
10435
|
switch (type) {
|
|
10436
|
+
case "pill":
|
|
10437
|
+
return cn(
|
|
10438
|
+
"px-ds-2 py-ds-1 rounded-[var(--ds-radius-sm)]",
|
|
10439
|
+
active ? "bg-[var(--ds-accent-primary)] text-[var(--ds-text-on-primary)] font-[var(--ds-weight-heading)]" : "text-[var(--ds-text-secondary)] hover:text-[var(--ds-text-primary)] hover:bg-[var(--ds-bg-muted)]"
|
|
10440
|
+
);
|
|
10423
10441
|
case "underline":
|
|
10424
10442
|
return cn(
|
|
10425
10443
|
"px-ds-2 py-ds-2 relative",
|
|
@@ -10430,7 +10448,7 @@ function getTypeClasses(type, active) {
|
|
|
10430
10448
|
"px-ds-2 py-ds-1",
|
|
10431
10449
|
active ? "text-[var(--ds-accent-primary)] font-medium" : "text-[var(--ds-text-muted)] hover:text-[var(--ds-text-secondary)]"
|
|
10432
10450
|
);
|
|
10433
|
-
|
|
10451
|
+
case "tint":
|
|
10434
10452
|
return cn(
|
|
10435
10453
|
"px-ds-2 py-ds-1 rounded-[var(--ds-radius-sm)]",
|
|
10436
10454
|
active ? "bg-[var(--ds-accent-subtle)] text-[var(--ds-accent-primary)] font-[var(--ds-weight-heading)]" : "text-[var(--ds-text-secondary)] hover:text-[var(--ds-text-primary)] hover:bg-[var(--ds-bg-muted)]"
|
|
@@ -10464,7 +10482,7 @@ var Navbar = forwardRef(function Navbar2({
|
|
|
10464
10482
|
actions,
|
|
10465
10483
|
userMenu,
|
|
10466
10484
|
variant = "default",
|
|
10467
|
-
type = "
|
|
10485
|
+
type: typeProp = "tint",
|
|
10468
10486
|
align = "left",
|
|
10469
10487
|
size,
|
|
10470
10488
|
position = "flush",
|
|
@@ -10478,6 +10496,7 @@ var Navbar = forwardRef(function Navbar2({
|
|
|
10478
10496
|
const showHamburger = appShell?.isMobile && appShell.hasMobileMenu && !(isSmallPhone && appShell.hasMobileNav) || !!onMenuClick;
|
|
10479
10497
|
const handleHamburger = () => onMenuClick ? onMenuClick() : appShell?.setSidebarOpen(!appShell.sidebarOpen);
|
|
10480
10498
|
const hideNavLinks = appShell?.isMobile && (appShell.hasMobileMenu || appShell.hasMobileNav);
|
|
10499
|
+
const type = resolveNavItemType(typeProp);
|
|
10481
10500
|
const isMinimal = type === "minimal";
|
|
10482
10501
|
const isFloating = position === "floating";
|
|
10483
10502
|
const resolvedSize = size ?? (variant === "compact" ? "sm" : "md");
|
|
@@ -10584,7 +10603,7 @@ function NavMenu({
|
|
|
10584
10603
|
label,
|
|
10585
10604
|
items,
|
|
10586
10605
|
active = false,
|
|
10587
|
-
type = "
|
|
10606
|
+
type = "tint",
|
|
10588
10607
|
onItemClick,
|
|
10589
10608
|
className
|
|
10590
10609
|
}) {
|
|
@@ -10624,6 +10643,7 @@ function NavMenu({
|
|
|
10624
10643
|
);
|
|
10625
10644
|
const isUnderline = type === "underline";
|
|
10626
10645
|
const isMinimal = type === "minimal";
|
|
10646
|
+
const isPill = type === "pill";
|
|
10627
10647
|
const triggerClasses = cn(
|
|
10628
10648
|
"inline-flex items-center gap-ds-1 cursor-pointer transition-colors whitespace-nowrap",
|
|
10629
10649
|
"focus-visible:outline-none focus-visible:shadow-[var(--ds-shadow-focus)]",
|
|
@@ -10633,9 +10653,14 @@ function NavMenu({
|
|
|
10633
10653
|
) : isMinimal ? cn(
|
|
10634
10654
|
"px-ds-2 py-ds-1 text-sm",
|
|
10635
10655
|
hasActiveChild ? "text-[var(--ds-text-primary)] font-medium" : "text-[var(--ds-text-secondary)] hover:text-[var(--ds-text-primary)]"
|
|
10656
|
+
) : isPill ? cn(
|
|
10657
|
+
"px-ds-3 py-ds-1.5 text-sm rounded-[var(--ds-radius-md)]",
|
|
10658
|
+
hasActiveChild ? "bg-[var(--ds-accent-primary)] text-[var(--ds-text-on-primary)] font-medium" : "text-[var(--ds-text-secondary)] hover:bg-[var(--ds-bg-muted)] hover:text-[var(--ds-text-primary)]"
|
|
10636
10659
|
) : cn(
|
|
10660
|
+
// tint (and the deprecated `default` alias) — the same soft accent fill
|
|
10661
|
+
// NavItem uses, so a menu trigger and a link read as one row (decision 30).
|
|
10637
10662
|
"px-ds-3 py-ds-1.5 text-sm rounded-[var(--ds-radius-md)]",
|
|
10638
|
-
hasActiveChild ? "bg-[var(--ds-
|
|
10663
|
+
hasActiveChild ? "bg-[var(--ds-accent-subtle)] text-[var(--ds-accent-primary)] font-medium" : "text-[var(--ds-text-secondary)] hover:bg-[var(--ds-bg-muted)] hover:text-[var(--ds-text-primary)]"
|
|
10639
10664
|
),
|
|
10640
10665
|
className
|
|
10641
10666
|
);
|
|
@@ -10722,7 +10747,9 @@ function NavMenuItemRow({
|
|
|
10722
10747
|
},
|
|
10723
10748
|
className: cn(
|
|
10724
10749
|
"flex items-center gap-ds-2 mx-ds-1 px-ds-2 py-ds-1.5 rounded-[var(--ds-radius-sm)] transition-colors cursor-pointer",
|
|
10725
|
-
|
|
10750
|
+
// The active row takes the accent tint like an active NavItem; it marks
|
|
10751
|
+
// the current page, not a hover.
|
|
10752
|
+
item.active ? "bg-[var(--ds-accent-subtle)] text-[var(--ds-accent-primary)] font-medium" : "text-[var(--ds-text-secondary)] hover:bg-[var(--ds-bg-muted)] hover:text-[var(--ds-text-primary)]"
|
|
10726
10753
|
),
|
|
10727
10754
|
children: [
|
|
10728
10755
|
item.icon && /* @__PURE__ */ jsx(
|
|
@@ -10765,7 +10792,7 @@ function NavMenuGroup({
|
|
|
10765
10792
|
))
|
|
10766
10793
|
] });
|
|
10767
10794
|
}
|
|
10768
|
-
function MobileHeaderMenu({ items, type = "
|
|
10795
|
+
function MobileHeaderMenu({ items, type = "tint", onItemClick, className }) {
|
|
10769
10796
|
return /* @__PURE__ */ jsx("nav", { className: cn("flex flex-col", className), style: { padding: "var(--ds-space-4)" }, children: /* @__PURE__ */ jsx("div", { className: "flex flex-col", style: { gap: type === "underline" ? 0 : "var(--ds-space-1)" }, children: items.map((item, i) => /* @__PURE__ */ jsx(
|
|
10770
10797
|
MobileMenuItem,
|
|
10771
10798
|
{
|
|
@@ -10822,6 +10849,23 @@ function MobileMenuItem({
|
|
|
10822
10849
|
}
|
|
10823
10850
|
);
|
|
10824
10851
|
}
|
|
10852
|
+
if (type === "pill") {
|
|
10853
|
+
return /* @__PURE__ */ jsxs(
|
|
10854
|
+
"button",
|
|
10855
|
+
{
|
|
10856
|
+
onClick,
|
|
10857
|
+
className: cn(
|
|
10858
|
+
"flex items-center gap-ds-3 px-ds-3 py-ds-2.5 text-sm rounded-[var(--ds-radius-md)] cursor-pointer w-full text-left",
|
|
10859
|
+
"transition-colors duration-[var(--ds-transition-speed)]",
|
|
10860
|
+
item.active ? "bg-[var(--ds-accent-primary)] text-[var(--ds-text-on-primary)] font-[var(--ds-weight-heading)]" : "text-[var(--ds-text-secondary)] hover:text-[var(--ds-text-primary)] hover:bg-[var(--ds-bg-muted)]"
|
|
10861
|
+
),
|
|
10862
|
+
children: [
|
|
10863
|
+
item.icon && /* @__PURE__ */ jsx(Icon, { name: item.icon, size: 18, className: "shrink-0" }),
|
|
10864
|
+
/* @__PURE__ */ jsx("span", { children: item.label })
|
|
10865
|
+
]
|
|
10866
|
+
}
|
|
10867
|
+
);
|
|
10868
|
+
}
|
|
10825
10869
|
return /* @__PURE__ */ jsxs(
|
|
10826
10870
|
"button",
|
|
10827
10871
|
{
|