quasar-ui-danx 0.4.1 → 0.4.2

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.
@@ -1,135 +1,89 @@
1
1
  <template>
2
- <QDialog
3
- :full-height="fullHeight"
4
- :full-width="fullWidth"
5
- :model-value="!!modelValue"
6
- :no-backdrop-dismiss="!backdropDismiss"
7
- :maximized="maximized"
8
- @update:model-value="onClose"
2
+ <DialogLayout
3
+ class="dx-confirm-dialog"
4
+ v-bind="layoutProps"
5
+ @close="onClose"
9
6
  >
10
- <QCard class="flex flex-col flex-nowrap">
11
- <QCardSection
12
- v-if="title || $slots.title"
13
- class="pl-6 pr-10 border-b border-gray-300"
14
- >
15
- <h3
16
- class="font-normal flex items-center"
17
- :class="titleClass"
18
- >
19
- <slot name="title">
20
- {{ title }}
21
- </slot>
22
- </h3>
23
- <div
24
- v-if="subtitle"
25
- class="mt-1 text-sm"
7
+ <template
8
+ v-for="slotName in childSlots"
9
+ #[slotName]
10
+ >
11
+ <slot :name="slotName" />
12
+ </template>
13
+
14
+ <template #actions>
15
+ <div class="dx-dialog-button-cancel">
16
+ <QBtn
17
+ :label="cancelText"
18
+ class="dx-dialog-button"
19
+ @click="onClose"
26
20
  >
27
- {{ subtitle }}
28
- </div>
29
- </QCardSection>
30
- <QCardSection v-if="$slots.toolbar">
31
- <slot name="toolbar" />
32
- </QCardSection>
33
- <QCardSection
34
- v-if="content || $slots.default"
35
- class="px-6 bg-gray-100 flex-grow max-h-full overflow-y-auto"
36
- :class="contentClass"
37
- >
38
- <slot>{{ content }}</slot>
39
- </QCardSection>
40
- <div class="flex px-6 py-4 border-t border-gray-300">
41
- <div class="flex-grow">
42
- <QBtn
43
- :label="cancelText"
44
- class="action-btn btn-white-gray"
45
- @click="onClose"
46
- >
47
- <slot name="cancel-text" />
48
- </QBtn>
49
- </div>
50
- <slot name="actions" />
51
- <div v-if="!hideConfirm">
52
- <QBtn
53
- :label="$slots['confirm-text'] ? '' : confirmText"
54
- class="action-btn ml-4"
55
- :class="confirmClass"
56
- :loading="isSaving"
57
- :disable="disabled"
58
- data-testid="confirm-button"
59
- @click="onConfirm"
60
- >
61
- <slot name="confirm-text" />
62
- </QBtn>
63
- </div>
21
+ <slot name="cancel-text" />
22
+ </QBtn>
64
23
  </div>
65
- <a
66
- class="absolute top-0 right-0 p-4 text-black"
67
- @click="onClose"
24
+ <slot name="actions" />
25
+ <div
26
+ v-if="!hideConfirm"
27
+ class="dx-dialog-button-confirm"
68
28
  >
69
- <CloseIcon class="w-5" />
70
- </a>
71
- </QCard>
72
- </QDialog>
29
+ <QBtn
30
+ :label="$slots['confirm-text'] ? '' : confirmText"
31
+ class="dx-dialog-button"
32
+ :class="confirmClass"
33
+ :loading="isSaving"
34
+ :disable="disabled"
35
+ data-testid="confirm-button"
36
+ @click="onConfirm"
37
+ >
38
+ <slot name="confirm-text" />
39
+ </QBtn>
40
+ </div>
41
+ </template>
42
+ </DialogLayout>
73
43
  </template>
74
44
 
75
45
  <script setup>
76
- import { XIcon as CloseIcon } from "@heroicons/vue/outline";
46
+ import { computed } from "vue";
47
+ import DialogLayout from "./DialogLayout";
77
48
 
78
49
  const emit = defineEmits(["update:model-value", "confirm", "close"]);
