quasar-ui-danx 0.4.27 → 0.4.29

Sign up to get free protection for your applications and to get access to all the features.
Files changed (51) hide show
  1. package/README.md +35 -35
  2. package/dist/danx.es.js +24686 -24119
  3. package/dist/danx.es.js.map +1 -1
  4. package/dist/danx.umd.js +109 -109
  5. package/dist/danx.umd.js.map +1 -1
  6. package/dist/style.css +1 -1
  7. package/package.json +1 -1
  8. package/src/components/ActionTable/ActionTable.vue +29 -7
  9. package/src/components/ActionTable/Filters/FilterableField.vue +14 -2
  10. package/src/components/ActionTable/Form/ActionForm.vue +17 -12
  11. package/src/components/ActionTable/Form/Fields/DateField.vue +24 -20
  12. package/src/components/ActionTable/Form/Fields/DateRangeField.vue +57 -53
  13. package/src/components/ActionTable/Form/Fields/EditOnClickTextField.vue +9 -2
  14. package/src/components/ActionTable/Form/Fields/EditableDiv.vue +51 -21
  15. package/src/components/ActionTable/Form/Fields/FieldLabel.vue +1 -1
  16. package/src/components/ActionTable/Form/Fields/SelectField.vue +27 -6
  17. package/src/components/ActionTable/Form/Fields/SelectOrCreateField.vue +56 -0
  18. package/src/components/ActionTable/Form/Fields/TextField.vue +2 -0
  19. package/src/components/ActionTable/Form/Fields/index.ts +1 -0
  20. package/src/components/ActionTable/Form/RenderedForm.vue +7 -20
  21. package/src/components/ActionTable/Form/Utilities/MaxLengthCounter.vue +1 -1
  22. package/src/components/ActionTable/Form/Utilities/SaveStateIndicator.vue +37 -0
  23. package/src/components/ActionTable/Form/Utilities/index.ts +1 -0
  24. package/src/components/ActionTable/Layouts/ActionTableLayout.vue +20 -23
  25. package/src/components/ActionTable/Toolbars/ActionToolbar.vue +44 -36
  26. package/src/components/ActionTable/{listControls.ts → controls.ts} +13 -9
  27. package/src/components/ActionTable/index.ts +1 -1
  28. package/src/components/DragAndDrop/ListItemDraggable.vue +45 -31
  29. package/src/components/DragAndDrop/dragAndDrop.ts +221 -220
  30. package/src/components/DragAndDrop/listDragAndDrop.ts +269 -227
  31. package/src/components/PanelsDrawer/PanelsDrawer.vue +7 -7
  32. package/src/components/PanelsDrawer/PanelsDrawerTabs.vue +3 -3
  33. package/src/components/Utility/Buttons/ShowHideButton.vue +86 -0
  34. package/src/components/Utility/Buttons/index.ts +1 -0
  35. package/src/components/Utility/Dialogs/ActionFormDialog.vue +30 -0
  36. package/src/components/Utility/Dialogs/CreateNewWithNameDialog.vue +26 -0
  37. package/src/components/Utility/Dialogs/RenderedFormDialog.vue +50 -0
  38. package/src/components/Utility/Dialogs/index.ts +3 -0
  39. package/src/helpers/FileUpload.ts +4 -4
  40. package/src/helpers/actions.ts +84 -20
  41. package/src/helpers/files.ts +56 -43
  42. package/src/helpers/formats.ts +23 -20
  43. package/src/helpers/objectStore.ts +24 -12
  44. package/src/types/actions.d.ts +50 -26
  45. package/src/types/controls.d.ts +23 -25
  46. package/src/types/fields.d.ts +1 -0
  47. package/src/types/files.d.ts +2 -2
  48. package/src/types/index.d.ts +5 -0
  49. package/src/types/shared.d.ts +9 -0
  50. package/src/types/tables.d.ts +3 -3
  51. package/types/vue-shims.d.ts +3 -2
