@urbicon-ui/blocks 6.31.0 → 6.33.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/components/Calendar/CalendarAgendaView.svelte +6 -2
- package/dist/components/Calendar/CalendarDayView.svelte +6 -2
- package/dist/internal/date-grid/date-grid.svelte.js +5 -3
- package/dist/primitives/ButtonGroup/ButtonGroup.svelte +29 -5
- package/dist/primitives/Toolbar/Toolbar.svelte +11 -1
- package/docs/MIGRATION-v5.md +6 -4
- package/package.json +5 -4
|
@@ -62,14 +62,18 @@
|
|
|
62
62
|
const agendaKey = $derived(`${ctx.displayedYear}-${ctx.displayedMonth}`);
|
|
63
63
|
|
|
64
64
|
function handleKeydown(e: KeyboardEvent) {
|
|
65
|
+
// Direction-gated like the swipes and header arrows (the DateGridScaffold
|
|
66
|
+
// pattern): an arrow key at the bound is inert — no navDirection flip, no
|
|
67
|
+
// clamped no-op onMonthChange emit. Disabled calendars ignore keys entirely.
|
|
68
|
+
if (ctx.disabled) return;
|
|
65
69
|
switch (e.key) {
|
|
66
70
|
case 'ArrowLeft':
|
|
67
71
|
e.preventDefault();
|
|
68
|
-
ctx.navigate(-1);
|
|
72
|
+
if (ctx.canGoBack) ctx.navigate(-1);
|
|
69
73
|
break;
|
|
70
74
|
case 'ArrowRight':
|
|
71
75
|
e.preventDefault();
|
|
72
|
-
ctx.navigate(1);
|
|
76
|
+
if (ctx.canGoForward) ctx.navigate(1);
|
|
73
77
|
break;
|
|
74
78
|
}
|
|
75
79
|
}
|
|
@@ -33,14 +33,18 @@
|
|
|
33
33
|
const totalEventCount = $derived(eventsWithInfo.length);
|
|
34
34
|
|
|
35
35
|
function handleKeydown(e: KeyboardEvent) {
|
|
36
|
+
// Direction-gated like the swipes and header arrows (the DateGridScaffold
|
|
37
|
+
// pattern): an arrow key at the bound is inert — no navDirection flip, no
|
|
38
|
+
// clamped no-op onDayChange emit. Disabled calendars ignore keys entirely.
|
|
39
|
+
if (ctx.disabled) return;
|
|
36
40
|
switch (e.key) {
|
|
37
41
|
case 'ArrowLeft':
|
|
38
42
|
e.preventDefault();
|
|
39
|
-
ctx.navigate(-1);
|
|
43
|
+
if (ctx.canGoBack) ctx.navigate(-1);
|
|
40
44
|
break;
|
|
41
45
|
case 'ArrowRight':
|
|
42
46
|
e.preventDefault();
|
|
43
|
-
ctx.navigate(1);
|
|
47
|
+
if (ctx.canGoForward) ctx.navigate(1);
|
|
44
48
|
break;
|
|
45
49
|
}
|
|
46
50
|
}
|
|
@@ -296,9 +296,11 @@ export class DateGridController {
|
|
|
296
296
|
break;
|
|
297
297
|
}
|
|
298
298
|
// Week/day steps carry no month bounds of their own, so clamp the shifted
|
|
299
|
-
// reference to [minDate, maxDate] too
|
|
300
|
-
//
|
|
301
|
-
//
|
|
299
|
+
// reference to [minDate, maxDate] too. Swipes and the day/agenda arrow keys
|
|
300
|
+
// are canGoBack/canGoForward-gated like the header arrows these days, but the
|
|
301
|
+
// custom-header API (goTo/navigateWeek/navigateDay) is not — this clamp stays
|
|
302
|
+
// as the backstop so no caller can step the anchor onto an all-disabled
|
|
303
|
+
// week/day past the boundary.
|
|
302
304
|
case 'week':
|
|
303
305
|
next = clampDate(addDays(referenceDate, delta * 7), minDate, maxDate);
|
|
304
306
|
break;
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
<script lang="ts">
|
|
2
2
|
import { buttonGroupVariants, type ButtonGroupVariants } from '..';
|
|
3
3
|
import { getBlocksConfig, resolveSlotClasses } from '../../provider';
|
|
4
|
+
import { composeHandlers } from '../../utils/compose-handlers';
|
|
4
5
|
import { edgeEnabledIndex, nextEnabledIndex } from '../../utils';
|
|
5
6
|
import { getTierContext, setTierContext } from '../../utils/tier-context';
|
|
6
7
|
import type { ButtonGroupContext, ButtonGroupProps } from './index';
|
|
@@ -25,6 +26,12 @@
|
|
|
25
26
|
preset,
|
|
26
27
|
ariaLabel,
|
|
27
28
|
ariaLabelledBy,
|
|
29
|
+
// Pulled out of restProps so the `{...restProps}`-first spread (internal
|
|
30
|
+
// attributes win — see docs/COMPONENT-API-CONVENTIONS.md) can't clobber
|
|
31
|
+
// it: the roving keyboard navigation below is composed with a consumer's
|
|
32
|
+
// own handler (internal first, consumer second) instead of either side
|
|
33
|
+
// silently replacing the other.
|
|
34
|
+
onkeydown: onkeydownProp,
|
|
28
35
|
...restProps
|
|
29
36
|
}: ButtonGroupProps = $props();
|
|
30
37
|
|
|
@@ -271,18 +278,35 @@
|
|
|
271
278
|
const ariaOrientation = $derived(ariaRole === 'radiogroup' ? orientation : undefined);
|
|
272
279
|
</script>
|
|
273
280
|
|
|
281
|
+
<!--
|
|
282
|
+
restProps spreads FIRST so component-owned state wins (COMPONENT-API-CONVENTIONS
|
|
283
|
+
§restProps ordering) — a consumer role/tabindex through restProps must not
|
|
284
|
+
defeat the radiogroup semantics. The attributes after the spread are
|
|
285
|
+
conditional merges, not plain overrides, because an explicit `undefined`
|
|
286
|
+
after a spread REMOVES the attribute:
|
|
287
|
+
- role: always internally computed (radiogroup/group) — internal wins outright.
|
|
288
|
+
- aria-label / aria-labelledby: the dedicated props win, a consumer's own
|
|
289
|
+
`aria-label`/`aria-labelledby` through restProps is the fallback.
|
|
290
|
+
- aria-orientation: internal on the radiogroup arm; on the `group` arm it is
|
|
291
|
+
actively removed even against restProps — ARIA disallows aria-orientation
|
|
292
|
+
on role=group (aria-allowed-attr), mirroring Button's aria-pressed force-off.
|
|
293
|
+
- aria-disabled: internal `true` is unoverridable, idle falls back to the
|
|
294
|
+
consumer value; the default DOM output stays byte-identical (attr absent).
|
|
295
|
+
- onkeydown is destructured (never in restProps) and composed: the roving
|
|
296
|
+
keyboard nav always runs, a consumer handler runs after it.
|
|
297
|
+
-->
|
|
274
298
|
<div
|
|
275
299
|
bind:this={containerElement}
|
|
300
|
+
{...restProps}
|
|
276
301
|
role={ariaRole}
|
|
277
302
|
class={unstyled
|
|
278
303
|
? [slotClasses?.base, className].filter(Boolean).join(' ')
|
|
279
304
|
: styles.base({ class: [slotClasses?.base, className] })}
|
|
280
|
-
aria-label={ariaLabel}
|
|
281
|
-
aria-labelledby={ariaLabelledBy}
|
|
305
|
+
aria-label={ariaLabel ?? restProps['aria-label']}
|
|
306
|
+
aria-labelledby={ariaLabelledBy ?? restProps['aria-labelledby']}
|
|
282
307
|
aria-orientation={ariaOrientation}
|
|
283
|
-
aria-disabled={disabled || undefined}
|
|
284
|
-
onkeydown={handleKeyDown}
|
|
285
|
-
{...restProps}
|
|
308
|
+
aria-disabled={disabled || restProps['aria-disabled'] || undefined}
|
|
309
|
+
onkeydown={composeHandlers(handleKeyDown, onkeydownProp)}
|
|
286
310
|
>
|
|
287
311
|
{@render children?.()}
|
|
288
312
|
</div>
|
|
@@ -39,14 +39,24 @@
|
|
|
39
39
|
);
|
|
40
40
|
</script>
|
|
41
41
|
|
|
42
|
+
<!--
|
|
43
|
+
restProps spreads FIRST so component-owned state wins (COMPONENT-API-CONVENTIONS
|
|
44
|
+
§restProps ordering) — a consumer role through restProps must not defeat the
|
|
45
|
+
toolbar semantics. No conditional merges are needed here (unlike
|
|
46
|
+
Button/ButtonGroup), because every attribute after the spread is always
|
|
47
|
+
defined: role is static, `orientation` has a default, and `aria-label` is a
|
|
48
|
+
required prop destructured out of restProps. `aria-orientation` is valid on
|
|
49
|
+
role=toolbar on both arms, so there is no removal case; `aria-labelledby`
|
|
50
|
+
and other native/data-* attributes pass through the spread untouched.
|
|
51
|
+
-->
|
|
42
52
|
<div
|
|
53
|
+
{...restProps}
|
|
43
54
|
class={unstyled
|
|
44
55
|
? [slotClasses?.base, className].filter(Boolean).join(' ')
|
|
45
56
|
: styles.base({ class: [slotClasses?.base, className] })}
|
|
46
57
|
role="toolbar"
|
|
47
58
|
aria-orientation={orientation}
|
|
48
59
|
aria-label={ariaLabel}
|
|
49
|
-
{...restProps}
|
|
50
60
|
>
|
|
51
61
|
{@render children()}
|
|
52
62
|
</div>
|
package/docs/MIGRATION-v5.md
CHANGED
|
@@ -58,10 +58,12 @@ its disclosure sibling `Collapsible`.)
|
|
|
58
58
|
|
|
59
59
|
## 3. Table chrome
|
|
60
60
|
|
|
61
|
-
The Table no longer renders a frame by default. The new `
|
|
62
|
-
controls the container chrome
|
|
61
|
+
The Table no longer renders a frame by default. The new `variant` prop
|
|
62
|
+
controls the container chrome. (The prop was named `appearance` from v5.0
|
|
63
|
+
to v6.32; it now shares the single style-axis name `variant` with every
|
|
64
|
+
other component.)
|
|
63
65
|
|
|
64
|
-
| `
|
|
66
|
+
| `variant` | Effect |
|
|
65
67
|
| ------------ | ------------------------------------------------------------ |
|
|
66
68
|
| `flush` (default) | No frame; the table sits inline in the reading flow. |
|
|
67
69
|
| `surface` | Quiet tinted zone — `bg-surface-quiet`. |
|
|
@@ -73,7 +75,7 @@ The dead `tableVariants` export is removed (was unused in any consumer).
|
|
|
73
75
|
<!-- v4 — implicit frame -->
|
|
74
76
|
<Table data={rows} columns={cols} />
|
|
75
77
|
<!-- v5 — explicit equivalent -->
|
|
76
|
-
<Table data={rows} columns={cols}
|
|
78
|
+
<Table data={rows} columns={cols} variant="framed" />
|
|
77
79
|
<!-- v5 — new editorial default -->
|
|
78
80
|
<Table data={rows} columns={cols} />
|
|
79
81
|
```
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@urbicon-ui/blocks",
|
|
3
|
-
"version": "6.
|
|
3
|
+
"version": "6.33.0",
|
|
4
4
|
"description": "Svelte 5 UI component library with Tailwind CSS 4, OKLCH design tokens and zero runtime dependencies",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"repository": {
|
|
@@ -31,7 +31,8 @@
|
|
|
31
31
|
"format": "biome format --write . && prettier --write \"**/*.svelte\"",
|
|
32
32
|
"lint": "biome check . && svelte-check --tsconfig ./tsconfig.json",
|
|
33
33
|
"test": "vitest",
|
|
34
|
-
"test:run": "vitest run"
|
|
34
|
+
"test:run": "vitest run",
|
|
35
|
+
"size": "bun scripts/bundle-size.ts"
|
|
35
36
|
},
|
|
36
37
|
"files": [
|
|
37
38
|
"LICENSE",
|
|
@@ -94,8 +95,8 @@
|
|
|
94
95
|
"@sveltejs/package": "^2.5.8",
|
|
95
96
|
"@sveltejs/vite-plugin-svelte": "^7.0.0",
|
|
96
97
|
"@tailwindcss/vite": "^4.3.1",
|
|
97
|
-
"@urbicon-ui/i18n": "6.
|
|
98
|
-
"@urbicon-ui/shared-types": "6.
|
|
98
|
+
"@urbicon-ui/i18n": "6.33.0",
|
|
99
|
+
"@urbicon-ui/shared-types": "6.33.0",
|
|
99
100
|
"prettier": "^3.8.4",
|
|
100
101
|
"prettier-plugin-svelte": "^4.1.1",
|
|
101
102
|
"prettier-plugin-tailwindcss": "^0.8.0",
|