@antelopejs/dms 0.7.3 → 0.7.4

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/CHANGELOG.md CHANGED
@@ -1,5 +1,17 @@
1
1
  # Changelog
2
2
 
3
+ ## v0.7.4
4
+
5
+ [compare changes](https://github.com/AntelopeJS/dms/compare/v0.7.3...v0.7.4)
6
+
7
+ ### 🩹 Fixes
8
+
9
+ - **table-view:** Open the toolbar search from its button again ([#193](https://github.com/AntelopeJS/dms/pull/193))
10
+
11
+ ### ❤️ Contributors
12
+
13
+ - Antony Rizzitelli <rizzitelli.antony@pm.me>
14
+
3
15
  ## v0.7.3
4
16
 
5
17
  [compare changes](https://github.com/AntelopeJS/dms/compare/v0.7.2...v0.7.3)
@@ -1,7 +1,7 @@
1
1
  <script setup lang="ts" generic="T extends Data">
2
- import { injectLocal, useFocus, useFocusWithin } from "@vueuse/core";
2
+ import { injectLocal, useFocusWithin } from "@vueuse/core";
3
3
  import { tv } from "tailwind-variants";
4
- import type { ShallowRef } from "vue";
4
+ import { nextTick, type ShallowRef } from "vue";
5
5
  import type { DmsAppConfig } from "#dms-core/shared/types/app-config";
6
6
 
7
7
  import TableMenu from "./Menu.vue";
@@ -162,7 +162,6 @@ const searchActive = ref(false);
162
162
  const searchInputRef = ref<HTMLInputElement>();
163
163
  const searchSectionRef = ref<HTMLElement>();
164
164
 
165
- const { focused: inputFocus } = useFocus(searchInputRef);
166
165
  const { focused: searchAreaFocused } = useFocusWithin(searchSectionRef);
167
166
 
168
167
  // A search set from outside (a view opened) shows in its field.
@@ -183,16 +182,17 @@ tableSharedData.onFiltersCleared(() => {
183
182
  if (!searchAreaFocused.value) searchActive.value = false;
184
183
  });
185
184
 
186
- watch(searchAreaFocused, (isFocused) => {
185
+ // Opening the search unmounts the trigger button that held the focus: the
186
+ // area reads as left for a moment, until the field takes the focus. Only an
187
+ // area still left once the field rendered folds the search back.
188
+ watch(searchAreaFocused, async (isFocused) => {
187
189
  if (isFocused || !searchActive.value) return;
190
+ await nextTick();
191
+ if (searchAreaFocused.value || !searchActive.value) return;
188
192
  if (tableSharedData?.globalFilterState.value) return;
189
193
  searchActive.value = false;
190
194
  });
191
195
 
192
- const toggleSearch = () => {
193
- searchActive.value = !searchActive.value;
194
- inputFocus.value = !inputFocus.value;
195
- };
196
196
 
197
197
  const searchFieldRef = ref<{ $el: HTMLElement }>();
198
198
 
@@ -205,6 +205,12 @@ const focusSearchBar = () => {
205
205
  ?.focus();
206
206
  };
207
207
 
208
+ const openSearch = async () => {
209
+ searchActive.value = true;
210
+ await nextTick();
211
+ focusSearchBar();
212
+ };
213
+
208
214
  const searchPlaceholderText = computed(() =>
209
215
  props.searchPlaceholder
210
216
  ? processI18n(props.searchPlaceholder)
@@ -426,7 +432,7 @@ const uiTableActions = computed(() => uiTableActionsVariant());
426
432
  square
427
433
  :aria-label="t('dms.table.search_open')"
428
434
  :class="uiTableActions.trigger()"
429
- @click="toggleSearch"
435
+ @click="openSearch"
430
436
  />
431
437
 
432
438
  <div :class="uiTableActions.searchContainer({ searchActive })">
@@ -37,8 +37,13 @@ const ButtonStub = defineComponent({
37
37
  h("button", slots.default?.()),
38
38
  });
39
39
 
40
+ // A real UInput wraps its field: the toolbar focuses the input inside it.
40
41
  const InputStub = defineComponent({
41
- setup: () => () => h("input"),
42
+ inheritAttrs: false,
43
+ setup:
44
+ (_, { attrs }) =>
45
+ () =>
46
+ h("div", [h("input", attrs)]),
42
47
  });
43
48
 
44
49
  let app: App | undefined;
@@ -88,6 +93,7 @@ function mountActions(searchPlaceholder: string | undefined, search = "") {
88
93
  app.component(name, stub);
89
94
  }
90
95
  const container = document.createElement("div");
96
+ document.body.append(container);
91
97
  app.mount(container);
92
98
  return container;
93
99
  }
@@ -110,6 +116,7 @@ beforeEach(() => {
110
116
  afterEach(() => {
111
117
  app?.unmount();
112
118
  app = undefined;
119
+ document.body.replaceChildren();
113
120
  vi.unstubAllGlobals();
114
121
  });
115
122
 
@@ -121,6 +128,20 @@ describe("table toolbar search", () => {
121
128
  );
122
129
  });
123
130
 
131
+ it("opens the search field from its button and focuses it", async () => {
132
+ const container = mountActions(undefined);
133
+ const trigger = container.querySelector("button");
134
+ trigger?.focus();
135
+ trigger?.click();
136
+ await nextTick();
137
+ await nextTick();
138
+ const input = container.querySelector("input");
139
+ expect(input).not.toBeNull();
140
+ expect(document.activeElement).toBe(input);
141
+ await nextTick();
142
+ expect(container.querySelector("input")).not.toBeNull();
143
+ });
144
+
124
145
  it("uses the configured placeholder, which also names the field", async () => {
125
146
  const container = mountActions("$page.members.search", "ada");
126
147
  await nextTick();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@antelopejs/dms",
3
- "version": "0.7.3",
3
+ "version": "0.7.4",
4
4
  "repository": {
5
5
  "type": "git",
6
6
  "url": "git+https://github.com/AntelopeJS/dms.git"