@nubisco/ui 3.2.0 → 3.4.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.
Files changed (89) hide show
  1. package/dist/components/Board.d.ts +23 -0
  2. package/dist/components/Board.vue.d.ts +16 -8
  3. package/dist/components/Board.vue.d.ts.map +1 -1
  4. package/dist/components/Button.vue.d.ts.map +1 -1
  5. package/dist/components/Charts/GanttChart.vue.d.ts.map +1 -1
  6. package/dist/components/Charts/InterpolationChart.vue.d.ts.map +1 -1
  7. package/dist/components/Charts/shared/palette.d.ts +76 -1
  8. package/dist/components/Charts/shared/palette.d.ts.map +1 -1
  9. package/dist/components/CommandPalette.vue.d.ts.map +1 -1
  10. package/dist/components/Confirm.d.ts +199 -0
  11. package/dist/components/Confirm.env.d.ts +52 -0
  12. package/dist/components/Confirm.env.d.ts.map +1 -0
  13. package/dist/components/Confirm.vue.d.ts +61 -0
  14. package/dist/components/Confirm.vue.d.ts.map +1 -0
  15. package/dist/components/DatePicker.vue.d.ts +1 -1
  16. package/dist/components/InlineEdit.d.ts +24 -0
  17. package/dist/components/InlineEdit.vue.d.ts +20 -0
  18. package/dist/components/InlineEdit.vue.d.ts.map +1 -0
  19. package/dist/components/InlineLoading.d.ts +37 -0
  20. package/dist/components/InlineLoading.vue.d.ts +30 -0
  21. package/dist/components/InlineLoading.vue.d.ts.map +1 -0
  22. package/dist/components/MenuItem.vue.d.ts +1 -1
  23. package/dist/components/Modal.d.ts +35 -1
  24. package/dist/components/Modal.vue.d.ts +10 -1
  25. package/dist/components/Modal.vue.d.ts.map +1 -1
  26. package/dist/components/NotificationCenter.d.ts +184 -0
  27. package/dist/components/NotificationCenter.vue.d.ts +130 -0
  28. package/dist/components/NotificationCenter.vue.d.ts.map +1 -0
  29. package/dist/components/NotificationCenterItem.d.ts +53 -0
  30. package/dist/components/NotificationCenterItem.vue.d.ts +36 -0
  31. package/dist/components/NotificationCenterItem.vue.d.ts.map +1 -0
  32. package/dist/components/ProgressBar.vue.d.ts.map +1 -1
  33. package/dist/components/Shell.d.ts +138 -8
  34. package/dist/components/Shell.vue.d.ts +30 -3
  35. package/dist/components/Shell.vue.d.ts.map +1 -1
  36. package/dist/components/ShellPanel.d.ts +16 -0
  37. package/dist/components/ShellPanel.vue.d.ts +1 -0
  38. package/dist/components/ShellPanel.vue.d.ts.map +1 -1
  39. package/dist/components/SidebarLink.d.ts +14 -1
  40. package/dist/components/Skeleton.d.ts +87 -0
  41. package/dist/components/Skeleton.vue.d.ts +17 -0
  42. package/dist/components/Skeleton.vue.d.ts.map +1 -0
  43. package/dist/components/Spinner.d.ts +80 -0
  44. package/dist/components/Spinner.overlay.d.ts +56 -0
  45. package/dist/components/Spinner.overlay.d.ts.map +1 -0
  46. package/dist/components/Spinner.vue.d.ts +25 -0
  47. package/dist/components/Spinner.vue.d.ts.map +1 -0
  48. package/dist/components/Stepper.context.d.ts +48 -0
  49. package/dist/components/Stepper.context.d.ts.map +1 -0
  50. package/dist/components/Stepper.d.ts +101 -0
  51. package/dist/components/Stepper.vue.d.ts +31 -0
  52. package/dist/components/Stepper.vue.d.ts.map +1 -0
  53. package/dist/components/StepperStep.vue.d.ts +24 -0
  54. package/dist/components/StepperStep.vue.d.ts.map +1 -0
  55. package/dist/components/TextInput.vue.d.ts +2 -2
  56. package/dist/components/TextInput.vue.d.ts.map +1 -1
  57. package/dist/components/Toast.vue.d.ts +43 -0
  58. package/dist/components/Toast.vue.d.ts.map +1 -1
  59. package/dist/components/Toaster.d.ts +93 -0
  60. package/dist/components/Toaster.vue.d.ts +30 -0
  61. package/dist/components/Toaster.vue.d.ts.map +1 -0
  62. package/dist/components/UserMenu.vue.d.ts.map +1 -1
  63. package/dist/components/index.d.ts.map +1 -1
  64. package/dist/composables/useConfirm.composable.d.ts +45 -0
  65. package/dist/composables/useConfirm.composable.d.ts.map +1 -0
  66. package/dist/composables/useInlineLoading.composable.d.ts +43 -0
  67. package/dist/composables/useInlineLoading.composable.d.ts.map +1 -0
  68. package/dist/composables/useLoadingAnnouncer.composable.d.ts +63 -0
  69. package/dist/composables/useLoadingAnnouncer.composable.d.ts.map +1 -0
  70. package/dist/composables/useScrollLock.composable.d.ts +47 -0
  71. package/dist/composables/useScrollLock.composable.d.ts.map +1 -0
  72. package/dist/composables/useShellSlot.composable.d.ts +193 -0
  73. package/dist/composables/useShellSlot.composable.d.ts.map +1 -0
  74. package/dist/composables/useToast.composable.d.ts +325 -0
  75. package/dist/composables/useToast.composable.d.ts.map +1 -0
  76. package/dist/directives/ToolTip.content.d.ts +20 -0
  77. package/dist/directives/ToolTip.content.d.ts.map +1 -0
  78. package/dist/directives/ToolTip.directive.d.ts +94 -8
  79. package/dist/directives/ToolTip.directive.d.ts.map +1 -1
  80. package/dist/global.d.ts +20 -0
  81. package/dist/index.cjs +8 -9
  82. package/dist/index.mjs +13970 -10511
  83. package/dist/main.d.ts +46 -3
  84. package/dist/main.d.ts.map +1 -1
  85. package/dist/ui.css +1 -1
  86. package/package.json +1 -1
  87. package/src/styles/_reset.scss +5 -0
  88. package/src/styles/_theme.scss +171 -0
  89. package/src/styles/directives/_tooltip.scss +143 -21