79
50
  const props = defineProps({
80
- modelValue: { type: [String, Boolean, Object], default: true },
81
- title: {
82
- type: String,
83
- default: ""
84
- },
85
- titleClass: {
86
- type: String,
87
- default: ""
88
- },
89
- subtitle: {
90
- type: String,
91
- default: ""
92
- },
93
- content: {
94
- type: String,
95
- default: ""
96
- },
97
- backdropDismiss: Boolean,
98
- maximized: Boolean,
99
- fullWidth: Boolean,
100
- fullHeight: Boolean,
101
- disabled: Boolean,
102
- isSaving: Boolean,
103
- closeOnConfirm: Boolean,
104
- hideConfirm: Boolean,
105
- confirmText: {
106
- type: String,
107
- default: "Confirm"
108
- },
109
- cancelText: {
110
- type: String,
111
- default: "Cancel"
112
- },
113
- confirmClass: {
114
- type: String,
115
- default: "bg-blue-600 text-white"
116
- },
117
- contentClass: {
118
- type: String,
119
- default: ""
120
- }
51
+ ...DialogLayout.props,
52
+ disabled: Boolean,
53
+ isSaving: Boolean,
54
+ closeOnConfirm: Boolean,
55
+ hideConfirm: Boolean,
56
+ confirmText: {
57
+ type: String,
58
+ default: "Confirm"
59
+ },
60
+ cancelText: {
61
+ type: String,
62
+ default: "Cancel"
63
+ },
64
+ confirmClass: {
65
+ type: String,
66
+ default: ""
67
+ },
68
+ contentClass: {
69
+ type: String,
70
+ default: ""
71
+ }
121
72
  });
122
73
 
74
+ const layoutProps = computed(() => ({ ...props, disabled: undefined }));
75
+ const childSlots = computed(() => ["title", "subtitle", "default", "toolbar"]);
76
+
123
77
  function onConfirm() {
124
- emit("confirm");
78
+ emit("confirm");
125
79
 
126
- if (props.closeOnConfirm) {
127
- emit("close");
128
- }
80
+ if (props.closeOnConfirm) {
81
+ emit("close");
82
+ }
129
83
  }
130
84
 
131
85
  function onClose() {
132
- emit("update:model-value", false);
133
- emit("close");
86
+ emit("update:model-value", false);
87
+ emit("close");
134
88
  }
135
89
  </script>
@@ -0,0 +1,95 @@
1
+ <template>
2
+ <QDialog
3
+ class="dx-dialog"
4
+ :full-height="fullHeight"
5
+ :full-width="fullWidth"
6
+ :model-value="!!modelValue"
7
+ :no-backdrop-dismiss="!backdropDismiss"
8
+ :maximized="maximized"
9
+ @update:model-value="onClose"
10
+ >
11
+ <QCard class="dx-dialog-card flex flex-col flex-nowrap">
12
+ <QCardSection
13
+ class="dx-dialog-header flex items-center"
14
+ >
15
+ <div class="flex-grow">
16
+ <h3
17
+ v-if="title || $slots.title"
18
+ class="dx-dialog-title flex items-center"
19
+ :class="titleClass"
20
+ >
21
+ <slot name="title">
22
+ {{ title }}
23
+ </slot>
24
+ </h3>
25
+ <div
26
+ v-if="subtitle || $slots.subtitle"
27
+ class="dx-dialog-subtitle"
28
+ >
29
+ <slot name="subtitle">
30
+ {{ subtitle }}
31
+ </slot>
32
+ </div>
33
+ </div>
34
+ <div>
35
+ <div
36
+ class="dx-close-button cursor-pointer"
37
+ @click="onClose"
38
+ >
39
+ <CloseIcon class="w-5" />
40
+ </div>
41
+ </div>
42
+ </QCardSection>
43
+ <QCardSection v-if="$slots.toolbar">
44
+ <slot name="toolbar" />
45
+ </QCardSection>
46
+ <QCardSection
47
+ v-if="content || $slots.default"
48
+ class="dx-dialog-content flex-grow max-h-full overflow-y-auto"
49
+ :class="contentClass"
50
+ >
51
+ <slot>{{ content }}</slot>
52
+ </QCardSection>
53
+ <div class="flex dx-dialog-actions">
54
+ <slot name="actions" />
55
+ </div>
56
+ </QCard>
57
+ </QDialog>
58
+ </template>
59
+
60
+ <script setup>
61
+ import { XIcon as CloseIcon } from "@heroicons/vue/outline";
62
+
63
+ const emit = defineEmits(["close"]);
64
+ defineProps({
65
+ modelValue: { type: [String, Boolean, Object], default: true },
66
+ title: {
67
+ type: String,
68
+ default: ""
69
+ },
70
+ titleClass: {
71
+ type: String,
72
+ default: ""
73
+ },
74
+ subtitle: {
75
+ type: String,
76
+ default: ""
77
+ },
78
+ content: {
79
+ type: String,
80
+ default: ""
81
+ },
82
+ backdropDismiss: Boolean,
83
+ maximized: Boolean,
84
+ fullWidth: Boolean,
85
+ fullHeight: Boolean,
86
+ contentClass: {
87
+ type: String,
88
+ default: ""
89
+ }
90
+ });
91
+
92
+ function onClose() {
93
+ emit("close");
94
+ }
95
+ </script>
@@ -1,95 +1,55 @@
1
1
  <template>
