@spaethtech/svelte-ui 0.6.1-dev.33.c371f46 → 0.7.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.
|
@@ -162,7 +162,9 @@ examples):
|
|
|
162
162
|
`onShow(ctx)`/`onHide(ctx)` control focus — set `ctx.autoFocus` to a selector/element/`false`,
|
|
163
163
|
`ctx.restoreFocus` likewise) · `ConfirmDialog` (title + message + Confirm/Cancel, built on Dialog)
|
|
164
164
|
· `Popup` `Menu` · `tooltip` (a Svelte `use:` action) · `anchored` (positioning engine)
|
|
165
|
-
- **Navigation:** `TabStrip` `
|
|
165
|
+
- **Navigation:** `TabStrip` (tabs; `size`/`variant`, `gap`/`pad` bordered spacer cells, `height` for a
|
|
166
|
+
fixed-height bar with bottom-aligned tabs, `activeSurface` to flow the active tab into the content
|
|
167
|
+
below) · `SideBarMenu`
|
|
166
168
|
- **Feedback:** `Alert` `Banner` `Badge` `Toaster` + `toast`
|
|
167
169
|
- **Layout:** `Card` `CardHeader` `CardBody` `CardFooter` · **`Grid`** (auto-placed equal-cell grid;
|
|
168
170
|
`columns` + `gap`)
|
|
@@ -49,6 +49,12 @@
|
|
|
49
49
|
* row bottom-aligns to the base line and the extra space breathes ABOVE it. `size` still sets the
|
|
50
50
|
* tab height; `height` sets the whole bar. Unset → the strip hugs the tab row. */
|
|
51
51
|
height?: number;
|
|
52
|
+
/** CSS colour for the ACTIVE tab's fill AND its bottom border — so the base line disappears under
|
|
53
|
+
* it and the tab reads as one surface with the content below. Default `"transparent"` (reveals
|
|
54
|
+
* whatever surface the strip sits on — today's behaviour). Set a token/colour to force a specific
|
|
55
|
+
* surface, e.g. `activeSurface="var(--ui-color-background)"` when the strip sits in a container
|
|
56
|
+
* whose background differs from the content below. Any CSS colour value. */
|
|
57
|
+
activeSurface?: string;
|
|
52
58
|
onselect?: (index: number) => void;
|
|
53
59
|
right?: Snippet;
|
|
54
60
|
/** Optional aria-label for the strip when it renders as a navigation landmark
|
|
@@ -67,6 +73,7 @@
|
|
|
67
73
|
gap = 0,
|
|
68
74
|
pad = 0,
|
|
69
75
|
height,
|
|
76
|
+
activeSurface = "transparent",
|
|
70
77
|
onselect,
|
|
71
78
|
right,
|
|
72
79
|
"aria-label": ariaLabel,
|
|
@@ -230,13 +237,18 @@
|
|
|
230
237
|
].join(" "),
|
|
231
238
|
);
|
|
232
239
|
|
|
233
|
-
// Selected:
|
|
234
|
-
//
|
|
235
|
-
//
|
|
236
|
-
//
|
|
237
|
-
//
|
|
238
|
-
|
|
239
|
-
|
|
240
|
+
// Selected: label + icon take `var(--ui-accent)` (the variant colour, or plain text for
|
|
241
|
+
// neutral/ghost — icons inherit via currentColor), the clearest signal of the strip's variant. The
|
|
242
|
+
// FILL + bottom-border colour are driven by `activeSurface` via inline `style` (below) — a dynamic
|
|
243
|
+
// colour can't be a Tailwind class (the scanner never sees a runtime-built arbitrary value). Default
|
|
244
|
+
// `transparent`: the tab shows whatever surface the strip sits on and the base line breaks under it
|
|
245
|
+
// (the folder-tab effect on ANY background) — identical to before.
|
|
246
|
+
const selectedStyleClass = "[color:var(--ui-accent)]";
|
|
247
|
+
// Applied only to the active tab. `background-color` = the fill; `border-bottom-color` = the same, so
|
|
248
|
+
// the base-line segment under the active tab vanishes into that surface.
|
|
249
|
+
const selectedStyle = $derived(
|
|
250
|
+
`background-color:${activeSurface}; border-bottom-color:${activeSurface}`,
|
|
251
|
+
);
|
|
240
252
|
|
|
241
253
|
// `ghost` is the "transparent, hover-tint only" grey variant (per `types/variants.ts`): unlike
|
|
242
254
|
// `neutral`, its inactive tabs have NO resting fill — they sit on the bare surface and only tint on
|
|
@@ -276,6 +288,7 @@
|
|
|
276
288
|
: isActive
|
|
277
289
|
? selectedStyleClass
|
|
278
290
|
: `${unselectedStyleClass} ${lineBottom}`}
|
|
291
|
+
{@const tabStyle = isActive && !t.disabled ? selectedStyle : undefined}
|
|
279
292
|
{@const tabTabIndex = t.disabled ? -1 : semanticMode === "tablist" ? (isRoving ? 0 : -1) : 0}
|
|
280
293
|
{@const tabAriaCurrent =
|
|
281
294
|
semanticMode === "navigation" && isActive ? ("page" as const) : undefined}
|
|
@@ -305,6 +318,7 @@
|
|
|
305
318
|
focusedIndex = i;
|
|
306
319
|
}}
|
|
307
320
|
class={`${tabBase} ${stateClass}`}
|
|
321
|
+
style={tabStyle}
|
|
308
322
|
>
|
|
309
323
|
{#if t.icon}{@render t.icon()}{/if}
|
|
310
324
|
<span class={`truncate ${t.icon ? labelClass : "inline-block"}`}>{t.label}</span>
|
|
@@ -328,6 +342,7 @@
|
|
|
328
342
|
focusedIndex = i;
|
|
329
343
|
}}
|
|
330
344
|
class={`${tabBase} ${stateClass}`}
|
|
345
|
+
style={tabStyle}
|
|
331
346
|
disabled={t.disabled}
|
|
332
347
|
>
|
|
333
348
|
{#if t.icon}{@render t.icon()}{/if}
|
|
@@ -42,6 +42,12 @@ interface Props extends Omit<HTMLAttributes<HTMLUListElement>, "onselect"> {
|
|
|
42
42
|
* row bottom-aligns to the base line and the extra space breathes ABOVE it. `size` still sets the
|
|
43
43
|
* tab height; `height` sets the whole bar. Unset → the strip hugs the tab row. */
|
|
44
44
|
height?: number;
|
|
45
|
+
/** CSS colour for the ACTIVE tab's fill AND its bottom border — so the base line disappears under
|
|
46
|
+
* it and the tab reads as one surface with the content below. Default `"transparent"` (reveals
|
|
47
|
+
* whatever surface the strip sits on — today's behaviour). Set a token/colour to force a specific
|
|
48
|
+
* surface, e.g. `activeSurface="var(--ui-color-background)"` when the strip sits in a container
|
|
49
|
+
* whose background differs from the content below. Any CSS colour value. */
|
|
50
|
+
activeSurface?: string;
|
|
45
51
|
onselect?: (index: number) => void;
|
|
46
52
|
right?: Snippet;
|
|
47
53
|
/** Optional aria-label for the strip when it renders as a navigation landmark
|
package/docs/components.md
CHANGED
|
@@ -197,6 +197,22 @@ Thin wrappers over `Input`, each preconfigured with an MDI icon (rendered into I
|
|
|
197
197
|
- **Location**: `src/lib/components/NumberInput.svelte`
|
|
198
198
|
- **Features**: number formatting and validation
|
|
199
199
|
|
|
200
|
+
## Navigation
|
|
201
|
+
|
|
202
|
+
### TabStrip
|
|
203
|
+
|
|
204
|
+
A horizontal tab bar (renders as a `tablist` of buttons, or a `navigation` of links when any tab has
|
|
205
|
+
`href`). Tabs split into left / right clusters; a continuous base line runs under the strip and breaks
|
|
206
|
+
under the active tab. Fully demoed at `/tabstrip`.
|
|
207
|
+
|
|
208
|
+
- **Location**: `src/lib/components/TabStrip/TabStrip.svelte`
|
|
209
|
+
- **Axes**: `size`, `variant` (both `Responsive`)
|
|
210
|
+
- **Props**: `tabs` (`TabDefinition[]`), `activeTabIndex` (bindable), `mode` (`'expanded'` |
|
|
211
|
+
`'collapsed'`, responsive), `borderless`, `gap` (rem — bordered cells between tabs), `pad` (rem —
|
|
212
|
+
leading/trailing side cells), **`height`** (rem — total bar height; tabs bottom-align, space above),
|
|
213
|
+
**`activeSurface`** (CSS colour for the active tab's fill + bottom border; default `"transparent"`),
|
|
214
|
+
`right` (Snippet), `aria-label`.
|
|
215
|
+
|
|
200
216
|
## Data Components
|
|
201
217
|
|
|
202
218
|
These pair with the headless **`@spaethtech/svelte-ui/data`** layer (query-language parser/AST, `createGrid`,
|