@lessly/ui 4.1.1 → 5.0.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/dist/{chunk-LTHOLX7I.js → chunk-OTYVKDP2.js} +37 -6
- package/dist/index.d.ts +125 -8
- package/dist/index.js +348 -197
- package/dist/router.d.ts +27 -6
- package/dist/router.js +128 -44
- package/dist/styles-federated.css +61 -17
- package/dist/styles.css +62 -54
- package/dist/tailwind-preset.js +30 -4
- package/package.json +2 -2
package/dist/router.d.ts
CHANGED
|
@@ -68,16 +68,37 @@ interface SidebarNavProps {
|
|
|
68
68
|
declare function SidebarNav({ items, collapsed, basePath, LinkComponent, isItemActive, className, }: SidebarNavProps): React.JSX.Element;
|
|
69
69
|
|
|
70
70
|
interface AppSidebarProps {
|
|
71
|
-
|
|
71
|
+
/** The rows in the middle, as links. Optional since #878: a rail whose middle is not a list of
|
|
72
|
+
* links writes it as `children` instead. */
|
|
73
|
+
items?: NavItem[];
|
|
74
|
+
/** The middle, written by the caller — panes, disclosures, a back row, anything `NavItem` has no
|
|
75
|
+
* field for. It stands exactly where the rows stand, and it owns its own scrolling: the box the
|
|
76
|
+
* rail gives it holds the rail's own inset and does not scroll, so an `overflow-y-auto` region
|
|
77
|
+
* inside it measures against the rail's own height instead of against a box the padding made
|
|
78
|
+
* taller.
|
|
79
|
+
*
|
|
80
|
+
* Like `railTop` it takes a function, for the same reason: the rail drives its own collapse, so
|
|
81
|
+
* this is the only way a caller's node can read a state it has no other route to.
|
|
82
|
+
*
|
|
83
|
+
* Passing this and `items` together is a caller error. This wins — a middle somebody wrote is
|
|
84
|
+
* the more specific instruction, where a list may have arrived through a wrapper's spread — and
|
|
85
|
+
* development says so out loud, because the alternative is rows that render nowhere in silence. */
|
|
86
|
+
children?: React.ReactNode | ((collapsed: boolean) => React.ReactNode);
|
|
72
87
|
/** Expanded-slot mark/wordmark, rendered when `header` is absent. Also the narrow rail's fallback
|
|
73
88
|
* when `logoCollapsed` isn't given. */
|
|
74
89
|
logo?: React.ReactNode;
|
|
75
|
-
/**
|
|
76
|
-
*
|
|
90
|
+
/** The band's mark — a small one, standing on the glyph column at 32. It is drawn at both widths
|
|
91
|
+
* and never fades: at the narrow width it is the whole of the identity, and at the wide one it is
|
|
92
|
+
* the mark the node in `header` leads with. Falls back to `logo`. */
|
|
77
93
|
logoCollapsed?: React.ReactNode;
|
|
78
94
|
/** Identity slot above the rail — e.g. an <OrgProductSwitcher/> (#266). Falls back to `logo`.
|
|
79
|
-
* Expanded-only:
|
|
80
|
-
*
|
|
95
|
+
* Expanded-only: it fades out at the narrow width, because a switcher clipped to the rail's own
|
|
96
|
+
* width reads as a tile with a severed word beside it.
|
|
97
|
+
*
|
|
98
|
+
* A node here draws no mark of its own. `logoCollapsed ?? logo` is the band's one mark and the
|
|
99
|
+
* rail draws it at BOTH widths, so a second one stands 2px beside it, solid, in the same band.
|
|
100
|
+
* `OrgProductSwitcher` yields its own with `mark="hold"`, which leaves its box and its words
|
|
101
|
+
* exactly where they are. */
|
|
81
102
|
header?: React.ReactNode;
|
|
82
103
|
/** Top of the rail — e.g. a <QuickSearchRow/>. It sits between the header's rule and the rows,
|
|
83
104
|
* and it is pinned: outside the scroll region, so it holds one place while the rows below it
|
|
@@ -94,7 +115,7 @@ interface AppSidebarProps {
|
|
|
94
115
|
isItemActive?: (item: NavItem, pathname: string) => boolean;
|
|
95
116
|
className?: string;
|
|
96
117
|
}
|
|
97
|
-
declare function AppSidebar({ items, logo, logoCollapsed, header, railTop, collapsed: controlled, defaultCollapsed, onCollapsedChange, basePath, LinkComponent, isItemActive, className, }: AppSidebarProps): React.JSX.Element;
|
|
118
|
+
declare function AppSidebar({ items, children, logo, logoCollapsed, header, railTop, collapsed: controlled, defaultCollapsed, onCollapsedChange, basePath, LinkComponent, isItemActive, className, }: AppSidebarProps): React.JSX.Element;
|
|
98
119
|
|
|
99
120
|
interface AppShellProps {
|
|
100
121
|
/** The sidebar, typically an <AppSidebar/>. Rendered in the desktop rail and, on mobile, inside a
|
package/dist/router.js
CHANGED
|
@@ -9,14 +9,17 @@ import {
|
|
|
9
9
|
SheetDescription,
|
|
10
10
|
SheetTitle,
|
|
11
11
|
SheetTrigger,
|
|
12
|
+
SidebarDrawer,
|
|
12
13
|
Tooltip,
|
|
13
14
|
TooltipContent,
|
|
14
15
|
TooltipProvider,
|
|
15
16
|
TooltipTrigger,
|
|
16
17
|
cn,
|
|
18
|
+
railToggleLabel,
|
|
17
19
|
useIsMobile,
|
|
18
|
-
useSidebar
|
|
19
|
-
|
|
20
|
+
useSidebar,
|
|
21
|
+
useSidebarDrawer
|
|
22
|
+
} from "./chunk-OTYVKDP2.js";
|
|
20
23
|
|
|
21
24
|
// src/components/extension-link.tsx
|
|
22
25
|
import { Link } from "react-router";
|
|
@@ -99,19 +102,19 @@ function SidebarNav({
|
|
|
99
102
|
}
|
|
100
103
|
|
|
101
104
|
// src/components/app-sidebar.tsx
|
|
102
|
-
import * as React from "react";
|
|
103
105
|
import { Fragment, jsx as jsx3, jsxs as jsxs2 } from "react/jsx-runtime";
|
|
104
|
-
var SidebarDrawerContext = React.createContext(false);
|
|
105
|
-
function SidebarDrawer({ children }) {
|
|
106
|
-
return /* @__PURE__ */ jsx3(SidebarDrawerContext.Provider, { value: true, children });
|
|
107
|
-
}
|
|
108
106
|
function Divider({ testId, className }) {
|
|
109
107
|
return /* @__PURE__ */ jsx3("div", { "data-testid": testId, className: cn("h-px shrink-0 bg-border-subtle", className) });
|
|
110
108
|
}
|
|
111
109
|
var RAIL_WIDE = "w-[248px]";
|
|
112
110
|
var RAIL_NARROW = "w-[64px]";
|
|
111
|
+
var footTooltipOffset = (collapsed) => collapsed ? 16 : 4;
|
|
112
|
+
function drawsNothing(node) {
|
|
113
|
+
return node == null || typeof node === "boolean" || node === "" || Array.isArray(node) && node.length === 0;
|
|
114
|
+
}
|
|
113
115
|
function AppSidebar({
|
|
114
116
|
items,
|
|
117
|
+
children,
|
|
115
118
|
logo,
|
|
116
119
|
logoCollapsed,
|
|
117
120
|
header,
|
|
@@ -124,7 +127,7 @@ function AppSidebar({
|
|
|
124
127
|
isItemActive,
|
|
125
128
|
className
|
|
126
129
|
}) {
|
|
127
|
-
const drawer =
|
|
130
|
+
const drawer = useSidebarDrawer();
|
|
128
131
|
const { collapsed: railCollapsed, toggle } = useSidebar({
|
|
129
132
|
collapsed: controlled,
|
|
130
133
|
defaultCollapsed,
|
|
@@ -132,54 +135,135 @@ function AppSidebar({
|
|
|
132
135
|
});
|
|
133
136
|
const collapsed = drawer ? false : railCollapsed;
|
|
134
137
|
const railTopNode = typeof railTop === "function" ? railTop(collapsed) : railTop;
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
138
|
+
const separateMark = header != null || logoCollapsed != null;
|
|
139
|
+
const asked = typeof children === "function" ? children(collapsed) : children;
|
|
140
|
+
const written = drawsNothing(asked) ? null : asked;
|
|
141
|
+
if (process.env.NODE_ENV !== "production" && written !== null && items != null) {
|
|
142
|
+
console.warn(
|
|
143
|
+
"[AppSidebar] `children` and `items` are two middles and only one is drawn: `children` wins and the rows are dropped. Put the links inside the middle you wrote, or drop `children`."
|
|
144
|
+
);
|
|
145
|
+
}
|
|
146
|
+
return (
|
|
147
|
+
// ONE PROVIDER, ROUND THE WHOLE RAIL.
|
|
148
|
+
//
|
|
149
|
+
// The rail composes a tooltip at its foot and `SidebarNav` composes one per row at the narrow
|
|
150
|
+
// width, and a provider per instance is what `.storybook/preview.tsx` states the rule against:
|
|
151
|
+
// nested, the foot's control opened at Radix's own 700ms while every row beside it opened at
|
|
152
|
+
// 200, and it could never join their skip-delay group. Here rather than left to `AppShell`, so
|
|
153
|
+
// a rail rendered on its own still has one — nesting inside the shell's is harmless.
|
|
154
|
+
/* @__PURE__ */ jsx3(TooltipProvider, { children: /* @__PURE__ */ jsx3(
|
|
155
|
+
"aside",
|
|
156
|
+
{
|
|
157
|
+
"data-collapsed": collapsed,
|
|
158
|
+
className: cn(
|
|
159
|
+
"flex h-full shrink-0 flex-col overflow-hidden motion-rail-collapse",
|
|
160
|
+
// A nav row drops its own label at the narrow width. What this fades is a label whatever
|
|
161
|
+
// stands in `railTop` keeps mounted at both — QuickSearchRow's, for one — so the closing
|
|
162
|
+
// edge slides over the words instead of cutting through them.
|
|
163
|
+
//
|
|
164
|
+
// The trailing mark goes on the same clock: a disclosure chevron is `nav-row-trailing`, it
|
|
165
|
+
// is as far past the closing edge as the words beside it, and left untimed it snapped out
|
|
166
|
+
// while they faded.
|
|
167
|
+
//
|
|
168
|
+
// `duration-fast` is the token scale rather than a typed number, so a `@lessly/tokens`
|
|
169
|
+
// release retunes it, and the step reaches the utility as `var(--motion-duration-fast,
|
|
170
|
+
// 100ms)` — the same variable `.motion-rail-collapse` reads, which the token layer's
|
|
171
|
+
// `prefers-reduced-motion` block takes to 0ms, so the words and the width stop together.
|
|
172
|
+
// `motion-reduce:transition-none` is what a consumer running the preset without
|
|
173
|
+
// `@lessly/ui/styles.css` stops on: they are left with the 100ms fallback, and no media
|
|
174
|
+
// query reaches a literal.
|
|
175
|
+
"[&_[data-slot=nav-row-label]]:transition-opacity [&_[data-slot=nav-row-label]]:duration-fast",
|
|
176
|
+
"[&_[data-slot=nav-row-label]]:motion-reduce:transition-none",
|
|
177
|
+
"[&_[data-slot=nav-row-trailing]]:transition-opacity [&_[data-slot=nav-row-trailing]]:duration-fast",
|
|
178
|
+
"[&_[data-slot=nav-row-trailing]]:motion-reduce:transition-none",
|
|
179
|
+
collapsed ? RAIL_NARROW : RAIL_WIDE,
|
|
180
|
+
collapsed && "[&_[data-slot=nav-row-label]]:opacity-0 [&_[data-slot=nav-row-trailing]]:opacity-0",
|
|
181
|
+
className
|
|
161
182
|
),
|
|
162
|
-
|
|
163
|
-
/* @__PURE__ */ jsx3(
|
|
164
|
-
|
|
183
|
+
children: /* @__PURE__ */ jsxs2("div", { className: cn("flex h-full shrink-0 flex-col", RAIL_WIDE), children: [
|
|
184
|
+
/* @__PURE__ */ jsx3("div", { className: cn("relative flex h-14 shrink-0 items-center", drawer ? "pl-3 pr-10" : "px-3"), children: separateMark ? /* @__PURE__ */ jsxs2(Fragment, { children: [
|
|
185
|
+
/* @__PURE__ */ jsx3(
|
|
186
|
+
"div",
|
|
187
|
+
{
|
|
188
|
+
"data-testid": "sidebar-identity-expanded",
|
|
189
|
+
"aria-hidden": collapsed || void 0,
|
|
190
|
+
inert: collapsed,
|
|
191
|
+
className: cn(
|
|
192
|
+
"flex w-full items-center gap-2 transition-opacity duration-normal motion-reduce:transition-none",
|
|
193
|
+
collapsed && "pointer-events-none opacity-0"
|
|
194
|
+
),
|
|
195
|
+
children: header ?? logo
|
|
196
|
+
}
|
|
197
|
+
),
|
|
198
|
+
/* @__PURE__ */ jsx3(
|
|
199
|
+
"div",
|
|
200
|
+
{
|
|
201
|
+
"data-testid": "sidebar-identity-collapsed",
|
|
202
|
+
"aria-hidden": !collapsed || void 0,
|
|
203
|
+
inert: !collapsed,
|
|
204
|
+
className: cn("absolute", RAIL_COLUMN_BOX, !collapsed && "pointer-events-none"),
|
|
205
|
+
children: logoCollapsed ?? logo
|
|
206
|
+
}
|
|
207
|
+
)
|
|
208
|
+
] }) : (
|
|
209
|
+
/* ONE MARK, MOUNTED ONCE.
|
|
210
|
+
With neither `header` nor `logoCollapsed`, both slots resolve to the same `logo`, and
|
|
211
|
+
a node fading into an identical node is not a transition — it is one mark ghosted off
|
|
212
|
+
another. Mounted twice it was worse than a picture: one `id` inside an SVG logo
|
|
213
|
+
belongs to two elements and `getElementById` finds the hidden one, a `ref` fires
|
|
214
|
+
twice and measures the transparent copy, effects subscribe twice, and `inert` pauses
|
|
215
|
+
no player.
|
|
216
|
+
It stands in RAIL_COLUMN_BOX at BOTH widths, which is the box the closed mark and the
|
|
217
|
+
foot's toggle already stand in: centre 32, the column every row's glyph is on. That
|
|
218
|
+
is a class list that never changes, so there is no frame for it to move on. */
|
|
219
|
+
/* @__PURE__ */ jsx3("div", { "data-testid": "sidebar-identity-single", className: RAIL_COLUMN_BOX, children: logo })
|
|
220
|
+
) }),
|
|
221
|
+
/* @__PURE__ */ jsx3(Divider, { testId: "sidebar-divider-header" }),
|
|
222
|
+
railTopNode && /* @__PURE__ */ jsx3("div", { "data-testid": "sidebar-rail-top", className: "shrink-0 px-3 pt-3", children: railTopNode }),
|
|
223
|
+
written !== null ? /* @__PURE__ */ jsx3(
|
|
224
|
+
"div",
|
|
225
|
+
{
|
|
226
|
+
"data-testid": "sidebar-body",
|
|
227
|
+
className: cn(
|
|
228
|
+
"flex min-h-0 flex-1 flex-col overflow-hidden px-3 pb-2",
|
|
229
|
+
railTopNode ? "pt-2" : "pt-3"
|
|
230
|
+
),
|
|
231
|
+
children: written
|
|
232
|
+
}
|
|
233
|
+
) : /* @__PURE__ */ jsx3(
|
|
234
|
+
ScrollArea,
|
|
235
|
+
{
|
|
236
|
+
className: "min-h-0 flex-1",
|
|
237
|
+
viewportClassName: cn("px-3 pb-2", railTopNode ? "pt-2" : "pt-3"),
|
|
238
|
+
viewportProps: { "data-testid": "sidebar-scroll" },
|
|
239
|
+
children: /* @__PURE__ */ jsx3(SidebarNav, { items: items ?? [], collapsed, basePath, LinkComponent, isItemActive })
|
|
240
|
+
}
|
|
241
|
+
),
|
|
242
|
+
!drawer && /* @__PURE__ */ jsxs2(Fragment, { children: [
|
|
243
|
+
/* @__PURE__ */ jsx3(Divider, { testId: "sidebar-divider-foot" }),
|
|
244
|
+
/* @__PURE__ */ jsx3("div", { className: "flex shrink-0 px-3 py-2", children: /* @__PURE__ */ jsxs2(Tooltip, { children: [
|
|
245
|
+
/* @__PURE__ */ jsx3(TooltipTrigger, { asChild: true, "aria-describedby": void 0, children: /* @__PURE__ */ jsx3(RailToggle, { collapsed, onClick: toggle }) }),
|
|
246
|
+
/* @__PURE__ */ jsx3(TooltipContent, { side: "right", sideOffset: footTooltipOffset(collapsed), children: railToggleLabel(collapsed) })
|
|
247
|
+
] }) })
|
|
248
|
+
] })
|
|
165
249
|
] })
|
|
166
|
-
|
|
167
|
-
}
|
|
250
|
+
}
|
|
251
|
+
) })
|
|
168
252
|
);
|
|
169
253
|
}
|
|
170
254
|
|
|
171
255
|
// src/components/app-shell.tsx
|
|
172
|
-
import * as
|
|
256
|
+
import * as React from "react";
|
|
173
257
|
import { Menu } from "lucide-react";
|
|
174
258
|
import { useLocation as useLocation2 } from "react-router";
|
|
175
259
|
import { Fragment as Fragment2, jsx as jsx4, jsxs as jsxs3 } from "react/jsx-runtime";
|
|
176
260
|
function expandedSidebar(sidebar) {
|
|
177
|
-
return
|
|
261
|
+
return React.isValidElement(sidebar) ? React.cloneElement(sidebar, { collapsed: false }) : sidebar;
|
|
178
262
|
}
|
|
179
263
|
function AppShell({ sidebar, topBar, children, className }) {
|
|
180
264
|
const { pathname } = useLocation2();
|
|
181
|
-
const [mobileOpen, setMobileOpen] =
|
|
182
|
-
|
|
265
|
+
const [mobileOpen, setMobileOpen] = React.useState(false);
|
|
266
|
+
React.useEffect(() => {
|
|
183
267
|
setMobileOpen(false);
|
|
184
268
|
}, [pathname]);
|
|
185
269
|
const isMobile = useIsMobile();
|
|
@@ -196,7 +280,7 @@ function AppShell({ sidebar, topBar, children, className }) {
|
|
|
196
280
|
/* @__PURE__ */ jsxs3(SheetContent, { side: "left", className: "w-[248px] bg-bg-primary p-0", children: [
|
|
197
281
|
/* @__PURE__ */ jsx4(SheetTitle, { className: "sr-only", children: "Navigation" }),
|
|
198
282
|
/* @__PURE__ */ jsx4(SheetDescription, { className: "sr-only", children: "Application navigation menu" }),
|
|
199
|
-
/* @__PURE__ */ jsx4(SidebarDrawer, { children: expandedSidebar(sidebar) })
|
|
283
|
+
/* @__PURE__ */ jsx4(SidebarDrawer, { onDismiss: () => setMobileOpen(false), children: expandedSidebar(sidebar) })
|
|
200
284
|
] })
|
|
201
285
|
] }),
|
|
202
286
|
/* @__PURE__ */ jsx4("div", { className: "flex items-center gap-2", children: topBar })
|
|
@@ -19,7 +19,7 @@
|
|
|
19
19
|
--bg-elevated: #252936;
|
|
20
20
|
--bg-overlay: #252936;
|
|
21
21
|
--bg-sunken: #0e1015;
|
|
22
|
-
--bg-selected: #
|
|
22
|
+
--bg-selected: #252735;
|
|
23
23
|
--bg-brand: #06297d;
|
|
24
24
|
--bg-brand-subtle: #1f2541;
|
|
25
25
|
--bg-brand-hover: #08349b;
|
|
@@ -103,12 +103,12 @@
|
|
|
103
103
|
--grid-container-max: 1440px;
|
|
104
104
|
|
|
105
105
|
/* typography text-styles — theme-invariant, :root only (see typographyVars in build.js) */
|
|
106
|
-
--text-display-xl-font-family: "
|
|
106
|
+
--text-display-xl-font-family: "Sora", "Inter", system-ui, -apple-system, sans-serif;
|
|
107
107
|
--text-display-xl-font-size: 3.5rem;
|
|
108
108
|
--text-display-xl-line-height: 1.05;
|
|
109
109
|
--text-display-xl-font-weight: 400;
|
|
110
110
|
--text-display-xl-letter-spacing: -0.02em;
|
|
111
|
-
--text-display-lg-font-family: "
|
|
111
|
+
--text-display-lg-font-family: "Sora", "Inter", system-ui, -apple-system, sans-serif;
|
|
112
112
|
--text-display-lg-font-size: 3rem;
|
|
113
113
|
--text-display-lg-line-height: 1.1;
|
|
114
114
|
--text-display-lg-font-weight: 400;
|
|
@@ -283,7 +283,7 @@
|
|
|
283
283
|
--bg-elevated: #edeef0;
|
|
284
284
|
--bg-overlay: #ffffff;
|
|
285
285
|
--bg-sunken: #e1e2e4;
|
|
286
|
-
--bg-selected: #
|
|
286
|
+
--bg-selected: #eceded;
|
|
287
287
|
--bg-brand-subtle: #e4ecfe;
|
|
288
288
|
--bg-brand-hover: #05226a;
|
|
289
289
|
--bg-brand-bright-hover: #0b4cd5;
|
|
@@ -342,6 +342,27 @@
|
|
|
342
342
|
--overlay-modal-bg: #ffffff;
|
|
343
343
|
--focus-ring-color: #0940b8;
|
|
344
344
|
|
|
345
|
+
/* Same value as :root on purpose, re-declared so .light lists every colour token a
|
|
346
|
+
light consumer gets rather than leaving some to inheritance. Why, and what holds
|
|
347
|
+
it honest: docs/tokens.md, "Theme invariance". */
|
|
348
|
+
--bg-brand: #06297d;
|
|
349
|
+
--bg-brand-bright: #165ff2;
|
|
350
|
+
--bg-success: #13703c;
|
|
351
|
+
--bg-success-bright: #21be63;
|
|
352
|
+
--bg-danger: #78100b;
|
|
353
|
+
--text-on-brand: #f6f7f7;
|
|
354
|
+
--text-on-success: #f6f7f7;
|
|
355
|
+
--text-on-success-bright: #08090c;
|
|
356
|
+
--text-on-warning: #08090c;
|
|
357
|
+
--text-on-danger: #f6f7f7;
|
|
358
|
+
--border-selected: #737c95;
|
|
359
|
+
--border-brand: #165ff2;
|
|
360
|
+
--border-warning: #b3780e;
|
|
361
|
+
--border-danger: #e82020;
|
|
362
|
+
--field-border-hover: #737c95;
|
|
363
|
+
--field-border-filled: #737c95;
|
|
364
|
+
--field-border-error: #e82020;
|
|
365
|
+
|
|
345
366
|
/* shadcn role bridge re-declared so .light on a nested element (not just <html>)
|
|
346
367
|
re-resolves the aliases to light values. */
|
|
347
368
|
--background: var(--bg-primary);
|
|
@@ -471,11 +492,15 @@
|
|
|
471
492
|
--color-bg-surface: var(--bg-surface);
|
|
472
493
|
--color-bg-elevated: var(--bg-elevated);
|
|
473
494
|
--color-bg-sunken: var(--bg-sunken);
|
|
495
|
+
--color-bg-brand: var(--bg-brand);
|
|
474
496
|
--color-bg-brand-subtle: var(--bg-brand-subtle);
|
|
475
497
|
--color-bg-brand-hover: var(--bg-brand-hover);
|
|
498
|
+
--color-bg-brand-bright: var(--bg-brand-bright);
|
|
499
|
+
--color-bg-success: var(--bg-success);
|
|
476
500
|
--color-bg-success-subtle: var(--bg-success-subtle);
|
|
477
501
|
--color-bg-warning: var(--bg-warning);
|
|
478
502
|
--color-bg-warning-subtle: var(--bg-warning-subtle);
|
|
503
|
+
--color-bg-danger: var(--bg-danger);
|
|
479
504
|
--color-bg-danger-subtle: var(--bg-danger-subtle);
|
|
480
505
|
--color-bg-teal-subtle: var(--bg-teal-subtle);
|
|
481
506
|
--color-bg-violet-subtle: var(--bg-violet-subtle);
|
|
@@ -485,6 +510,10 @@
|
|
|
485
510
|
--color-text-tertiary: var(--text-tertiary);
|
|
486
511
|
--color-text-disabled: var(--text-disabled);
|
|
487
512
|
--color-text-inverse: var(--text-inverse);
|
|
513
|
+
--color-text-on-brand: var(--text-on-brand);
|
|
514
|
+
--color-text-on-success: var(--text-on-success);
|
|
515
|
+
--color-text-on-warning: var(--text-on-warning);
|
|
516
|
+
--color-text-on-danger: var(--text-on-danger);
|
|
488
517
|
--color-text-brand: var(--text-brand);
|
|
489
518
|
--color-text-success: var(--text-success);
|
|
490
519
|
--color-text-warning: var(--text-warning);
|
|
@@ -502,17 +531,25 @@
|
|
|
502
531
|
--color-border-subtle: var(--border-subtle);
|
|
503
532
|
--color-border-default: var(--border-default);
|
|
504
533
|
--color-border-strong: var(--border-strong);
|
|
534
|
+
--color-border-brand: var(--border-brand);
|
|
505
535
|
--color-border-focus: var(--border-focus);
|
|
506
536
|
--color-border-success: var(--border-success);
|
|
537
|
+
--color-border-warning: var(--border-warning);
|
|
538
|
+
--color-border-danger: var(--border-danger);
|
|
507
539
|
}
|
|
508
540
|
|
|
509
541
|
/* === Fonts === */
|
|
542
|
+
/* This kit declares no face of its own, and scripts/build-styles.mjs refuses a build where one
|
|
543
|
+
reappears here. Written without the at-rule spelled out: that guard is a character scanner
|
|
544
|
+
over this file, so naming the rule in prose would register as a block.
|
|
510
545
|
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
546
|
+
The faces live in @lessly/tokens/fonts.css — Inter, Fira Mono and Sora, against RELATIVE
|
|
547
|
+
`./fonts/...` paths at files inside that package. A consumer imports that sheet and is done.
|
|
548
|
+
What stood here declared four of them a second time against ABSOLUTE `/fonts/**.woff2`, which
|
|
549
|
+
named files the kit does not ship and every consumer had to serve itself; one who did not
|
|
550
|
+
rendered in system fallback with no error at all. Sora, which `--text-display-*-font-family`
|
|
551
|
+
has named since @lessly/tokens@0.8.0, was never declared here in any form and so never
|
|
552
|
+
painted at all. */
|
|
516
553
|
|
|
517
554
|
/* === Theme Variables === */
|
|
518
555
|
/* The token palettes (colors, typography, motion, shadows, grid) live in
|
|
@@ -606,8 +643,10 @@
|
|
|
606
643
|
|
|
607
644
|
/* === Motion === */
|
|
608
645
|
/* Backs the <AutoHeight> primitive: eases a container's height as its content changes size.
|
|
609
|
-
|
|
610
|
-
|
|
646
|
+
A real class because `height` is a property no Tailwind transition utility names: the only way to
|
|
647
|
+
write it in a class list is the arbitrary `transition-[height]`, which the content scanner can
|
|
648
|
+
drop the first time a file writes it. (The duration is not the reason — `duration-normal` carries
|
|
649
|
+
the same variable this line does.)
|
|
611
650
|
Overflow is NOT clipped here — the component clips only while the height is animating (so the
|
|
612
651
|
settled box doesn't slice focus rings or tooltips on full-width children). */
|
|
613
652
|
.motion-auto-height {
|
|
@@ -617,9 +656,11 @@
|
|
|
617
656
|
}
|
|
618
657
|
|
|
619
658
|
/* Backs ToggleGroup's `sliding` mark: one thumb that travels between equal-width slots instead of a
|
|
620
|
-
fill appearing on each. A
|
|
621
|
-
|
|
622
|
-
`
|
|
659
|
+
fill appearing on each. A named primitive rather than the three utilities that would now say the
|
|
660
|
+
same thing, so the thumb's timing is stated once and cannot drift between the call sites that
|
|
661
|
+
write it. `slide` because the thumb crosses the width of a slot — `ui`, the hover/focus tint step,
|
|
662
|
+
would clip it to near a snap. `standard` because it is on screen before and after and only moves
|
|
663
|
+
in place. */
|
|
623
664
|
.motion-segment-thumb {
|
|
624
665
|
transition-property: transform;
|
|
625
666
|
transition-duration: var(--motion-duration-slide);
|
|
@@ -630,9 +671,9 @@
|
|
|
630
671
|
frame as it travels. One class on both, so the mark cannot be retuned away from the edge it
|
|
631
672
|
answers for — the same reason two carets read one `caretMotion`. `transform` is here rather than
|
|
632
673
|
in a class of its own because the bar is that edge said in miniature: retune one and the two stop
|
|
633
|
-
arriving together. A real class for the reason the
|
|
634
|
-
|
|
635
|
-
|
|
674
|
+
arriving together. A real class for the reason the first one above is, and more so: `width,
|
|
675
|
+
transform` is a pair no Tailwind utility names at all, so writing it in a class list means the
|
|
676
|
+
arbitrary `transition-[width,transform]` — the form the scanner can drop. */
|
|
636
677
|
.motion-rail-collapse {
|
|
637
678
|
transition-property: width, transform;
|
|
638
679
|
transition-duration: var(--motion-duration-normal);
|
|
@@ -697,6 +738,9 @@
|
|
|
697
738
|
/* === Animation layer (tw-animate-css, compiled) — see scripts/build-styles.mjs === */
|
|
698
739
|
/*! tailwindcss v4.3.2 | MIT License | https://tailwindcss.com */
|
|
699
740
|
@layer properties;
|
|
741
|
+
.animate-accordion-down {
|
|
742
|
+
animation: accordion-down var(--tw-animation-duration,var(--tw-duration,.2s))var(--tw-ease,ease-out)var(--tw-animation-delay,0s)var(--tw-animation-iteration-count,1)var(--tw-animation-direction,normal)var(--tw-animation-fill-mode,none);
|
|
743
|
+
}
|
|
700
744
|
.animate-in {
|
|
701
745
|
animation: enter var(--tw-animation-duration,var(--tw-duration,.15s))var(--tw-ease,ease)var(--tw-animation-delay,0s)var(--tw-animation-iteration-count,1)var(--tw-animation-direction,normal)var(--tw-animation-fill-mode,none);
|
|
702
746
|
}
|