sprintify-ui 0.0.9 → 0.0.11

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 (51) hide show
  1. package/README.md +14 -3
  2. package/dist/sprintify-ui.es.js +3851 -6637
  3. package/dist/style.css +2 -2
  4. package/dist/tailwindcss/index.js +283 -32
  5. package/dist/types/src/components/BaseAutocomplete.vue.d.ts +0 -1
  6. package/dist/types/src/components/BaseAutocompleteFetch.vue.d.ts +0 -1
  7. package/dist/types/src/components/BaseBelongsTo.vue.d.ts +13 -3
  8. package/dist/types/src/components/BaseDataTable.vue.d.ts +95 -64
  9. package/dist/types/src/components/BaseDialog.vue.d.ts +8 -8
  10. package/dist/types/src/components/BaseFilePicker.vue.d.ts +3 -3
  11. package/dist/types/src/components/BaseLoadingCover.vue.d.ts +12 -12
  12. package/dist/types/src/components/BaseMenuItem.vue.d.ts +4 -4
  13. package/dist/types/src/components/BaseNavbarItemContent.vue.d.ts +4 -4
  14. package/dist/types/src/components/BaseTableColumn.vue.d.ts +4 -4
  15. package/dist/types/src/svg/BaseEmptyState.vue.d.ts +2 -0
  16. package/dist/types/src/{components/BaseSpinner.vue.d.ts → svg/BaseSpinnerLarge.vue.d.ts} +0 -0
  17. package/dist/types/src/svg/BaseSpinnerSmall.vue.d.ts +44 -0
  18. package/dist/types/src/types/types.d.ts +1 -1
  19. package/package.json +4 -2
  20. package/src/assets/form.css +1 -10
  21. package/src/assets/main.css +0 -1
  22. package/src/assets/tailwind.css +3 -5
  23. package/src/components/BaseAutocomplete.stories.js +7 -4
  24. package/src/components/BaseAutocomplete.vue +44 -15
  25. package/src/components/BaseAutocompleteFetch.stories.js +6 -3
  26. package/src/components/BaseAutocompleteFetch.vue +8 -3
  27. package/src/components/BaseBelongsTo.stories.js +9 -4
  28. package/src/components/BaseBelongsTo.vue +1 -0
  29. package/src/components/BaseButton.stories.js +11 -3
  30. package/src/components/BaseCard.vue +1 -1
  31. package/src/components/BaseDataIterator.stories.js +102 -3
  32. package/src/components/BaseDataIterator.vue +44 -12
  33. package/src/components/BaseDataTable.stories.js +149 -2
  34. package/src/components/BaseDataTable.vue +34 -28
  35. package/src/components/BaseDataTableToggleColumns.vue +1 -1
  36. package/src/components/BaseDateSelect.vue +6 -2
  37. package/src/components/BaseDescriptionListItem.vue +40 -4
  38. package/src/components/BaseDialog.stories.js +51 -0
  39. package/src/components/BaseDialog.vue +13 -7
  40. package/src/components/BaseFilePicker.stories.js +51 -0
  41. package/src/components/BaseFilePicker.vue +6 -6
  42. package/src/components/BaseFileUploader.stories.js +80 -0
  43. package/src/components/BaseFileUploader.vue +12 -3
  44. package/src/components/BaseLoadingCover.vue +8 -16
  45. package/src/components/BaseTable.vue +42 -29
  46. package/src/components/BaseTableColumn.vue +2 -2
  47. package/src/svg/BaseEmptyState.vue +34 -0
  48. package/src/{components/BaseSpinner.vue → svg/BaseSpinnerLarge.vue} +0 -0
  49. package/src/svg/BaseSpinnerSmall.vue +9 -0
  50. package/src/types/types.ts +1 -1
  51. package/src/assets/button.css +0 -80
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "sprintify-ui",
3
- "version": "0.0.9",
3
+ "version": "0.0.11",
4
4
  "scripts": {
5
5
  "build": "rimraf dist && vue-tsc && vite build",
6
6
  "docs:dev": "vitepress dev docs",
@@ -23,7 +23,8 @@
23
23
  "tailwindcss": "^3.0.0",
24
24
  "vue": "^3.0.0",
25
25
  "vue-i18n": "^9.0.0",
26
- "vue-router": "^4.0.0"
26
+ "vue-router": "^4.0.0",
27
+ "pikaday": "^1.8.2"
27
28
  },
