@autoafleveren/ui 1.7.0 → 1.8.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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@autoafleveren/ui",
3
- "version": "1.7.0",
3
+ "version": "1.8.1",
4
4
  "type": "module",
5
5
  "files": [
6
6
  "dist/*",
@@ -97,10 +97,11 @@
97
97
  class="app-context-menu fixed z-100 flex w-64 flex-col rounded-lg bg-secondary p-2 drop-shadow-card empty:hidden"
98
98
  data-test-context-menu
99
99
  >
100
- <div v-if="enableSearch && actionsWithFallback.length > 0">
100
+ <div v-if="search?.enabled && actionsWithFallback.length > 0">
101
101
  <AppInput
102
+ v-bind="search"
102
103
  :model-value="searchActionsQuery"
103
- :placeholder="searchPlaceholder ?? ''"
104
+ :placeholder="search?.placeholder ?? ''"
104
105
  class="mb-2 text-zinc-700"
105
106
  type="text"
106
107
  data-test-driver-search
@@ -93,7 +93,7 @@ describe('the AppContextMenu ShortcutItem component', () => {
93
93
  });
94
94
 
95
95
  it('should render the search input when enableSearch is true', () => {
96
- const wrapper = createWrapper(actionsMock, { enableSearch: true });
96
+ const wrapper = createWrapper(actionsMock, { search: { enabled: true } });
97
97
  const searchInput = wrapper.findComponent({ name: 'AppInput' });
98
98
 
99
99
  expect(searchInput.exists()).toBe(true);
@@ -101,8 +101,7 @@ describe('the AppContextMenu ShortcutItem component', () => {
101
101
 
102
102
  it('should use the searchPlaceholder prop as the input placeholder', () => {
103
103
  const wrapper = createWrapper(actionsMock, {
104
- enableSearch: true,
105
- searchPlaceholder: 'Search actions...',
104
+ search: { enabled: true, placeholder: 'Search actions...' },
106
105
  });
107
106
 
108
107
  const searchInput = wrapper.findComponent({ name: 'AppInput' });
@@ -111,7 +110,7 @@ describe('the AppContextMenu ShortcutItem component', () => {
111
110
  });
112
111
 
113
112
  it('should default the placeholder to an empty string when searchPlaceholder is not provided', () => {
114
- const wrapper = createWrapper(actionsMock, { enableSearch: true });
113
+ const wrapper = createWrapper(actionsMock, { search: { enabled: true } });
115
114
  const searchInput = wrapper.findComponent({ name: 'AppInput' });
116
115
 
117
116
  expect(searchInput.attributes('placeholder')).toBe('');
@@ -119,7 +118,7 @@ describe('the AppContextMenu ShortcutItem component', () => {
119
118
 
120
119
  it('should display noResultsText when searching yields no results', async () => {
121
120
  const wrapper = createWrapper(actionsMock, {
122
- enableSearch: true,
121
+ search: { enabled: true },
123
122
  noResultsText: 'No results found',
124
123
  });
125
124
 
@@ -138,7 +137,7 @@ describe('the AppContextMenu ShortcutItem component', () => {
138
137
  });
139
138
 
140
139
  it('should default noResultsText to an empty string when not provided', async () => {
141
- const wrapper = createWrapper(actionsMock, { enableSearch: true });
140
+ const wrapper = createWrapper(actionsMock, { search: { enabled: true } });
142
141
  const searchInput = wrapper.findComponent({ name: 'AppInput' });
143
142
 
144
143
  await searchInput.vm.$emit('update:modelValue', 'test_action_non_existant');
@@ -154,7 +153,7 @@ describe('the AppContextMenu ShortcutItem component', () => {
154
153
  });
155
154
 
156
155
  it('should filter actions based on search query', async () => {
157
- const wrapper = createWrapper(actionsMock, { enableSearch: true });
156
+ const wrapper = createWrapper(actionsMock, { search: { enabled: true } });
158
157
  const searchInput = wrapper.findComponent({ name: 'AppInput' });
159
158
 
160
159
  await searchInput.vm.$emit('update:modelValue', 'Action #1');
@@ -198,7 +197,7 @@ describe('the AppContextMenu ShortcutItem component', () => {
198
197
  { ...actionsMock[0], name: 'Action 5' },
199
198
  ];
200
199
 
201
- const wrapper = createWrapper(manyActions, { enableSearch: true, maxList: 2 });
200
+ const wrapper = createWrapper(manyActions, { search: { enabled: true }, maxList: 2 });
202
201
  const searchInput = wrapper.findComponent({ name: 'AppInput' });
203
202
 
204
203
  await searchInput.vm.$emit('update:modelValue', 'Action');
@@ -1,5 +1,6 @@
1
1
  import type { App } from 'vue';
2
2
  import type AppContextMenu from './AppContextMenu.vue';
3
+ import type { AppInputProps } from '~components/AppInput/index.d';
3
4
 
4
5
  export type { Action } from '~components/AppActionBar/index.d';
5
6
 
@@ -8,8 +9,10 @@ export interface Props {
8
9
  event: PointerEvent | MouseEvent;
9
10
  actions?: Action[];
10
11
  confirmed?: Action['key'];
11
- enableSearch?: boolean;
12
- searchPlaceholder?: string;
12
+ search?: Omit<AppInputProps<string>, 'modelValue'> & {
13
+ enabled?: boolean;
14
+ placeholder?: string;
15
+ };
13
16
  noResultsText?: string;
14
17
  maxList?: number;
15
18
  }
@@ -1,18 +1,27 @@
1
- import { createApp, inject, isRef, ref } from 'vue';
2
- import { RouterView } from 'vue-router';
1
+ /* eslint-disable vue/one-component-per-file,@typescript-eslint/explicit-function-return-type */
2
+ import { createApp, defineComponent, h, inject, isRef, ref } from 'vue';
3
+ import { RouterView, useRoute } from 'vue-router';
3
4
  import { AppDrawer } from '~components';
4
5
 
5
6
  import type { App, Component, MaybeRef } from 'vue';
6
7
  import type { ModalInstance, DrawerProps } from '~components/AppDrawer/index.d';
7
8
 
9
+ // eslint-disable-next-line @typescript-eslint/naming-convention
10
+ const KeyedRouterView = defineComponent({
11
+ name: 'KeyedRouterView',
12
+
13
+ setup() {
14
+ const route = useRoute();
15
+
16
+ return () => h(RouterView, { key: route.fullPath });
17
+ },
18
+ });
19
+
8
20
  const state = {
9
21
  instances: ref<ModalInstance[]>([]),
10
22
  };
11
23
 
12
- function closeDrawer(modalInstance: Omit<ModalInstance, 'withRouter' | 'unique'>): void {
13
- modalInstance?.instance?.unmount();
14
- modalInstance?.element?.remove();
15
-
24
+ function removeInstance(modalInstance: Omit<ModalInstance, 'withRouter' | 'unique'>): void {
16
25
  const index = state.instances.value.findIndex(instance => instance.instance._uid === modalInstance.instance._uid);
17
26
 
18
27
  if (index > -1) {
@@ -20,6 +29,13 @@ function closeDrawer(modalInstance: Omit<ModalInstance, 'withRouter' | 'unique'>
20
29
  }
21
30
  }
22
31
 
32
+ function closeDrawer(modalInstance: Omit<ModalInstance, 'withRouter' | 'unique'>): void {
33
+ removeInstance(modalInstance);
34
+
35
+ modalInstance?.instance?.unmount();
36
+ modalInstance?.element?.remove();
37
+ }
38
+
23
39
  export function useDrawer(component?: MaybeRef<Component | string>, options?: DrawerProps) {
24
40
  const instance = ref<ModalInstance>();
25
41
 
@@ -44,7 +60,7 @@ export function useDrawer(component?: MaybeRef<Component | string>, options?: Dr
44
60
  }
45
61
 
46
62
  if (!options?.content && !openOptions.content && openOptions.router) {
47
- openOptions.content = RouterView;
63
+ openOptions.content = KeyedRouterView;
48
64
  }
49
65
 
50
66
  window.scrollTo(0, 0);
@@ -92,7 +108,7 @@ export function useDrawer(component?: MaybeRef<Component | string>, options?: Dr
92
108
  mountDrawer(modalInstance, modalRootElement, !!openOptions.router);
93
109
 
94
110
  if (openOptions.router && !openOptions.unique) {
95
- modalInstance?.config?.globalProperties?.$router?.push?.(openOptions.router);
111
+ modalInstance?.config?.globalProperties?.$router?.replace?.(openOptions.router);
96
112
  }
97
113
 
98
114
  return;
@@ -102,18 +118,23 @@ export function useDrawer(component?: MaybeRef<Component | string>, options?: Dr
102
118
  mountDrawer(modalInstance, modalRootElement, !!openOptions.router);
103
119
 
104
120
  if (openOptions.router) {
105
- modalInstance?.config?.globalProperties?.$router?.push?.(openOptions.router);
121
+ modalInstance?.config?.globalProperties?.$router?.replace?.(openOptions.router);
106
122
  }
107
123
  });
108
124
  }
109
125
  }).finally(() => {
110
126
  if (modalInstance) {
127
+ // Immediately remove from state so subsequent open() calls
128
+ // don't try to reuse this closing instance
129
+ removeInstance({
130
+ ref: modalRef,
131
+ instance: modalInstance,
132
+ element: modalRootElement,
133
+ });
134
+
111
135
  setTimeout(() => {
112
- closeDrawer({
113
- ref: modalRef,
114
- instance: modalInstance,
115
- element: modalRootElement,
116
- });
136
+ modalInstance?.unmount();
137
+ modalRootElement?.remove();
117
138
  }, 500);
118
139
  }
119
140
  });