@@ -7,231 +7,273 @@ import { DragAndDrop } from "./dragAndDrop";
7
7
  * @class
8
8
  */
9
9
  export class ListDragAndDrop extends DragAndDrop {
10
- listPosition = 0;
11
- cursorPosition = 0;
12
- initialPosition = 0;
13
- onPositionChangeCb = null;
14
- onDragPositionChangeCb = null;
15
- placeholder = null;
16
-
17
- constructor(options = {}) {
18
- super({
19
- showPlaceholder: true,
20
- ...options
21
- });
22
- }
23
-
24
- /**
25
- * Callback that fires after dragging has ended and the list position has changed from the original
26
- * @param cb
27
- * @returns {ListDragAndDrop}
28
- */
29
- onPositionChange(cb) {
30
- this.onPositionChangeCb = cb;
31
- return this;
32
- }
33
-
34
- /**
35
- * Callback that fires while dragging the element when the cursor's position has changed in the list
36
- * @param cb
37
- * @returns {ListDragAndDrop}
38
- */
39
- onDragPositionChange(cb) {
40
- this.onDragPositionChangeCb = cb;
41
- return this;
42
- }
43
-
44
- /**
45
- * Start listening for drag events and prepare an element for drag/drop
46
- * @param e
47
- * @param data
48
- */
49
- dragStart(e, data) {
50
- super.dragStart(e, data);
51
-
52
- if (this.currentDropZone) {
53
- this.listPosition = this.getListPosition(e.target);
54
- this.initialPosition = this.listPosition;
55
- this.updateScrollPosition();
56
- }
57
- }
58
-
59
- /**
60
- * When dragging has ended, check for list position changes and fire the onPositionChange callback if it has
61
- */
62
- dragEnd(e) {
63
- const draggableData = this.draggableData;
64
- this.placeholder?.remove();
65
- super.dragEnd(e);
66
-
67
- // If our list position has changed, trigger the drop callback
68
- if (this.listPosition !== this.initialPosition) {
69
- this.onPositionChangeCb &&
70
- this.onPositionChangeCb(this.listPosition, this.initialPosition, draggableData);
71
- }
72
- }
73
-
74
- /**
75
- * The dragging element is moving
76
- * @param e
77
- */
78
- dragOver(e) {
79
- super.dragOver(e);
80
- this.updateListPosition(e);
81
- }
82
-
83
- /**
84
- * Notify if the targeted position of the cursor is different from the current position
85
- * @param e
86
- */
87
- updateListPosition(e) {
88
- const prevPosition = this.listPosition;
89
- const newPosition = this.getListPositionOfPoint({
90
- x: e.clientX,
91
- y: e.clientY
92
- });
93
-
94
- // If the cursor position has changed, we should update the rendering and see if our actual list position has
95
- // changed
96
- if (this.cursorPosition !== newPosition) {
97
- this.cursorPosition = newPosition;
98
- this.listPosition =
99
- this.initialPosition < this.cursorPosition
100
- ? this.cursorPosition - 1
101
- : this.cursorPosition;
102
- if (this.options.showPlaceholder) {
103
- this.renderPlaceholder();
104
- }
105
-
106
- // The position has changed, trigger the callback
107
- if (this.listPosition !== prevPosition) {
108
- this.onDragPositionChangeCb &&
109
- this.onDragPositionChangeCb(this.listPosition, this.draggableData);
110
- }
111
- }
112
- }
113
-
114
- /**
115
- * Find the numeric position of the element in the children of the list
116
- * @returns {Number|null}
117
- * @param item
118
- */
119
- getListPosition(item) {
120
- let index = 0;
121
- for (const child of this.getChildren()) {
122
- if (child === item) {
123
- return index;
124
- }
125
- index++;
126
- }
127
-
128
- return null;
129
- }
130
-
131
- /**
132
- * Get all the children of the current drop zone, excluding the placeholder
133
- * @returns {*}
134
- */
135
- getChildren() {
136
- return [...this.currentDropZone.children].filter(
137
- (c) => c.className.match(/drag-placeholder/) === null
138
- );
139
- }
140
-
141
- /**
142
- * Find the element at the current cursor position in the given drop zone
143
- * @param point
144
- * @returns {null}
145
- */
146
- getListPositionOfPoint(point) {
147
- let index = 0;
148
- const children = this.getChildren();
149
-
150
- while (index < children.length) {
151
- const rect = children[index].getBoundingClientRect();
152
- if (this.isVertical()) {
153
- if (point.y < rect.top + rect.height / 2) {
154
- break;
155
- }
156
- } else {
157
- if (point.x < rect.left + rect.width / 2) {
158
- break;
159
- }
160
- }
161
- index++;
162
- }
163
-
164
- return index;
165
- }
166
-
167
- /**
168
- * Updates the scroll position while dragging an element so a user can navigate a longer list while dragging
169
- */
170
- updateScrollPosition() {
171
- if (this.currentDropZone) {
172
- const rect = this.currentDropZone.getBoundingClientRect();
173
- const threshold = 100;
174
- let velocity = 0;
175
- const velocityFn = (x) => x * 5;
176
- const cursorPos = this.isVertical() ? this.cursorY : this.cursorX;
177
- const rectStart = this.isVertical() ? rect.top : rect.left;
178
- const rectEnd = this.isVertical() ? rect.bottom : rect.right;
179
- const beforeDiff = rectStart + threshold - cursorPos;
180
- const afterDiff = cursorPos - (rectEnd - threshold);
181
-
182
- if (beforeDiff > 0) {
183
- velocity = -velocityFn(beforeDiff);
184
- } else if (afterDiff > 0) {
185
- velocity = velocityFn(afterDiff);
186
- }
187
-
188
- if (velocity) {
189
- if (this.isVertical()) {
190
- this.currentDropZone.scrollTo({
191
- top: this.currentDropZone.scrollTop + velocity,
192
- behavior: "smooth"
193
- });
194
- } else {
195
- this.currentDropZone.scrollTo({
196
- left: this.currentDropZone.scrollLeft + velocity,
197
- behavior: "smooth"
198
- });
199
- }
200
- }
201
-
202
- setTimeout(() => this.updateScrollPosition(), 500);
203
- }
204
- }
205
-
206
- /**
207
- * Render a placeholder element at the given position (in between the elements)
208
- */
209
- renderPlaceholder() {
210
- if (!this.placeholder) {
211
- this.placeholder = document.createElement("div");
212
- this.placeholder.classList.add("drag-placeholder");
213
- }
214
-
215
- // Make sure the placeholder is oriented correctly
216
- if (this.isVertical()) {
217
- this.placeholder.classList.add("direction-vertical");
218
- this.placeholder.classList.remove("direction-horizontal");
219
- this.placeholder.style.height = undefined;
220
- } else {
221
- this.placeholder.classList.add("direction-horizontal");
222
- this.placeholder.classList.remove("direction-vertical");
223
- this.placeholder.style.height =
224
- this.currentDropZone.getBoundingClientRect().height + "px";
225
- }
226
-
227
- const children = this.getChildren();
228
- if (this.cursorPosition < children.length) {
229
- this.currentDropZone.insertBefore(
230
- this.placeholder,
231
- children[this.cursorPosition]
232
- );
233
- } else {
234
- this.currentDropZone.appendChild(this.placeholder);
235
- }
236
- }
10
+ listPosition = 0;
11
+ cursorPosition = 0;
12
+ initialPosition = 0;
13
+ initialDropZone: HTMLElement | null = null;
14
+ onPositionChangeCb = null;
15
+ onDragPositionChangeCb = null;
16
+ onDropZoneChangeCb = null;
17
+ placeholder = null;
18
+
19
+ constructor(options = {}) {
20
+ super({
21
+ showPlaceholder: true,
22
+ allowDropZoneChange: true,
23
+ ...options
24
+ });
25
+ }
26
+
27
+ /**
28
+ * Callback that fires after dragging has ended and the list position has changed from the original
29
+ */
30
+ onPositionChange(cb): ListDragAndDrop {
31
+ this.onPositionChangeCb = cb;
32
+ return this;
33
+ }
34
+
35
+ /**
36
+ * Callback that fires when the drop zone has changed
37
+ */
38
+ onDropZoneChange(cb): ListDragAndDrop {
39
+ this.onDropZoneChangeCb = cb;
40
+ return this;
41
+ }
42
+
43
+ /**
44
+ * Callback that fires while dragging the element when the cursor's position has changed in the list
45
+ * @param cb
46
+ * @returns {ListDragAndDrop}
47
+ */
48
+ onDragPositionChange(cb) {
49
+ this.onDragPositionChangeCb = cb;
50
+ return this;
51
+ }
52
+
53
+ /**
54
+ * Start listening for drag events and prepare an element for drag/drop
55
+ * @param e
56
+ * @param data
57
+ */
58
+ dragStart(e, data) {
59
+ super.dragStart(e, data);
60
+
61
+ if (this.currentDropZone) {
62
+ this.listPosition = this.getListPosition(e.target);
63
+ this.initialPosition = this.listPosition;
64
+ this.initialDropZone = this.currentDropZone;
65
+ this.updateScrollPosition();
66
+ }
67
+ }
68
+
69
+ /**
70
+ * When dragging has ended, check for list position changes and fire the onPositionChange callback if it has
71
+ */
72
+ dragEnd(e) {
73
+ const draggableData = this.draggableData;
74
+ this.placeholder?.remove();
75
+ const newDropZone = this.currentDropZone;
76
+ super.dragEnd(e);
77
+
78
+ // If the list drop zone has changed, trigger the callback for drop zone change
79
+ if (newDropZone && newDropZone !== this.initialDropZone) {
80
+ this.onDropZoneChangeCb && this.onDropZoneChangeCb(e, newDropZone, this.listPosition, this.initialPosition, draggableData);
81
+ } else if (this.listPosition !== this.initialPosition) {
82
+ // If our list position has changed, trigger the position change callback
83
+ this.onPositionChangeCb &&
84
+ this.onPositionChangeCb(this.listPosition, this.initialPosition, draggableData);
85
+ }
86
+ }
87
+
88
+ /**
89
+ * The dragging element is moving
90
+ * @param e
91
+ */
92
+ dragOver(e) {
93
+ super.dragOver(e);
94
+ this.updateListPosition(e);
95
+ }
96
+
97
+ /**
98
+ * Notify if the targeted position of the cursor is different from the current position
99
+ * @param e
100
+ */
101
+ updateListPosition(e: MouseEvent) {
102
+ const point = {
103
+ x: e.clientX,
104
+ y: e.clientY
105
+ };
106
+ const newDropZone = this.getDropZoneForTarget(e.target as HTMLElement);
107
+ if (newDropZone !== this.currentDropZone) {
108
+ this.currentDropZone = newDropZone;
109
+ this.cursorPosition = 0;
110
+ this.listPosition = 0;
111
+ this.placeholder?.remove();
112
+ }
113
+
114
+ const prevPosition = this.listPosition;
115
+ const newPosition = this.getListPositionOfPoint(point);
116
+
117
+ // If the cursor position has changed, we should update the rendering and see if our actual list position has
118
+ // changed
119
+ if (this.cursorPosition !== newPosition) {
120
+ this.cursorPosition = newPosition;
121
+ this.listPosition =
122
+ this.initialPosition < this.cursorPosition
123
+ ? this.cursorPosition - 1
124
+ : this.cursorPosition;
125
+ if (this.options.showPlaceholder) {
126
+ this.renderPlaceholder();
127
+ }
128
+
129
+ // The position has changed, trigger the callback
130
+ if (this.listPosition !== prevPosition) {
131
+ this.onDragPositionChangeCb &&
132
+ this.onDragPositionChangeCb(this.listPosition, this.draggableData);
133
+ }
134
+ }
135
+ }
136
+
137
+ /**
138
+ * Find the numeric position of the element in the children of the list
139
+ * @returns {Number|null}
140
+ * @param item
141
+ */
142
+ getListPosition(item) {
143
+ let index = 0;
144
+ for (const child of this.getChildren()) {
145
+ if (child === item) {
146
+ return index;
147
+ }
148
+ index++;
149
+ }
150
+
151
+ return null;
152
+ }
153
+
154
+ /**
155
+ * Get all the children of the current drop zone, excluding the placeholder
156
+ * @returns {*}
157
+ */
158
+ getChildren() {
159
+ return [...(this.currentDropZone?.children || [])].filter(
160
+ (c) => c.className.match(/dx-drag-placeholder/) === null
161
+ );
162
+ }
163
+
164
+ /**
165
+ * Get the list element that is the parent of the target element
166
+ */
167
+ getDropZoneForTarget(target: HTMLElement): HTMLElement | null {
168
+ return target.closest(`[data-drop-zone]`);
169
+ }
170
+
171
+ /**
172
+ * Check if the current drop zone is the same as the initial drop zone
173
+ */
174
+ isSameDropZone() {
175
+ return this.currentDropZone === this.initialDropZone;
176
+ }
177
+
178
+ /**
179
+ * Find the element at the current cursor position in the given drop zone
180
+ * @param point
181
+ * @returns {null}
182
+ */
183
+ getListPositionOfPoint(point) {
184
+ let index = 0;
185
+ const children = this.getChildren();
186
+
187
+ while (index < children.length) {
188
+ const rect = children[index].getBoundingClientRect();
189
+ if (this.isVertical()) {
190
+ if (point.y < rect.top + rect.height / 2) {
191
+ break;
192
+ }
193
+ } else {
194
+ if (point.x < rect.left + rect.width / 2) {
195
+ break;
196
+ }
197
+ }
198
+ index++;
199
+ }
200
+
201
+ return index;
202
+ }
203
+
204
+ /**
205
+ * Updates the scroll position while dragging an element so a user can navigate a longer list while dragging
206
+ */
207
+ updateScrollPosition() {
208
+ if (this.currentDropZone) {
209
+ const rect = this.currentDropZone.getBoundingClientRect();
210
+ const threshold = 100;
211
+ let velocity = 0;
212
+ const velocityFn = (x) => x * 5;
213
+ const cursorPos = this.isVertical() ? this.cursorY : this.cursorX;
214
+ const rectStart = this.isVertical() ? rect.top : rect.left;
215
+ const rectEnd = this.isVertical() ? rect.bottom : rect.right;
216
+ const beforeDiff = rectStart + threshold - cursorPos;
217
+ const afterDiff = cursorPos - (rectEnd - threshold);
218
+
219
+ if (beforeDiff > 0) {
220
+ velocity = -velocityFn(beforeDiff);
221
+ } else if (afterDiff > 0) {
222
+ velocity = velocityFn(afterDiff);
223
+ }
224
+
225
+ if (velocity) {
226
+ if (this.isVertical()) {
227
+ this.currentDropZone.scrollTo({
228
+ top: this.currentDropZone.scrollTop + velocity,
229
+ behavior: "smooth"
230
+ });
231
+ } else {
232
+ this.currentDropZone.scrollTo({
233
+ left: this.currentDropZone.scrollLeft + velocity,
234
+ behavior: "smooth"
235
+ });
236
+ }
237
+ }
238
+
239
+ setTimeout(() => this.updateScrollPosition(), 500);
240
+ }
241
+ }
242
+
243
+ /**
244
+ * Render a placeholder element at the given position (in between the elements)
245
+ */
246
+ renderPlaceholder() {
247
+ // If we're not allowed to change drop zones and we're not in the same drop zone, don't render the placeholder
248
+ if (!this.options.allowDropZoneChange && !this.isSameDropZone()) {
249
+ return;
250
+ }
251
+
252
+ if (!this.placeholder) {
253
+ this.placeholder = document.createElement("div");
254
+ this.placeholder.classList.add("dx-drag-placeholder");
255
+ }
256
+
257
+ // Make sure the placeholder is oriented correctly
258
+ if (this.isVertical()) {
259
+ this.placeholder.classList.add("dx-direction-vertical");
260
+ this.placeholder.classList.remove("dx-direction-horizontal");
261
+ this.placeholder.style.height = undefined;
262
+ } else {
263
+ this.placeholder.classList.add("dx-direction-horizontal");
264
+ this.placeholder.classList.remove("dx-direction-vertical");
265
+ this.placeholder.style.height =
266
+ this.currentDropZone.getBoundingClientRect().height + "px";
267
+ }
268
+
269
+ const children = this.getChildren();
270
+ if (this.cursorPosition < children.length) {
271
+ this.currentDropZone.insertBefore(
272
+ this.placeholder,
273
+ children[this.cursorPosition]
274
+ );
275
+ } else {
276
+ this.currentDropZone.appendChild(this.placeholder);
277
+ }
278
+ }
237
279
  }