2
- <QDialog
3
- :full-height="fullHeight"
4
- :full-width="fullWidth"
5
- :model-value="!!modelValue"
6
- :no-backdrop-dismiss="!backdropDismiss"
7
- :maximized="maximized"
8
- @update:model-value="onClose"
2
+ <DialogLayout
3
+ class="dx-info-dialog"
4
+ v-bind="$props"
5
+ @close="onClose"
9
6
  >
10
- <QCard class="flex flex-col flex-nowrap">
11
- <QCardSection
12
- v-if="title || $slots.title"
13
- class="pl-6 pr-10 border-b border-gray-300"
14
- >
15
- <h3
16
- class="font-normal flex items-center"
17
- :class="titleClass"
7
+ <template
8
+ v-if="$slots.title"
9
+ #title
10
+ >
11
+ <slot name="title" />
12
+ </template>
13
+ <template
14
+ v-if="$slots.subtitle"
15
+ #subtitle
16
+ >
17
+ <slot name="subtitle" />
18
+ </template>
19
+ <template #actions>
20
+ <div class="flex-grow">
21
+ <QBtn
22
+ :label="doneText"
23
+ class="dx-dialog-button dx-dialog-button-done"
24
+ :class="doneClass"
25
+ @click="onClose"
18
26
  >
19
- <slot name="title">
20
- {{ title }}
21
- </slot>
22
- </h3>
23
- <div
24
- v-if="subtitle"
25
- class="mt-1 text-sm"
26
- >
27
- {{ subtitle }}
28
- </div>
29
- </QCardSection>
30
- <QCardSection
31
- v-if="content || $slots.default"
32
- class="px-6 bg-gray-100 flex-grow max-h-full overflow-y-auto"
33
- >
34
- <slot>{{ content }}</slot>
35
- </QCardSection>
36
- <div
37
- class="flex items-center justify-center px-6 py-4 border-t border-gray-300"
38
- >
39
- <div class="flex-grow text-right">
40
- <QBtn
41
- :label="doneText"
42
- class="action-btn btn-white-gray"
43
- @click="onClose"
44
- >
45
- <slot name="done-text" />
46
- </QBtn>
47
- </div>
27
+ <slot name="done-text" />
28
+ </QBtn>
48
29
  </div>
49
- <a
50
- class="absolute top-0 right-0 p-4 text-black"
51
- @click="onClose"
52
- >
53
- <CloseIcon class="w-5" />
54
- </a>
55
- </QCard>
56
- </QDialog>
30
+ <slot name="actions" />
31
+ </template>
32
+ </DialogLayout>
57
33
  </template>
58
34
 
59
35
  <script setup>
60
- import { XIcon as CloseIcon } from "@heroicons/vue/outline";
36
+ import DialogLayout from "./DialogLayout";
61
37
 
62
38
  const emit = defineEmits(["update:model-value", "close"]);