28
29
  "dependencies": {
29
30
  "@headlessui/vue": "^1.7.4"
@@ -72,6 +73,7 @@
72
73
  "prettier-plugin-tailwindcss": "^0.1.13",
73
74
  "qs": "^6.11.0",
74
75
  "rimraf": "^3.0.2",
76
+ "rollup-plugin-analyzer": "^4.0.0",
75
77
  "scroll-lock": "^2.1.5",
76
78
  "tailwindcss": "^3.2.4",
77
79
  "typescript": "^4.4.4",
@@ -1,13 +1,4 @@
1
-
2
- .form-input-label {
3
- @apply block text-sm leading-tight text-slate-600;
4
- }
5
-
6
- .form-input-error {
7
- @apply text-sm leading-tight text-red-600;
8
- }
9
-
10
- /** Placehoder color */
1
+ /** Placeholder color */
11
2
 
12
3
  input,
13
4
  textarea {
@@ -1,3 +1,2 @@
1
1
  @import './pikaday.css';
2
- @import './button.css';
3
2
  @import './form.css';
@@ -1,5 +1,3 @@
1
- @import "tailwindcss/base";
2
-
3
- @import "tailwindcss/components";
4
-
5
- @import "tailwindcss/utilities";
1
+ @tailwind base;
2
+ @tailwind components;
3
+ @tailwind utilities;
@@ -87,16 +87,19 @@ export const SlotFooter = (args) => {
87
87
  components: { BaseAutocomplete },
88
88
  setup() {
89
89
  const value = ref(null);
90
- return { args, value };
90
+ function onClick() {
91
+ alert(1);
92
+ }
93
+ return { args, value, onClick };
91
94
  },
92
95
  template: `
93
96
  <BaseAutocomplete
94
97
  v-model="value"
95
- v-bind="args"
98
+ v-bind="args"
96
99
  >
97
100
  <template #footer>
98
- <div class="text-center p-1 pt-2 mt-2 border-t">
99
- <button class="btn btn-sm w-full btn-slate-200-outline">This is the footer 💯</button>
101
+ <div class="text-center p-2 border-t">
102
+ <button @click=onClick class="btn btn-sm w-full btn-slate-200-outline">This is the footer 💯</button>
100
103
  </div>
101
104
  </template>
102
105
  </BaseAutocomplete>
@@ -50,7 +50,10 @@
50
50
  v-show="showDropdown"
51
51
  class="absolute top-1 z-[1] min-h-[110px] w-full overflow-hidden rounded border border-slate-300 bg-white shadow-md"
52
52
  >
53
- <div ref="dropdown" class="max-h-[214px] w-full overflow-y-auto p-1">
53
+ <div
54
+ ref="dropdown"
55
+ class="max-h-[214px] min-h-[75px] w-full overflow-y-auto"
56
+ >
54
57
  <slot v-if="filteredNormalizedOptions.length == 0" name="empty">
55
58
  <div
56
59
  class="flex items-center justify-center px-5 py-10 text-center text-slate-600"
@@ -59,7 +62,7 @@
59
62
  </div>
60
63
  </slot>
61
64
 
62
- <ul v-else>
65
+ <ul v-else class="p-1">
63
66
  <li
64
67
  v-for="option in filteredNormalizedOptions"
65
68
  :key="option.value"
@@ -70,7 +73,7 @@
70
73
  type="button"
71
74
  tabindex="-1"
72
75
  @click="onSelect(option)"
73
- @mousedown="dontLooseFocus"
76
+ @mousedown.prevent="dontLooseFocus"
74
77
  >
75
78
  <slot
76
79
  name="option"
@@ -91,12 +94,12 @@
91
94
  </button>
92
95
  </li>
93
96
  </ul>
97
+ </div>
94
98
 
95
- <slot
96
- :options="filteredNormalizedOptions"
97
- :dont-loose-focus="dontLooseFocus"
98
- name="footer"
99
- />
99
+ <div ref="footer">
100
+ <div v-if="$slots.footer" class="bg-white">
101
+ <slot :options="filteredNormalizedOptions" name="footer" />
102
+ </div>
100
103
  </div>
101
104
 
102
105
  <Transition>
@@ -131,7 +134,7 @@ import {
131
134
  Selection,
132
135
  NormalizedSelection,
133
136
  } from '@/types/types';
134
- import { useInfiniteScroll } from '@vueuse/core';
137
+ import { useInfiniteScroll, useMutationObserver } from '@vueuse/core';
135
138
  import BaseSkeleton from './BaseSkeleton.vue';
136
139
 
137
140
  const props = defineProps({
@@ -198,7 +201,7 @@ onMounted(() => {
198
201
  () => {
199
202
  emit('scrollBottom');
200
203
  },
201
- { distance: 10 }
204
+ { distance: 60 }
202
205
  );
203
206
  });
204
207
 
@@ -255,12 +258,18 @@ const filteredNormalizedOptions = computed((): NormalizedOption[] => {
255
258
  });
256
259
  });
257
260
 
258
- const dontLooseFocus = (event: Event, next: null | (() => void) = null) => {
259
- event.preventDefault();
261
+ function preventUnfocus(elements: HTMLElement[]) {
262
+ elements.forEach((e) => {
263
+ e.removeEventListener('mousedown', dontLooseFocus);
264
+ });
265
+ elements.forEach((e) => {
266
+ e.addEventListener('mousedown', dontLooseFocus);
267
+ });
268
+ }
269
+
270
+ const dontLooseFocus = (event: Event) => {
260
271
  inputElement.value?.focus();
261
- if (next) {
262
- next();
263
- }
272
+ event.preventDefault();
264
273
  };
265
274
 
266
275
  const onTextFocus = () => {
@@ -373,4 +382,24 @@ const setKeywords = (input: string) => {
373
382
  keywords.value = input;
374
383
  emit('typing', input);
375
384
  };
385
+
386
+ const footer = ref(null) as Ref<HTMLDivElement | null>;
387
+
388
+ function preventUnfocusOnFooter() {
389
+ const elements = (footer.value?.querySelectorAll('button, a') ??
390
+ []) as HTMLElement[];
391
+ preventUnfocus(elements);
392
+ }
393
+
394
+ onMounted(() => {
395
+ preventUnfocusOnFooter();
396
+ });
397
+
398
+ useMutationObserver(
399
+ footer,
400
+ () => {
401
+ preventUnfocusOnFooter();
402
+ },
403
+ { attributes: false, childList: true }
404
+ );
376
405
  </script>
@@ -79,7 +79,10 @@ export const SlotFooter = (args) => {
79
79
  components: { BaseAutocompleteFetch },
80
80
  setup() {
81
81
  const value = ref(null);
82
- return { args, value };
82
+ function onClick() {
83
+ alert(1);
84
+ }
85
+ return { args, value, onClick };
83
86
  },
84
87
  template: `
85
88
  <BaseAutocompleteFetch
@@ -87,8 +90,8 @@ export const SlotFooter = (args) => {
87
90
  v-bind="args"
88
91
  >
89
92
  <template #footer>
90
- <div class="text-center p-1 pt-2 mt-2 border-t">
91
- <button class="btn btn-sm w-full btn-slate-200-outline">This is the footer 💯</button>
93
+ <div class="text-center p-2 border-t">
94
+ <button @click=onClick class="btn btn-sm w-full btn-slate-200-outline">This is the footer 💯</button>
92
95
  </div>
93
96
  </template>
94
97
  </BaseAutocompleteFetch>
@@ -22,12 +22,17 @@
22
22
 
23
23
  <template #footer="footerProps">
24
24
  <slot name="footer" v-bind="footerProps" :keywords="keywords">
25
- <div v-if="createNewUrl" class="p-2">
25
+ <div
26
+ v-if="createNewUrl"
27
+ class="p-2"
28
+ :class="{
29
+ 'border-t border-slate-300': footerProps.options.length > 0,
30
+ }"
31
+ >
26
32
  <router-link
27
33
  :to="createNewUrl"
28
34
  target="_blank"
29
- class="btn flex items-center justify-center font-normal shadow"
30
- @mousedown="footerProps.dontLooseFocus"
35
+ class="btn btn-slate-200-outline flex items-center justify-center"
31
36
  >
32
37
  <BaseIcon
33
38
  icon="heroicons-solid:plus"
@@ -40,10 +40,12 @@ export const Disabled = (args) => {
40
40
  return {
41
41
  components: { BaseBelongsTo },
42
42
  setup() {
43
- return { args };
43
+ const value = ref(null);
44
+ return { args, value };
44
45
  },
45
46
  template: `<BaseBelongsTo
46
47
  v-bind="args"
48
+ v-model="value"
47
49
  :current-model="{title: 'Dark Vader', id: 1}"
48
50
  :disabled="true"
49
51
  ></BaseBelongsTo>`,
@@ -88,7 +90,10 @@ export const SlotFooter = (args) => {
88
90
  components: { BaseBelongsTo },
89
91
  setup() {
90
92
  const value = ref(null);
91
- return { args, value };
93
+ function onClick() {
94
+ alert(1);
95
+ }
96
+ return { args, value, onClick };
92
97
  },
93
98
  template: `
94
99
  <BaseBelongsTo
@@ -96,8 +101,8 @@ export const SlotFooter = (args) => {
96
101
  v-bind="args"
97
102
  >
98
103
  <template #footer>
99
- <div class="text-center p-1 pt-2 mt-2 border-t">
100
- <button class="btn btn-sm w-full btn-slate-200-outline">This is the footer 💯</button>
104
+ <div class="text-center p-2 border-t">
105
+ <button @click=onClick class="btn btn-sm w-full btn-slate-200-outline">This is the footer 💯</button>
101
106
  </div>
102
107
  </template>
103
108
  </BaseBelongsTo>
@@ -29,6 +29,7 @@ import { PropType } from 'vue';
29
29
  import { RouteLocationRaw } from 'vue-router';
30
30
  import { AxiosResponse } from 'axios';
31
31
  import { config } from '@/index';
32
+ import BaseAutocompleteFetch from './BaseAutocompleteFetch.vue';
32
33
 
33
34
  const props = defineProps({
34
35
  modelValue: {
@@ -5,8 +5,11 @@ const colors = [
5
5
  'btn-secondary',
6
6
  'btn-secondary-outline',
7
7
  'btn-success',
8
+ 'btn-success-outline',
8
9
  'btn-warning',
10
+ 'btn-warning-outline',
9
11
  'btn-danger',
12
+ 'btn-danger-outline',
10
13
  'btn-white',
11
14
  'btn-slate-100',
12
15
  'btn-slate-100-outline',
@@ -41,7 +44,7 @@ const Template = (args) => ({
41
44
 
42
45
  export const Demo = Template.bind({});
43
46
  Demo.args = {
44
- class: 'btn-primary btn-base',
47
+ class: '',
45
48
  };
46
49
 
47
50
  export const Loading = Template.bind({});
@@ -55,8 +58,13 @@ export const Colors = (args) => ({
55
58
  return { args, colors };
56
59
  },
57
60
  template: `
61
+ <p class="text-xs text-slate-600 leading-tight mb-1">btn</p>
62
+ <BaseButton class="btn">
63
+ Click here
64
+ </BaseButton>
65
+ <div class="mb-4"></div>
58
66
  <div v-for="color in colors" :key="color" class="mb-4">
59
- <p class="text-xs text-slate-600 leading-tight mb-1">{{ color }}</p>
67
+ <p class="text-xs text-slate-600 leading-tight mb-1">btn {{ color }}</p>
60
68
  <BaseButton :class="color">
61
69
  Click here
62
70
  </BaseButton>
@@ -71,7 +79,7 @@ export const Sizes = (args) => ({
71
79
  },
72
80
  template: `
73
81
  <div v-for="size in sizes" :key="size" class="mb-4">
74
- <p class="text-xs text-slate-600 leading-tight mb-1">{{ size }}</p>
82
+ <p class="text-xs text-slate-600 leading-tight mb-1">btn {{ size }}</p>
75
83
  <BaseButton class="btn-primary" :class="size">
76
84
  Click here
77
85
  </BaseButton>
@@ -4,7 +4,7 @@
4
4
  class="border-t border-b border-slate-300 bg-white"
5
5
  :class="{
6
6
  'rounded-lg border-r border-l shadow-sm': width != windowWidth,
7
- 'overflow-hidden': clipped,
7
+ 'relative isolate overflow-hidden': clipped,
8
8
  }"
9
9
  >
10
10
  <slot />
@@ -1,4 +1,5 @@
1
1
  import BaseDataIterator from './BaseDataIterator.vue';
2
+ import BaseSelect from './BaseSelect.vue';
2
3
  import BaseCard from './BaseCard.vue';
3
4
  import BaseCardRow from './BaseCardRow.vue';
4
5
  import BaseLoadingCover from './BaseLoadingCover.vue';
@@ -43,16 +44,67 @@ const template = `
43
44
 
44
45
  <BaseLoadingCover
45
46
  v-show="loading"
46
- backdropClass="bg-slate-100 bg-opacity-50"
47
+ size="lg"
48
+ backdropClass="bg-white bg-opacity-50"
47
49
  >
48
50
  </BaseLoadingCover>
49
51
  </div>
50
52
  </template>
53
+
54
+ <template #filters="{ query, updateQueryValue }">
55
+ <div class="space-y-3">
56
+ <div>
57
+ <p class="mb-1 text-sm">
58
+ Type
59
+ </p>
60
+ <BaseSelect
61
+ :model-value="query.type ?? null"
62
+ class="w-full rounded border-slate-300"
63
+ @update:model-value="updateQueryValue('type', $event)"
64
+ >
65
+ <option value="">-</option>
66
+ <option value="video">
67
+ Video
68
+ </option>
69
+ <option value="article">
70
+ Article
71
+ </option>
72
+ </BaseSelect>
73
+ </div>
74
+ <div>
75
+ <p class="mb-1 text-sm">
76
+ Access Level
77
+ </p>
78
+ <BaseSelect
79
+ :model-value="query.access_level ?? null"
80
+ class="w-full rounded border-slate-300"
81
+ @update:model-value="updateQueryValue('access_level', $event)"
82
+ >
83
+ <option value="">-</option>
84
+ <option value="public">
85
+ Public
86
+ </option>
87
+ <option value="member">
88
+ Member
89
+ </option>
90
+ <option value="vip">
91
+ VIP
92
+ </option>
93
+ </BaseSelect>
94
+ </div>
95
+ </div>
96
+ </template>
51
97
  </BaseDataIterator>
52
98
  `;
53
99
 
54
100
  const Template = (args) => ({
55
- components: { BaseDataIterator, BaseCard, BaseCardRow, BaseLoadingCover },
101
+ components: {
102
+ BaseDataIterator,
103
+ BaseCard,
104
+ BaseCardRow,
105
+ BaseLoadingCover,
106
+ BaseSelect,
107
+ },
56
108
  setup() {
57
109
  return { args };
58
110
  },
@@ -83,7 +135,54 @@ Demo.args = {
83
135
  ],
84
136
  };
85
137
 
86
- export const Simple = Template.bind({});
138
+ const SimpleTemplate = (args) => ({
139
+ components: {
140
+ BaseDataIterator,
141
+ BaseCard,
142
+ BaseCardRow,
143
+ BaseLoadingCover,
144
+ },
145
+ setup() {
146
+ return { args };
147
+ },
148
+ template: `
149
+ <BaseDataIterator v-bind="args">
150
+ <template #default="{ items, loading }">
151
+ <div class="relative">
152
+ <div class="space-y-1.5">
153
+ <a
154
+ v-for="item in items"
155
+ :key="item.id"
156
+ :href="item.website_url"
157
+ target="_blank"
158
+ class="block group"
159
+ >
160
+ <BaseCard class="group-hover:bg-slate-100">
161
+ <BaseCardRow size="sm">
162
+ <div class="font-medium text-slate-900">
163
+ {{ item.title }}
164
+ </div>
165
+ <p class="text-xs leading-tight text-slate-500">
166
+ {{ item.subtitle }}
167
+ </p>
168
+ </BaseCardRow>
169
+ </BaseCard>
170
+ </a>
171
+ </div>
172
+
173
+ <BaseLoadingCover
174
+ v-show="loading"
175
+ size="lg"
176
+ backdropClass="bg-white bg-opacity-50"
177
+ >
178
+ </BaseLoadingCover>
179
+ </div>
180
+ </template>
181
+ </BaseDataIterator>
182
+ `,
183
+ });
184
+
185
+ export const Simple = SimpleTemplate.bind({});
87
186
  Simple.args = {
88
187
  searchable: false,
89
188
  actions: [],
@@ -6,7 +6,10 @@
6
6
  'grid-cols-[1fr_300px]': hasSidebar,
7
7
  }"
8
8
  >
9
- <div class="col-span-2 min-w-0 lg:col-span-1">
9
+ <div
10
+ class="min-w-0"
11
+ :class="{ 'col-span-1': !mobileLayout, 'col-span-2': mobileLayout }"
12
+ >
10
13
  <!-- Header -->
11
14
  <div class="mb-4 flex space-x-2 empty:mb-0">
12
15
  <!-- Search bar -->
@@ -52,7 +55,7 @@
52
55
  <!-- Filters (mobile) -->
53
56
  <button
54
57
  v-if="mobileLayout && hasFilters"
55
- class="btn flex h-11 items-center justify-center py-1 text-base"
58
+ class="btn flex h-11 items-center justify-center py-1 text-base shadow-sm"
56
59
  type="button"
57
60
  @click="showFilters = true"
58
61
  >
@@ -131,7 +134,7 @@
131
134
  </div>
132
135
  </div>
133
136
 
134
- <div v-if="!mobileLayout && hasSidebar">
137
+ <div v-if="!mobileLayout" ref="sidebar">
135
138
  <slot
136
139
  name="sidebarTop"
137
140
  :pagination-metadata="paginationMetadata"
@@ -201,7 +204,6 @@ const DEFAULT_QUERY = {
201
204
  import { cloneDeep, debounce, isArray, merge, set } from 'lodash';
202
205
  import hash from 'object-hash';
203
206
  import { ComputedRef, PropType, Ref } from 'vue';
204
- import { useBreakpoints } from '@/composables/breakpoints';
205
207
  import {
206
208
  Collection,
207
209
  DataTableQuery,
@@ -217,6 +219,7 @@ import BaseCardRow from './BaseCardRow.vue';
217
219
  import BasePaginationSimple from './BasePaginationSimple.vue';
218
220
  import BaseModalSide from './BaseModalSide.vue';
219
221
  import { config } from '@/index';
222
+ import { useMutationObserver, useResizeObserver } from '@vueuse/core';
220
223
 
221
224
  const props = defineProps({
222
225
  /**
@@ -299,7 +302,10 @@ const route = useRoute();
299
302
  const router = useRouter();
300
303
  const routeName = route.name;
301
304
 
302
- const breakpoints = useBreakpoints();
305
+ const width = ref(800);
306
+ useResizeObserver(dataIteratorNode, () => {
307
+ width.value = dataIteratorNode.value?.clientWidth ?? 800;
308
+ });
303
309
 
304
310
  /** Data table state */
305
311
 
@@ -315,7 +321,7 @@ const query = ref(cloneDeep(props.defaultQuery)) as Ref<DataTableQuery>;
315
321
  const slots = useSlots();
316
322
 
317
323
  const mobileLayout = computed(() => {
318
- return breakpoints.smaller('lg').value;
324
+ return width.value < 1024;
319
325
  });
320
326
 
321
327
  const hasFilters = computed((): boolean => {
@@ -323,14 +329,40 @@ const hasFilters = computed((): boolean => {
323
329
  return numberOfFilterSlots !== undefined;
324
330
  });
325
331
 
326
- const hasSidebar = computed(() => {
327
- return (
328
- hasFilters.value ||
329
- slots.sidebarTop !== undefined ||
330
- slots.sidebarBottom !== undefined
331
- );
332
+ /*
333
+ |--------------------------------------------------------------------------
334
+ | Has sidebar observer
335
+ |--------------------------------------------------------------------------
336
+ */
337
+
338
+ const hasSidebar = ref(false);
339
+ const sidebar = ref(null) as Ref<null | HTMLElement>;
340
+
341
+ function checkIfSidebarIsEmpty() {
342
+ hasSidebar.value = (sidebar?.value?.childElementCount ?? 0) > 0;
343
+ }
344
+
345
+ const checkIfSidebarIsEmptyDebounce = debounce(checkIfSidebarIsEmpty, 100);
346
+
347
+ useMutationObserver(sidebar, checkIfSidebarIsEmptyDebounce, {
348
+ attributes: false,
349
+ childList: true,
332
350
  });
333
351
 
352
+ onMounted(() => {
353
+ checkIfSidebarIsEmpty();
354
+ });
355
+
356
+ watch(
357
+ () => mobileLayout.value,
358
+ () => {
359
+ // After the sidebar appears...
360
+ nextTick(() => {
361
+ checkIfSidebarIsEmpty();
362
+ });
363
+ }
364
+ );
365
+
334
366
  /*
335
367
  |--------------------------------------------------------------------------
336
368
  | Query params