@vuecs/navigation 1.1.1 → 2.1.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 (98) hide show
  1. package/README.md +54 -142
  2. package/dist/components/index.d.ts +1 -1
  3. package/dist/components/index.d.ts.map +1 -1
  4. package/dist/components/item/index.d.ts +2 -0
  5. package/dist/components/item/index.d.ts.map +1 -0
  6. package/dist/components/item/module.d.ts +16 -0
  7. package/dist/components/item/module.d.ts.map +1 -0
  8. package/dist/components/items/index.d.ts +2 -0
  9. package/dist/components/items/index.d.ts.map +1 -0
  10. package/dist/components/items/module.d.ts +27 -0
  11. package/dist/components/items/module.d.ts.map +1 -0
  12. package/dist/helpers/component/build.d.ts +3 -0
  13. package/dist/helpers/component/build.d.ts.map +1 -0
  14. package/dist/helpers/component/index.d.ts +3 -0
  15. package/dist/helpers/component/index.d.ts.map +1 -0
  16. package/dist/helpers/component/types.d.ts +17 -0
  17. package/dist/helpers/component/types.d.ts.map +1 -0
  18. package/dist/helpers/index.d.ts +8 -0
  19. package/dist/helpers/index.d.ts.map +1 -0
  20. package/dist/helpers/level.d.ts +11 -0
  21. package/dist/helpers/level.d.ts.map +1 -0
  22. package/dist/helpers/match.d.ts +7 -0
  23. package/dist/helpers/match.d.ts.map +1 -0
  24. package/dist/helpers/normalize.d.ts +8 -0
  25. package/dist/helpers/normalize.d.ts.map +1 -0
  26. package/dist/helpers/reset.d.ts +3 -0
  27. package/dist/helpers/reset.d.ts.map +1 -0
  28. package/dist/helpers/trace.d.ts +3 -0
  29. package/dist/helpers/trace.d.ts.map +1 -0
  30. package/dist/helpers/url.d.ts.map +1 -0
  31. package/dist/index.cjs +456 -456
  32. package/dist/index.cjs.map +1 -1
  33. package/dist/index.css +87 -0
  34. package/dist/index.d.ts +4 -6
  35. package/dist/index.d.ts.map +1 -1
  36. package/dist/index.mjs +455 -452
  37. package/dist/index.mjs.map +1 -1
  38. package/dist/manager/index.d.ts +4 -0
  39. package/dist/manager/index.d.ts.map +1 -0
  40. package/dist/manager/module.d.ts +20 -0
  41. package/dist/manager/module.d.ts.map +1 -0
  42. package/dist/manager/singleton.d.ts +5 -0
  43. package/dist/manager/singleton.d.ts.map +1 -0
  44. package/dist/manager/types.d.ts +9 -0
  45. package/dist/manager/types.d.ts.map +1 -0
  46. package/dist/types.d.ts +33 -0
  47. package/dist/types.d.ts.map +1 -0
  48. package/package.json +10 -6
  49. package/dist/components/item.d.ts +0 -26
  50. package/dist/components/item.d.ts.map +0 -1
  51. package/dist/components/items.d.ts +0 -27
  52. package/dist/components/items.d.ts.map +0 -1
  53. package/dist/core/build.d.ts +0 -4
  54. package/dist/core/build.d.ts.map +0 -1
  55. package/dist/core/check.d.ts +0 -3
  56. package/dist/core/check.d.ts.map +0 -1
  57. package/dist/core/expansion.d.ts +0 -6
  58. package/dist/core/expansion.d.ts.map +0 -1
  59. package/dist/core/flatten.d.ts +0 -3
  60. package/dist/core/flatten.d.ts.map +0 -1
  61. package/dist/core/index.d.ts +0 -12
  62. package/dist/core/index.d.ts.map +0 -1
  63. package/dist/core/match.d.ts +0 -3
  64. package/dist/core/match.d.ts.map +0 -1
  65. package/dist/core/reduce.d.ts +0 -8
  66. package/dist/core/reduce.d.ts.map +0 -1
  67. package/dist/core/refresh.d.ts +0 -3
  68. package/dist/core/refresh.d.ts.map +0 -1
  69. package/dist/core/replace.d.ts +0 -6
  70. package/dist/core/replace.d.ts.map +0 -1
  71. package/dist/core/reset.d.ts +0 -3
  72. package/dist/core/reset.d.ts.map +0 -1
  73. package/dist/core/select.d.ts +0 -4
  74. package/dist/core/select.d.ts.map +0 -1
  75. package/dist/core/tier.d.ts +0 -7
  76. package/dist/core/tier.d.ts.map +0 -1
  77. package/dist/core/toggle.d.ts +0 -4
  78. package/dist/core/toggle.d.ts.map +0 -1
  79. package/dist/module.d.ts +0 -3
  80. package/dist/module.d.ts.map +0 -1
  81. package/dist/provider/index.d.ts +0 -3
  82. package/dist/provider/index.d.ts.map +0 -1
  83. package/dist/provider/module.d.ts +0 -5
  84. package/dist/provider/module.d.ts.map +0 -1
  85. package/dist/provider/type.d.ts +0 -8
  86. package/dist/provider/type.d.ts.map +0 -1
  87. package/dist/store/index.d.ts +0 -3
  88. package/dist/store/index.d.ts.map +0 -1
  89. package/dist/store/module.d.ts +0 -7
  90. package/dist/store/module.d.ts.map +0 -1
  91. package/dist/store/type.d.ts +0 -16
  92. package/dist/store/type.d.ts.map +0 -1
  93. package/dist/type.d.ts +0 -27
  94. package/dist/type.d.ts.map +0 -1
  95. package/dist/utils/index.d.ts +0 -2
  96. package/dist/utils/index.d.ts.map +0 -1
  97. package/dist/utils/url.d.ts.map +0 -1
  98. /package/dist/{utils → helpers}/url.d.ts +0 -0
