@urbicon-ui/blocks 6.7.2 → 6.8.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/Guide/GuideProvider.svelte +4 -3
- package/dist/components/Guide/index.d.ts +8 -1
- package/dist/i18n/index.d.ts +2 -342
- package/dist/utils/guide.svelte.d.ts +52 -0
- package/dist/utils/guide.svelte.js +212 -8
- package/dist/utils/index.d.ts +1 -1
- package/dist/utils/index.js +1 -1
- package/package.json +3 -3
|
@@ -3,14 +3,15 @@
|
|
|
3
3
|
import type { GuideProviderProps } from './index';
|
|
4
4
|
import { setGuideContext } from './guide.context';
|
|
5
5
|
|
|
6
|
-
let { storage, controller, children }: GuideProviderProps = $props();
|
|
6
|
+
let { storage, navigate, controller, children }: GuideProviderProps = $props();
|
|
7
7
|
|
|
8
8
|
// Use a consumer-supplied controller (for programmatic access from outside the provider)
|
|
9
9
|
// or create one. Built once from the initial props — a stable controller/adapter is
|
|
10
10
|
// expected, so later prop changes are intentionally ignored. SSR-safe: the default
|
|
11
|
-
// adapter only touches localStorage inside load/save.
|
|
11
|
+
// adapter only touches localStorage inside load/save. `storage`/`navigate` are ignored
|
|
12
|
+
// when a `controller` is supplied (it already carries them).
|
|
12
13
|
// svelte-ignore state_referenced_locally
|
|
13
|
-
const instance = controller ?? new GuideController({ storage });
|
|
14
|
+
const instance = controller ?? new GuideController({ storage, navigate });
|
|
14
15
|
setGuideContext(instance);
|
|
15
16
|
</script>
|
|
16
17
|
|
|
@@ -30,10 +30,17 @@ import type { GuideArticleSlots, GuideBeaconSlots, GuideBeaconVariants, GuideHin
|
|
|
30
30
|
export interface GuideProviderProps {
|
|
31
31
|
/** Persistence adapter for "seen" state (tours/hints). @default localStorage-backed adapter */
|
|
32
32
|
storage?: GuideStorageAdapter;
|
|
33
|
+
/**
|
|
34
|
+
* Navigation hook for declarative cross-route tours, forwarded to the internally created
|
|
35
|
+
* controller. A SvelteKit consumer wires `(route) => goto(route)`; a step's `route` then
|
|
36
|
+
* navigates before its spotlight. Ignored when a `controller` is supplied (set it there).
|
|
37
|
+
* @default undefined
|
|
38
|
+
*/
|
|
39
|
+
navigate?: (route: string) => void | Promise<void>;
|
|
33
40
|
/**
|
|
34
41
|
* Supply a pre-created `GuideController` for programmatic access from outside the provider
|
|
35
42
|
* (start tours, open the panel, query `hasSeen`). When omitted, the provider creates one
|
|
36
|
-
* internally and shares it via context. When supplied, `storage`
|
|
43
|
+
* internally and shares it via context. When supplied, `storage` and `navigate` are ignored.
|
|
37
44
|
*/
|
|
38
45
|
controller?: GuideController;
|
|
39
46
|
/** App subtree wired to the Guide context. */
|
package/dist/i18n/index.d.ts
CHANGED
|
@@ -343,177 +343,7 @@ declare const blocksTranslations: {
|
|
|
343
343
|
};
|
|
344
344
|
};
|
|
345
345
|
};
|
|
346
|
-
export declare const blocksI18n: import("@urbicon-ui/i18n").PackageI18n<
|
|
347
|
-
readonly accessibility: {
|
|
348
|
-
readonly avatar: "Avatar";
|
|
349
|
-
readonly clearInput: "Clear input";
|
|
350
|
-
readonly clearSearch: "Clear search";
|
|
351
|
-
readonly clearSelection: "Clear selection";
|
|
352
|
-
readonly closeDialog: "Close dialog";
|
|
353
|
-
readonly closeDrawer: "Close drawer";
|
|
354
|
-
readonly dismiss: "Dismiss";
|
|
355
|
-
readonly fileUpload: "File upload";
|
|
356
|
-
readonly loading: "Loading";
|
|
357
|
-
readonly maximum: "Maximum";
|
|
358
|
-
readonly minimum: "Minimum";
|
|
359
|
-
readonly pagination: "Page navigation";
|
|
360
|
-
readonly progress: "Progress";
|
|
361
|
-
readonly slider: "Slider";
|
|
362
|
-
readonly toggle: "Toggle";
|
|
363
|
-
readonly toggleOptions: "Toggle options";
|
|
364
|
-
readonly removableBadge: "Removable badge";
|
|
365
|
-
readonly removeBadge: "Remove badge";
|
|
366
|
-
readonly removeFile: "Remove {{name}}";
|
|
367
|
-
};
|
|
368
|
-
readonly button: {
|
|
369
|
-
readonly close: "Close";
|
|
370
|
-
readonly apply: "Apply";
|
|
371
|
-
readonly cancel: "Cancel";
|
|
372
|
-
readonly confirm: "Confirm";
|
|
373
|
-
};
|
|
374
|
-
readonly menu: {
|
|
375
|
-
readonly placeholder: "Select an option...";
|
|
376
|
-
};
|
|
377
|
-
readonly common: {
|
|
378
|
-
readonly loading: "Loading...";
|
|
379
|
-
};
|
|
380
|
-
readonly languages: {
|
|
381
|
-
readonly de: "Deutsch";
|
|
382
|
-
readonly en: "English";
|
|
383
|
-
readonly es: "Español";
|
|
384
|
-
readonly fr: "Français";
|
|
385
|
-
readonly it: "Italiano";
|
|
386
|
-
readonly nl: "Nederlands";
|
|
387
|
-
};
|
|
388
|
-
readonly localeSwitcher: {
|
|
389
|
-
readonly ariaLabel: "Language selection";
|
|
390
|
-
readonly placeholder: "Select language...";
|
|
391
|
-
};
|
|
392
|
-
readonly pagination: {
|
|
393
|
-
readonly next: "Next";
|
|
394
|
-
readonly first: "First";
|
|
395
|
-
readonly last: "Last";
|
|
396
|
-
readonly page: "Page";
|
|
397
|
-
readonly previous: "Previous";
|
|
398
|
-
};
|
|
399
|
-
readonly calendar: {
|
|
400
|
-
readonly recurring: "Recurring event";
|
|
401
|
-
readonly previousMonth: "Previous month";
|
|
402
|
-
readonly nextMonth: "Next month";
|
|
403
|
-
readonly previousWeek: "Previous week";
|
|
404
|
-
readonly nextWeek: "Next week";
|
|
405
|
-
readonly previousDay: "Previous day";
|
|
406
|
-
readonly nextDay: "Next day";
|
|
407
|
-
readonly previousYear: "Previous year";
|
|
408
|
-
readonly nextYear: "Next year";
|
|
409
|
-
readonly today: "Today";
|
|
410
|
-
readonly calendarGrid: "Calendar";
|
|
411
|
-
readonly weekdays: "Weekdays";
|
|
412
|
-
readonly weekNumber: "Week number";
|
|
413
|
-
readonly events: "Events";
|
|
414
|
-
readonly noEvents: "No events";
|
|
415
|
-
readonly showMore: "{{count}} more";
|
|
416
|
-
readonly legend: "Legend";
|
|
417
|
-
readonly yearView: "Year overview";
|
|
418
|
-
readonly weekView: "Week view";
|
|
419
|
-
readonly dayView: "Day view";
|
|
420
|
-
readonly monthView: "Month view";
|
|
421
|
-
readonly viewMonth: "Month";
|
|
422
|
-
readonly viewYear: "Year";
|
|
423
|
-
readonly viewWeek: "Week";
|
|
424
|
-
readonly viewDay: "Day";
|
|
425
|
-
readonly multiDayLabel: "Day {{current}} of {{total}}";
|
|
426
|
-
readonly agendaView: "Agenda view";
|
|
427
|
-
readonly viewAgenda: "Agenda";
|
|
428
|
-
readonly viewSwitcher: "View mode";
|
|
429
|
-
};
|
|
430
|
-
readonly planner: {
|
|
431
|
-
readonly previousWeek: "Previous week";
|
|
432
|
-
readonly nextWeek: "Next week";
|
|
433
|
-
readonly previousMonth: "Previous month";
|
|
434
|
-
readonly nextMonth: "Next month";
|
|
435
|
-
readonly previousRange: "Previous range";
|
|
436
|
-
readonly nextRange: "Next range";
|
|
437
|
-
readonly today: "Today";
|
|
438
|
-
readonly grid: "Planner";
|
|
439
|
-
readonly weekNumber: "Week number";
|
|
440
|
-
readonly itemCount: "{{count}} items";
|
|
441
|
-
};
|
|
442
|
-
readonly commandPalette: {
|
|
443
|
-
readonly noResults: "No results found.";
|
|
444
|
-
readonly search: "Search...";
|
|
445
|
-
readonly hints: {
|
|
446
|
-
readonly navigate: "Navigate";
|
|
447
|
-
readonly select: "Select";
|
|
448
|
-
readonly close: "Close";
|
|
449
|
-
};
|
|
450
|
-
};
|
|
451
|
-
readonly compositionBar: {
|
|
452
|
-
readonly total: "Total";
|
|
453
|
-
readonly summary: "Composition: {{total}} ({{count}} shares) — {{parts}}";
|
|
454
|
-
readonly share: "Share";
|
|
455
|
-
readonly value: "Value";
|
|
456
|
-
readonly percent: "Percent";
|
|
457
|
-
readonly remaining: "remaining";
|
|
458
|
-
};
|
|
459
|
-
readonly guide: {
|
|
460
|
-
readonly next: "Next";
|
|
461
|
-
readonly previous: "Back";
|
|
462
|
-
readonly skip: "Skip tour";
|
|
463
|
-
readonly done: "Done";
|
|
464
|
-
readonly step: "Step {{current}} of {{total}}";
|
|
465
|
-
readonly tour: "Guided tour";
|
|
466
|
-
readonly close: "Close";
|
|
467
|
-
readonly openHelp: "Help";
|
|
468
|
-
readonly backToList: "All topics";
|
|
469
|
-
readonly info: "More information";
|
|
470
|
-
readonly infoAbout: "More information about {{label}}";
|
|
471
|
-
readonly dismiss: "Dismiss hint";
|
|
472
|
-
readonly startTour: "Start the guided tour";
|
|
473
|
-
readonly actionRequired: "Complete the highlighted action to continue";
|
|
474
|
-
readonly filterPlaceholder: "Filter topics…";
|
|
475
|
-
readonly noResults: "No matching topics";
|
|
476
|
-
};
|
|
477
|
-
readonly datepicker: {
|
|
478
|
-
readonly placeholder: "Select a date...";
|
|
479
|
-
readonly rangePlaceholder: "Select a date range...";
|
|
480
|
-
readonly clear: "Clear selection";
|
|
481
|
-
readonly openCalendar: "Open calendar";
|
|
482
|
-
readonly invalidDate: "Invalid date";
|
|
483
|
-
readonly outOfRange: "Date is outside the allowed range";
|
|
484
|
-
readonly invalidRange: "Invalid date range";
|
|
485
|
-
};
|
|
486
|
-
readonly fileUpload: {
|
|
487
|
-
readonly exists: "File already added";
|
|
488
|
-
readonly invalidType: "File type {{type}} is not allowed";
|
|
489
|
-
readonly tooLarge: "File exceeds {{size}} limit";
|
|
490
|
-
readonly tooMany: "Maximum {{count}} files allowed";
|
|
491
|
-
readonly tooSmall: "File must be at least {{size}}";
|
|
492
|
-
};
|
|
493
|
-
readonly sankey: {
|
|
494
|
-
readonly summary: "Sankey diagram: {{nodes}} nodes, {{links}} links — {{flows}}";
|
|
495
|
-
readonly source: "Source";
|
|
496
|
-
readonly target: "Target";
|
|
497
|
-
readonly value: "Value";
|
|
498
|
-
};
|
|
499
|
-
readonly slider: {
|
|
500
|
-
readonly rangeStatus: {
|
|
501
|
-
readonly insideRecommended: "In recommended range";
|
|
502
|
-
readonly insideValid: "In valid range";
|
|
503
|
-
readonly insideValidOnly: "Outside recommended range, but valid";
|
|
504
|
-
readonly outsideValid: "Outside valid range";
|
|
505
|
-
};
|
|
506
|
-
};
|
|
507
|
-
readonly themeSwitcher: {
|
|
508
|
-
readonly lightMode: "Light mode";
|
|
509
|
-
readonly darkMode: "Dark mode";
|
|
510
|
-
readonly systemTheme: "System theme";
|
|
511
|
-
};
|
|
512
|
-
readonly time: {
|
|
513
|
-
readonly ago: "{{value}} {{unit}} ago";
|
|
514
|
-
readonly now: "now";
|
|
515
|
-
};
|
|
516
|
-
}>;
|
|
346
|
+
export declare const blocksI18n: import("@urbicon-ui/i18n").PackageI18n<import("@urbicon-ui/i18n").Translations>;
|
|
517
347
|
/**
|
|
518
348
|
* Context-scoped translation hook for the blocks package. Call during component
|
|
519
349
|
* initialisation, then use the returned `t` (conventionally aliased `bt`):
|
|
@@ -526,177 +356,7 @@ export declare const blocksI18n: import("@urbicon-ui/i18n").PackageI18n<{
|
|
|
526
356
|
* Resolves against the nearest `<I18nProvider>`'s locale (or the base locale
|
|
527
357
|
* when none is mounted) and re-renders reactively on locale change.
|
|
528
358
|
*/
|
|
529
|
-
export declare const useBlocksI18n:
|
|
530
|
-
readonly accessibility: {
|
|
531
|
-
readonly avatar: "Avatar";
|
|
532
|
-
readonly clearInput: "Clear input";
|
|
533
|
-
readonly clearSearch: "Clear search";
|
|
534
|
-
readonly clearSelection: "Clear selection";
|
|
535
|
-
readonly closeDialog: "Close dialog";
|
|
536
|
-
readonly closeDrawer: "Close drawer";
|
|
537
|
-
readonly dismiss: "Dismiss";
|
|
538
|
-
readonly fileUpload: "File upload";
|
|
539
|
-
readonly loading: "Loading";
|
|
540
|
-
readonly maximum: "Maximum";
|
|
541
|
-
readonly minimum: "Minimum";
|
|
542
|
-
readonly pagination: "Page navigation";
|
|
543
|
-
readonly progress: "Progress";
|
|
544
|
-
readonly slider: "Slider";
|
|
545
|
-
readonly toggle: "Toggle";
|
|
546
|
-
readonly toggleOptions: "Toggle options";
|
|
547
|
-
readonly removableBadge: "Removable badge";
|
|
548
|
-
readonly removeBadge: "Remove badge";
|
|
549
|
-
readonly removeFile: "Remove {{name}}";
|
|
550
|
-
};
|
|
551
|
-
readonly button: {
|
|
552
|
-
readonly close: "Close";
|
|
553
|
-
readonly apply: "Apply";
|
|
554
|
-
readonly cancel: "Cancel";
|
|
555
|
-
readonly confirm: "Confirm";
|
|
556
|
-
};
|
|
557
|
-
readonly menu: {
|
|
558
|
-
readonly placeholder: "Select an option...";
|
|
559
|
-
};
|
|
560
|
-
readonly common: {
|
|
561
|
-
readonly loading: "Loading...";
|
|
562
|
-
};
|
|
563
|
-
readonly languages: {
|
|
564
|
-
readonly de: "Deutsch";
|
|
565
|
-
readonly en: "English";
|
|
566
|
-
readonly es: "Español";
|
|
567
|
-
readonly fr: "Français";
|
|
568
|
-
readonly it: "Italiano";
|
|
569
|
-
readonly nl: "Nederlands";
|
|
570
|
-
};
|
|
571
|
-
readonly localeSwitcher: {
|
|
572
|
-
readonly ariaLabel: "Language selection";
|
|
573
|
-
readonly placeholder: "Select language...";
|
|
574
|
-
};
|
|
575
|
-
readonly pagination: {
|
|
576
|
-
readonly next: "Next";
|
|
577
|
-
readonly first: "First";
|
|
578
|
-
readonly last: "Last";
|
|
579
|
-
readonly page: "Page";
|
|
580
|
-
readonly previous: "Previous";
|
|
581
|
-
};
|
|
582
|
-
readonly calendar: {
|
|
583
|
-
readonly recurring: "Recurring event";
|
|
584
|
-
readonly previousMonth: "Previous month";
|
|
585
|
-
readonly nextMonth: "Next month";
|
|
586
|
-
readonly previousWeek: "Previous week";
|
|
587
|
-
readonly nextWeek: "Next week";
|
|
588
|
-
readonly previousDay: "Previous day";
|
|
589
|
-
readonly nextDay: "Next day";
|
|
590
|
-
readonly previousYear: "Previous year";
|
|
591
|
-
readonly nextYear: "Next year";
|
|
592
|
-
readonly today: "Today";
|
|
593
|
-
readonly calendarGrid: "Calendar";
|
|
594
|
-
readonly weekdays: "Weekdays";
|
|
595
|
-
readonly weekNumber: "Week number";
|
|
596
|
-
readonly events: "Events";
|
|
597
|
-
readonly noEvents: "No events";
|
|
598
|
-
readonly showMore: "{{count}} more";
|
|
599
|
-
readonly legend: "Legend";
|
|
600
|
-
readonly yearView: "Year overview";
|
|
601
|
-
readonly weekView: "Week view";
|
|
602
|
-
readonly dayView: "Day view";
|
|
603
|
-
readonly monthView: "Month view";
|
|
604
|
-
readonly viewMonth: "Month";
|
|
605
|
-
readonly viewYear: "Year";
|
|
606
|
-
readonly viewWeek: "Week";
|
|
607
|
-
readonly viewDay: "Day";
|
|
608
|
-
readonly multiDayLabel: "Day {{current}} of {{total}}";
|
|
609
|
-
readonly agendaView: "Agenda view";
|
|
610
|
-
readonly viewAgenda: "Agenda";
|
|
611
|
-
readonly viewSwitcher: "View mode";
|
|
612
|
-
};
|
|
613
|
-
readonly planner: {
|
|
614
|
-
readonly previousWeek: "Previous week";
|
|
615
|
-
readonly nextWeek: "Next week";
|
|
616
|
-
readonly previousMonth: "Previous month";
|
|
617
|
-
readonly nextMonth: "Next month";
|
|
618
|
-
readonly previousRange: "Previous range";
|
|
619
|
-
readonly nextRange: "Next range";
|
|
620
|
-
readonly today: "Today";
|
|
621
|
-
readonly grid: "Planner";
|
|
622
|
-
readonly weekNumber: "Week number";
|
|
623
|
-
readonly itemCount: "{{count}} items";
|
|
624
|
-
};
|
|
625
|
-
readonly commandPalette: {
|
|
626
|
-
readonly noResults: "No results found.";
|
|
627
|
-
readonly search: "Search...";
|
|
628
|
-
readonly hints: {
|
|
629
|
-
readonly navigate: "Navigate";
|
|
630
|
-
readonly select: "Select";
|
|
631
|
-
readonly close: "Close";
|
|
632
|
-
};
|
|
633
|
-
};
|
|
634
|
-
readonly compositionBar: {
|
|
635
|
-
readonly total: "Total";
|
|
636
|
-
readonly summary: "Composition: {{total}} ({{count}} shares) — {{parts}}";
|
|
637
|
-
readonly share: "Share";
|
|
638
|
-
readonly value: "Value";
|
|
639
|
-
readonly percent: "Percent";
|
|
640
|
-
readonly remaining: "remaining";
|
|
641
|
-
};
|
|
642
|
-
readonly guide: {
|
|
643
|
-
readonly next: "Next";
|
|
644
|
-
readonly previous: "Back";
|
|
645
|
-
readonly skip: "Skip tour";
|
|
646
|
-
readonly done: "Done";
|
|
647
|
-
readonly step: "Step {{current}} of {{total}}";
|
|
648
|
-
readonly tour: "Guided tour";
|
|
649
|
-
readonly close: "Close";
|
|
650
|
-
readonly openHelp: "Help";
|
|
651
|
-
readonly backToList: "All topics";
|
|
652
|
-
readonly info: "More information";
|
|
653
|
-
readonly infoAbout: "More information about {{label}}";
|
|
654
|
-
readonly dismiss: "Dismiss hint";
|
|
655
|
-
readonly startTour: "Start the guided tour";
|
|
656
|
-
readonly actionRequired: "Complete the highlighted action to continue";
|
|
657
|
-
readonly filterPlaceholder: "Filter topics…";
|
|
658
|
-
readonly noResults: "No matching topics";
|
|
659
|
-
};
|
|
660
|
-
readonly datepicker: {
|
|
661
|
-
readonly placeholder: "Select a date...";
|
|
662
|
-
readonly rangePlaceholder: "Select a date range...";
|
|
663
|
-
readonly clear: "Clear selection";
|
|
664
|
-
readonly openCalendar: "Open calendar";
|
|
665
|
-
readonly invalidDate: "Invalid date";
|
|
666
|
-
readonly outOfRange: "Date is outside the allowed range";
|
|
667
|
-
readonly invalidRange: "Invalid date range";
|
|
668
|
-
};
|
|
669
|
-
readonly fileUpload: {
|
|
670
|
-
readonly exists: "File already added";
|
|
671
|
-
readonly invalidType: "File type {{type}} is not allowed";
|
|
672
|
-
readonly tooLarge: "File exceeds {{size}} limit";
|
|
673
|
-
readonly tooMany: "Maximum {{count}} files allowed";
|
|
674
|
-
readonly tooSmall: "File must be at least {{size}}";
|
|
675
|
-
};
|
|
676
|
-
readonly sankey: {
|
|
677
|
-
readonly summary: "Sankey diagram: {{nodes}} nodes, {{links}} links — {{flows}}";
|
|
678
|
-
readonly source: "Source";
|
|
679
|
-
readonly target: "Target";
|
|
680
|
-
readonly value: "Value";
|
|
681
|
-
};
|
|
682
|
-
readonly slider: {
|
|
683
|
-
readonly rangeStatus: {
|
|
684
|
-
readonly insideRecommended: "In recommended range";
|
|
685
|
-
readonly insideValid: "In valid range";
|
|
686
|
-
readonly insideValidOnly: "Outside recommended range, but valid";
|
|
687
|
-
readonly outsideValid: "Outside valid range";
|
|
688
|
-
};
|
|
689
|
-
};
|
|
690
|
-
readonly themeSwitcher: {
|
|
691
|
-
readonly lightMode: "Light mode";
|
|
692
|
-
readonly darkMode: "Dark mode";
|
|
693
|
-
readonly systemTheme: "System theme";
|
|
694
|
-
};
|
|
695
|
-
readonly time: {
|
|
696
|
-
readonly ago: "{{value}} {{unit}} ago";
|
|
697
|
-
readonly now: "now";
|
|
698
|
-
};
|
|
699
|
-
}>;
|
|
359
|
+
export declare const useBlocksI18n: any;
|
|
700
360
|
export declare const hasBlocksTranslation: (key: string) => boolean, getBlocksLocales: () => import("@urbicon-ui/i18n").Locale[];
|
|
701
361
|
export type BlocksTranslationKey = keyof typeof enTranslations;
|
|
702
362
|
export { blocksTranslations };
|
|
@@ -15,6 +15,18 @@ export interface GuideTopicMeta {
|
|
|
15
15
|
export interface GuideStep {
|
|
16
16
|
/** `data-guide` id of the element to anchor to. Omit for a centered, target-less step. */
|
|
17
17
|
target?: string;
|
|
18
|
+
/**
|
|
19
|
+
* Optional route this step lives on — declarative cross-route touring. When set and different
|
|
20
|
+
* from the current location, the controller calls its injected `navigate` hook to go there
|
|
21
|
+
* **before** the spotlight, then re-anchors once the target appears on the new page (via the
|
|
22
|
+
* surface's existing `reapplyStepHighlight`). Such a tour-internal navigation keeps the tour
|
|
23
|
+
* running; a *foreign* navigation (the user leaving on their own) still stops it. Compared
|
|
24
|
+
* against `window.location.pathname` by default, so use a normalized path (no query/hash);
|
|
25
|
+
* inject a {@link GuideControllerOptions.navigationSource} for a custom router or base path.
|
|
26
|
+
* A `route` step with no `navigate` hook wired logs a DEV warning and stays put (no crash).
|
|
27
|
+
* @see GuideControllerOptions.navigate
|
|
28
|
+
*/
|
|
29
|
+
route?: string;
|
|
18
30
|
/** Step heading. */
|
|
19
31
|
title?: string;
|
|
20
32
|
/** Step body text. */
|
|
@@ -103,12 +115,45 @@ export interface GuideOverlayStackLike {
|
|
|
103
115
|
/** Number of modal overlays currently open — drives the non-modal hide (§3.4). */
|
|
104
116
|
readonly depth: number;
|
|
105
117
|
}
|
|
118
|
+
/**
|
|
119
|
+
* Source of the current route and navigation notifications the controller needs for cross-route
|
|
120
|
+
* tours (injectable for tests and custom routers). The default {@link createBrowserNavigationSource}
|
|
121
|
+
* reads `window.location.pathname` and subscribes via the Navigation API, falling back to `popstate`.
|
|
122
|
+
*/
|
|
123
|
+
export interface GuideNavigationSource {
|
|
124
|
+
/** The current path, compared against a step's `route` (e.g. `"/expenses"`). `''` on the server. */
|
|
125
|
+
current(): string;
|
|
126
|
+
/**
|
|
127
|
+
* Subscribe to navigations; `onNavigate` receives the new path. Returns an unsubscribe. The
|
|
128
|
+
* controller subscribes only while a tour with at least one `route` step is active, so a tour
|
|
129
|
+
* that never declares a route observes no navigation (preserving the manual-`goto` recipe).
|
|
130
|
+
*/
|
|
131
|
+
subscribe(onNavigate: (path: string) => void): () => void;
|
|
132
|
+
}
|
|
106
133
|
/** Options for {@link GuideController}; every dependency is injectable for testing. */
|
|
107
134
|
export interface GuideControllerOptions {
|
|
108
135
|
/** Persistence adapter. @default localStorage-backed adapter */
|
|
109
136
|
storage?: GuideStorageAdapter;
|
|
110
137
|
/** Overlay stack to integrate with. @default the shared `overlayStack` singleton */
|
|
111
138
|
overlayStack?: GuideOverlayStackLike;
|
|
139
|
+
/**
|
|
140
|
+
* Navigation hook for declarative cross-route tours. When a step's `route` differs from the
|
|
141
|
+
* current location, the controller calls this to navigate there before spotlighting the step.
|
|
142
|
+
* Framework-agnostic by injection — a SvelteKit consumer wires `(route) => goto(route)`. May be
|
|
143
|
+
* sync or async; a thrown/rejected navigation is swallowed (DEV-warned). A `route` step with no
|
|
144
|
+
* hook wired logs a DEV warning and stays on the current route (no crash). @default undefined
|
|
145
|
+
*/
|
|
146
|
+
navigate?: (route: string) => void | Promise<void>;
|
|
147
|
+
/**
|
|
148
|
+
* Source for the current path + navigation events, used to decide whether a step's `route`
|
|
149
|
+
* needs navigating and to tell a tour-internal navigation from a foreign one (which stops the
|
|
150
|
+
* tour). @default a browser source reading `window.location.pathname` and listening via the
|
|
151
|
+
* Navigation API. Where that API is unavailable it falls back to `popstate` (back/forward only,
|
|
152
|
+
* not `pushState`), so a foreign *forward* navigation may go unobserved — inject a router-backed
|
|
153
|
+
* source (SvelteKit: `afterNavigate` + the `page` store; see docs/GUIDE.md §9) for reliable
|
|
154
|
+
* detection, or to handle a configured base path / custom router.
|
|
155
|
+
*/
|
|
156
|
+
navigationSource?: GuideNavigationSource;
|
|
112
157
|
/** Force DEV-mode warnings on/off. @default `import.meta.env?.DEV ?? false` */
|
|
113
158
|
dev?: boolean;
|
|
114
159
|
}
|
|
@@ -117,6 +162,13 @@ export interface GuideControllerOptions {
|
|
|
117
162
|
* resilient to private-mode / quota failures (mirrors `persistent-state`).
|
|
118
163
|
*/
|
|
119
164
|
export declare function createLocalStorageAdapter(key?: string): GuideStorageAdapter;
|
|
165
|
+
/**
|
|
166
|
+
* The default {@link GuideNavigationSource}: reads `window.location.pathname` and observes SPA
|
|
167
|
+
* navigations through the Navigation API when available — catching link clicks, programmatic
|
|
168
|
+
* navigation (`goto`), and back/forward — falling back to `popstate` (back/forward only) where it
|
|
169
|
+
* is not. SSR-safe: `current()` returns `''` and `subscribe()` is a no-op without a `window`.
|
|
170
|
+
*/
|
|
171
|
+
export declare function createBrowserNavigationSource(): GuideNavigationSource;
|
|
120
172
|
/**
|
|
121
173
|
* Headless engine for the Guide system — the UI-free state machine behind every
|
|
122
174
|
* Guide surface (Panel, Marker, Mention, Hint, Tour).
|
|
@@ -42,6 +42,57 @@ export function createLocalStorageAdapter(key = SEEN_STORAGE_KEY) {
|
|
|
42
42
|
}
|
|
43
43
|
};
|
|
44
44
|
}
|
|
45
|
+
/**
|
|
46
|
+
* The default {@link GuideNavigationSource}: reads `window.location.pathname` and observes SPA
|
|
47
|
+
* navigations through the Navigation API when available — catching link clicks, programmatic
|
|
48
|
+
* navigation (`goto`), and back/forward — falling back to `popstate` (back/forward only) where it
|
|
49
|
+
* is not. SSR-safe: `current()` returns `''` and `subscribe()` is a no-op without a `window`.
|
|
50
|
+
*/
|
|
51
|
+
export function createBrowserNavigationSource() {
|
|
52
|
+
let warnedFallback = false;
|
|
53
|
+
return {
|
|
54
|
+
current() {
|
|
55
|
+
return BROWSER ? window.location.pathname : '';
|
|
56
|
+
},
|
|
57
|
+
subscribe(onNavigate) {
|
|
58
|
+
if (!BROWSER)
|
|
59
|
+
return () => { };
|
|
60
|
+
const nav = window.navigation;
|
|
61
|
+
if (nav && typeof nav.addEventListener === 'function') {
|
|
62
|
+
const handler = (event) => {
|
|
63
|
+
if (event.downloadRequest != null)
|
|
64
|
+
return; // a download is not a route change
|
|
65
|
+
const url = event.destination?.url;
|
|
66
|
+
if (typeof url !== 'string')
|
|
67
|
+
return;
|
|
68
|
+
let path;
|
|
69
|
+
try {
|
|
70
|
+
path = new URL(url).pathname;
|
|
71
|
+
}
|
|
72
|
+
catch {
|
|
73
|
+
return; // opaque/cross-origin destination — not a same-app route
|
|
74
|
+
}
|
|
75
|
+
onNavigate(path);
|
|
76
|
+
};
|
|
77
|
+
nav.addEventListener('navigate', handler);
|
|
78
|
+
return () => nav.removeEventListener('navigate', handler);
|
|
79
|
+
}
|
|
80
|
+
// `popstate` only catches back/forward, not `pushState` (a SvelteKit `goto` / intercepted
|
|
81
|
+
// link click), so a foreign *forward* navigation goes unobserved and the tour won't stop.
|
|
82
|
+
// Warn once so a degraded-detection browser is diagnosable; inject a router-backed
|
|
83
|
+
// navigationSource for reliable detection (docs/GUIDE.md §9).
|
|
84
|
+
if (import.meta.env?.DEV && !warnedFallback) {
|
|
85
|
+
warnedFallback = true;
|
|
86
|
+
console.warn('[Guide] the Navigation API is unavailable; cross-route foreign-navigation detection falls back to popstate and will miss pushState navigations (link clicks, goto). Inject a router-backed navigationSource for reliable detection — see docs/GUIDE.md §9.');
|
|
87
|
+
}
|
|
88
|
+
const onPop = () => onNavigate(window.location.pathname);
|
|
89
|
+
window.addEventListener('popstate', onPop);
|
|
90
|
+
return () => window.removeEventListener('popstate', onPop);
|
|
91
|
+
}
|
|
92
|
+
};
|
|
93
|
+
}
|
|
94
|
+
/** DEV-only: grace period for a navigated-to `route` step's target before warning it never showed. */
|
|
95
|
+
const ROUTE_TARGET_TIMEOUT_MS = 4000;
|
|
45
96
|
let tourIdCounter = 0;
|
|
46
97
|
/** Opaque id for overlay-stack registration. Never SSR-rendered, so no hydration risk. */
|
|
47
98
|
function nextOverlayId() {
|
|
@@ -101,6 +152,17 @@ export class GuideController {
|
|
|
101
152
|
// independently of #activeTour (today they always change in lockstep).
|
|
102
153
|
#tourOverlayId = $state(null);
|
|
103
154
|
#tourUnregister = null;
|
|
155
|
+
// ── Cross-route touring ─────────────────────────────────
|
|
156
|
+
#navigate;
|
|
157
|
+
#navSource;
|
|
158
|
+
/** The path a tour-internal navigation is heading to; distinguishes our own nav from a foreign one. */
|
|
159
|
+
#expectedRoute = null;
|
|
160
|
+
/** Last path the tour is known to be on — set at start, updated on each handled navigation. */
|
|
161
|
+
#knownPath = '';
|
|
162
|
+
/** Unsubscribe from the navigation source; non-null only while a route-using tour runs. */
|
|
163
|
+
#navUnsub = null;
|
|
164
|
+
/** DEV-only timer that warns when a navigated-to step's target never appears. */
|
|
165
|
+
#routeTargetTimer = null;
|
|
104
166
|
// ── Highlight (shared by tour steps + Mention→UI, Direction B) ──
|
|
105
167
|
#highlightedId = $state(null);
|
|
106
168
|
// ── Panel state (UI in Phase 3) ─────────────────────────
|
|
@@ -112,6 +174,8 @@ export class GuideController {
|
|
|
112
174
|
constructor(options = {}) {
|
|
113
175
|
this.#storage = options.storage ?? createLocalStorageAdapter();
|
|
114
176
|
this.#overlayStack = options.overlayStack ?? overlayStack;
|
|
177
|
+
this.#navigate = options.navigate;
|
|
178
|
+
this.#navSource = options.navigationSource ?? createBrowserNavigationSource();
|
|
115
179
|
// `import.meta.env?.DEV` is `boolean | undefined` (undefined outside Vite);
|
|
116
180
|
// `?? false` keeps `#dev` a strict boolean and means non-Vite consumers
|
|
117
181
|
// simply get no dev warnings (rather than a crash).
|
|
@@ -240,8 +304,14 @@ export class GuideController {
|
|
|
240
304
|
this.#stepIndex = 0;
|
|
241
305
|
this.#tourOverlayId = nextOverlayId();
|
|
242
306
|
this.#tourUnregister = this.#overlayStack.register(this.#tourOverlayId, () => this.skip());
|
|
243
|
-
|
|
244
|
-
|
|
307
|
+
// Observe navigation only for tours that declare a step route. This keeps the manual-`goto`
|
|
308
|
+
// recipe (consumer navigates in `onStep`, no `step.route`) untouched, where a navigation is
|
|
309
|
+
// the consumer's own and must NOT be read as a foreign one that stops the tour.
|
|
310
|
+
this.#knownPath = this.#navSource.current();
|
|
311
|
+
if (tour.steps.some((s) => typeof s.route === 'string')) {
|
|
312
|
+
this.#navUnsub = this.#navSource.subscribe((path) => this.#onLocationChange(path));
|
|
313
|
+
}
|
|
314
|
+
this.#activateStep('start');
|
|
245
315
|
return true;
|
|
246
316
|
}
|
|
247
317
|
/** Advance to the next step, or finish the tour if on the last step. */
|
|
@@ -253,16 +323,14 @@ export class GuideController {
|
|
|
253
323
|
return;
|
|
254
324
|
}
|
|
255
325
|
this.#stepIndex += 1;
|
|
256
|
-
this.#
|
|
257
|
-
this.#emitStep('next');
|
|
326
|
+
this.#activateStep('next');
|
|
258
327
|
}
|
|
259
328
|
/** Go back one step. No-op on the first step. */
|
|
260
329
|
prev() {
|
|
261
330
|
if (!this.#activeTour || this.isFirstStep)
|
|
262
331
|
return;
|
|
263
332
|
this.#stepIndex -= 1;
|
|
264
|
-
this.#
|
|
265
|
-
this.#emitStep('prev');
|
|
333
|
+
this.#activateStep('prev');
|
|
266
334
|
}
|
|
267
335
|
/** Dismiss the tour without completing it — marks it seen, fires `onSkip`. */
|
|
268
336
|
skip() {
|
|
@@ -304,6 +372,132 @@ export class GuideController {
|
|
|
304
372
|
if (this.#activeTour)
|
|
305
373
|
this.#applyStepHighlight();
|
|
306
374
|
}
|
|
375
|
+
// ─── Cross-route touring ──────────────────────────────────────────────────
|
|
376
|
+
/**
|
|
377
|
+
* Make the now-current step active: trigger its cross-route navigation (if any), apply the
|
|
378
|
+
* highlight, then fire `onStep`. Shared by `startTour`/`next`/`prev`, so every entry point
|
|
379
|
+
* navigates symmetrically — including `prev()` stepping back across a route boundary.
|
|
380
|
+
*/
|
|
381
|
+
#activateStep(via) {
|
|
382
|
+
this.#clearRouteTargetWarning();
|
|
383
|
+
this.#maybeNavigate();
|
|
384
|
+
this.#applyStepHighlight();
|
|
385
|
+
this.#emitStep(via);
|
|
386
|
+
}
|
|
387
|
+
/**
|
|
388
|
+
* If the active step lives on a different route, navigate there via the injected hook and record
|
|
389
|
+
* it as the `expectedRoute`, so the resulting navigation is recognized as the tour's own rather
|
|
390
|
+
* than a foreign one. Already on the route → nothing to do. No hook wired → DEV warning, stay put.
|
|
391
|
+
*/
|
|
392
|
+
#maybeNavigate() {
|
|
393
|
+
// Each step starts with a clean slate — no navigation is pending until we trigger one below.
|
|
394
|
+
// (A step that doesn't navigate must not inherit the previous step's `expectedRoute`.)
|
|
395
|
+
this.#expectedRoute = null;
|
|
396
|
+
const route = this.currentStep?.route;
|
|
397
|
+
if (route == null)
|
|
398
|
+
return;
|
|
399
|
+
if (route === this.#navSource.current())
|
|
400
|
+
return;
|
|
401
|
+
if (!this.#navigate) {
|
|
402
|
+
if (this.#dev) {
|
|
403
|
+
console.warn(`[Guide] tour "${this.#activeTour?.id}" step ${this.#stepIndex}: step has route "${route}" but no navigate hook was provided to the GuideController — staying on the current route.`);
|
|
404
|
+
}
|
|
405
|
+
return;
|
|
406
|
+
}
|
|
407
|
+
this.#expectedRoute = route;
|
|
408
|
+
this.#scheduleRouteTargetWarning();
|
|
409
|
+
try {
|
|
410
|
+
const result = this.#navigate(route);
|
|
411
|
+
if (result && typeof result.then === 'function') {
|
|
412
|
+
result.catch((err) => {
|
|
413
|
+
if (this.#dev)
|
|
414
|
+
console.warn('[Guide] navigate hook rejected:', err);
|
|
415
|
+
this.#abortPendingNavigation(route);
|
|
416
|
+
});
|
|
417
|
+
}
|
|
418
|
+
}
|
|
419
|
+
catch (err) {
|
|
420
|
+
if (this.#dev)
|
|
421
|
+
console.warn('[Guide] navigate hook threw:', err);
|
|
422
|
+
this.#abortPendingNavigation(route);
|
|
423
|
+
}
|
|
424
|
+
}
|
|
425
|
+
/**
|
|
426
|
+
* Roll back the bookkeeping for a navigation that failed (hook threw/rejected) — but only if it
|
|
427
|
+
* is still the pending one, so a newer step's navigation (the user clicked Next while this hook
|
|
428
|
+
* was in flight) is never clobbered by a late rejection. Clears the now-meaningless "target never
|
|
429
|
+
* appeared" timer too, so it can't later fire a misleading warning for a navigation that never ran.
|
|
430
|
+
*/
|
|
431
|
+
#abortPendingNavigation(route) {
|
|
432
|
+
if (this.#expectedRoute !== route)
|
|
433
|
+
return;
|
|
434
|
+
this.#expectedRoute = null;
|
|
435
|
+
this.#clearRouteTargetWarning();
|
|
436
|
+
}
|
|
437
|
+
/**
|
|
438
|
+
* React to a navigation observed while a route-using tour runs. A navigation matching the pending
|
|
439
|
+
* `expectedRoute` is the tour's own → clear the flag and keep running (the ring lands via the
|
|
440
|
+
* surface's `reapplyStepHighlight`). Any other navigation is foreign — the user left, or a
|
|
441
|
+
* youngest-gesture-wins race — and tears the tour down, analytics-silent (`stopTour`).
|
|
442
|
+
*/
|
|
443
|
+
#onLocationChange(path) {
|
|
444
|
+
if (!this.#activeTour)
|
|
445
|
+
return;
|
|
446
|
+
if (path === this.#knownPath)
|
|
447
|
+
return; // no pathname change (e.g. a hash/query update) — ignore
|
|
448
|
+
this.#knownPath = path;
|
|
449
|
+
if (this.#expectedRoute !== null && path === this.#expectedRoute) {
|
|
450
|
+
// The tour's own navigation landed — keep running. For a *targeted* step, keep `#expectedRoute`
|
|
451
|
+
// set until the target settles (`#applyStepHighlight`) so a redirecting / multi-hop source (the
|
|
452
|
+
// Navigation API emitting one event per hop) firing a *second* event for the redirect target is
|
|
453
|
+
// still recognized as a mismatch (and DEV-warned) instead of silently stopping. A *targetless*
|
|
454
|
+
// route step has no target to wait for — it is settled on landing, so clear now; otherwise a
|
|
455
|
+
// later foreign navigation would misfire the "navigated toward …" warning. (`#maybeNavigate`
|
|
456
|
+
// also resets it on the next step. Clearing here can't move into `#applyStepHighlight`, which
|
|
457
|
+
// runs synchronously in `#activateStep` before the nav lands — it would mis-read our own nav.)
|
|
458
|
+
if (this.currentStep?.target == null)
|
|
459
|
+
this.#expectedRoute = null;
|
|
460
|
+
return;
|
|
461
|
+
}
|
|
462
|
+
// Any other navigation stops the tour (analytics-silent). When one was pending, a landed path
|
|
463
|
+
// that doesn't match is most often a normalized `step.route` (trailing slash, base/locale
|
|
464
|
+
// prefix) rather than a genuine foreign nav — so surface it instead of a silent teardown on a
|
|
465
|
+
// one-character mismatch. (The strict stop is kept either way: better than running on a wrong page.)
|
|
466
|
+
if (this.#dev && this.#expectedRoute !== null) {
|
|
467
|
+
console.warn(`[Guide] tour "${this.#activeTour?.id}" navigated toward "${this.#expectedRoute}" but landed on "${path}" — stopping as a foreign navigation. If "${path}" is just a normalized form of the step's route (trailing slash, base/locale prefix), set step.route to the router's actual path.`);
|
|
468
|
+
}
|
|
469
|
+
this.#expectedRoute = null;
|
|
470
|
+
this.stopTour();
|
|
471
|
+
}
|
|
472
|
+
/**
|
|
473
|
+
* DEV-only: after navigating for a `route` step, warn if its target never appears so the spotlight
|
|
474
|
+
* can't land (the step still renders, centered over the scrim — it never hangs). Browser-gated, so
|
|
475
|
+
* no timer is ever scheduled under SSR or in node tests.
|
|
476
|
+
*/
|
|
477
|
+
#scheduleRouteTargetWarning() {
|
|
478
|
+
if (!this.#dev || !BROWSER)
|
|
479
|
+
return;
|
|
480
|
+
const step = this.currentStep;
|
|
481
|
+
if (!step?.target)
|
|
482
|
+
return;
|
|
483
|
+
this.#clearRouteTargetWarning();
|
|
484
|
+
const index = this.#stepIndex;
|
|
485
|
+
const targetId = step.target;
|
|
486
|
+
const route = step.route;
|
|
487
|
+
this.#routeTargetTimer = setTimeout(() => {
|
|
488
|
+
this.#routeTargetTimer = null;
|
|
489
|
+
if (this.#stepIndex === index && !this.resolveTarget(targetId)) {
|
|
490
|
+
console.warn(`[Guide] tour "${this.#activeTour?.id}" step ${index}: navigated to "${route}" but target "${targetId}" never appeared — showing the step without a spotlight ring.`);
|
|
491
|
+
}
|
|
492
|
+
}, ROUTE_TARGET_TIMEOUT_MS);
|
|
493
|
+
}
|
|
494
|
+
/** Cancel a pending route-target warning (target appeared, the step changed, or teardown). */
|
|
495
|
+
#clearRouteTargetWarning() {
|
|
496
|
+
if (this.#routeTargetTimer !== null) {
|
|
497
|
+
clearTimeout(this.#routeTargetTimer);
|
|
498
|
+
this.#routeTargetTimer = null;
|
|
499
|
+
}
|
|
500
|
+
}
|
|
307
501
|
#endTour() {
|
|
308
502
|
const tour = this.#activeTour;
|
|
309
503
|
this.#teardownTour();
|
|
@@ -313,8 +507,12 @@ export class GuideController {
|
|
|
313
507
|
if (tour && tour.once !== false)
|
|
314
508
|
this.markSeen(tour.id);
|
|
315
509
|
}
|
|
316
|
-
/** Reset all tour state and release the overlay-stack
|
|
510
|
+
/** Reset all tour state and release the overlay-stack + navigation registrations. No persistence. */
|
|
317
511
|
#teardownTour() {
|
|
512
|
+
this.#clearRouteTargetWarning();
|
|
513
|
+
this.#navUnsub?.();
|
|
514
|
+
this.#navUnsub = null;
|
|
515
|
+
this.#expectedRoute = null;
|
|
318
516
|
this.clearHighlight();
|
|
319
517
|
this.#tourUnregister?.();
|
|
320
518
|
this.#tourUnregister = null;
|
|
@@ -364,10 +562,16 @@ export class GuideController {
|
|
|
364
562
|
// Unlike Direction-B hover (which never scrolls), a tour drives the viewport —
|
|
365
563
|
// the scroll is reduced-motion-aware inside `highlight`.
|
|
366
564
|
this.highlight(step.target, { scroll: true });
|
|
565
|
+
this.#clearRouteTargetWarning(); // target landed → no "never appeared" warning needed
|
|
566
|
+
this.#expectedRoute = null; // the navigated-to target resolved → navigation fully settled
|
|
367
567
|
}
|
|
368
568
|
else {
|
|
369
569
|
this.clearHighlight();
|
|
370
|
-
|
|
570
|
+
// A step bound to another route legitimately has no target on the current page — during the
|
|
571
|
+
// navigation gap, or when no navigate hook is wired — so don't warn "not found" there; the
|
|
572
|
+
// missing-hook and never-appeared paths own those diagnostics instead.
|
|
573
|
+
const offRoute = step.route != null && step.route !== this.#navSource.current();
|
|
574
|
+
if (this.#dev && !offRoute) {
|
|
371
575
|
console.warn(`[Guide] tour "${this.#activeTour?.id}" step ${this.#stepIndex}: target "${step.target}" not found in DOM.`);
|
|
372
576
|
}
|
|
373
577
|
}
|
package/dist/utils/index.d.ts
CHANGED
|
@@ -2,7 +2,7 @@ export * from './date.js';
|
|
|
2
2
|
export * from './draggable.js';
|
|
3
3
|
export * from './figma-token-export.js';
|
|
4
4
|
export { arrow, autoUpdate, type ComputePositionReturn, computePosition, flip, type Middleware, offset, type Placement, type Strategy, shift, size } from './floating.js';
|
|
5
|
-
export { createLocalStorageAdapter, GuideController, type GuideControllerOptions, type GuideDirection, type GuideEndEvent, type GuideOverlayStackLike, type GuideStep, type GuideStepEvent, type GuideStorageAdapter, type GuideTopicMeta, type GuideTour } from './guide.svelte.js';
|
|
5
|
+
export { createBrowserNavigationSource, createLocalStorageAdapter, GuideController, type GuideControllerOptions, type GuideDirection, type GuideEndEvent, type GuideNavigationSource, type GuideOverlayStackLike, type GuideStep, type GuideStepEvent, type GuideStorageAdapter, type GuideTopicMeta, type GuideTour } from './guide.svelte.js';
|
|
6
6
|
export * from './id.js';
|
|
7
7
|
export { observeTargetResolution } from './observe-target.js';
|
|
8
8
|
export { createOptionalContext } from './optional-context.js';
|
package/dist/utils/index.js
CHANGED
|
@@ -2,7 +2,7 @@ export * from './date.js';
|
|
|
2
2
|
export * from './draggable.js';
|
|
3
3
|
export * from './figma-token-export.js';
|
|
4
4
|
export { arrow, autoUpdate, computePosition, flip, offset, shift, size } from './floating.js';
|
|
5
|
-
export { createLocalStorageAdapter, GuideController } from './guide.svelte.js';
|
|
5
|
+
export { createBrowserNavigationSource, createLocalStorageAdapter, GuideController } from './guide.svelte.js';
|
|
6
6
|
export * from './id.js';
|
|
7
7
|
export { observeTargetResolution } from './observe-target.js';
|
|
8
8
|
export { createOptionalContext } from './optional-context.js';
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@urbicon-ui/blocks",
|
|
3
|
-
"version": "6.
|
|
3
|
+
"version": "6.8.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.8.0",
|
|
95
|
+
"@urbicon-ui/shared-types": "6.8.0",
|
|
96
96
|
"prettier": "^3.8.4",
|
|
97
97
|
"prettier-plugin-svelte": "^4.1.1",
|
|
98
98
|
"prettier-plugin-tailwindcss": "^0.8.0",
|