@@ -0,0 +1,193 @@
1
+ import { defineComponent, type ComputedRef, type InjectionKey, type ShallowRef } from 'vue';
2
+ /**
3
+ * Shell regions a view is allowed to contribute controls to.
4
+ *
5
+ * These are exactly the regions `NbShell` renders as a single addressable
6
+ * element. `sidebar-*` is deliberately absent: navigation is the application's
7
+ * to declare once, not a per-view contribution, and a view that could inject
8
+ * rail items could also make the rail change shape on every route.
9
+ * `menubar` is absent because it is the legacy in-body bar, kept for the two
10
+ * apps that still pass it and not worth a new contract.
11
+ */
12
+ export type TShellSlotName = 'outer-menu' | 'inner-menu' | 'notification' | 'topbar-left' | 'topbar-right' | 'fixedbar' | 'bottom' | 'inspector';
13
+ /**
14
+ * What happens when two views hold the same region at the same time, which is
15
+ * the normal state of affairs for the frame or two a route transition takes.
16
+ *
17
+ * - `'last'` (default): the most recently registered contributor renders and
18
+ * the others stand down. The leaving view's controls disappear the moment
19
+ * the arriving view registers, so the topbar never shows two page titles or
20
+ * two Save buttons. When the newer contributor unmounts, the previous one
21
+ * becomes active again, which is what makes a contribution inside a dialog
22
+ * or a nested route behave.
23
+ * - `'all'`: every contributor renders, ordered by `order` then registration.
24
+ * For genuinely additive regions (a status chip from a background sync
25
+ * alongside the page's own actions).
26
+ */
27
+ export type TShellSlotClaim = 'last' | 'all';
28
+ export interface IShellSlotOptions {
29
+ /**
30
+ * Sort key within a region when `claim: 'all'`. Lower renders first (further
31
+ * left in a horizontal region, higher in a stacked one). Ties keep
32
+ * registration order. Ignored when `claim` is `'last'`, where there is only
33
+ * ever one contribution to place.
34
+ *
35
+ * Teleports append in mount order, which for concurrent views is whatever
36
+ * order the router happened to create them in. So under `claim: 'all'` the
37
+ * outlet wraps its content in a flex box carrying a CSS `order`, and that is
38
+ * what actually sorts the region. The wrapper inherits the region's own gap
39
+ * and cross-axis alignment (both with an explicit `inherit`), so
40
+ * contributions line up with static slot content rather than reading as a
41
+ * nested group.
42
+ *
43
+ * CSS `order` only sorts flex and grid children, and three of the eight
44
+ * regions (`outer-menu`, `inner-menu`, `notification`) are block containers
45
+ * whose internal layout belongs to the product, not to us. `NbShell`
46
+ * therefore switches exactly those three to a column flex container while a
47
+ * shared contribution is registered, and back when the last one leaves: see
48
+ * `sharedCount` below and `.nb-shell__region--ordered` in `Shell.vue`. The
49
+ * switch is scoped to the new API on purpose, so a product that never calls
50
+ * `useShellSlot` keeps byte-identical layout in the regions it already fills
51
+ * by hand.
52
+ * @default 0
53
+ */
54
+ order?: number;
55
+ /**
56
+ * How this contributor shares the region with others.
57
+ * @default 'last'
58
+ */
59
+ claim?: TShellSlotClaim;
60
+ }
61
+ /** One registered contributor, as the shell sees it. */
62
+ interface IShellSlotEntry {
63
+ id: number;
64
+ name: TShellSlotName;
65
+ order: number;
66
+ claim: TShellSlotClaim;
67
+ seq: number;
68
+ /**
69
+ * True while the contributor is alive but off screen, which in practice
70
+ * means a `<KeepAlive>`-cached route component that has been deactivated.
71
+ * Such an entry is skipped by `activeIds` and by `count`, so a cached page's
72
+ * controls neither render nor keep a region open.
73
+ */
74
+ deactivated: boolean;
75
+ }
76
+ /**
77
+ * The contract `NbShell` provides and `useShellSlot` consumes. Not public API:
78
+ * consumers go through the composable, which is the whole point of the piece.
79
+ */
80
+ export interface IShellSlotRegistry {
81
+ register(entry: IShellSlotEntry): void;
82
+ unregister(id: number): void;
83
+ /** The live host element for a region, or null before the shell has mounted it. */
84
+ elementFor(name: TShellSlotName): ShallowRef<HTMLElement | null>;
85
+ /** Ids that should render right now for a region, in render order. */
86
+ activeIds(name: TShellSlotName): ComputedRef<number[]>;
87
+ /**
88
+ * Suspend or resume a registration without losing it. Called from the
89
+ * composable's `onDeactivated` / `onActivated`, which is the only lifecycle
90
+ * pair `<KeepAlive>` gives us: a deactivated component is not unmounted, its
91
+ * effect scope is not disposed, and its teleported nodes stay exactly where
92
+ * they were.
93
+ */
94
+ setActive(id: number, active: boolean): void;
95
+ }
96
+ export declare const NB_SHELL_SLOT_KEY: InjectionKey<IShellSlotRegistry>;
97
+ export interface IShellSlot {
98
+ /** This contributor's id. Useful in tests and debugging; not needed to render. */
99
+ readonly id: number;
100
+ /** The region this contributor targets. */
101
+ readonly name: TShellSlotName;
102
+ /**
103
+ * The host element inside the shell. `null` until the shell has mounted the
104
+ * region, which is normal on the first tick: a view's `onMounted` runs
105
+ * BEFORE its ancestors'. Reactive, so anything bound to it corrects itself
106
+ * without a `nextTick` dance.
107
+ */
108
+ readonly target: Readonly<ShallowRef<HTMLElement | null>>;
109
+ /** True once `target` exists. */
110
+ readonly ready: ComputedRef<boolean>;
111
+ /**
112
+ * True when this contributor both has a target and has won the region under
113
+ * the current `claim`. `Outlet` already checks this; read it when you need
114
+ * to skip expensive work rather than just skip rendering.
115
+ */
116
+ readonly active: ComputedRef<boolean>;
117
+ /**
118
+ * Renders its default slot into the region. Use it as a component:
119
+ * `<component :is="topbar.Outlet"><NbButton ... /></component>`.
120
+ *
121
+ * Content stays owned by the view: it is teleported, not re-created, so its
122
+ * reactive state, event handlers and component instances are the view's.
123
+ */
124
+ readonly Outlet: ReturnType<typeof defineComponent>;
125
+ }
126
+ /**
127
+ * Contribute controls from a view into a region of the surrounding `NbShell`.
128
+ *
129
+ * Eight of our twelve applications solved this with a hand-rolled DOM id
130
+ * (`#cms-topbar`, `#ob-topbar-left`, `#page-actions`, five more), and every one
131
+ * of them re-derived the same two problems: the target element does not exist
132
+ * when the view mounts, and during a route transition two views hold the region
133
+ * at once. This composable is the supported answer to both.
134
+ *
135
+ * ```vue
136
+ * <script setup lang="ts">
137
+ * import { useShellSlot } from '@nubisco/ui'
138
+ * const topbar = useShellSlot('topbar-right')
139
+ * </script>
140
+ *
141
+ * <template>
142
+ * <topbar.Outlet>
143
+ * <NbButton size="sm" @click="save">Save</NbButton>
144
+ * </topbar.Outlet>
145
+ * <article>...</article>
146
+ * </template>
147
+ * ```
148
+ *
149
+ * Contributing also makes the region exist: `NbShell` counts registrations the
150
+ * same way it counts slot content, so a topbar with no static slots and no
151
+ * contributions is not rendered at all, and appears the moment a view claims
152
+ * it. Nothing to hide from the outside with a `:deep()` override.
153
+ *
154
+ * Under `<KeepAlive>` the contribution follows the page rather than the
155
+ * component instance. A cached route component that is deactivated releases the
156
+ * region on the way out and takes it back (as the newest claimant) on the way
157
+ * in, so `<router-view v-slot="{ Component }"><KeepAlive><component
158
+ * :is="Component" /></KeepAlive></router-view>` behaves the same as an
159
+ * uncached one.
160
+ *
161
+ * Outside an `NbShell` the composable is inert: `ready` stays false, `Outlet`
162
+ * renders nothing, no warning, no throw. That keeps a view usable in isolation
163
+ * (a storybook page, a unit test, a print route) without branching on it.
164
+ *
165
+ * The same is true inside a shell that is not rendering the region: a
166
+ * contribution to `topbar-left` under `<NbShell topbar="never">` has no host
167
+ * element to teleport into, so `ready` stays false and nothing renders. The
168
+ * shell warns about that case in development, because it is a configuration
169
+ * mistake rather than a legitimate isolated mount.
170
+ */
171
+ export declare function useShellSlot(name: TShellSlotName, options?: IShellSlotOptions): IShellSlot;
172
+ /**
173
+ * Builds the registry side of the contract. Called by `NbShell`; exported so
174
+ * the shell and the composable cannot drift apart, not as consumer API.
175
+ */
176
+ export declare function createShellSlotRegistry(): {
177
+ registry: IShellSlotRegistry;
178
+ /**
179
+ * Reactive count of *live* contributors per region, for the shell's own
180
+ * `v-if`. Deactivated (`<KeepAlive>`-cached) entries do not count, so a
181
+ * topbar opened by a page that has since been cached closes again.
182
+ */
183
+ count: (name: TShellSlotName) => number;
184
+ /**
185
+ * Reactive count of live `claim: 'all'` contributors per region. The shell
186
+ * uses it to decide whether a block region needs to become a flex container
187
+ * for the duration, which is the only way a CSS `order` can sort it.
188
+ */
189
+ sharedCount: (name: TShellSlotName) => number;
190
+ setElement: (name: TShellSlotName, el: HTMLElement | null) => void;
191
+ };
192
+ export {};
193
+ //# sourceMappingURL=useShellSlot.composable.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useShellSlot.composable.d.ts","sourceRoot":"","sources":["../../src/composables/useShellSlot.composable.ts"],"names":[],"mappings":"AAAA,OAAO,EAEL,eAAe,EAWf,KAAK,WAAW,EAChB,KAAK,YAAY,EAEjB,KAAK,UAAU,EAEhB,MAAM,KAAK,CAAA;AAEZ;;;;;;;;;GASG;AACH,MAAM,MAAM,cAAc,GACtB,YAAY,GACZ,YAAY,GACZ,cAAc,GACd,aAAa,GACb,cAAc,GACd,UAAU,GACV,QAAQ,GACR,WAAW,CAAA;AAEf;;;;;;;;;;;;;GAaG;AACH,MAAM,MAAM,eAAe,GAAG,MAAM,GAAG,KAAK,CAAA;AAE5C,MAAM,WAAW,iBAAiB;IAChC;;;;;;;;;;;;;;;;;;;;;;;;OAwBG;IACH,KAAK,CAAC,EAAE,MAAM,CAAA;IACd;;;OAGG;IACH,KAAK,CAAC,EAAE,eAAe,CAAA;CACxB;AAED,wDAAwD;AACxD,UAAU,eAAe;IACvB,EAAE,EAAE,MAAM,CAAA;IACV,IAAI,EAAE,cAAc,CAAA;IACpB,KAAK,EAAE,MAAM,CAAA;IACb,KAAK,EAAE,eAAe,CAAA;IACtB,GAAG,EAAE,MAAM,CAAA;IACX;;;;;OAKG;IACH,WAAW,EAAE,OAAO,CAAA;CACrB;AAED;;;GAGG;AACH,MAAM,WAAW,kBAAkB;IACjC,QAAQ,CAAC,KAAK,EAAE,eAAe,GAAG,IAAI,CAAA;IACtC,UAAU,CAAC,EAAE,EAAE,MAAM,GAAG,IAAI,CAAA;IAC5B,mFAAmF;IACnF,UAAU,CAAC,IAAI,EAAE,cAAc,GAAG,UAAU,CAAC,WAAW,GAAG,IAAI,CAAC,CAAA;IAChE,sEAAsE;IACtE,SAAS,CAAC,IAAI,EAAE,cAAc,GAAG,WAAW,CAAC,MAAM,EAAE,CAAC,CAAA;IACtD;;;;;;OAMG;IACH,SAAS,CAAC,EAAE,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,GAAG,IAAI,CAAA;CAC7C;AAED,eAAO,MAAM,iBAAiB,EAAE,YAAY,CAAC,kBAAkB,CACrC,CAAA;AAO1B,MAAM,WAAW,UAAU;IACzB,kFAAkF;IAClF,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAA;IACnB,2CAA2C;IAC3C,QAAQ,CAAC,IAAI,EAAE,cAAc,CAAA;IAC7B;;;;;OAKG;IACH,QAAQ,CAAC,MAAM,EAAE,QAAQ,CAAC,UAAU,CAAC,WAAW,GAAG,IAAI,CAAC,CAAC,CAAA;IACzD,iCAAiC;IACjC,QAAQ,CAAC,KAAK,EAAE,WAAW,CAAC,OAAO,CAAC,CAAA;IACpC;;;;OAIG;IACH,QAAQ,CAAC,MAAM,EAAE,WAAW,CAAC,OAAO,CAAC,CAAA;IACrC;;;;;;OAMG;IACH,QAAQ,CAAC,MAAM,EAAE,UAAU,CAAC,OAAO,eAAe,CAAC,CAAA;CACpD;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4CG;AACH,wBAAgB,YAAY,CAC1B,IAAI,EAAE,cAAc,EACpB,OAAO,GAAE,iBAAsB,GAC9B,UAAU,CAqGZ;AAED;;;GAGG;AACH,wBAAgB,uBAAuB,IAAI;IACzC,QAAQ,EAAE,kBAAkB,CAAA;IAC5B;;;;OAIG;IACH,KAAK,EAAE,CAAC,IAAI,EAAE,cAAc,KAAK,MAAM,CAAA;IACvC;;;;OAIG;IACH,WAAW,EAAE,CAAC,IAAI,EAAE,cAAc,KAAK,MAAM,CAAA;IAC7C,UAAU,EAAE,CAAC,IAAI,EAAE,cAAc,EAAE,EAAE,EAAE,WAAW,GAAG,IAAI,KAAK,IAAI,CAAA;CACnE,CAwEA"}
@@ -0,0 +1,325 @@
1
+ import { type ComputedRef, type InjectionKey, type Ref } from 'vue';
2
+ import type { TToastVariant, IToastCta } from '../components/Toast.vue';
3
+ /**
4
+ * The toast queue: the clock, the cap and the ordering that `NbToaster`
5
+ * renders.
6
+ *
7
+ * The split matters. `NbToast` knows how one message looks, `NbToaster` knows
8
+ * where the stack sits and how it moves, and this file knows *when* a message
9
+ * leaves. Timing lives here rather than in the item because the whole region
10
+ * pauses together: while the pointer rests on the top toast, the two below it
11
+ * must stop counting down as well, and an item that owns its own timer cannot
12
+ * know that. Three applications hand-rolled a host over `NbToast` and all
13
+ * three got a different part of this wrong, which is why it is now library
14
+ * code.
15
+ */
16
+ /**
17
+ * Why a toast ended. Passed to `IToastOptions.onDismiss`.
18
+ *
19
+ * - `user`: the close button, or Escape while the toast held focus.
20
+ * - `timeout`: the countdown ran out.
21
+ * - `action`: the reader pressed the toast's own action.
22
+ * - `replaced`: a newer message took its place, either because a `key` push
23
+ * claimed its slot or because the stack was full of toasts that can never
24
+ * expire.
25
+ * - `navigated`: `dismissTransient()`, from a router guard.
26
+ * - `cleared`: `dismissAll()`, typically sign-out.
27
+ *
28
+ * The reason is the only thing that separates "Deleted. [Undo]" committing
29
+ * from cancelling, so it is never collapsed into a boolean.
30
+ */
31
+ export type TToastDismissReason = 'user' | 'timeout' | 'action' | 'replaced' | 'navigated' | 'cleared';
32
+ /** Everything a caller can say about a toast. Only `message` is required. */
33
+ export interface IToastOptions {
34
+ /** The news, in one sentence. Written in the past tense: "Draft saved". */
35
+ message: string;
36
+ /** Tone. Also decides the icon, the politeness and the default duration. */
37
+ variant?: TToastVariant;
38
+ /** Optional short heading. Skip it when the message already stands alone. */
39
+ title?: string;
40
+ /**
41
+ * Milliseconds on screen. `0` means it stays until dismissed. Omit it and
42
+ * the variant decides (see `NB_TOAST_DURATIONS`).
43
+ */
44
+ duration?: number;
45
+ /**
46
+ * One action. A toast that carries one never auto-dismisses unless an
47
+ * explicit `duration` says it should: an action that removes itself while
48
+ * it is being reached for is not an action.
49
+ */
50
+ cta?: IToastCta;
51
+ /**
52
+ * De-duplication key. Pushing again with a key that is already queued takes
53
+ * over that toast's slot instead of adding a second one, so a double-clicked
54
+ * Save button produces one "Saved", not two.
55
+ *
56
+ * The second push replaces the message wholesale: only the id, the slot and
57
+ * the position survive, and every field the new call leaves out goes back to
58
+ * its default rather than lingering from the previous one. A first push with
59
+ * a `title` and an `error` variant followed by a bare
60
+ * `push({ key, message })` is a plain info toast, not the old error wearing
61
+ * a new sentence. The displaced message's `onDismiss` fires with reason
62
+ * `replaced` before the new one takes the slot.
63
+ */
64
+ key?: string;
65
+ /**
66
+ * Survive a route change.
67
+ *
68
+ * A toast is scoped to the moment, and the moment usually ends with the
69
+ * route: "Draft saved" outliving the draft's page is news about a screen
70
+ * the user has left, and its `Undo` acts on a record they can no longer
71
+ * see. `dismissTransient()`, called from a router guard, clears everything
72
+ * that does not set this.
73
+ *
74
+ * Set it for news that is true wherever the user ends up: "Signed out",
75
+ * "Export ready", "Connection restored".
76
+ */
77
+ retain?: boolean;
78
+ /**
79
+ * Called once, when the toast leaves the queue, with the reason it left.
80
+ *
81
+ * This is the observation point the CTA pattern needs. "Deleted. [Undo]"
82
+ * only works if something commits the delete when the toast goes and
83
+ * cancels it when Undo is pressed, and the difference between those two is
84
+ * exactly the reason:
85
+ *
86
+ * ```ts
87
+ * let undone = false
88
+ * toast.push({
89
+ * message: 'Comment deleted',
90
+ * cta: { label: 'Undo', action: () => { undone = true; restore(row) } },
91
+ * onDismiss: (reason) => { if (!undone) commitDelete(row) },
92
+ * })
93
+ * ```
94
+ *
95
+ * It fires exactly once per pushed message, and the reason is always the
96
+ * true one. Two rules keep that promise:
97
+ *
98
+ * - `update()` is not an end of life, so a progress toast that becomes a
99
+ * result calls it once, at the end. `update()` therefore cannot change
100
+ * the callback either: it is not in `TToastPatch`.
101
+ * - A second `push()` sharing a `key` is a *different* message taking over
102
+ * the slot, so the message being displaced ends first, with reason
103
+ * `replaced`, and the new callback takes over from there. Deleting row 1
104
+ * and then row 2 under one key commits row 1 and then row 2, in that
105
+ * order, rather than committing row 1 twice.
106
+ */
107
+ onDismiss?: (reason: TToastDismissReason) => void;
108
+ }
109
+ /**
110
+ * A partial change to a live toast, as accepted by `IToastHandle.update()`.
111
+ *
112
+ * `onDismiss` is deliberately not in it. The callback is the commit point of
113
+ * the message that was pushed, and an update only rewrites the words of that
114
+ * same message: swapping the callback halfway would either drop a commit or
115
+ * run it twice, which is the one thing this queue promises never to do. When
116
+ * the *message* really is a new one, push it (with a `key` if it should reuse
117
+ * the slot) and the queue ends the old one first, with reason `replaced`.
118
+ *
119
+ * Passing it anyway is ignored, and warns outside production.
120
+ */
121
+ export type TToastPatch = Omit<Partial<IToastOptions>, 'onDismiss'>;
122
+ /** A queued toast, as `NbToaster` reads it. */
123
+ export interface IToastRecord extends IToastOptions {
124
+ /** Queue-unique id. Stable for the life of the toast. */
125
+ id: string;
126
+ variant: TToastVariant;
127
+ /** Resolved duration: never undefined here, `0` means persistent. */
128
+ duration: number;
129
+ /** `true` once it holds one of the visible slots. */
130
+ visible: boolean;
131
+ /**
132
+ * Incremented every time the countdown restarts (admission, or an update
133
+ * that changed the message). `NbToaster` keys the timer bar on it so the
134
+ * bar restarts with the clock instead of continuing from where it was.
135
+ */
136
+ cycle: number;
137
+ }
138
+ /**
139
+ * What `push()` hands back so the caller can keep talking about a toast it
140
+ * created: the save-in-progress that becomes a save-succeeded.
141
+ */
142
+ export interface IToastHandle {
143
+ /** The record id, for `queue.dismiss(id)` or logging. */
144
+ readonly id: string;
145
+ /**
146
+ * Rewrite the toast in place. It keeps its slot and its position, so the
147
+ * stack does not jump. The countdown restarts, because the words changed
148
+ * and the reader has not seen the new ones yet.
149
+ *
150
+ * Passing a `variant` without a `duration` adopts that variant's default,
151
+ * which is what turns a persistent "Saving..." into a self-clearing
152
+ * "Saved". Fields left out of the patch are left alone.
153
+ *
154
+ * `onDismiss` is not patchable: see `TToastPatch`.
155
+ */
156
+ update(patch: TToastPatch): void;
157
+ /**
158
+ * Remove it now. Safe to call after it has already gone. The reason is
159
+ * forwarded to `onDismiss`; it defaults to `user` because the usual caller
160
+ * is a control the reader pressed.
161
+ */
162
+ dismiss(reason?: TToastDismissReason): void;
163
+ /** `false` once it has been dismissed or has expired. */
164
+ isActive(): boolean;
165
+ }
166
+ /** Options for a standalone queue. */
167
+ export interface IToastQueueOptions {
168
+ /** How many toasts may be on screen at once. Default `3`. */
169
+ max?: number;
170
+ /** Per-variant duration overrides, merged over `NB_TOAST_DURATIONS`. */
171
+ durations?: Partial<Record<TToastVariant, number>>;
172
+ /**
173
+ * The visually hidden severity word each variant is announced with, for
174
+ * applications that are not in English. Merged over `NB_TOAST_STATUS_LABELS`.
175
+ * An empty string suppresses the word for that variant.
176
+ */
177
+ statusLabels?: Partial<Record<TToastVariant, string>>;
178
+ /** Accessible name of every close button in this queue. */
179
+ closeLabel?: string;
180
+ }
181
+ /** The strings `NbToaster` reads out of its queue. */
182
+ export interface IToastLabels {
183
+ status: Record<TToastVariant, string>;
184
+ close: string;
185
+ }
186
+ /** The queue object shared by `useToast()` and `NbToaster`. */
187
+ export interface IToastQueue {
188
+ /** Everything queued: the visible slots first, then whatever is waiting. */
189
+ readonly items: ComputedRef<IToastRecord[]>;
190
+ /** The records `NbToaster` renders, oldest first. */
191
+ readonly visible: ComputedRef<IToastRecord[]>;
192
+ /** Records admitted but waiting for a free slot. */
193
+ readonly pending: ComputedRef<IToastRecord[]>;
194
+ /** `true` while the clock is held (pointer, focus, or a hidden tab). */
195
+ readonly paused: Ref<boolean>;
196
+ /** Visible-slot cap. Writable, so a host can widen it for one screen. */
197
+ readonly max: Ref<number>;
198
+ /**
199
+ * Translated strings for this queue. `NbToaster` passes them to every
200
+ * toast, so a Spanish product states them once instead of per call.
201
+ */
202
+ readonly labels: IToastLabels;
203
+ /** Queue a toast. Returns the handle. */
204
+ push(options: IToastOptions): IToastHandle;
205
+ /** `variant: 'info'`, message-first for the common call. */
206
+ info(message: string, options?: Omit<IToastOptions, 'message' | 'variant'>): IToastHandle;
207
+ /** `variant: 'success'`. */
208
+ success(message: string, options?: Omit<IToastOptions, 'message' | 'variant'>): IToastHandle;
209
+ /** `variant: 'warning'`. */
210
+ warning(message: string, options?: Omit<IToastOptions, 'message' | 'variant'>): IToastHandle;
211
+ /** `variant: 'error'`. Persistent by default. */
212
+ error(message: string, options?: Omit<IToastOptions, 'message' | 'variant'>): IToastHandle;
213
+ /** Rewrite a live toast by id, field by field. No-op if it has gone. */
214
+ update(id: string, patch: TToastPatch): void;
215
+ /** Remove one toast and let the next pending one in. */
216
+ dismiss(id: string, reason?: TToastDismissReason): void;
217
+ /**
218
+ * Clear the whole queue, visible and pending, `retain` included. Sign-out,
219
+ * tenant switch, anything after which no queued message is still true.
220
+ */
221
+ dismissAll(reason?: TToastDismissReason): void;
222
+ /**
223
+ * Clear everything that did not ask to survive a route change. Call it from
224
+ * a router guard:
225
+ *
226
+ * ```ts
227
+ * router.afterEach(() => toast.dismissTransient())
228
+ * ```
229
+ *
230
+ * Nothing in this file knows about a router, and it must not: the library
231
+ * has no dependency on one and cannot guess whether a product's tab switch
232
+ * is a navigation. The queue provides the operation, the application says
233
+ * when.
234
+ */
235
+ dismissTransient(reason?: TToastDismissReason): void;
236
+ /** Hold every countdown. Idempotent. */
237
+ pause(): void;
238
+ /** Resume from the exact remaining time, not from the start. */
239
+ resume(): void;
240
+ /** Remaining milliseconds for a record, for tests and instrumentation. */
241
+ remaining(id: string): number;
242
+ }
243
+ /**
244
+ * Default time on screen, per variant.
245
+ *
246
+ * The scale is reading time, not importance: a success is four words the user
247
+ * expected, a warning is a sentence they did not. An error stays until it is
248
+ * dismissed, because "it failed" is the start of a task and a message that
249
+ * removes itself before the user can act on it is worse than no message.
250
+ */
251
+ export declare const NB_TOAST_DURATIONS: Record<TToastVariant, number>;
252
+ /**
253
+ * The word a screen reader hears before the message, per variant.
254
+ *
255
+ * Severity is otherwise carried by an icon (aria-hidden) and an accent colour,
256
+ * which is exactly the WCAG 1.4.1 failure: "Could not reach the server" with
257
+ * no indication that it is an error. Override the map per queue rather than
258
+ * per toast when the product is not in English.
259
+ */
260
+ export declare const NB_TOAST_STATUS_LABELS: Record<TToastVariant, string>;
261
+ /**
262
+ * Build an isolated queue. Applications use `useToast()`, which shares one
263
+ * queue per page; tests and stories want their own so one spec cannot leave a
264
+ * toast behind for the next.
265
+ */
266
+ export declare function createToastQueue(options?: IToastQueueOptions): IToastQueue;
267
+ /**
268
+ * Injection key for a queue scoped to one application instance.
269
+ *
270
+ * ```ts
271
+ * app.provide(NB_TOAST_QUEUE_KEY, createToastQueue())
272
+ * ```
273
+ *
274
+ * `useToast()` prefers it whenever it is called from a component, and
275
+ * `NbToaster` renders it without being given a `:queue`. Two reasons to use
276
+ * it: server rendering, where a module-level singleton is shared by every
277
+ * request the Node process is handling concurrently, and a host application
278
+ * that mounts several Vue apps in one page and does not want one app's toasts
279
+ * announced by another's toaster.
280
+ *
281
+ * It cannot be reached from a plain module (a service, a router guard, a
282
+ * store action) because there is no component instance there, which is why the
283
+ * shared queue below stays the default rather than being replaced by this.
284
+ */
285
+ export declare const NB_TOAST_QUEUE_KEY: InjectionKey<IToastQueue>;
286
+ /**
287
+ * The toast queue for the current context.
288
+ *
289
+ * Inside a component, an app-scoped queue provided under
290
+ * `NB_TOAST_QUEUE_KEY` wins. Everywhere else, and when nothing was provided,
291
+ * this is one shared queue per page, created on first use, so a service
292
+ * module, a route guard and a deeply nested component all reach the same
293
+ * stack without prop drilling or a plugin install. Mount a single
294
+ * `<NbToaster />` to render it.
295
+ *
296
+ * @example
297
+ * const toast = useToast()
298
+ * toast.success('Draft saved')
299
+ *
300
+ * @example Progress that resolves into its own result
301
+ * const saving = toast.info('Saving changes...', { duration: 0 })
302
+ * try {
303
+ * await save()
304
+ * saving.update({ variant: 'success', message: 'Changes saved' })
305
+ * } catch {
306
+ * saving.update({ variant: 'error', message: 'Could not save changes' })
307
+ * }
308
+ */
309
+ export declare function useToast(): IToastQueue;
310
+ /**
311
+ * Drop the shared queue, clearing whatever was in it.
312
+ *
313
+ * For tests, so one spec cannot leave a toast behind for the next, and for a
314
+ * single-render script (a static build, a prerender pass) that wants the
315
+ * module back in its initial state.
316
+ *
317
+ * It is not request isolation. A module-level singleton is shared by every
318
+ * request a Node process is serving at once, and resetting it globally
319
+ * between awaits would empty a queue another request is still filling. Server
320
+ * rendering with concurrent requests wants a queue per application instance:
321
+ * `app.provide(NB_TOAST_QUEUE_KEY, createToastQueue())`, which is scoped to
322
+ * the app that `createSSRApp()` returned and dies with it.
323
+ */
324
+ export declare function resetToastQueue(): void;
325
+ //# sourceMappingURL=useToast.composable.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useToast.composable.d.ts","sourceRoot":"","sources":["../../src/composables/useToast.composable.ts"],"names":[],"mappings":"AAAA,OAAO,EAKL,KAAK,WAAW,EAChB,KAAK,YAAY,EACjB,KAAK,GAAG,EACT,MAAM,KAAK,CAAA;AACZ,OAAO,KAAK,EAAE,aAAa,EAAE,SAAS,EAAE,MAAM,yBAAyB,CAAA;AAEvE;;;;;;;;;;;;GAYG;AAEH;;;;;;;;;;;;;;GAcG;AACH,MAAM,MAAM,mBAAmB,GAC3B,MAAM,GACN,SAAS,GACT,QAAQ,GACR,UAAU,GACV,WAAW,GACX,SAAS,CAAA;AAEb,6EAA6E;AAC7E,MAAM,WAAW,aAAa;IAC5B,2EAA2E;IAC3E,OAAO,EAAE,MAAM,CAAA;IACf,4EAA4E;IAC5E,OAAO,CAAC,EAAE,aAAa,CAAA;IACvB,6EAA6E;IAC7E,KAAK,CAAC,EAAE,MAAM,CAAA;IACd;;;OAGG;IACH,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB;;;;OAIG;IACH,GAAG,CAAC,EAAE,SAAS,CAAA;IACf;;;;;;;;;;;;OAYG;IACH,GAAG,CAAC,EAAE,MAAM,CAAA;IACZ;;;;;;;;;;;OAWG;IACH,MAAM,CAAC,EAAE,OAAO,CAAA;IAChB;;;;;;;;;;;;;;;;;;;;;;;;;;;;OA4BG;IACH,SAAS,CAAC,EAAE,CAAC,MAAM,EAAE,mBAAmB,KAAK,IAAI,CAAA;CAClD;AAED;;;;;;;;;;;GAWG;AACH,MAAM,MAAM,WAAW,GAAG,IAAI,CAAC,OAAO,CAAC,aAAa,CAAC,EAAE,WAAW,CAAC,CAAA;AAEnE,+CAA+C;AAC/C,MAAM,WAAW,YAAa,SAAQ,aAAa;IACjD,yDAAyD;IACzD,EAAE,EAAE,MAAM,CAAA;IACV,OAAO,EAAE,aAAa,CAAA;IACtB,qEAAqE;IACrE,QAAQ,EAAE,MAAM,CAAA;IAChB,qDAAqD;IACrD,OAAO,EAAE,OAAO,CAAA;IAChB;;;;OAIG;IACH,KAAK,EAAE,MAAM,CAAA;CACd;AAED;;;GAGG;AACH,MAAM,WAAW,YAAY;IAC3B,yDAAyD;IACzD,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAA;IACnB;;;;;;;;;;OAUG;IACH,MAAM,CAAC,KAAK,EAAE,WAAW,GAAG,IAAI,CAAA;IAChC;;;;OAIG;IACH,OAAO,CAAC,MAAM,CAAC,EAAE,mBAAmB,GAAG,IAAI,CAAA;IAC3C,yDAAyD;IACzD,QAAQ,IAAI,OAAO,CAAA;CACpB;AAED,sCAAsC;AACtC,MAAM,WAAW,kBAAkB;IACjC,6DAA6D;IAC7D,GAAG,CAAC,EAAE,MAAM,CAAA;IACZ,wEAAwE;IACxE,SAAS,CAAC,EAAE,OAAO,CAAC,MAAM,CAAC,aAAa,EAAE,MAAM,CAAC,CAAC,CAAA;IAClD;;;;OAIG;IACH,YAAY,CAAC,EAAE,OAAO,CAAC,MAAM,CAAC,aAAa,EAAE,MAAM,CAAC,CAAC,CAAA;IACrD,2DAA2D;IAC3D,UAAU,CAAC,EAAE,MAAM,CAAA;CACpB;AAED,sDAAsD;AACtD,MAAM,WAAW,YAAY;IAC3B,MAAM,EAAE,MAAM,CAAC,aAAa,EAAE,MAAM,CAAC,CAAA;IACrC,KAAK,EAAE,MAAM,CAAA;CACd;AAED,+DAA+D;AAC/D,MAAM,WAAW,WAAW;IAC1B,4EAA4E;IAC5E,QAAQ,CAAC,KAAK,EAAE,WAAW,CAAC,YAAY,EAAE,CAAC,CAAA;IAC3C,qDAAqD;IACrD,QAAQ,CAAC,OAAO,EAAE,WAAW,CAAC,YAAY,EAAE,CAAC,CAAA;IAC7C,oDAAoD;IACpD,QAAQ,CAAC,OAAO,EAAE,WAAW,CAAC,YAAY,EAAE,CAAC,CAAA;IAC7C,wEAAwE;IACxE,QAAQ,CAAC,MAAM,EAAE,GAAG,CAAC,OAAO,CAAC,CAAA;IAC7B,yEAAyE;IACzE,QAAQ,CAAC,GAAG,EAAE,GAAG,CAAC,MAAM,CAAC,CAAA;IACzB;;;OAGG;IACH,QAAQ,CAAC,MAAM,EAAE,YAAY,CAAA;IAC7B,yCAAyC;IACzC,IAAI,CAAC,OAAO,EAAE,aAAa,GAAG,YAAY,CAAA;IAC1C,4DAA4D;IAC5D,IAAI,CACF,OAAO,EAAE,MAAM,EACf,OAAO,CAAC,EAAE,IAAI,CAAC,aAAa,EAAE,SAAS,GAAG,SAAS,CAAC,GACnD,YAAY,CAAA;IACf,4BAA4B;IAC5B,OAAO,CACL,OAAO,EAAE,MAAM,EACf,OAAO,CAAC,EAAE,IAAI,CAAC,aAAa,EAAE,SAAS,GAAG,SAAS,CAAC,GACnD,YAAY,CAAA;IACf,4BAA4B;IAC5B,OAAO,CACL,OAAO,EAAE,MAAM,EACf,OAAO,CAAC,EAAE,IAAI,CAAC,aAAa,EAAE,SAAS,GAAG,SAAS,CAAC,GACnD,YAAY,CAAA;IACf,iDAAiD;IACjD,KAAK,CACH,OAAO,EAAE,MAAM,EACf,OAAO,CAAC,EAAE,IAAI,CAAC,aAAa,EAAE,SAAS,GAAG,SAAS,CAAC,GACnD,YAAY,CAAA;IACf,wEAAwE;IACxE,MAAM,CAAC,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE,WAAW,GAAG,IAAI,CAAA;IAC5C,wDAAwD;IACxD,OAAO,CAAC,EAAE,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,mBAAmB,GAAG,IAAI,CAAA;IACvD;;;OAGG;IACH,UAAU,CAAC,MAAM,CAAC,EAAE,mBAAmB,GAAG,IAAI,CAAA;IAC9C;;;;;;;;;;;;OAYG;IACH,gBAAgB,CAAC,MAAM,CAAC,EAAE,mBAAmB,GAAG,IAAI,CAAA;IACpD,wCAAwC;IACxC,KAAK,IAAI,IAAI,CAAA;IACb,gEAAgE;IAChE,MAAM,IAAI,IAAI,CAAA;IACd,0EAA0E;IAC1E,SAAS,CAAC,EAAE,EAAE,MAAM,GAAG,MAAM,CAAA;CAC9B;AAED;;;;;;;GAOG;AACH,eAAO,MAAM,kBAAkB,EAAE,MAAM,CAAC,aAAa,EAAE,MAAM,CAK5D,CAAA;AAED;;;;;;;GAOG;AACH,eAAO,MAAM,sBAAsB,EAAE,MAAM,CAAC,aAAa,EAAE,MAAM,CAKhE,CAAA;AAUD;;;;GAIG;AACH,wBAAgB,gBAAgB,CAC9B,OAAO,GAAE,kBAAuB,GAC/B,WAAW,CAsSb;AAID;;;;;;;;;;;;;;;;;GAiBG;AACH,eAAO,MAAM,kBAAkB,EAAE,YAAY,CAAC,WAAW,CAC/B,CAAA;AAE1B;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,wBAAgB,QAAQ,IAAI,WAAW,CAStC;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAgB,eAAe,SAG9B"}
@@ -0,0 +1,20 @@
1
+ /**
2
+ * Tooltip content rendering, and nothing else.
3
+ *
4
+ * Split out of `ToolTip.directive.ts` because it answers a different question
5
+ * from the rest of it. Everything in that file is about WHEN a chip exists
6
+ * and WHERE it sits; everything here is about what is allowed inside one when
7
+ * the text did not come from the person writing the template. The two change
8
+ * for unrelated reasons: a new allowed tag is a security review, a new
9
+ * placement rule is a layout bug.
10
+ *
11
+ * Private to the directive. Nothing here is part of the public API.
12
+ */
13
+ import type { IComponentContent } from '../types/ContentRenderer';
14
+ declare const devWarn: (key: string, message: string) => void;
15
+ /**
16
+ * Renders tooltip content - supports both string and complex content structure
17
+ */
18
+ declare const renderTooltipContent: (content: string | Array<IComponentContent> | undefined | null) => string;
19
+ export { renderTooltipContent, devWarn };
20
+ //# sourceMappingURL=ToolTip.content.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ToolTip.content.d.ts","sourceRoot":"","sources":["../../src/directives/ToolTip.content.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AACH,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,yBAAyB,CAAA;AAwPhE,QAAA,MAAM,OAAO,GAAI,KAAK,MAAM,EAAE,SAAS,MAAM,SAM5C,CAAA;AA2DD;;GAEG;AACH,QAAA,MAAM,oBAAoB,GACxB,SAAS,MAAM,GAAG,KAAK,CAAC,iBAAiB,CAAC,GAAG,SAAS,GAAG,IAAI,KAC5D,MAYF,CAAA;AAED,OAAO,EAAE,oBAAoB,EAAE,OAAO,EAAE,CAAA"}