@@ -16,7 +16,7 @@
16
16
  <h2 v-if="title">
17
17
  {{ title }}
18
18
  </h2>
19
- <div v-if="!activeItem">
19
+ <div v-if="!target">
20
20
  Loading
21
21
  <QSpinnerHourglass />
22
22
  </div>
@@ -39,22 +39,22 @@
39
39
  </div>
40
40
  <div class="dx-panels-drawer-body flex-grow overflow-hidden h-full">
41
41
  <div
42
- v-if="activeItem.__timestamp > 0"
42
+ v-if="target.__timestamp > 0"
43
43
  class="flex items-stretch flex-nowrap h-full"
44
44
  >
45
45
  <PanelsDrawerTabs
46
- :key="'pd-tabs:' + activeItem.id"
46
+ :key="'pd-tabs:' + target.id"
47
47
  v-model="activePanel"
48
- :active-item="activeItem"
48
+ :target="target"
49
49
  :class="tabsClass"
50
50
  :panels="panels"
51
51
  @update:model-value="$emit('update:model-value', $event)"
52
52
  />
53
53
  <PanelsDrawerPanels
54
- :key="'pd-panels:' + activeItem.id"
54
+ :key="'pd-panels:' + target.id"
55
55
  :panels="panels"
56
56
  :active-panel="activePanel"
