vue3-router-tab 1.0.9 → 1.1.1

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/index.d.ts DELETED
@@ -1,134 +0,0 @@
1
- import type { App, Plugin } from 'vue'
2
- import type { RouteLocationRaw } from 'vue-router'
3
- import type {
4
- TabRecord,
5
- TabInput,
6
- RouterTabsOptions,
7
- CloseTabOptions,
8
- RouterTabsContext,
9
- RouterTabsMenuConfig,
10
- RouterTabsMenuItem,
11
- RouterTabsMenuPreset,
12
- RouterTabsSnapshot,
13
- RouterTabsSnapshotTab
14
- } from './lib/core/types'
15
-
16
- export type {
17
- TabRecord,
18
- TabInput,
19
- RouterTabsOptions,
20
- CloseTabOptions,
21
- RouterTabsContext,
22
- RouterTabsMenuConfig,
23
- RouterTabsMenuItem,
24
- RouterTabsMenuPreset,
25
- RouterTabsSnapshot,
26
- RouterTabsSnapshotTab
27
- }
28
-
29
- export declare const routerTabsKey: import('vue').InjectionKey<RouterTabsContext>
30
-
31
- export declare function useRouterTabs(options?: { optional?: boolean }): RouterTabsContext | null
32
-
33
- export interface RouterTabsPiniaOptions {
34
- storeId?: string
35
- storageKey?: string
36
- storage?: Storage | null
37
- fallbackRoute?: import('vue-router').RouteLocationRaw
38
- }
39
-
40
- export declare function useRouterTabsPiniaPersistence(options?: RouterTabsPiniaOptions & { store?: import('pinia').StoreDefinition<any, any, any, any> }): import('pinia').Store<any, any, any, any>
41
-
42
- export declare const RouterTabsPinia: import('vue').DefineComponent<RouterTabsPiniaOptions, {}, {}, {}, {}, import('vue').ComponentOptionsMixin, import('vue').ComponentOptionsMixin, {}, string, import('vue').VNodeProps & import('vue').AllowedComponentProps & import('vue').ComponentCustomProps, Readonly<RouterTabsPiniaOptions>, {}>
43
-
44
- export declare const RouterTab: import('vue').DefineComponent<{
45
- tabs: {
46
- type: import('vue').PropType<TabInput[]>
47
- default: () => TabInput[]
48
- }
49
- keepAlive: {
50
- type: BooleanConstructor
51
- default: boolean
52
- }
53
- maxAlive: {
54
- type: NumberConstructor
55
- default: number
56
- }
57
- keepLastTab: {
58
- type: BooleanConstructor
59
- default: boolean
60
- }
61
- append: {
62
- type: import('vue').PropType<'last' | 'next'>
63
- default: 'last' | 'next'
64
- }
65
- defaultPage: {
66
- type: import('vue').PropType<RouteLocationRaw>
67
- default: RouteLocationRaw
68
- }
69
- tabTransition: {
70
- type: import('vue').PropType<import('./lib/core/types').TransitionLike>
71
- default: string | import('./lib/core/types').TransitionLike
72
- }
73
- pageTransition: {
74
- type: import('vue').PropType<import('./lib/core/types').TransitionLike>
75
- default: () => import('./lib/core/types').TransitionLike
76
- }
77
- contextmenu: {
78
- type: import('vue').PropType<boolean | RouterTabsMenuConfig[]>
79
- default: true
80
- }
81
- storage: {
82
- type: BooleanConstructor | StringConstructor
83
- default: boolean
84
- }
85
- }, any, any, {}, {}, import('vue').ComponentOptionsMixin, import('vue').ComponentOptionsMixin, Record<string, any>, string, import('vue').VNodeProps & import('vue').AllowedComponentProps & import('vue').ComponentCustomProps, Readonly<{
86
- tabs?: TabInput[] | undefined
87
- keepAlive?: boolean | undefined
88
- maxAlive?: number | undefined
89
- keepLastTab?: boolean | undefined
90
- append?: 'last' | 'next' | undefined
91
- defaultPage?: RouteLocationRaw | undefined
92
- tabTransition?: import('./lib/core/types').TransitionLike | undefined
93
- pageTransition?: import('./lib/core/types').TransitionLike | undefined
94
- contextmenu?: boolean | RouterTabsMenuConfig[] | undefined
95
- storage?: boolean | string | undefined
96
- }> & {
97
- tabs?: TabInput[] | undefined
98
- keepAlive?: boolean | undefined
99
- maxAlive?: number | undefined
100
- keepLastTab?: boolean | undefined
101
- append?: 'last' | 'next' | undefined
102
- defaultPage?: RouteLocationRaw | undefined
103
- tabTransition?: import('./lib/core/types').TransitionLike | undefined
104
- pageTransition?: import('./lib/core/types').TransitionLike | undefined
105
- contextmenu?: boolean | RouterTabsMenuConfig[] | undefined
106
- storage?: boolean | string | undefined
107
- }, {
108
- tabs: TabInput[]
109
- keepAlive: boolean
110
- maxAlive: number
111
- keepLastTab: boolean
112
- append: 'last' | 'next'
113
- defaultPage: RouteLocationRaw
114
- tabTransition: import('./lib/core/types').TransitionLike
115
- pageTransition: import('./lib/core/types').TransitionLike
116
- contextmenu: true
117
- storage: boolean
118
- }>
119
-
120
- export interface RouterTabPlugin extends Plugin {}
121
-
122
- declare const plugin: RouterTabPlugin
123
-
124
- export default plugin
125
-
126
- declare module '@vue/runtime-core' {
127
- interface ComponentCustomProperties {
128
- $tabs: RouterTabsContext | null
129
- }
130
- }
131
- declare module './constants' {
132
- const value: any;
133
- export = value;
134
- }
@@ -1,13 +0,0 @@
1
- <template>
2
- <span class="router-tabs" aria-hidden="true" />
3
- </template>
4
-
5
- <script setup lang="ts">
6
- import { useRouterTabsPiniaPersistence } from '../pinia'
7
- defineOptions({ name: 'RouterTabs' })
8
- import type { RouterTabsPiniaOptions } from '../pinia'
9
-
10
- const props = defineProps<RouterTabsPiniaOptions>()
11
-
12
- useRouterTabsPiniaPersistence(props as RouterTabsPiniaOptions)
13
- </script>
package/lib/pinia.ts DELETED
@@ -1,149 +0,0 @@
1
- import { defineStore, type StoreDefinition } from 'pinia'
2
- import { onMounted, ref, watch } from 'vue'
3
- import type { RouteLocationRaw } from 'vue-router'
4
- import { useRouterTabs } from './useRouterTabs'
5
- import type { RouterTabsSnapshot } from './core/types'
6
-
7
- export interface RouterTabsPiniaOptions {
8
- /** Pinia store id. Defaults to 'routerTabs'. */
9
- storeId?: string
10
- /** Storage key used when persisting snapshots. Defaults to 'router-tabs:persistent'. */
11
- storageKey?: string
12
- /** Custom storage implementation (e.g. localStorage, sessionStorage). Defaults to window.localStorage. */
13
- storage?: Storage | null
14
- /** Fallback route to open when no snapshot exists. Defaults to RouterTab's default route. */
15
- fallbackRoute?: RouteLocationRaw
16
- /** Provide a custom store definition if you want to control persistence yourself. */
17
- store?: StoreDefinition<'routerTabs', { snapshot: RouterTabsSnapshot | null }, {}, { load(): void; setSnapshot(snapshot: RouterTabsSnapshot | null): void; clear(): void }>
18
- }
19
-
20
- const defaultStorageKey = 'router-tabs:persistent'
21
-
22
- function resolveStorage(storage?: Storage | null): Storage | null {
23
- if (typeof window === 'undefined') return null
24
- if (storage === undefined) return window.localStorage ?? null
25
- return storage
26
- }
27
-
28
- function createDefaultStore(options: RouterTabsPiniaOptions) {
29
- const storage = resolveStorage(options.storage)
30
- const key = options.storageKey ?? defaultStorageKey
31
-
32
- return defineStore(options.storeId ?? 'routerTabs', {
33
- state: () => ({
34
- snapshot: null as RouterTabsSnapshot | null
35
- }),
36
- actions: {
37
- load() {
38
- if (!storage || this.snapshot) return
39
- try {
40
- const raw = storage.getItem(key)
41
- if (raw) {
42
- this.snapshot = JSON.parse(raw)
43
- }
44
- } catch (error) {
45
- if (import.meta.env?.DEV) {
46
- console.warn('[RouterTabs] Failed to load snapshot from storage', error)
47
- }
48
- }
49
- },
50
- setSnapshot(snapshot: RouterTabsSnapshot | null) {
51
- this.snapshot = snapshot
52
- if (!storage) return
53
-
54
- try {
55
- if (snapshot && snapshot.tabs.length) {
56
- storage.setItem(key, JSON.stringify(snapshot))
57
- } else {
58
- storage.removeItem(key)
59
- }
60
- } catch (error) {
61
- if (import.meta.env?.DEV) {
62
- console.warn('[RouterTabs] Failed to persist snapshot to storage', error)
63
- }
64
- }
65
- },
66
- clear() {
67
- this.setSnapshot(null)
68
- }
69
- }
70
- })
71
- }
72
-
73
- /**
74
- * Synchronise RouterTab state with a Pinia store so tab snapshots persist across reloads.
75
- *
76
- * ```ts
77
- * const store = useRouterTabsPiniaPersistence()
78
- * ```
79
- */
80
- export function useRouterTabsPiniaPersistence(options: RouterTabsPiniaOptions = {}) {
81
- const Store = options.store ?? createDefaultStore(options)
82
- const store = Store()
83
- const hydrating = ref(false)
84
- let initialized = false
85
-
86
- const attemptSetup = (controller: NonNullable<ReturnType<typeof useRouterTabs>>) => {
87
- if (!controller || initialized) return
88
- initialized = true
89
-
90
- onMounted(async () => {
91
- store.load()
92
- const snapshot = store.snapshot
93
-
94
- if (snapshot && snapshot.tabs?.length) {
95
- try {
96
- hydrating.value = true
97
- await controller.hydrate(snapshot)
98
- } finally {
99
- hydrating.value = false
100
- }
101
- } else {
102
- try {
103
- hydrating.value = true
104
- const fallback = options.fallbackRoute ?? controller.options.defaultRoute
105
- await controller.reset(fallback)
106
- } finally {
107
- hydrating.value = false
108
- }
109
- }
110
-
111
- store.setSnapshot(controller.snapshot())
112
- })
113
-
114
- watch(
115
- () => ({
116
- tabs: controller.tabs.map(tab => ({
117
- to: tab.to,
118
- title: tab.title,
119
- tips: tab.tips,
120
- icon: tab.icon,
121
- tabClass: tab.tabClass,
122
- closable: tab.closable
123
- })),
124
- active: controller.activeId.value
125
- }),
126
- () => {
127
- if (hydrating.value) return
128
- store.setSnapshot(controller.snapshot())
129
- },
130
- { deep: true }
131
- )
132
- }
133
-
134
- const controller = useRouterTabs({ optional: true })
135
- if (controller) {
136
- attemptSetup(controller)
137
- } else {
138
- onMounted(() => {
139
- const lateController = useRouterTabs({ optional: true })
140
- if (lateController) {
141
- attemptSetup(lateController)
142
- } else if (import.meta.env?.DEV) {
143
- console.warn('[RouterTabs] Pinia helper must be used inside <router-tab>.')
144
- }
145
- })
146
- }
147
-
148
- return store
149
- }