63
39
  defineProps({
64
- modelValue: { type: [Boolean, Object], default: true },
65
- title: {
66
- type: String,
67
- default: ""
68
- },
69
- titleClass: {
70
- type: String,
71
- default: ""
72
- },
73
- subtitle: {
74
- type: String,
75
- default: ""
76
- },
77
- content: {
78
- type: String,
79
- default: ""
80
- },
81
- backdropDismiss: Boolean,
82
- maximized: Boolean,
83
- fullWidth: Boolean,
84
- fullHeight: Boolean,
85
- doneText: {
86
- type: String,
87
- default: "Done"
88
- }
40
+ ...DialogLayout.props,
41
+ doneClass: {
42
+ type: [String, Object],
43
+ default: ""
44
+ },
45
+ doneText: {
46
+ type: String,
47
+ default: "Done"
48
+ }
89
49
  });
90
50
 
91
51
  function onClose() {
92
- emit("update:model-value", false);
93
- emit("close");
52
+ emit("update:model-value", false);
53
+ emit("close");
94
54
  }
95
55
  </script>
@@ -2,20 +2,29 @@
2
2
  import { isRef, isVNode } from "vue";
3
3
 
4
4
  const RenderVnode = (props) => {
5
- if (isVNode(props.vnode)) {
6
- return props.vnode;
7
- }
5
+ if (isVNode(props.vnode)) {
6
+ return props.vnode;
7
+ }
8
+
9
+ if (isRef(props.vnode)) {
10
+ return props.vnode.value;
11
+ }
8
12
 
9
- if (isRef(props.vnode)) {
10
- return props.vnode.value;
11
- }
13
+ if (typeof props.vnode === "function") {
14
+ return props.vnode(props.props);
15
+ }
12
16
 
13
- if (typeof props.vnode === "function") {
14
- return props.vnode();
15
- }
16
-
17
- return null;
17
+ return null;
18
+ };
19
+ RenderVnode.props = {
20
+ vnode: {
21
+ type: [Function, Object],
22
+ required: true
23
+ },
24
+ props: {
25
+ type: Object,
26
+ default: () => ({})
27
+ }
18
28
  };
19
- RenderVnode.props = { vnode: { type: [Function, Object], required: true } };
20
29
  export default RenderVnode;
21
30
  </script>
@@ -9,7 +9,7 @@ export type ActionTargetItem = {
9
9
  isSaving: Ref<boolean>;
10
10
  [key: string]: any;
11
11
  };
12
- export type ActionTarget = ActionTargetItem[] | ActionTargetItem;
12
+ export type ActionTarget = ActionTargetItem[] | ActionTargetItem | null;
13
13
 