package/dist/index.cjs CHANGED
@@ -3,438 +3,492 @@
3
3
  Object.defineProperty(exports, '__esModule', { value: true });
4
4
 
5
5
  var core = require('@vuecs/core');
6
- var vue = require('vue');
6
+ var eventEmitter = require('@posva/event-emitter');
7
7
  var link = require('@vuecs/link');
8
+ var vue = require('vue');
8
9
 
9
- let instance;
10
- function useNavigationProvider(module) {
11
- if (typeof instance !== 'undefined') {
12
- return instance;
13
- }
14
- if (typeof module === 'undefined') {
15
- throw new Error('A Navigation Provider must be set!');
16
- }
17
- instance = module;
18
- return instance;
19
- }
20
- function setNavigationProvider(module) {
21
- instance = module;
22
- }
23
- function createNavigationProvider(input) {
24
- return input;
10
+ function buildComponentOptions() {
11
+ const manager = core.createComponentOptionsManager({
12
+ name: 'navigation'
13
+ });
14
+ return {
15
+ groupClass: core.mergeOption('class', manager.get('groupClass'), 'vc-nav-items'),
16
+ groupTag: manager.get('groupTag') || 'ul',
17
+ itemClass: core.mergeOption('class', manager.get('itemClass'), 'vc-nav-item'),
18
+ itemTag: manager.get('itemTag') || 'li',
19
+ subGroupTitleClass: core.mergeOption('class', manager.get('subGroupTitleClass'), 'vc-nav-sub-level-title'),
20
+ subGroupItemsClass: core.mergeOption('class', manager.get('subGroupTitleClass'), 'vc-nav-sub-level-items'),
21
+ separatorTag: manager.get('separatorTag') || 'div',
22
+ separatorClass: core.mergeOption('class', manager.get('iconClass'), 'vc-nav-separator'),
23
+ iconClass: core.mergeOption('class', manager.get('iconClass'), 'vc-nav-icon'),
24
+ linkClass: core.mergeOption('class', manager.get('linkClass'), 'vc-nav-link'),
25
+ linkRootClass: core.mergeOption('class', manager.get('linkRootClass'), 'vc-nav-link-root'),
26
+ linkTextTag: manager.get('linkTextTag') || 'span',
27
+ linkTextClass: core.mergeOption('class', manager.get('linkTextClass'), 'vc-nav-link-text')
28
+ };
25
29
  }
26
30
 
27
- const StoreSymbol = Symbol.for('VLNavigationStore');
28
- function isStoreInjected() {
29
- if (!vue.hasInjectionContext()) {
30
- return false;
31
+ function findItemMatchesIF(items, options, parent) {
32
+ const output = [];
33
+ for(let i = 0; i < items.length; i++){
34
+ const item = items[i];
35
+ let { score } = parent;
36
+ if (options.path) {
37
+ if (item.activeMatch) {
38
+ if (item.activeMatch === options.path) {
39
+ score += 3;
40
+ } else if (options.path.startsWith(item.activeMatch)) {
41
+ score += 2;
42
+ }
43
+ }
44
+ if (item.url && item.url !== '/') {
45
+ if (item.url === options.path) {
46
+ score += 3;
47
+ } else if (options.path.startsWith(item.url)) {
48
+ score += 2;
49
+ }
50
+ }
51
+ }
52
+ if (item.default) {
53
+ score += 1;
54
+ }
55
+ if (item.children) {
56
+ const childMatches = findItemMatchesIF(item.children, options, {
57
+ score
58
+ });
59
+ output.push(...childMatches);
60
+ }
61
+ output.push({
62
+ data: item,
63
+ score
64
+ });
65
+ }
66
+ return output.sort((a, b)=>b.score - a.score);
67
+ }
68
+ function findBestItemMatches(items, options = {}) {
69
+ const result = findItemMatchesIF(items, options, {
70
+ score: 0
71
+ });
72
+ const [first] = result;
73
+ if (!first) {
74
+ return [];
31
75
  }
32
- const instance = vue.inject(StoreSymbol);
33
- return !!instance;
76
+ return result.filter((match)=>match.score === first.score).map((match)=>match.data);
34
77
  }
35
- function setupStore(app) {
36
- const store = {
37
- items: vue.ref([]),
38
- itemsActive: vue.ref([])
78
+
79
+ /*
80
+ * Copyright (c) 2024.
81
+ * Author Peter Placzek (tada5hi)
82
+ * For the full copyright and license information,
83
+ * view the LICENSE file that was distributed with this source code.
84
+ */ function normalizeItemIF(item, defaults, trace) {
85
+ const output = {
86
+ ...item,
87
+ level: defaults.level,
88
+ children: [],
89
+ trace: [
90
+ ...trace,
91
+ item.name
92
+ ]
39
93
  };
40
- if (typeof app === 'undefined') {
41
- if (isStoreInjected()) {
42
- return;
43
- }
44
- vue.provide(StoreSymbol, store);
45
- return;
94
+ if (!item.children) {
95
+ return output;
46
96
  }
47
- if (app._context && app._context.provides && app._context.provides[StoreSymbol]) {
48
- return;
97
+ for(let i = 0; i < item.children.length; i++){
98
+ output.children.push(normalizeItemIF(item.children[i], defaults, output.trace));
49
99
  }
50
- app.provide(StoreSymbol, store);
100
+ return output;
51
101
  }
52
- function injectStore() {
53
- const instance = vue.inject(StoreSymbol);
54
- if (!instance) {
55
- throw new Error('The Store is not set.');
56
- }
57
- return instance;
102
+ function normalizeItem(item, defaults) {
103
+ return normalizeItemIF(item, defaults, []);
104
+ }
105
+ function normalizeItems(items, options) {
106
+ return items.map((item)=>normalizeItem(item, options));
58
107
  }
59
108
 
60
- function isNavigationItemMatch(one, two) {
61
- if (!one || !two) {
109
+ /*
110
+ * Copyright (c) 2024.
111
+ * Author Peter Placzek (tada5hi)
112
+ * For the full copyright and license information,
113
+ * view the LICENSE file that was distributed with this source code.
114
+ */ function isTraceEqual(a, b) {
115
+ if (a.length !== b.length) {
62
116
  return false;
63
117
  }
64
- if (one.id && two.id && one.id === two.id) {
65
- return true;
66
- }
67
- if (one.name && two.name && one.name === two.name) {
68
- return true;
69
- }
70
- if (one.url && two.url && one.url === two.url) {
71
- return true;
72
- }
73
- if (one.children && two.children && one.children.length === two.children.length) {
74
- for(let i = 0; i < one.children.length; i++){
75
- if (!isNavigationItemMatch(one.children[i], two.children[i])) {
76
- return false;
77
- }
118
+ for(let i = 0; i < a.length; i++){
119
+ if (a[i] !== b[i]) {
120
+ return false;
78
121
  }
79
- return true;
80
122
  }
81
- return false;
123
+ return true;
82
124
  }
83
-
84
- // --------------------------------------------------
85
- function setNavigationExpansion(items, item, parentMatch = false) {
86
- let matchInIteration = false;
87
- for(let i = 0; i < items.length; i++){
88
- const isMatch = isNavigationItemMatch(items[i], item);
89
- let isChildMatch = false;
90
- const { children } = items[i];
91
- if (typeof children !== 'undefined') {
92
- const { items: childItems, match: childMatch } = setNavigationExpansion(children, item, isMatch);
93
- items[i].children = childItems;
94
- isChildMatch = childMatch;
95
- }
96
- if (isMatch) {
97
- items[i].active = true;
98
- }
99
- if (isMatch || isChildMatch) {
100
- items[i].display = true;
101
- items[i].displayChildren = true;
102
- }
103
- if (parentMatch) {
104
- items[i].display = true;
105
- }
106
- if (!matchInIteration) {
107
- matchInIteration = isMatch || isChildMatch;
125
+ function isTracePartOf(item, parent) {
126
+ for(let i = 0; i < item.length; i++){
127
+ if (parent[i] !== item[i]) {
128
+ return false;
108
129
  }
109
130
  }
110
- if (matchInIteration) {
111
- for(let i = 0; i < items.length; i++){
112
- items[i].display = true;
113
- }
114
- }
115
- return {
116
- items,
117
- match: matchInIteration
118
- };
131
+ return true;
119
132
  }
120
133
 
121
- function resetNavigationItem(items, root = true) {
134
+ function resetItemsByTraceIF(items, trace) {
122
135
  for(let i = 0; i < items.length; i++){
123
- items[i].display = root;
124
- items[i].displayChildren = false;
125
- items[i].active = false;
126
- const { children } = items[i];
127
- if (typeof children !== 'undefined') {
128
- items[i].children = resetNavigationItem(children, false);
136
+ const item = items[i];
137
+ const isEqual = isTraceEqual(items[i].trace, trace);
138
+ item.active = isEqual;
139
+ item.display = true;
140
+ if (isEqual) {
141
+ item.displayChildren = true;
142
+ } else {
143
+ item.displayChildren = isTracePartOf(item.trace, trace);
129
144
  }
145
+ item.children = resetItemsByTraceIF(item.children, trace);
130
146
  }
131
147
  return items;
132
148
  }
149
+ function resetItemsByTrace(items, trace) {
150
+ return resetItemsByTraceIF(items, trace);
151
+ }
133
152
 
134
- function findNavigationItemsForTier(items, tier) {
135
- const filterFn = (component)=>typeof component.tier !== 'undefined' && component.tier === tier;
136
- return items.filter(filterFn);
153
+ function findItemsWithLevel(items, tier) {
154
+ return items.filter((item)=>item.level === tier);
137
155
  }
138
- function findNavigationItemForTier(items, tier) {
139
- const data = findNavigationItemsForTier(items, tier);
156
+ function findItemWithLevel(tier, items) {
157
+ const data = findItemsWithLevel(items, tier);
140
158
  if (data.length >= 1) {
141
159
  return data[0];
142
160
  }
143
161
  return undefined;
144
162
  }
145
- function setTierForNavigationItems(items, tier) {
146
- const mapFn = (component)=>{
147
- component.tier = tier;
148
- return component;
149
- };
150
- if (vue.isRef(items)) {
151
- return items.value.map(mapFn);
152
- }
153
- return items.map(mapFn);
154
- }
155
- function removeTierFromNavigationItems(items, tier) {
156
- const filterFn = (items)=>typeof items.tier === 'undefined' || items.tier !== tier;
157
- if (vue.isRef(items)) {
158
- return items.value.filter(filterFn);
159
- }
160
- return items.filter(filterFn);
163
+ function removeItemsWithLevel(tier, items) {
164
+ return items.filter((item)=>item.level !== tier);
161
165
  }
162
-
163
- function replaceNavigationTierItemActive(store, tier, item) {
164
- const items = removeTierFromNavigationItems(store.itemsActive.value, tier);
165
- if (item) {
166
- item.tier = tier;
167
- store.itemsActive.value = [
168
- ...items,
169
- item
166
+ function replaceLevelItem(tier, input, next) {
167
+ const output = removeItemsWithLevel(tier, input);
168
+ if (next) {
169
+ next.level = tier;
170
+ return [
171
+ ...output,
172
+ next
170
173
  ];
171
- } else {
172
- store.itemsActive.value = items;
173
174
  }
175
+ return output;
174
176
  }
175
- function replaceNavigationTierItems(store, tier, items) {
176
- const componentsExisting = removeTierFromNavigationItems(store.items.value, tier);
177
- store.items.value = [
177
+ function replaceLevelItems(tier, src, next) {
178
+ const componentsExisting = removeItemsWithLevel(tier, src);
179
+ return [
178
180
  ...componentsExisting,
179
- ...setTierForNavigationItems(items, tier)
181
+ ...next
180
182
  ];
181
183
  }
182
184
 
183
- function refreshNavigationTierItems(store, tier) {
184
- const components = resetNavigationItem(findNavigationItemsForTier(store.items.value, tier));
185
- const component = findNavigationItemForTier(store.itemsActive.value, tier);
186
- if (component) {
187
- const { items } = setNavigationExpansion(components, component);
188
- replaceNavigationTierItems(store, tier, items);
189
- return;
190
- }
191
- replaceNavigationTierItems(store, tier, components);
185
+ function isAbsoluteURL(str) {
186
+ return str.substring(0, 7) === 'http://' || str.substring(0, 8) === 'https://';
192
187
  }
193
188
 
194
- async function buildNavigationForTier(store, tier, itemsActive) {
195
- if (typeof itemsActive === 'undefined' || itemsActive.length === 0) {
196
- let tierStartIndex = 0;
197
- const tierEndIndex = tier;
198
- itemsActive = [];
199
- while(tierStartIndex <= tierEndIndex){
200
- const component = findNavigationItemForTier(store.itemsActive.value, tierStartIndex);
201
- if (!component) {
189
+ class NavigationManager extends eventEmitter.EventEmitter {
190
+ getItems(tier) {
191
+ if (typeof tier === 'undefined') {
192
+ return this.items;
193
+ }
194
+ return this.items.filter((item)=>item.level === tier);
195
+ }
196
+ async buildOnce(options) {
197
+ if (this.built && !options.reset) {
198
+ return this.items;
199
+ }
200
+ return this.build(options);
201
+ }
202
+ async build(options) {
203
+ this.built = true;
204
+ this.items = [];
205
+ this.itemsActive = [];
206
+ let parent;
207
+ let level = 0;
208
+ while(true){
209
+ const raw = await this.itemsFn({
210
+ level,
211
+ parent
212
+ });
213
+ if (!raw || raw.length === 0) {
202
214
  break;
203
215
  }
204
- itemsActive.push(component);
205
- tierStartIndex++;
216
+ const items = normalizeItems(raw, {
217
+ level
218
+ });
219
+ const matches = findBestItemMatches(items, {
220
+ path: options.path
221
+ });
222
+ const [match] = matches;
223
+ if (!match) {
224
+ break;
225
+ }
226
+ this.itemsActive.push(match);
227
+ await this.buildLevel(level);
228
+ parent = match;
229
+ level++;
206
230
  }
231
+ this.emit('updated', this.items);
232
+ return this.items;
207
233
  }
208
- const items = await useNavigationProvider().getItems(tier, itemsActive);
209
- if (typeof items === 'undefined') {
210
- return false;
211
- }
212
- replaceNavigationTierItems(store, tier, items);
213
- refreshNavigationTierItems(store, tier);
214
- return true;
215
- }
216
-
217
- function flattenNestedNavigationItems(items) {
218
- const output = [];
219
- for(let i = 0; i < items.length; i++){
220
- const { children, ...data } = items[i];
221
- output.push(data);
222
- if (children && children.length > 0) {
223
- output.push(...flattenNestedNavigationItems([
224
- ...children
225
- ]));
234
+ async select(level, itemNew) {
235
+ const itemOld = findItemWithLevel(level, this.itemsActive);
236
+ if (itemOld && isTraceEqual(itemOld.trace, itemNew.trace)) {
237
+ return;
238
+ }
239
+ this.itemsActive = this.itemsActive.filter((el)=>el.level < level);
240
+ this.itemsActive.push(itemNew);
241
+ const startLevel = level;
242
+ while(true){
243
+ const built = await this.buildLevel(level, startLevel === level);
244
+ if (!built) {
245
+ break;
246
+ }
247
+ level++;
226
248
  }
227
249
  }
228
- return output;
229
- }
230
-
231
- async function selectNavigationTierItem(store, tier, component) {
232
- const isMatch = isNavigationItemMatch(findNavigationItemForTier(store.itemsActive.value, tier), component);
233
- if (isMatch) {
234
- return;
250
+ async toggle(level, item) {
251
+ let isMatch;
252
+ if (item.displayChildren) {
253
+ isMatch = true;
254
+ } else {
255
+ const itemOld = findItemWithLevel(level, this.itemsActive);
256
+ isMatch = !!itemOld && isTraceEqual(item.trace, itemOld.trace);
257
+ }
258
+ if (isMatch) {
259
+ this.itemsActive = removeItemsWithLevel(level, this.itemsActive);
260
+ } else {
261
+ this.itemsActive = replaceLevelItem(level, this.itemsActive, item);
262
+ }
263
+ await this.buildLevel(level, true);
264
+ }
265
+ async buildLevel(level, cached) {
266
+ let items;
267
+ if (cached) {
268
+ items = findItemsWithLevel(this.items, level);
269
+ } else {
270
+ const parent = findItemWithLevel(level - 1, this.itemsActive);
271
+ const raw = await this.itemsFn({
272
+ level,
273
+ parent
274
+ });
275
+ items = raw && raw.length > 0 ? normalizeItems(raw, {
276
+ level
277
+ }) : [];
278
+ }
279
+ if (!items || items.length === 0) {
280
+ this.items = this.items.filter((item)=>item.level < level);
281
+ this.emit('tierUpdated', level, []);
282
+ return false;
283
+ }
284
+ let trace = [];
285
+ const item = findItemWithLevel(level, this.itemsActive);
286
+ if (item) {
287
+ trace = item.trace;
288
+ }
289
+ resetItemsByTrace(items, trace);
290
+ this.items = replaceLevelItems(level, this.items, items);
291
+ this.emit('tierUpdated', level, items);
292
+ return true;
235
293
  }
236
- replaceNavigationTierItemActive(store, tier, component);
237
- refreshNavigationTierItems(store, tier);
238
- tier++;
239
- // eslint-disable-next-line no-constant-condition
240
- while(true){
241
- const built = await buildNavigationForTier(store, tier);
242
- if (!built) {
243
- break;
294
+ constructor(options){
295
+ super();
296
+ let itemsFn;
297
+ if (typeof options.items === 'function') {
298
+ itemsFn = options.items;
299
+ } else {
300
+ itemsFn = async ({ level })=>{
301
+ if (level > 0) {
302
+ return [];
303
+ }
304
+ return options.items;
305
+ };
244
306
  }
245
- tier++;
307
+ this.itemsFn = itemsFn;
308
+ this.items = [];
309
+ this.itemsActive = [];
310
+ this.built = false;
246
311
  }
247
312
  }
248
313
 
249
- function toggleNavigation(store, tier, component) {
250
- const isMatch = component.displayChildren || isNavigationItemMatch(findNavigationItemForTier(store.itemsActive.value, tier), component);
251
- if (isMatch) {
252
- replaceNavigationTierItemActive(store, tier, undefined);
253
- } else {
254
- replaceNavigationTierItemActive(store, tier, component);
314
+ const sym = Symbol.for('VCNavigationManager');
315
+ function injectNavigationManager(app) {
316
+ const instance = core.inject(sym, app);
317
+ if (!instance) {
318
+ throw new Error('A navigation provider has not been provided.');
255
319
  }
256
- refreshNavigationTierItems(store, tier);
320
+ return instance;
257
321
  }
258
-
259
- function isAbsoluteURL(str) {
260
- return str.substring(0, 7) === 'http://' || str.substring(0, 8) === 'https://';
322
+ function provideNavigationManager(manager, app) {
323
+ core.provide(sym, manager, app);
261
324
  }
262
325
 
263
- var SlotName;
264
- (function(SlotName) {
326
+ var SlotName = /*#__PURE__*/ function(SlotName) {
265
327
  SlotName["ITEM"] = "item";
266
328
  SlotName["SEPARATOR"] = "separator";
267
329
  SlotName["LINK"] = "link";
268
330
  SlotName["SUB"] = "sub";
269
331
  SlotName["SUB_TITLE"] = "sub-title";
270
332
  SlotName["SUB_ITEMS"] = "sub-items";
271
- })(SlotName || (SlotName = {}));
272
- var ElementType;
273
- (function(ElementType) {
333
+ return SlotName;
334
+ }({});
335
+ var ElementType = /*#__PURE__*/ function(ElementType) {
274
336
  ElementType["LINK"] = "link";
275
337
  ElementType["SEPARATOR"] = "separator";
276
- })(ElementType || (ElementType = {}));
338
+ return ElementType;
339
+ }({});
277
340
 
278
341
  const VCNavItem = vue.defineComponent({
279
342
  props: {
280
- tier: {
281
- type: Number,
282
- default: 0
283
- },
284
- component: {
343
+ data: {
285
344
  type: Object,
286
345
  required: true
287
346
  }
288
347
  },
289
348
  setup (props, { slots }) {
290
- const store = injectStore();
291
- const component = vue.toRef(props, 'component');
292
- const selectComponent = async (value)=>{
293
- await selectNavigationTierItem(store, props.tier, value);
349
+ const itemsNode = vue.resolveComponent('VCNavItems');
350
+ const options = buildComponentOptions();
351
+ const manager = injectNavigationManager();
352
+ const data = vue.toRef(props, 'data');
353
+ const select = async (value)=>{
354
+ await manager.select(data.value.level, value);
355
+ };
356
+ const toggle = async (value)=>{
357
+ await manager.toggle(data.value.level, value);
294
358
  };
295
- const toggleComponentExpansion = async (value)=>toggleNavigation(store, props.tier, value);
296
359
  return ()=>{
297
360
  const buildItem = ()=>{
298
- let item;
299
- switch(component.value.type){
300
- case ElementType.SEPARATOR:
301
- {
302
- const hasSlot = core.hasNormalizedSlot(SlotName.SEPARATOR, slots);
303
- if (hasSlot) {
304
- item = core.normalizeSlot(SlotName.SEPARATOR, {
305
- component: component.value
306
- }, slots);
307
- } else {
308
- item = vue.h('div', {
309
- class: 'nav-separator'
310
- }, component.value.name);
361
+ // type: separator
362
+ if (data.value.type === ElementType.SEPARATOR) {
363
+ const hasSlot = core.hasNormalizedSlot(SlotName.SEPARATOR, slots);
364
+ if (hasSlot) {
365
+ return core.normalizeSlot(SlotName.SEPARATOR, {
366
+ data: data.value
367
+ }, slots);
368
+ }
369
+ return vue.h(options.separatorTag, {
370
+ class: options.separatorClass
371
+ }, data.value.name);
372
+ }
373
+ // type: group
374
+ if (!data.value.children || data.value.children.length === 0) {
375
+ const hasSlot = core.hasNormalizedSlot(SlotName.LINK, slots);
376
+ if (hasSlot) {
377
+ return core.normalizeSlot(SlotName.LINK, {
378
+ data: data.value,
379
+ select,
380
+ isActive: data.value.active
381
+ }, slots);
382
+ }
383
+ const linkProps = {
384
+ active: data.value.active,
385
+ disabled: false,
386
+ prefetch: true
387
+ };
388
+ if (data.value.url) {
389
+ if (isAbsoluteURL(data.value.url) || data.value.url.startsWith('#')) {
390
+ linkProps.href = data.value.url;
391
+ if (data.value.urlTarget) {
392
+ linkProps.target = data.value.urlTarget;
311
393
  }
312
- break;
394
+ } else {
395
+ linkProps.to = data.value.url;
313
396
  }
314
- default:
315
- {
316
- if (typeof component.value.children === 'undefined') {
317
- const hasSlot = core.hasNormalizedSlot(SlotName.LINK, slots);
318
- if (hasSlot) {
319
- item = core.normalizeSlot(SlotName.LINK, {
320
- component: component.value,
321
- selectComponent,
322
- isActive: component.value.active
323
- }, slots);
324
- } else {
325
- const linkProps = {
326
- active: component.value.active,
327
- disabled: false,
328
- prefetch: true
329
- };
330
- if (component.value.url) {
331
- if (isAbsoluteURL(component.value.url) || component.value.url.startsWith('#')) {
332
- linkProps.href = component.value.url;
333
- if (component.value.urlTarget) {
334
- linkProps.target = component.value.urlTarget;
335
- }
336
- } else {
337
- linkProps.to = component.value.url;
338
- }
339
- }
340
- item = vue.h(link.VCLink, {
341
- class: [
342
- 'nav-link',
343
- {
344
- 'root-link': component.value.root
345
- }
346
- ],
347
- ...linkProps,
348
- onClicked () {
349
- if (!component.value.url) {
350
- return selectComponent.call(null, component.value);
351
- }
352
- return undefined;
353
- },
354
- onClick () {
355
- return selectComponent.call(null, component.value);
356
- }
357
- }, {
358
- default: ()=>[
359
- ...component.value.icon ? [
360
- vue.h('i', {
361
- class: component.value.icon
362
- })
363
- ] : [],
364
- vue.h('span', {
365
- class: 'nav-link-text'
366
- }, [
367
- component.value.name
368
- ])
369
- ]
370
- });
371
- }
372
- } else if (core.hasNormalizedSlot(SlotName.SUB, slots)) {
373
- item = core.normalizeSlot(SlotName.SUB, {
374
- component: component.value,
375
- selectComponent,
376
- toggleComponentExpansion
377
- }, slots);
378
- } else {
379
- let title;
380
- if (core.hasNormalizedSlot(SlotName.SUB_TITLE, slots)) {
381
- title = core.normalizeSlot(SlotName.SUB_TITLE, {
382
- component: component.value,
383
- selectComponent,
384
- toggleComponentExpansion
385
- });
386
- } else {
387
- title = vue.h('div', {
388
- class: 'nav-sub-title',
389
- onClick ($event) {
390
- $event.preventDefault();
391
- return toggleComponentExpansion.call(null, component.value);
392
- }
393
- }, [
394
- [
395
- ...component.value.icon ? [
396
- vue.h('i', {
397
- class: component.value.icon
398
- })
399
- ] : [],
400
- vue.h('span', {
401
- class: 'nav-link-text'
402
- }, [
403
- component.value.name
404
- ])
405
- ]
406
- ]);
407
- }
408
- let items;
409
- if (core.hasNormalizedSlot(SlotName.SUB_ITEMS, slots)) {
410
- items = core.normalizeSlot(SlotName.SUB_ITEMS, {
411
- component: component.value,
412
- selectComponent,
413
- toggleComponentExpansion
414
- });
415
- } else if (component.value.displayChildren) {
416
- const navigationComponents = vue.resolveComponent('VCNavItems');
417
- items = vue.h(navigationComponents, {
418
- class: 'list-unstyled nav-sub-items',
419
- tier: props.tier,
420
- entities: component.value.children
421
- });
422
- }
423
- item = [
424
- title,
425
- items
426
- ];
397
+ }
398
+ return vue.h(link.VCLink, {
399
+ class: [
400
+ options.linkClass,
401
+ data.value.url && data.value.url === '/' ? [
402
+ options.linkRootClass
403
+ ] : []
404
+ ],
405
+ ...linkProps,
406
+ onClicked () {
407
+ if (!data.value.url) {
408
+ return select.call(null, data.value);
427
409
  }
428
- break;
410
+ return undefined;
411
+ },
412
+ onClick () {
413
+ return select.call(null, data.value);
414
+ }
415
+ }, {
416
+ default: ()=>[
417
+ ...data.value.icon ? [
418
+ vue.h('i', {
419
+ class: data.value.icon
420
+ })
421
+ ] : [],
422
+ vue.h(options.linkTextTag, {
423
+ class: options.linkTextClass
424
+ }, [
425
+ data.value.name
426
+ ])
427
+ ]
428
+ });
429
+ }
430
+ if (core.hasNormalizedSlot(SlotName.SUB, slots)) {
431
+ return core.normalizeSlot(SlotName.SUB, {
432
+ data: data.value,
433
+ select,
434
+ toggle
435
+ }, slots);
436
+ }
437
+ let title;
438
+ if (core.hasNormalizedSlot(SlotName.SUB_TITLE, slots)) {
439
+ title = core.normalizeSlot(SlotName.SUB_TITLE, {
440
+ data: data.value,
441
+ select,
442
+ toggle
443
+ });
444
+ } else {
445
+ title = vue.h('div', {
446
+ class: options.subGroupTitleClass,
447
+ onClick ($event) {
448
+ $event.preventDefault();
449
+ return toggle(data.value);
429
450
  }
451
+ }, [
452
+ [
453
+ ...data.value.icon ? [
454
+ vue.h('i', {
455
+ class: data.value.icon
456
+ })
457
+ ] : [],
458
+ vue.h(options.linkTextTag, {
459
+ class: options.linkTextClass
460
+ }, [
461
+ data.value.name
462
+ ])
463
+ ]
464
+ ]);
430
465
  }
431
- return item;
466
+ if (!data.value.displayChildren) {
467
+ return title;
468
+ }
469
+ let vNodes;
470
+ if (core.hasNormalizedSlot(SlotName.SUB_ITEMS, slots)) {
471
+ vNodes = core.normalizeSlot(SlotName.SUB_ITEMS, {
472
+ data: data.value,
473
+ select,
474
+ toggle
475
+ });
476
+ } else {
477
+ vNodes = vue.h(itemsNode, {
478
+ level: data.value.level,
479
+ data: data.value.children
480
+ });
481
+ }
482
+ return [
483
+ title,
484
+ vNodes
485
+ ];
432
486
  };
433
- return vue.h('div', {
487
+ return vue.h(options.itemTag, {
434
488
  class: [
435
- 'nav-item',
489
+ options.itemClass,
436
490
  {
437
- active: component.value.active || component.value.displayChildren
491
+ active: data.value.active || data.value.displayChildren
438
492
  }
439
493
  ]
440
494
  }, [
@@ -446,127 +500,76 @@ const VCNavItem = vue.defineComponent({
446
500
 
447
501
  const VCNavItems = vue.defineComponent({
448
502
  props: {
449
- tier: {
503
+ level: {
450
504
  type: Number,
451
505
  default: 0
452
506
  },
453
- entities: {
507
+ data: {
454
508
  type: Array,
455
509
  default: undefined
456
510
  }
457
511
  },
458
512
  setup (props, { slots }) {
459
- const store = injectStore();
460
- const items = vue.computed(()=>{
461
- if (typeof props.entities !== 'undefined') {
462
- return props.entities;
463
- }
464
- return findNavigationItemsForTier(store.items.value, props.tier);
465
- });
466
- const buildChild = (context)=>{
467
- if (core.hasNormalizedSlot(SlotName.ITEM, slots)) {
468
- return core.normalizeSlot(SlotName.ITEM, context, slots);
469
- }
470
- return vue.h(VCNavItem, context);
471
- };
472
- const buildChildren = ()=>{
473
- const entities = [];
474
- if (items.value) {
475
- for(let i = 0; i < items.value.length; i++){
476
- if (items.value[i].display) {
477
- entities.push(vue.h('li', {
478
- key: i
479
- }, [
480
- buildChild({
481
- tier: props.tier,
482
- component: items.value[i]
483
- })
484
- ]));
485
- }
513
+ const options = buildComponentOptions();
514
+ const manager = injectNavigationManager();
515
+ const managerItems = vue.ref([]);
516
+ if (!props.data) {
517
+ managerItems.value = manager.getItems(props.level);
518
+ }
519
+ const counter = vue.ref(0);
520
+ let removeListener;
521
+ vue.onMounted(()=>{
522
+ removeListener = manager.on('tierUpdated', (tier, items)=>{
523
+ if (tier !== props.level) {
524
+ return;
486
525
  }
526
+ managerItems.value = items;
527
+ counter.value++;
528
+ });
529
+ });
530
+ vue.onUnmounted(()=>{
531
+ if (typeof removeListener === 'function') {
532
+ removeListener();
533
+ removeListener = undefined;
487
534
  }
488
- return entities;
489
- };
490
- return ()=>vue.h('ul', {
491
- class: 'nav-items'
492
- }, [
493
- buildChildren()
494
- ]);
495
- }
496
- });
497
-
498
- async function buildNavigation(context = {}) {
499
- const store = injectStore();
500
- const navigationProvider = useNavigationProvider();
501
- let itemsActive = [];
502
- if (typeof context.itemsActive !== 'undefined') {
503
- itemsActive = context.itemsActive;
504
- } else if (context.route) {
505
- if (typeof navigationProvider.getItemsActiveByRoute !== 'undefined') {
506
- itemsActive = await navigationProvider.getItemsActiveByRoute(context.route);
507
- } else if (typeof navigationProvider.getItemsActiveByURL !== 'undefined') {
508
- itemsActive = await navigationProvider.getItemsActiveByURL(context.route.fullPath);
509
- }
510
- } else if (context.url && typeof navigationProvider.getItemsActiveByURL !== 'undefined') {
511
- itemsActive = await navigationProvider.getItemsActiveByURL(context.url);
512
- }
513
- if (itemsActive.length > 0) {
514
- for(let i = 0; i < itemsActive.length; i++){
515
- if (typeof itemsActive[i].tier === 'undefined') {
516
- itemsActive[i].tier = i;
535
+ });
536
+ const items = vue.computed(()=>{
537
+ if (typeof props.data !== 'undefined') {
538
+ return props.data;
517
539
  }
518
- }
519
- }
520
- let tierIndex = 0;
521
- let url;
522
- if (typeof context.url === 'string') {
523
- url = context.url;
524
- } else if (typeof context.route !== 'undefined') {
525
- url = context.route.fullPath;
526
- }
527
- // eslint-disable-next-line no-constant-condition
528
- while(true){
529
- let items = await navigationProvider.getItems(tierIndex, itemsActive);
530
- if (!items || items.length === 0) {
531
- break;
532
- }
533
- // ensure tier property
534
- items = setTierForNavigationItems(items, tierIndex);
535
- let currentItem = findNavigationItemForTier(itemsActive, tierIndex);
536
- if (!currentItem) {
537
- if (url) {
538
- const urlMatches = items.filter((item)=>isNavigationItemMatch(item, {
539
- url
540
- }));
541
- if (urlMatches.length > 0) {
542
- [currentItem] = urlMatches;
540
+ return managerItems.value;
541
+ });
542
+ return ()=>{
543
+ const vNodes = [];
544
+ for(let i = 0; i < items.value.length; i++){
545
+ if (!items.value[i].display && !items.value[i].displayChildren) {
546
+ continue;
543
547
  }
544
- }
545
- if (!currentItem) {
546
- const defaultItem = items.filter((item)=>item.default);
547
- if (defaultItem.length > 0) {
548
- currentItem = defaultItem;
548
+ let vNode;
549
+ if (core.hasNormalizedSlot(SlotName.ITEM, slots)) {
550
+ vNode = core.normalizeSlot(SlotName.ITEM, {
551
+ data: items.value[i]
552
+ }, slots);
549
553
  } else {
550
- [currentItem] = items;
554
+ vNode = vue.h(VCNavItem, {
555
+ key: `${i}:${counter.value}`,
556
+ data: items.value[i]
557
+ });
551
558
  }
559
+ vNodes.push(vNode);
552
560
  }
553
- currentItem.tier = tierIndex;
554
- itemsActive.push(currentItem);
555
- }
556
- if (!currentItem) {
557
- continue;
558
- }
559
- replaceNavigationTierItemActive(store, tierIndex, currentItem);
560
- await buildNavigationForTier(store, tierIndex, itemsActive);
561
- tierIndex++;
561
+ return vue.h(options.groupTag, {
562
+ class: props.data ? options.subGroupItemsClass : options.groupClass
563
+ }, vNodes);
564
+ };
562
565
  }
563
- }
566
+ });
564
567
 
565
568
  function install(instance, options) {
566
- if (options.provider) {
567
- setNavigationProvider(options.provider);
568
- }
569
- setupStore(instance);
569
+ const manager = new NavigationManager({
570
+ items: options.items
571
+ });
572
+ provideNavigationManager(manager, instance);
570
573
  const storeManager = core.installStoreManager(instance);
571
574
  if (options.storeManager) {
572
575
  core.applyStoreManagerOptions(storeManager, options.storeManager);
@@ -582,15 +585,12 @@ var index = {
582
585
  install
583
586
  };
584
587
 
588
+ exports.NavigationManager = NavigationManager;
585
589
  exports.VCNavItem = VCNavItem;
586
590
  exports.VCNavItems = VCNavItems;
587
- exports.buildNavigation = buildNavigation;
588
- exports.buildNavigationForTier = buildNavigationForTier;
589
- exports.createNavigationProvider = createNavigationProvider;
590
591
  exports.default = index;
591
- exports.flattenNestedNavigationItems = flattenNestedNavigationItems;
592
+ exports.injectNavigationManager = injectNavigationManager;
592
593
  exports.install = install;
593
- exports.setNavigationProvider = setNavigationProvider;
594
- exports.useNavigationProvider = useNavigationProvider;
594
+ exports.provideNavigationManager = provideNavigationManager;
595
595
  module.exports = Object.assign(exports.default, exports);
596
596
  //# sourceMappingURL=index.cjs.map