@urbicon-ui/blocks 6.23.0 → 6.25.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/README.md +14 -0
- package/dist/components/Calendar/CalendarTimeGrid.svelte +2 -1
- package/dist/components/Calendar/calendar.variants.js +5 -3
- package/dist/components/CommandPalette/CommandPalette.svelte +32 -16
- package/dist/components/CommandPalette/CommandPalette.svelte.d.ts +1 -1
- package/dist/components/CommandPalette/commandPalette.variants.d.ts +10 -0
- package/dist/components/CommandPalette/commandPalette.variants.js +9 -7
- package/dist/components/CommandPalette/index.d.ts +19 -0
- package/dist/components/CompositionBar/CompositionBar.svelte +1 -1
- package/dist/components/CompositionBar/composition-bar.variants.js +1 -1
- package/dist/components/Planner/planner.variants.js +1 -1
- package/dist/components/Sankey/sankey.variants.js +1 -1
- package/dist/components/Sparkline/Sparkline.svelte +10 -4
- package/dist/components/Sparkline/index.d.ts +9 -1
- package/dist/internal/charts/variants.js +2 -2
- package/dist/internal/date-grid/DateGridScaffold.svelte +9 -2
- package/dist/internal/date-grid/date-grid.svelte.d.ts +4 -2
- package/dist/internal/date-grid/date-grid.svelte.js +63 -7
- package/dist/primitives/Avatar/Avatar.svelte +38 -24
- package/dist/primitives/Avatar/index.d.ts +1 -1
- package/dist/primitives/Badge/Badge.svelte +8 -2
- package/dist/primitives/Badge/index.d.ts +67 -32
- package/dist/primitives/Button/Button.svelte +12 -25
- package/dist/primitives/ButtonGroup/ButtonGroup.svelte +5 -1
- package/dist/primitives/Checkbox/Checkbox.svelte +1 -1
- package/dist/primitives/Collapsible/Collapsible.svelte +10 -0
- package/dist/primitives/Collapsible/index.d.ts +13 -2
- package/dist/primitives/ConfirmDialog/ConfirmDialog.svelte +14 -0
- package/dist/primitives/ConfirmDialog/index.d.ts +15 -3
- package/dist/primitives/Dialog/Dialog.svelte +31 -8
- package/dist/primitives/Drawer/Drawer.svelte +29 -7
- package/dist/primitives/Input/Input.svelte +7 -1
- package/dist/primitives/JourneyTimeline/journey-timeline.variants.js +3 -3
- package/dist/primitives/Menu/Menu.svelte +8 -0
- package/dist/primitives/Menu/index.d.ts +11 -13
- package/dist/primitives/Pagination/Pagination.svelte +28 -15
- package/dist/primitives/Popover/Popover.svelte +107 -4
- package/dist/primitives/Popover/index.d.ts +15 -2
- package/dist/primitives/Popover/index.js +1 -1
- package/dist/primitives/Popover/popover.variants.d.ts +25 -0
- package/dist/primitives/Popover/popover.variants.js +35 -0
- package/dist/primitives/Progress/progress.variants.js +1 -1
- package/dist/primitives/RadioGroup/RadioGroup.svelte +6 -2
- package/dist/primitives/RadioGroup/RadioItem.svelte +1 -1
- package/dist/primitives/RadioGroup/radioGroup.variants.js +1 -1
- package/dist/primitives/Select/index.d.ts +8 -1
- package/dist/primitives/Slider/Slider.svelte +32 -3
- package/dist/primitives/Stepper/stepper.variants.js +1 -1
- package/dist/primitives/Textarea/Textarea.svelte +5 -1
- package/dist/primitives/Toast/Toaster.svelte +81 -7
- package/dist/primitives/Toggle/Toggle.svelte +6 -2
- package/dist/primitives/Tooltip/tooltip.variants.js +13 -2
- package/dist/style/foundation.css +30 -3
- package/dist/style/interaction.css +19 -2
- package/dist/style/semantic.css +72 -1
- package/dist/style/themes/neutral.css +10 -1
- package/dist/style/themes/ocean.css +5 -1
- package/dist/utils/compose-handlers.d.ts +72 -0
- package/dist/utils/compose-handlers.js +65 -0
- package/dist/utils/figma-token-export.js +1 -1
- package/dist/utils/guide.svelte.js +92 -29
- package/dist/utils/index.d.ts +1 -1
- package/dist/utils/index.js +1 -1
- package/dist/utils/overlay-tokens.d.ts +17 -0
- package/dist/utils/overlay-tokens.js +30 -0
- package/dist/utils/use-floating-panel.svelte.js +9 -3
- package/dist/utils/variants.js +5 -1
- package/package.json +3 -3
|
@@ -96,10 +96,12 @@ const ROUTE_TARGET_TIMEOUT_MS = 4000;
|
|
|
96
96
|
/**
|
|
97
97
|
* Heuristic: does `landed` look like a router-normalized form of `route` — a trailing slash
|
|
98
98
|
* (`/expenses/`) or a base/locale prefix (`/de/expenses`) — rather than an unrelated redirect target
|
|
99
|
-
* (`/login`)?
|
|
100
|
-
*
|
|
101
|
-
*
|
|
102
|
-
*
|
|
99
|
+
* (`/login`)? On the *synchronous* (re-entrant) path it only tunes DEV diagnostics — `#selfNavigating`
|
|
100
|
+
* is the causal signal there. On the *asynchronous* path (the default source) there is no causal
|
|
101
|
+
* signal, so this heuristic decides own-vs-foreign for a pending navigation: a normalized-looking
|
|
102
|
+
* landing keeps the tour running (DEV-warned, since it is a guess), an unrelated one stops it.
|
|
103
|
+
* `route` is a normalized pathname (leading `/`), so the suffix test lands on a real segment
|
|
104
|
+
* boundary — `/myexpenses` does not end with `/expenses`.
|
|
103
105
|
*/
|
|
104
106
|
function looksLikeNormalizedRoute(landed, route) {
|
|
105
107
|
const stripSlash = (s) => (s.length > 1 && s.endsWith('/') ? s.slice(0, -1) : s);
|
|
@@ -191,9 +193,9 @@ export class GuideController {
|
|
|
191
193
|
* `true` only while our own injected `#navigate()` call is on the stack. A `navigationSource` that
|
|
192
194
|
* reports its location change **synchronously, re-entrant** during that call (SvelteKit's
|
|
193
195
|
* `afterNavigate` fires inside `goto`) IS that very navigation — never a foreign one. This is the
|
|
194
|
-
* exact signal; the
|
|
195
|
-
*
|
|
196
|
-
*
|
|
196
|
+
* exact signal; the `#expectedRoute` matching in `#onLocationChange` (exact path, or a
|
|
197
|
+
* `looksLikeNormalizedRoute` landing for a router that normalizes) is only an async-source proxy
|
|
198
|
+
* for the same thing.
|
|
197
199
|
*
|
|
198
200
|
* A boolean (not a depth counter) is enough: the sole re-entrant callee of a sync source is
|
|
199
201
|
* `#onLocationChange`, which never calls `#maybeNavigate`. A `navigate` hook that *synchronously*
|
|
@@ -202,6 +204,16 @@ export class GuideController {
|
|
|
202
204
|
* never open, so it can't keep a genuinely foreign navigation alive.
|
|
203
205
|
*/
|
|
204
206
|
#selfNavigating = false;
|
|
207
|
+
/**
|
|
208
|
+
* Own navigations superseded before their report arrived — a rapid `next()`/`prev()` while the
|
|
209
|
+
* previous step's navigation was still in flight moves its `#expectedRoute` here instead of
|
|
210
|
+
* dropping it, so the late report is still recognized as the tour's own (not a foreign stop).
|
|
211
|
+
* Entries live only until the *current* navigation settles (report, or target resolve) or the
|
|
212
|
+
* tour tears down — bounding the window in which a genuinely foreign visit to one of these paths
|
|
213
|
+
* would be misread as ours. A plain `Set` — pure bookkeeping, never rendered, so the `SvelteSet`
|
|
214
|
+
* rule doesn't apply.
|
|
215
|
+
*/
|
|
216
|
+
#supersededRoutes = new Set();
|
|
205
217
|
/** Last path the tour is known to be on — set at start, updated on each handled navigation. */
|
|
206
218
|
#knownPath = '';
|
|
207
219
|
/** Unsubscribe from the navigation source; non-null only while a route-using tour runs. */
|
|
@@ -487,8 +499,14 @@ export class GuideController {
|
|
|
487
499
|
*/
|
|
488
500
|
#maybeNavigate() {
|
|
489
501
|
// Each step starts with a clean slate — no navigation is pending until we trigger one below.
|
|
490
|
-
// (A step that doesn't navigate must not inherit the previous step's `expectedRoute`.)
|
|
491
|
-
|
|
502
|
+
// (A step that doesn't navigate must not inherit the previous step's `expectedRoute`.) A
|
|
503
|
+
// pending navigation superseded here (rapid next/prev while it was still in flight) is
|
|
504
|
+
// remembered: its report may land *after* this step activates, and must still be read as the
|
|
505
|
+
// tour's own navigation — not a foreign one that stops the tour (async epoch race).
|
|
506
|
+
if (this.#expectedRoute !== null) {
|
|
507
|
+
this.#supersededRoutes.add(this.#expectedRoute);
|
|
508
|
+
this.#expectedRoute = null;
|
|
509
|
+
}
|
|
492
510
|
const route = this.currentStep?.route;
|
|
493
511
|
if (route == null)
|
|
494
512
|
return;
|
|
@@ -539,27 +557,53 @@ export class GuideController {
|
|
|
539
557
|
this.#expectedRoute = null;
|
|
540
558
|
this.#clearRouteTargetWarning();
|
|
541
559
|
}
|
|
560
|
+
/** Does `path` look like `route`'s landing — exact, or a router-normalized form of it? */
|
|
561
|
+
#isOwnLanding(path, route) {
|
|
562
|
+
return path === route || looksLikeNormalizedRoute(path, route);
|
|
563
|
+
}
|
|
542
564
|
/**
|
|
543
565
|
* React to a navigation observed while a route-using tour runs. A navigation that is the tour's own
|
|
544
|
-
* — reported synchronously during our `#navigate()` call (`#selfNavigating`),
|
|
545
|
-
*
|
|
566
|
+
* — reported synchronously during our `#navigate()` call (`#selfNavigating`), matching the pending
|
|
567
|
+
* `#expectedRoute` (exactly, or as a router-normalized landing), or matching a navigation this tour
|
|
568
|
+
* triggered and then superseded — keeps it running (the ring lands via the surface's
|
|
546
569
|
* `reapplyStepHighlight`). Any other navigation is foreign — the user left, or a
|
|
547
570
|
* youngest-gesture-wins race — and tears the tour down, analytics-silent (`stopTour`).
|
|
548
571
|
*/
|
|
549
572
|
#onLocationChange(path) {
|
|
550
573
|
if (!this.#activeTour)
|
|
551
574
|
return;
|
|
552
|
-
if (path === this.#knownPath)
|
|
553
|
-
|
|
575
|
+
if (path === this.#knownPath) {
|
|
576
|
+
// No pathname change (a hash/query update, or a re-report of the path we're already on).
|
|
577
|
+
// A same-path report can still BE the pending navigation's landing: two consecutive steps on
|
|
578
|
+
// the same logical route under a normalizing router re-navigate without the pathname ever
|
|
579
|
+
// changing. A *targetless* step settles on landing, so clear its expectation here too —
|
|
580
|
+
// skipping that (the pre-fix behavior) armed a misleading "navigated toward …" DEV warning
|
|
581
|
+
// on the next genuine foreign navigation. (A *targeted* step keeps the expectation until its
|
|
582
|
+
// target resolves, exactly like the main own-navigation branch below.)
|
|
583
|
+
if (this.#expectedRoute !== null &&
|
|
584
|
+
this.currentStep?.target == null &&
|
|
585
|
+
(this.#selfNavigating || this.#isOwnLanding(path, this.#expectedRoute))) {
|
|
586
|
+
this.#expectedRoute = null;
|
|
587
|
+
}
|
|
588
|
+
return;
|
|
589
|
+
}
|
|
554
590
|
this.#knownPath = path;
|
|
555
|
-
const
|
|
556
|
-
|
|
557
|
-
//
|
|
558
|
-
//
|
|
591
|
+
const expected = this.#expectedRoute;
|
|
592
|
+
const matchesExpected = expected !== null && path === expected;
|
|
593
|
+
// With an *async* source (the default) `#selfNavigating` is already false by the time the report
|
|
594
|
+
// lands, so recognizing the tour's own navigation falls to path matching. Exact-only matching
|
|
595
|
+
// false-stopped the tour on a router-normalized landing (`/expenses/`, `/de/expenses`) for a raw
|
|
596
|
+
// `step.route` — the async form of #41 — so a normalized-looking landing for the pending route
|
|
597
|
+
// counts as ours too (a heuristic, hence DEV-warned below; the sync path has the causal signal
|
|
598
|
+
// and stays silent).
|
|
599
|
+
const matchesNormalized = expected !== null && !matchesExpected && looksLikeNormalizedRoute(path, expected);
|
|
600
|
+
// A location report is the tour's OWN navigation when it matches the pending `#expectedRoute`
|
|
601
|
+
// (exactly or normalized — the async-source proxy, for a report landing a tick after the hook
|
|
602
|
+
// returns), or when it arrives synchronously, re-entrant, during our injected `#navigate()` call
|
|
559
603
|
// (`#selfNavigating`). The latter is a *causal* signal — our navigate produced this report,
|
|
560
|
-
// whatever path it carries — so it covers a
|
|
561
|
-
//
|
|
562
|
-
if (this.#selfNavigating || matchesExpected) {
|
|
604
|
+
// whatever path it carries — so it also covers a synchronous redirect an exact or normalized
|
|
605
|
+
// match would miss. Either keeps the tour running.
|
|
606
|
+
if (this.#selfNavigating || matchesExpected || matchesNormalized) {
|
|
563
607
|
// A *synchronous* report on a path that isn't the expected route is still causally ours, but it
|
|
564
608
|
// landed somewhere unexpected: a normalized variant of `step.route` (fine — the target anchors
|
|
565
609
|
// once it mounts) or a genuine redirect off the route (an auth guard → `/login`). We keep
|
|
@@ -569,11 +613,20 @@ export class GuideController {
|
|
|
569
613
|
// bubble is otherwise invisible in both DEV and PROD.)
|
|
570
614
|
if (this.#dev &&
|
|
571
615
|
this.#selfNavigating &&
|
|
572
|
-
|
|
616
|
+
expected !== null &&
|
|
573
617
|
!matchesExpected &&
|
|
574
|
-
!
|
|
575
|
-
console.warn(`[Guide] tour "${this.#activeTour?.id}" navigated toward "${
|
|
618
|
+
!matchesNormalized) {
|
|
619
|
+
console.warn(`[Guide] tour "${this.#activeTour?.id}" navigated toward "${expected}" but synchronously landed on "${path}" — keeping the tour running as its own navigation. If this was a redirect off the step's route (not a normalized form of it), stop the tour explicitly from your router guard.`);
|
|
576
620
|
}
|
|
621
|
+
else if (this.#dev && !this.#selfNavigating && matchesNormalized) {
|
|
622
|
+
// The async normalized match is a guess (no causal signal) — keep running, but surface it so
|
|
623
|
+
// the consumer can make the match exact.
|
|
624
|
+
console.warn(`[Guide] tour "${this.#activeTour?.id}" navigated toward "${expected}" and landed on "${path}" — treating it as the router's normalized form of the step route and keeping the tour running. Set step.route to the router's actual landed path to make the match exact.`);
|
|
625
|
+
}
|
|
626
|
+
// The current navigation reported → any older superseded navigation can no longer report
|
|
627
|
+
// (navigation reports arrive in order), so drop those epochs — a later *foreign* visit to one
|
|
628
|
+
// of their paths must stop the tour again.
|
|
629
|
+
this.#supersededRoutes.clear();
|
|
577
630
|
// For a *targeted* step, keep `#expectedRoute` set until the target settles
|
|
578
631
|
// (`#applyStepHighlight`) so a redirecting / multi-hop source (the Navigation API emitting one
|
|
579
632
|
// event per hop) firing a *second* event for the redirect target is still recognized as a
|
|
@@ -586,12 +639,20 @@ export class GuideController {
|
|
|
586
639
|
this.#expectedRoute = null;
|
|
587
640
|
return;
|
|
588
641
|
}
|
|
589
|
-
//
|
|
590
|
-
//
|
|
591
|
-
//
|
|
592
|
-
//
|
|
593
|
-
|
|
594
|
-
|
|
642
|
+
// A late report of a navigation this tour triggered and then superseded (rapid next/prev while
|
|
643
|
+
// it was still in flight) is causally ours — keep running and keep waiting for the *current*
|
|
644
|
+
// navigation's own report. Silent: the route was recorded causally in `#maybeNavigate`; only
|
|
645
|
+
// its normalization is heuristic. (Trade-off, bounded by the in-flight window: a genuinely
|
|
646
|
+
// foreign visit to one of these paths during that window is misread as ours.)
|
|
647
|
+
for (const superseded of this.#supersededRoutes) {
|
|
648
|
+
if (this.#isOwnLanding(path, superseded))
|
|
649
|
+
return;
|
|
650
|
+
}
|
|
651
|
+
// Any other navigation stops the tour (analytics-silent). When one was pending, surface the
|
|
652
|
+
// mismatch in DEV instead of tearing down silently — with normalized landings recognized above,
|
|
653
|
+
// reaching this with a pending route means a genuinely unrelated landing (e.g. a redirect).
|
|
654
|
+
if (this.#dev && expected !== null) {
|
|
655
|
+
console.warn(`[Guide] tour "${this.#activeTour?.id}" navigated toward "${expected}" but landed on "${path}" — stopping as a foreign navigation (the landed path is not a normalized form of the step's route either).`);
|
|
595
656
|
}
|
|
596
657
|
this.#expectedRoute = null;
|
|
597
658
|
this.stopTour();
|
|
@@ -640,6 +701,7 @@ export class GuideController {
|
|
|
640
701
|
this.#navUnsub?.();
|
|
641
702
|
this.#navUnsub = null;
|
|
642
703
|
this.#expectedRoute = null;
|
|
704
|
+
this.#supersededRoutes.clear();
|
|
643
705
|
this.clearHighlight();
|
|
644
706
|
this.#tourUnregister?.();
|
|
645
707
|
this.#tourUnregister = null;
|
|
@@ -691,6 +753,7 @@ export class GuideController {
|
|
|
691
753
|
this.highlight(step.target, { scroll: true });
|
|
692
754
|
this.#clearRouteTargetWarning(); // target landed → no "never appeared" warning needed
|
|
693
755
|
this.#expectedRoute = null; // the navigated-to target resolved → navigation fully settled
|
|
756
|
+
this.#supersededRoutes.clear(); // …and with it every older, superseded navigation epoch
|
|
694
757
|
}
|
|
695
758
|
else {
|
|
696
759
|
this.clearHighlight();
|
package/dist/utils/index.d.ts
CHANGED
|
@@ -7,7 +7,7 @@ export * from './id.js';
|
|
|
7
7
|
export { observeTargetResolution } from './observe-target.js';
|
|
8
8
|
export { createOptionalContext } from './optional-context.js';
|
|
9
9
|
export { overlayStack } from './overlay-stack.svelte.js';
|
|
10
|
-
export { type EasingFn, getOverlayMotion, OVERLAY_MOTION_DEFAULTS, type OverlayMotion, type OverlayMotionOverride } from './overlay-tokens.js';
|
|
10
|
+
export { type EasingFn, getOverlayMotion, maxTransitionDurationMs, OVERLAY_MOTION_DEFAULTS, type OverlayMotion, type OverlayMotionOverride } from './overlay-tokens.js';
|
|
11
11
|
export * from './persistent-state.svelte.js';
|
|
12
12
|
export { edgeEnabledIndex, nextEnabledIndex } from './roving.js';
|
|
13
13
|
export { getTierContext, type InteractiveTier, setTierContext, type TierContext } from './tier-context.js';
|
package/dist/utils/index.js
CHANGED
|
@@ -7,7 +7,7 @@ export * from './id.js';
|
|
|
7
7
|
export { observeTargetResolution } from './observe-target.js';
|
|
8
8
|
export { createOptionalContext } from './optional-context.js';
|
|
9
9
|
export { overlayStack } from './overlay-stack.svelte.js';
|
|
10
|
-
export { getOverlayMotion, OVERLAY_MOTION_DEFAULTS } from './overlay-tokens.js';
|
|
10
|
+
export { getOverlayMotion, maxTransitionDurationMs, OVERLAY_MOTION_DEFAULTS } from './overlay-tokens.js';
|
|
11
11
|
export * from './persistent-state.svelte.js';
|
|
12
12
|
export { edgeEnabledIndex, nextEnabledIndex } from './roving.js';
|
|
13
13
|
export { getTierContext, setTierContext } from './tier-context.js';
|
|
@@ -45,6 +45,23 @@ export interface OverlayMotionOverride {
|
|
|
45
45
|
}
|
|
46
46
|
/** Defaults mirror the CSS custom properties in `interaction.css`. */
|
|
47
47
|
export declare const OVERLAY_MOTION_DEFAULTS: OverlayMotion;
|
|
48
|
+
/**
|
|
49
|
+
* Longest `transition-duration` currently applying to an element, in ms.
|
|
50
|
+
*
|
|
51
|
+
* Used by Popover's exit-motion lag: the panel's CSS transition (token-driven,
|
|
52
|
+
* per-instance-overridable, collapsed by reduced motion) is the single source
|
|
53
|
+
* of truth for how long closed content must stay mounted, so the lag is read
|
|
54
|
+
* from the live computed style instead of duplicating the token resolution in
|
|
55
|
+
* JS. Returns `0` when the element is missing, has no transition, or the
|
|
56
|
+
* environment has no CSS engine (SSR, jsdom) — callers then tear down
|
|
57
|
+
* synchronously, which keeps unstyled consumers and node tests on the
|
|
58
|
+
* pre-motion behaviour.
|
|
59
|
+
*
|
|
60
|
+
* `transition-duration` computes to a comma list (one entry per transition
|
|
61
|
+
* property); the max governs because the exit isn't over until the slowest
|
|
62
|
+
* property lands.
|
|
63
|
+
*/
|
|
64
|
+
export declare function maxTransitionDurationMs(el: Element | null | undefined): number;
|
|
48
65
|
/**
|
|
49
66
|
* Read the current overlay motion settings.
|
|
50
67
|
*
|
|
@@ -28,6 +28,36 @@ export const OVERLAY_MOTION_DEFAULTS = {
|
|
|
28
28
|
panelScaleStart: 0.96,
|
|
29
29
|
panelFlyDistance: 320
|
|
30
30
|
};
|
|
31
|
+
/**
|
|
32
|
+
* Longest `transition-duration` currently applying to an element, in ms.
|
|
33
|
+
*
|
|
34
|
+
* Used by Popover's exit-motion lag: the panel's CSS transition (token-driven,
|
|
35
|
+
* per-instance-overridable, collapsed by reduced motion) is the single source
|
|
36
|
+
* of truth for how long closed content must stay mounted, so the lag is read
|
|
37
|
+
* from the live computed style instead of duplicating the token resolution in
|
|
38
|
+
* JS. Returns `0` when the element is missing, has no transition, or the
|
|
39
|
+
* environment has no CSS engine (SSR, jsdom) — callers then tear down
|
|
40
|
+
* synchronously, which keeps unstyled consumers and node tests on the
|
|
41
|
+
* pre-motion behaviour.
|
|
42
|
+
*
|
|
43
|
+
* `transition-duration` computes to a comma list (one entry per transition
|
|
44
|
+
* property); the max governs because the exit isn't over until the slowest
|
|
45
|
+
* property lands.
|
|
46
|
+
*/
|
|
47
|
+
export function maxTransitionDurationMs(el) {
|
|
48
|
+
if (!el || typeof window === 'undefined')
|
|
49
|
+
return 0;
|
|
50
|
+
const raw = getComputedStyle(el).transitionDuration;
|
|
51
|
+
if (!raw)
|
|
52
|
+
return 0;
|
|
53
|
+
let max = 0;
|
|
54
|
+
for (const part of raw.split(',')) {
|
|
55
|
+
const ms = parseDurationMs(part, 0);
|
|
56
|
+
if (ms > max)
|
|
57
|
+
max = ms;
|
|
58
|
+
}
|
|
59
|
+
return max;
|
|
60
|
+
}
|
|
31
61
|
function parseDurationMs(value, fallback) {
|
|
32
62
|
if (!value)
|
|
33
63
|
return fallback;
|
|
@@ -80,9 +80,11 @@ export function useFloatingPanel(opts) {
|
|
|
80
80
|
if (!isOpen || !ref) {
|
|
81
81
|
cleanupPosition?.();
|
|
82
82
|
cleanupPosition = undefined;
|
|
83
|
-
//
|
|
84
|
-
//
|
|
85
|
-
|
|
83
|
+
// The keyboard-aware height clamp is deliberately NOT dropped here: the
|
|
84
|
+
// panel may still be painting its CSS exit transition (allow-discrete /
|
|
85
|
+
// Popover's lagged display), and un-clamping mid-fade would let clamped
|
|
86
|
+
// content grow while it fades out. The show path below resets it before
|
|
87
|
+
// the next open instead.
|
|
86
88
|
// Guard on the live `:popover-open` state only (not the current mode):
|
|
87
89
|
// a panel that was promoted to the top layer must still be torn down even
|
|
88
90
|
// if its mode has since flipped to `fixed`/`inline`.
|
|
@@ -102,6 +104,10 @@ export function useFloatingPanel(opts) {
|
|
|
102
104
|
}
|
|
103
105
|
if (zIndexValue)
|
|
104
106
|
floating.style.zIndex = zIndexValue;
|
|
107
|
+
// Drop the previous open's keyboard-aware height clamp before showing, so
|
|
108
|
+
// this open re-measures from the full design cap instead of inheriting a
|
|
109
|
+
// stale value. (Moved off the hide path — see the comment there.)
|
|
110
|
+
floating.style.removeProperty('--blocks-overlay-available-height');
|
|
105
111
|
if (useTopLayer && !floating.matches(':popover-open')) {
|
|
106
112
|
try {
|
|
107
113
|
floating.showPopover();
|
package/dist/utils/variants.js
CHANGED
|
@@ -232,7 +232,11 @@ const BUCKET_PATTERNS = [
|
|
|
232
232
|
[/^text-shadow-(2xs|xs|sm|md|lg|none)$/, 'text-shadow'],
|
|
233
233
|
[/^text-shadow$/, 'text-shadow'],
|
|
234
234
|
[/^text-shadow-/, 'text-shadow-color'],
|
|
235
|
-
|
|
235
|
+
// `\d+xs` covers the library's sub-xs scale (--text-2xs/--text-3xs in
|
|
236
|
+
// foundation.css) and mirrors `\d+xl` for consumer-added steps. Without it
|
|
237
|
+
// `text-2xs` falls through to the text-color catch-all below, so a color
|
|
238
|
+
// override would silently strip the font size.
|
|
239
|
+
[/^text-(\d+xs|xs|sm|base|lg|xl|\d+xl)(\/[\w.-]+)?$/, 'text-size'],
|
|
236
240
|
// Data-type hints disambiguate the overloaded `text-` arbitraries.
|
|
237
241
|
[/^text-\[length:/, 'text-size'],
|
|
238
242
|
[/^text-\[color:/, 'text-color'],
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@urbicon-ui/blocks",
|
|
3
|
-
"version": "6.
|
|
3
|
+
"version": "6.25.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": {
|
|
@@ -91,8 +91,8 @@
|
|
|
91
91
|
"@sveltejs/package": "^2.5.8",
|
|
92
92
|
"@sveltejs/vite-plugin-svelte": "^7.0.0",
|
|
93
93
|
"@tailwindcss/vite": "^4.3.1",
|
|
94
|
-
"@urbicon-ui/i18n": "6.
|
|
95
|
-
"@urbicon-ui/shared-types": "6.
|
|
94
|
+
"@urbicon-ui/i18n": "6.25.0",
|
|
95
|
+
"@urbicon-ui/shared-types": "6.25.0",
|
|
96
96
|
"prettier": "^3.8.4",
|
|
97
97
|
"prettier-plugin-svelte": "^4.1.1",
|
|
98
98
|
"prettier-plugin-tailwindcss": "^0.8.0",
|