14
14
  export interface ActionOptions {
15
15
  name?: string;
@@ -23,9 +23,9 @@ export interface ActionOptions {
23
23
  vnode?: ((target: ActionTarget) => VNode) | undefined;
24
24
  enabled?: (target: object) => boolean;
25
25
  batchEnabled?: (targets: object[]) => boolean;
26
- optimistic?: (action: ActionOptions, target: object, input: any) => void;
27
- onAction?: (action: string | null | undefined, target: object, input: any) => Promise<any>;
28
- onBatchAction?: (action: string | null | undefined, targets: object[], input: any) => Promise<any>;
26
+ optimistic?: (action: ActionOptions, target: ActionTargetItem | null, input: any) => void;
27
+ onAction?: (action: string | null | undefined, target: ActionTargetItem | null, input: any) => Promise<any>;
28
+ onBatchAction?: (action: string | null | undefined, targets: ActionTargetItem[], input: any) => Promise<any>;
29
29
  onStart?: (action: ActionOptions | null, targets: ActionTarget, input: any) => boolean;
30
30
  onSuccess?: (result: any, targets: ActionTarget, input: any) => any;
31
31
  onError?: (result: any, targets: ActionTarget, input: any) => any;
@@ -60,7 +60,7 @@ export function useActions(actions: ActionOptions[], globalOptions: ActionOption
60
60
  for (const t of target) {
61
61
  t.isSaving.value = saving;
62
62
  }
63
- } else {
63
+ } else if (target) {
64
64
  target.isSaving.value = saving;
65
65
  }
66
66
  }
@@ -73,7 +73,7 @@ export function useActions(actions: ActionOptions[], globalOptions: ActionOption
73
73
  * @param {any} input - The input data to pass to the action handler
74
74
  * @param isTriggered - Whether the action was triggered by a trigger function
75
75
  */
76
- async function performAction(name: string | object, target: ActionTarget, input: any = null, isTriggered = false) {
76
+ async function performAction(name: string | object, target: ActionTarget = null, input: any = null, isTriggered = false) {
77
77
  const action: ActionOptions | null | undefined = typeof name === "string" ? mappedActions.find(a => a.name === name) : name;
78
78
  if (!action) {
79
79
  throw new Error(`Unknown action: ${name}`);
@@ -1,80 +1,91 @@
1
1
  .danx-app {
2
- .q-tab {
3
- text-transform: capitalize
4
- }
5
-
6
- .q-table__card {
7
- background: inherit;
8
- color: inherit;
9
- }
10
-
11
- .q-checkbox__inner {
12
- color: inherit;
13
- }
14
-
15
- .q-toolbar {
16
- min-height: 0;
17
- padding: 0;
18
- }
19
-
20
- .q-notification__actions {
21
- color: inherit;
22
- }
23
-
24
- .q-date {
25
- min-width: 100px;
26
-
27
- .q-date__view {
28
- min-height: 0;
29
- }
30
- }
31
-
32
- .q-field {
33
- &.q-field--auto-height {
34
- .q-field__control {
35
- min-height: 0;
36
-
37
- .q-field__native {
38
- min-height: 0;
39
- color: inherit;
40
- }
41
- }
42
-
43
- }
44
-
45
- &.q-field--labeled {
46
- .q-field__control-container {
47
- padding-top: 1.1rem;
48
- }
49
- }
50
-
51
- .q-field__marginal, .q-field__input, .q-field__label {
52
- color: inherit;
53
- }
54
- }
2
+ .q-tab {
3
+ text-transform: capitalize
4
+ }
5
+
6
+ .q-table__card {
7
+ background: inherit;
8
+ color: inherit;
9
+ }
10
+
11
+ .q-checkbox__inner {
12
+ color: inherit;
13
+ }
14
+
15
+ .q-toolbar {
16
+ min-height: 0;
17
+ padding: 0;
18
+ }
19
+
20
+ .q-notification__actions {
21
+ color: inherit;
22
+ }
23
+
24
+ .q-date {
25
+ min-width: 100px;
26
+
27
+ .q-date__view {
28
+ min-height: 0;
29
+ }
30
+ }
31
+
32
+ .q-field {
33
+ &.q-field--auto-height {
34
+ .q-field__control {
35
+ min-height: 0;
36
+
37
+ .q-field__native {
38
+ min-height: 0;
39
+ color: inherit;
40
+ }
41
+ }
42
+
43
+ }
44
+
45
+ &.q-field--labeled {
46
+ .q-field__control-container {
47
+ padding-top: 1.1rem;
48
+ }
49
+ }
50
+
51
+ .q-field__marginal, .q-field__input, .q-field__label {
52
+ color: inherit;
53
+ }
54
+ }
55
+ }
56
+
57
+ .q-btn {
58
+ text-transform: inherit;
59
+ @apply bg-inherit text-inherit;
55
60
  }
56
61
 
57
62
  .q-item {
58
- min-height: 0;
63
+ min-height: 0;
59
64
  }
60
65
 
61
66
  .q-tab-panels {
62
- overflow: visible;
63
- background: inherit;
67
+ overflow: visible;
68
+ background: inherit;
64
69
 
65
- .q-panel {
66
- overflow: visible;
70
+ .q-panel {
71
+ overflow: visible;
67
72
 
68
- &.scroll {
69
- overflow: auto;
70
- }
73
+ &.scroll {
74
+ overflow: auto;
75
+ }
71
76
 
72
- .q-tab-panel {
73
- padding: 0;
74
- }
75
- }
77
+ .q-tab-panel {
78
+ padding: 0;
79
+ }
80
+ }
81
+
82
+ &.overflow-y-auto {
83
+ overflow-y: auto;
84
+ }
85
+ }
76
86
 
77
- &.overflow-y-auto {
78
- overflow-y: auto;
79
- }
87
+ .dx-dialog {
88
+ .q-card__section--vert {
89
+ @apply p-0;
90
+ }
80
91
  }