57
- :active-item="activeItem"
57
+ :active-item="target"
58
58
  :class="activePanelOptions?.class || panelsClass"
59
59
  />
60
60
  <div
@@ -79,7 +79,7 @@ import PanelsDrawerTabs from "./PanelsDrawerTabs";
79
79
  export interface Props {
80
80
  title?: string,
81
81
  modelValue?: string | number,
82
- activeItem: ActionTargetItem;
82
+ target: ActionTargetItem;
83
83
  tabsClass?: string | object,
84
84
  panelsClass?: string | object,
85
85
  position?: "standard" | "right" | "left";
@@ -13,7 +13,7 @@
13
13
  <RenderVnode
14
14
  v-if="panel.tabVnode"
15
15
  :key="panel.name"
16
- :vnode="panel.tabVnode(activeItem, modelValue)"
16
+ :vnode="panel.tabVnode(target, modelValue)"
17
17
  :is-active="modelValue === panel.name"
18
18
  :name="panel.name"
19
19
  :label="panel.label"
@@ -37,7 +37,7 @@ defineEmits(["update:model-value"]);
37
37
 
38
38
  interface Props {
39
39
  modelValue?: string | number;
40
- activeItem: ActionTargetItem;
40
+ target: ActionTargetItem;
41
41
  panels: ActionPanel[];
42
42
  }
43
43
 
@@ -51,7 +51,7 @@ function isEnabled(panel) {
51
51
  if (!panel.enabled) return false;
52
52
 
53
53
  if (typeof panel.enabled === "function") {
54
- return panel.enabled(props.activeItem);
54
+ return panel.enabled(props.target);
55
55
  }
56
56
 
57
57
  return true;
@@ -0,0 +1,86 @@
1
+ <template>
2
+ <QBtn
3
+ class="py-1 px-2"
4
+ :disable="disable"
5
+ @click="onToggle"
6
+ >
7
+ <div class="flex items-center flex-nowrap whitespace-nowrap">
8
+ <slot :is-showing="isShowing">
9
+ <component
10
+ :is="isShowing ? (hideIcon || DefaultHideIcon) : (showIcon || DefaultShowIcon)"
11
+ :class="iconClass"
12
+ />
13
+ <div
14
+ v-if="label"
15
+ :class="labelClass"
16
+ >
17
+ {{ (isShowing ? hideLabel : showLabel) || label }}
18
+ </div>
19
+ </slot>
20
+ </div>
21
+ <QTooltip v-if="tooltip">
22
+ {{ tooltip }}
23
+ </QTooltip>
24
+ </QBtn>
25
+ </template>
26
+ <script lang="ts" setup>
27
+ import { FaSolidEye as DefaultShowIcon, FaSolidEyeSlash as DefaultHideIcon } from "danx-icon";
28
+ import { nextTick } from "vue";
29
+ import { getItem, setItem } from "../../../helpers";
30
+
31
+ export interface Props {
32
+ name?: string;
33
+ showLabel?: string;
34
+ hideLabel?: string;
35
+ showIcon?: object | string;
36
+ hideIcon?: object | string;
37
+ iconClass?: string;
38
+ labelClass?: string;
39
+ label?: string;
40
+ tooltip?: string;
41
+ disable?: boolean;
42
+ }
43
+
44
+ const emit = defineEmits(["show", "hide"]);
45
+ const isShowing = defineModel<boolean>();
46
+ const props = withDefaults(defineProps<Props>(), {
47
+ name: "",
48
+ showLabel: "",
49
+ hideLabel: "",
50
+ showIcon: null,
51
+ hideIcon: null,
52
+ iconClass: "w-4 h-6",
53
+ labelClass: "ml-2",
54
+ label: "",
55
+ tooltip: ""
56
+ });
57
+
58
+ const SETTINGS_KEY = "show-hide-button";
59
+ const settings = getItem(SETTINGS_KEY, {});
60
+
61
+ if (props.name) {
62
+ if (settings[props.name] !== undefined) {
63
+ isShowing.value = settings[props.name];
64
+ }
65
+ }
66
+
67
+ function onToggle() {
68
+ isShowing.value = !isShowing.value;
69
+
70
+
71
+ // NOTE: use nextTick to ensure the value is updated before saving (if the parent does not pass a value for modelValue, this can cause a desync)
72
+ nextTick(() => {
73
+ if (isShowing.value) {
74
+ emit("show");
75
+ } else {
76
+ emit("hide");
77
+ }
78
+
79
+ if (props.name) {
80
+ settings[props.name] = isShowing.value;
81
+ setItem(SETTINGS_KEY, { ...getItem(SETTINGS_KEY, {}), [props.name]: isShowing.value });
82
+ }
83
+ });
84
+ }
85
+
86
+ </script>
@@ -1,2 +1,3 @@
1
1
  export { default as ExportButton } from "./ExportButton.vue";
2
2
  export { default as RefreshButton } from "./RefreshButton.vue";
3
+ export { default as ShowHideButton } from "./ShowHideButton.vue";