@usssa/component-library 1.0.0-alpha.134 → 1.0.0-alpha.136
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/README.md +1 -1
- package/package.json +1 -1
- package/src/components/core/UMenuItem.vue +16 -5
- package/src/components/core/UMultiSelectStd.vue +197 -10
- package/src/components/core/UPagination.vue +22 -4
- package/src/components/core/USelectStd.vue +204 -6
- package/src/components/core/USheet.vue +65 -49
package/README.md
CHANGED
package/package.json
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
<script setup>
|
|
2
|
-
import { computed
|
|
2
|
+
import { computed } from 'vue'
|
|
3
3
|
|
|
4
4
|
const emit = defineEmits(['onClick'])
|
|
5
5
|
const props = defineProps({
|
|
@@ -22,6 +22,10 @@ const props = defineProps({
|
|
|
22
22
|
iconClass: {
|
|
23
23
|
type: String,
|
|
24
24
|
},
|
|
25
|
+
inSheet: {
|
|
26
|
+
type: Boolean,
|
|
27
|
+
default: false,
|
|
28
|
+
},
|
|
25
29
|
label: {
|
|
26
30
|
type: String,
|
|
27
31
|
},
|
|
@@ -45,7 +49,7 @@ const backgroundColor = computed(() => {
|
|
|
45
49
|
if (props.selected && !props.destructive && !props.positive) {
|
|
46
50
|
return 'bg-blue-1'
|
|
47
51
|
}
|
|
48
|
-
return 'bg-neutral-1'
|
|
52
|
+
return props.inSheet ? 'bg-neutral-2' : 'bg-neutral-1'
|
|
49
53
|
})
|
|
50
54
|
|
|
51
55
|
const iconColor = computed(() => {
|
|
@@ -62,7 +66,7 @@ const iconColor = computed(() => {
|
|
|
62
66
|
const labelColor = computed(() => {
|
|
63
67
|
if (props.destructive) {
|
|
64
68
|
return 'text-accent'
|
|
65
|
-
} else if (props.selected) {
|
|
69
|
+
} else if (props.selected && !props.inSheet) {
|
|
66
70
|
return 'text-primary'
|
|
67
71
|
} else if (props.positive) {
|
|
68
72
|
return 'text-positive'
|
|
@@ -70,6 +74,13 @@ const labelColor = computed(() => {
|
|
|
70
74
|
return 'text-dark'
|
|
71
75
|
})
|
|
72
76
|
|
|
77
|
+
const labelStyle = computed(() => {
|
|
78
|
+
if (props.inSheet) {
|
|
79
|
+
return 'text-caption-lg'
|
|
80
|
+
}
|
|
81
|
+
return 'text-body-sm'
|
|
82
|
+
})
|
|
83
|
+
|
|
73
84
|
const type = computed(() => {
|
|
74
85
|
if (props.destructive) {
|
|
75
86
|
return 'destructive'
|
|
@@ -93,7 +104,7 @@ const handleClick = () => {
|
|
|
93
104
|
:dataTestId="dataTestId"
|
|
94
105
|
:disable="disable"
|
|
95
106
|
role="button"
|
|
96
|
-
tabindex="0"
|
|
107
|
+
:tabindex="inSheet ? '-1' : '0'"
|
|
97
108
|
@click="handleClick"
|
|
98
109
|
>
|
|
99
110
|
<q-item-section v-if="leftIcon" side>
|
|
@@ -105,7 +116,7 @@ const handleClick = () => {
|
|
|
105
116
|
/>
|
|
106
117
|
</q-item-section>
|
|
107
118
|
<slot name="leading_slot"></slot>
|
|
108
|
-
<q-item-section :class="`${labelColor}
|
|
119
|
+
<q-item-section :class="`${labelColor} ${labelStyle} label`" :tabindex="!inSheet ? '-1' : '0'">
|
|
109
120
|
{{ label }}
|
|
110
121
|
</q-item-section>
|
|
111
122
|
<q-item-section v-if="rightIcon" side>
|
|
@@ -1,16 +1,25 @@
|
|
|
1
1
|
<script setup>
|
|
2
|
-
import { ref, watch} from 'vue'
|
|
2
|
+
import { computed, ref, watch } from 'vue'
|
|
3
|
+
import UBtnStd from './UBtnStd.vue'
|
|
3
4
|
import UChip from './UChip.vue'
|
|
4
5
|
import UTooltip from './UTooltip.vue'
|
|
6
|
+
import USheet from './USheet.vue'
|
|
7
|
+
import UMenuItem from './UMenuItem.vue'
|
|
8
|
+
import { useScreenType } from '../../composables/useScreenType'
|
|
5
9
|
|
|
10
|
+
const emit = defineEmits(['update:modelValue'])
|
|
6
11
|
const props = defineProps({
|
|
12
|
+
caption: {
|
|
13
|
+
type: String,
|
|
14
|
+
default: '',
|
|
15
|
+
},
|
|
7
16
|
color: {
|
|
8
17
|
type: String,
|
|
9
18
|
default: 'neutral-7',
|
|
10
19
|
},
|
|
11
|
-
dataTestId:{
|
|
20
|
+
dataTestId: {
|
|
12
21
|
type: String,
|
|
13
|
-
default: 'multi-select'
|
|
22
|
+
default: 'multi-select',
|
|
14
23
|
},
|
|
15
24
|
filterFn: {
|
|
16
25
|
type: Function,
|
|
@@ -77,12 +86,85 @@ const props = defineProps({
|
|
|
77
86
|
useInput: {
|
|
78
87
|
type: Boolean,
|
|
79
88
|
required: false,
|
|
80
|
-
}
|
|
89
|
+
},
|
|
81
90
|
})
|
|
82
91
|
|
|
92
|
+
const $screen = useScreenType()
|
|
93
|
+
|
|
83
94
|
const chipModelVal = ref(true)
|
|
95
|
+
const dialogs = ref([])
|
|
96
|
+
const filterOptions = ref([...props.options])
|
|
84
97
|
const placeholderText = ref(props.placeholder)
|
|
98
|
+
const selectedItems = ref([...props.modelValue])
|
|
99
|
+
|
|
100
|
+
const sheetHeading = computed(()=> props.label)
|
|
101
|
+
|
|
102
|
+
const filterSheetOptions = (val, update) => {
|
|
103
|
+
if (val === '') {
|
|
104
|
+
update(() => {
|
|
105
|
+
filterOptions.value = [...props.options]
|
|
106
|
+
})
|
|
107
|
+
return
|
|
108
|
+
}
|
|
85
109
|
|
|
110
|
+
const typeValue = val.toLowerCase()
|
|
111
|
+
update(() => {
|
|
112
|
+
filterOptions.value = props.options.filter((option) =>
|
|
113
|
+
option.label.toLowerCase().includes(typeValue)
|
|
114
|
+
)
|
|
115
|
+
})
|
|
116
|
+
}
|
|
117
|
+
const handleApply = () => {
|
|
118
|
+
dialogs.value[0].open = false
|
|
119
|
+
emit('update:modelValue', selectedItems.value)
|
|
120
|
+
}
|
|
121
|
+
const handleClick = (event) => {
|
|
122
|
+
const isSelectElement = event.target.closest('.q-field__control')
|
|
123
|
+
if ($screen.value.isMobile && isSelectElement) {
|
|
124
|
+
event.stopPropagation()
|
|
125
|
+
dialogs.value = [
|
|
126
|
+
{
|
|
127
|
+
open: true,
|
|
128
|
+
height: 350,
|
|
129
|
+
persistent: true,
|
|
130
|
+
transitionDuration: 500,
|
|
131
|
+
position: 'bottom',
|
|
132
|
+
},
|
|
133
|
+
]
|
|
134
|
+
selectedItems.value = props.modelValue
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
const handleClose = () => {
|
|
138
|
+
dialogs.value[0].open = false
|
|
139
|
+
selectedItems.value = props.modelValue.length ? props.modelValue : []
|
|
140
|
+
}
|
|
141
|
+
const handleSheetItemClick = (val) => {
|
|
142
|
+
const exists = selectedItems.value.find((item) => item.value === val.value)
|
|
143
|
+
if (!exists) {
|
|
144
|
+
selectedItems.value = [...selectedItems.value, val]
|
|
145
|
+
} else {
|
|
146
|
+
selectedItems.value = selectedItems.value.filter(
|
|
147
|
+
(item) => item.value !== val.value
|
|
148
|
+
)
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
const handleSheetItemRemove = (item) => {
|
|
152
|
+
selectedItems.value = selectedItems.value.filter(
|
|
153
|
+
(option) => option.value !== item.value
|
|
154
|
+
)
|
|
155
|
+
}
|
|
156
|
+
const handleSheetSelectionUpdate = (val) => {
|
|
157
|
+
selectedItems.value = val
|
|
158
|
+
}
|
|
159
|
+
const isSelected = (value) => {
|
|
160
|
+
let getItems = selectedItems.value.filter((e) => e.value === value)
|
|
161
|
+
return getItems.length ? true : false
|
|
162
|
+
}
|
|
163
|
+
const removeItems = (item) => {
|
|
164
|
+
selectedItems.value = selectedItems.value.filter(
|
|
165
|
+
(option) => option.value !== item.value
|
|
166
|
+
)
|
|
167
|
+
}
|
|
86
168
|
const updateVal = (val) => {
|
|
87
169
|
props.updateFn(val)
|
|
88
170
|
placeholderText.value = val.length ? '' : props.placeholder
|
|
@@ -94,11 +176,19 @@ watch(
|
|
|
94
176
|
placeholderText.value = value
|
|
95
177
|
}
|
|
96
178
|
)
|
|
179
|
+
watch(
|
|
180
|
+
() => $screen.value,
|
|
181
|
+
(newValue) => {
|
|
182
|
+
if (newValue) {
|
|
183
|
+
selectedItems.value = [...props.modelValue]
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
)
|
|
97
187
|
</script>
|
|
98
188
|
|
|
99
189
|
<template>
|
|
100
|
-
<div class="q-gutter-xs" :dataTestId="dataTestId">
|
|
101
|
-
<label class="row items-center" for="select"
|
|
190
|
+
<div class="q-gutter-xs" :dataTestId="dataTestId" @click="handleClick">
|
|
191
|
+
<label class="row items-center" for="select">
|
|
102
192
|
<div class="u-select-label text-body-sm">
|
|
103
193
|
<span>{{ label }}</span>
|
|
104
194
|
<span v-if="isRequired" class="text-red-5 q-ml-xs">*</span>
|
|
@@ -121,6 +211,7 @@ watch(
|
|
|
121
211
|
<q-select
|
|
122
212
|
v-bind="$attrs"
|
|
123
213
|
:class="`u-multi-select field-${size}`"
|
|
214
|
+
behavior="menu"
|
|
124
215
|
bottom-slots
|
|
125
216
|
:color="color"
|
|
126
217
|
hide-bottom-space
|
|
@@ -133,7 +224,7 @@ watch(
|
|
|
133
224
|
options-selected-class="primary bg-blue-1"
|
|
134
225
|
:option-value="optionValue"
|
|
135
226
|
outlined
|
|
136
|
-
:placeholder="placeholderText"
|
|
227
|
+
:placeholder="modelValue.length ? '' : placeholderText"
|
|
137
228
|
popup-content-class="u-option-menu"
|
|
138
229
|
use-chips
|
|
139
230
|
:use-input="useInput"
|
|
@@ -168,7 +259,7 @@ watch(
|
|
|
168
259
|
|
|
169
260
|
<template v-if="hintText" v-slot:hint>
|
|
170
261
|
<div class="row no-wrap items-center">
|
|
171
|
-
<q-icon v-if="hintIcon" :class="hintIcon" size="1rem"/>
|
|
262
|
+
<q-icon v-if="hintIcon" :class="hintIcon" size="1rem" />
|
|
172
263
|
|
|
173
264
|
<div class="q-mx-xxs text-body-xs">
|
|
174
265
|
{{ hintText }}
|
|
@@ -177,7 +268,11 @@ watch(
|
|
|
177
268
|
</template>
|
|
178
269
|
|
|
179
270
|
<template v-slot:option="scope">
|
|
180
|
-
<q-item
|
|
271
|
+
<q-item
|
|
272
|
+
v-bind="scope.itemProps"
|
|
273
|
+
v-if="!$screen.isMobile"
|
|
274
|
+
class="items-center u-custom-options"
|
|
275
|
+
>
|
|
181
276
|
<div v-if="scope.opt.icon" class="q-pr-xs">
|
|
182
277
|
<q-icon :class="scope.opt.icon" color="neutral-13" size="1rem" />
|
|
183
278
|
</div>
|
|
@@ -186,7 +281,7 @@ watch(
|
|
|
186
281
|
<q-item-label class="text-body-sm">
|
|
187
282
|
{{ scope.opt.label }}
|
|
188
283
|
</q-item-label>
|
|
189
|
-
<q-item-label
|
|
284
|
+
<q-item-label v-if="scope.opt.description" caption>
|
|
190
285
|
{{ scope.opt.description }}
|
|
191
286
|
</q-item-label>
|
|
192
287
|
</q-item-section>
|
|
@@ -212,6 +307,95 @@ watch(
|
|
|
212
307
|
</template>
|
|
213
308
|
</q-select>
|
|
214
309
|
</div>
|
|
310
|
+
<USheet
|
|
311
|
+
v-if="$screen.isMobile"
|
|
312
|
+
v-model:dialogs="dialogs"
|
|
313
|
+
:heading="sheetHeading"
|
|
314
|
+
:heading-caption="caption"
|
|
315
|
+
:show-action-buttons="true"
|
|
316
|
+
>
|
|
317
|
+
<template #header>
|
|
318
|
+
<q-select
|
|
319
|
+
:model-value="selectedItems"
|
|
320
|
+
:class="`u-multi-select field-md q-mt-ba`"
|
|
321
|
+
behavior="menu"
|
|
322
|
+
multiple
|
|
323
|
+
outlined
|
|
324
|
+
:placeholder="selectedItems.length ? '' : placeholderText"
|
|
325
|
+
use-chips
|
|
326
|
+
:use-input="useInput"
|
|
327
|
+
@click="() => null"
|
|
328
|
+
@filter="filterSheetOptions"
|
|
329
|
+
@remove="handleSheetItemRemove"
|
|
330
|
+
@update:model-value="handleSheetSelectionUpdate"
|
|
331
|
+
>
|
|
332
|
+
<template v-if="leftIcon" v-slot:prepend>
|
|
333
|
+
<q-icon :class="leftIcon" size="1rem" />
|
|
334
|
+
</template>
|
|
335
|
+
<template v-slot:selected-item="scope">
|
|
336
|
+
<UChip
|
|
337
|
+
v-model="chipModelVal"
|
|
338
|
+
:chipLabel="scope.opt.label"
|
|
339
|
+
dense
|
|
340
|
+
:removable="true"
|
|
341
|
+
:tabindex="scope.tabindex"
|
|
342
|
+
@remove="removeItems(scope.opt)"
|
|
343
|
+
/>
|
|
344
|
+
</template>
|
|
345
|
+
</q-select>
|
|
346
|
+
</template>
|
|
347
|
+
<template #content>
|
|
348
|
+
<template v-if="filterOptions.length > 0">
|
|
349
|
+
<template v-for="(item, index) in filterOptions" :key="index">
|
|
350
|
+
<UMenuItem
|
|
351
|
+
iconClass=""
|
|
352
|
+
:destructive="item.destructive"
|
|
353
|
+
:disable="item.disable"
|
|
354
|
+
:hide="item.hide"
|
|
355
|
+
:index="index"
|
|
356
|
+
:inSheet="true"
|
|
357
|
+
:label="item.label"
|
|
358
|
+
labelStyle="text-caption-lg"
|
|
359
|
+
:leftIcon="item.icon"
|
|
360
|
+
:positive="item.positive"
|
|
361
|
+
:rightIcon="item.rightIcon"
|
|
362
|
+
:selected="isSelected(item.value)"
|
|
363
|
+
@onClick="handleSheetItemClick(item, index)"
|
|
364
|
+
>
|
|
365
|
+
<template #trailing_slot>
|
|
366
|
+
<slot name="trailing_slot">
|
|
367
|
+
<q-icon
|
|
368
|
+
v-if="isSelected(item.value)"
|
|
369
|
+
class="fa-kit-duotone fa-circle-check"
|
|
370
|
+
color="primary"
|
|
371
|
+
size="1rem"
|
|
372
|
+
/>
|
|
373
|
+
</slot>
|
|
374
|
+
</template>
|
|
375
|
+
</UMenuItem>
|
|
376
|
+
</template>
|
|
377
|
+
</template>
|
|
378
|
+
<template v-else>
|
|
379
|
+
<q-item>
|
|
380
|
+
<q-item-section class="text-grey">
|
|
381
|
+
{{ noSearchText }}
|
|
382
|
+
</q-item-section>
|
|
383
|
+
</q-item>
|
|
384
|
+
</template>
|
|
385
|
+
</template>
|
|
386
|
+
<template #action_primary_one>
|
|
387
|
+
<UBtnStd
|
|
388
|
+
color="primary"
|
|
389
|
+
label="Cancel"
|
|
390
|
+
outline
|
|
391
|
+
size="md"
|
|
392
|
+
@onClick="handleClose"
|
|
393
|
+
/>
|
|
394
|
+
</template>
|
|
395
|
+
<template #action_primary_two>
|
|
396
|
+
<UBtnStd color="primary" label="Apply" size="md" @onClick="handleApply" />
|
|
397
|
+
</template>
|
|
398
|
+
</USheet>
|
|
215
399
|
</template>
|
|
216
400
|
|
|
217
401
|
<style lang="sass">
|
|
@@ -273,4 +457,7 @@ watch(
|
|
|
273
457
|
border-radius: $xxs
|
|
274
458
|
padding: $xs
|
|
275
459
|
min-height: $lg
|
|
460
|
+
|
|
461
|
+
.sheet-card-wrapper .q-select__dropdown-icon
|
|
462
|
+
display: none !important
|
|
276
463
|
</style>
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
<script setup>
|
|
2
|
-
import { ref, watch } from 'vue'
|
|
2
|
+
import { computed, ref, watch } from 'vue'
|
|
3
|
+
import { useScreenType } from '../../composables/useScreenType'
|
|
3
4
|
import USelectStd from './USelectStd.vue'
|
|
4
5
|
|
|
5
6
|
const emit = defineEmits(['update:modelValue', 'onRowChange', 'onPageChange'])
|
|
@@ -37,12 +38,28 @@ const props = defineProps({
|
|
|
37
38
|
type: Number,
|
|
38
39
|
default: 5,
|
|
39
40
|
},
|
|
41
|
+
sheetLabel:{
|
|
42
|
+
type: String,
|
|
43
|
+
default: "Selections Per Page"
|
|
44
|
+
}
|
|
40
45
|
})
|
|
41
46
|
|
|
47
|
+
const $screen = useScreenType()
|
|
48
|
+
|
|
42
49
|
// refs
|
|
43
50
|
const currentPage = ref(props.modelValue)
|
|
44
51
|
const rowPerPage = ref(props.rowPerPage)
|
|
45
52
|
|
|
53
|
+
const perPageOptionsList = computed(() => {
|
|
54
|
+
if ($screen.value.isMobile) {
|
|
55
|
+
return [...props.perPageOptions].map(option => ({
|
|
56
|
+
...option,
|
|
57
|
+
label: option.label.split(' ')[0]
|
|
58
|
+
}));
|
|
59
|
+
}
|
|
60
|
+
return props.perPageOptions;
|
|
61
|
+
});
|
|
62
|
+
|
|
46
63
|
// custom functions
|
|
47
64
|
const onPageChange = (newPage) => {
|
|
48
65
|
currentPage.value = newPage
|
|
@@ -59,7 +76,7 @@ watch(currentPage, (newValue) => {
|
|
|
59
76
|
</script>
|
|
60
77
|
|
|
61
78
|
<template>
|
|
62
|
-
<div class="row u-pagination-container">
|
|
79
|
+
<div :class="`row u-pagination-container no-wrap items-center ${$screen.isMobile?'justify-between' : 'justify-end'}`">
|
|
63
80
|
<q-pagination
|
|
64
81
|
v-model="model"
|
|
65
82
|
class="u-pagination"
|
|
@@ -80,7 +97,8 @@ watch(currentPage, (newValue) => {
|
|
|
80
97
|
class="q-gutter-x-sm text-body-sm perpage-dropdown"
|
|
81
98
|
popupClass="pagination-dropdown"
|
|
82
99
|
color="primary"
|
|
83
|
-
:options="
|
|
100
|
+
:options="perPageOptionsList"
|
|
101
|
+
:sheetLabel="sheetLabel"
|
|
84
102
|
@update:model-value="onRowChange"
|
|
85
103
|
/>
|
|
86
104
|
</div>
|
|
@@ -97,7 +115,7 @@ watch(currentPage, (newValue) => {
|
|
|
97
115
|
margin-top: 0 !important
|
|
98
116
|
.q-field--outlined .q-field__control
|
|
99
117
|
display: inline-flex
|
|
100
|
-
width: 8.75rem
|
|
118
|
+
max-width: 8.75rem
|
|
101
119
|
|
|
102
120
|
.u-pagination
|
|
103
121
|
.q-icon
|
|
@@ -1,19 +1,27 @@
|
|
|
1
1
|
<script setup>
|
|
2
2
|
import { computed, ref, watch } from 'vue'
|
|
3
|
+
import { useScreenType } from '../../composables/useScreenType'
|
|
3
4
|
import UAvatar from './UAvatar.vue'
|
|
5
|
+
import UBtnStd from './UBtnStd.vue'
|
|
6
|
+
import UInputTextStd from './UInputTextStd.vue'
|
|
4
7
|
import UMenuItem from './UMenuItem.vue'
|
|
8
|
+
import USheet from './USheet.vue'
|
|
5
9
|
import UTooltip from './UTooltip.vue'
|
|
6
10
|
|
|
7
11
|
const emit = defineEmits(['update:modelValue'])
|
|
8
12
|
|
|
9
13
|
const props = defineProps({
|
|
14
|
+
caption: {
|
|
15
|
+
type: String,
|
|
16
|
+
default: '',
|
|
17
|
+
},
|
|
10
18
|
color: {
|
|
11
19
|
type: String,
|
|
12
20
|
default: 'neutral-7',
|
|
13
21
|
},
|
|
14
|
-
dataTestId:{
|
|
15
|
-
|
|
16
|
-
|
|
22
|
+
dataTestId: {
|
|
23
|
+
type: String,
|
|
24
|
+
default: 'select-std',
|
|
17
25
|
},
|
|
18
26
|
disableAvatar: {
|
|
19
27
|
type: Boolean,
|
|
@@ -66,6 +74,10 @@ const props = defineProps({
|
|
|
66
74
|
type: String,
|
|
67
75
|
default: '',
|
|
68
76
|
},
|
|
77
|
+
sheetLabel: {
|
|
78
|
+
type: String,
|
|
79
|
+
default: ''
|
|
80
|
+
},
|
|
69
81
|
showErrorIcon: {
|
|
70
82
|
type: Boolean,
|
|
71
83
|
default: false,
|
|
@@ -84,17 +96,77 @@ const props = defineProps({
|
|
|
84
96
|
},
|
|
85
97
|
})
|
|
86
98
|
|
|
99
|
+
const $screen = useScreenType()
|
|
100
|
+
|
|
101
|
+
const dialogs = ref([])
|
|
102
|
+
const initialOptions= ref([...props.options])
|
|
87
103
|
const placeholderText = ref(props?.placeholder)
|
|
104
|
+
const search = ref('')
|
|
105
|
+
const selectedItem = ref(props.modelValue)
|
|
106
|
+
|
|
107
|
+
const sheetHeading = computed(()=>{
|
|
108
|
+
if(props.sheetLabel){
|
|
109
|
+
return props.sheetLabel
|
|
110
|
+
}
|
|
111
|
+
return props.label
|
|
112
|
+
})
|
|
88
113
|
|
|
114
|
+
const filterOptions = computed(() => {
|
|
115
|
+
if (!search.value) return initialOptions.value
|
|
116
|
+
return props.options.filter((option) =>
|
|
117
|
+
option.label.toLowerCase().includes(search.value.toLocaleLowerCase())
|
|
118
|
+
)
|
|
119
|
+
})
|
|
89
120
|
const model = computed({
|
|
90
121
|
get() {
|
|
91
122
|
return props.modelValue
|
|
92
123
|
},
|
|
93
124
|
set(value) {
|
|
125
|
+
selectedItem.value = value
|
|
94
126
|
return emit('update:modelValue', value)
|
|
95
127
|
},
|
|
96
128
|
})
|
|
97
129
|
|
|
130
|
+
// sheet apply action
|
|
131
|
+
const handleApply = () => {
|
|
132
|
+
dialogs.value[0].open = false
|
|
133
|
+
model.value = selectedItem.value
|
|
134
|
+
}
|
|
135
|
+
// for opening the sheet in mobile screen
|
|
136
|
+
const handleClick = (event) => {
|
|
137
|
+
const isSelectElement = event.target.closest('.q-field__control')
|
|
138
|
+
if ($screen.value.isMobile && isSelectElement) {
|
|
139
|
+
event.stopPropagation()
|
|
140
|
+
dialogs.value = [
|
|
141
|
+
{
|
|
142
|
+
open: true,
|
|
143
|
+
height: 350,
|
|
144
|
+
persistent: true,
|
|
145
|
+
transitionDuration: 500,
|
|
146
|
+
position: 'bottom',
|
|
147
|
+
},
|
|
148
|
+
]
|
|
149
|
+
search.value = ''
|
|
150
|
+
if (model.value === '') {
|
|
151
|
+
selectedItem.value = ''
|
|
152
|
+
} else {
|
|
153
|
+
selectedItem.value = model.value
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
// sheet closing action
|
|
158
|
+
const handleClose = () => {
|
|
159
|
+
dialogs.value[0].open = false
|
|
160
|
+
if (model.value) {
|
|
161
|
+
if (selectedItem.value) {
|
|
162
|
+
if (model.value !== selectedItem.value) {
|
|
163
|
+
selectedItem.value = model.value
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
} else {
|
|
167
|
+
selectedItem.value = ''
|
|
168
|
+
}
|
|
169
|
+
}
|
|
98
170
|
// adding scroll if highlighted menu is not visible to user
|
|
99
171
|
const handleKeydown = () => {
|
|
100
172
|
setTimeout(() => {
|
|
@@ -119,6 +191,10 @@ const handleKeydown = () => {
|
|
|
119
191
|
}
|
|
120
192
|
}, 100)
|
|
121
193
|
}
|
|
194
|
+
// selecting sheet items
|
|
195
|
+
const handleSheetItemClick = (item, key) => {
|
|
196
|
+
selectedItem.value = item.value
|
|
197
|
+
}
|
|
122
198
|
|
|
123
199
|
const updateVal = (val) => {
|
|
124
200
|
placeholderText.value = val?.length ? '' : props?.placeholder
|
|
@@ -130,10 +206,22 @@ watch(
|
|
|
130
206
|
placeholderText.value = value
|
|
131
207
|
}
|
|
132
208
|
)
|
|
209
|
+
watch(
|
|
210
|
+
() => $screen.value,
|
|
211
|
+
(newValue) => {
|
|
212
|
+
if (newValue) {
|
|
213
|
+
selectedItem.value = props.modelValue
|
|
214
|
+
}
|
|
215
|
+
}
|
|
216
|
+
)
|
|
133
217
|
</script>
|
|
134
218
|
|
|
135
219
|
<template>
|
|
136
|
-
<section
|
|
220
|
+
<section
|
|
221
|
+
class="column q-gutter-y-xs"
|
|
222
|
+
:dataTestId="dataTestId"
|
|
223
|
+
@click="handleClick"
|
|
224
|
+
>
|
|
137
225
|
<label class="row items-center" for="select">
|
|
138
226
|
<div class="u-select-label text-body-sm">
|
|
139
227
|
<span>{{ label }}</span>
|
|
@@ -160,6 +248,7 @@ watch(
|
|
|
160
248
|
v-model="model"
|
|
161
249
|
:class="`u-select field-${size}`"
|
|
162
250
|
:popup-content-class="`u-options-menu ${popupClass}`"
|
|
251
|
+
behavior="menu"
|
|
163
252
|
options-selected-class="primary bg-blue-1"
|
|
164
253
|
bottom-slots
|
|
165
254
|
:color="color"
|
|
@@ -203,12 +292,14 @@ watch(
|
|
|
203
292
|
<template v-slot:option="scope">
|
|
204
293
|
<UMenuItem
|
|
205
294
|
v-bind="scope.itemProps"
|
|
295
|
+
v-if="!$screen.isMobile"
|
|
206
296
|
class="q-ma-xxs"
|
|
207
297
|
iconClass="icon-secondary-opacity"
|
|
208
298
|
:label="scope.opt.label"
|
|
209
299
|
:leftIcon="scope.opt.leftIcon"
|
|
300
|
+
:key="scope.opt.value"
|
|
210
301
|
:rightIcon="scope.opt.rightIcon"
|
|
211
|
-
:selected="scope.selected"
|
|
302
|
+
:selected="scope.selected || model === scope.label"
|
|
212
303
|
>
|
|
213
304
|
<template #leading_slot>
|
|
214
305
|
<slot name="leading_slot" />
|
|
@@ -225,7 +316,7 @@ watch(
|
|
|
225
316
|
<template #trailing_slot>
|
|
226
317
|
<slot name="trailing_slot">
|
|
227
318
|
<q-icon
|
|
228
|
-
v-if="scope.selected"
|
|
319
|
+
v-if="scope.selected || model === scope.label"
|
|
229
320
|
class="fa-kit-duotone fa-circle-check"
|
|
230
321
|
color="primary"
|
|
231
322
|
size="1rem"
|
|
@@ -235,6 +326,95 @@ watch(
|
|
|
235
326
|
</UMenuItem>
|
|
236
327
|
</template>
|
|
237
328
|
</q-select>
|
|
329
|
+
<USheet
|
|
330
|
+
v-if="$screen.isMobile"
|
|
331
|
+
v-model:dialogs="dialogs"
|
|
332
|
+
:heading="sheetHeading"
|
|
333
|
+
:heading-caption="caption"
|
|
334
|
+
:show-action-buttons="true"
|
|
335
|
+
>
|
|
336
|
+
<template #header>
|
|
337
|
+
<UInputTextStd
|
|
338
|
+
v-if="useInput"
|
|
339
|
+
v-model="search"
|
|
340
|
+
class="q-mt-ba"
|
|
341
|
+
:leftIcon="leftIcon"
|
|
342
|
+
:placeholder="placeholder"
|
|
343
|
+
size="md"
|
|
344
|
+
/>
|
|
345
|
+
</template>
|
|
346
|
+
<template #content>
|
|
347
|
+
<template v-if="filterOptions.length > 0">
|
|
348
|
+
<template v-for="(item, index) in filterOptions" :key="item.value">
|
|
349
|
+
<UMenuItem
|
|
350
|
+
iconClass=""
|
|
351
|
+
:destructive="item.destructive"
|
|
352
|
+
:disable="item.disable"
|
|
353
|
+
:hide="item.hide"
|
|
354
|
+
:inSheet="true"
|
|
355
|
+
:label="item.label"
|
|
356
|
+
labelStyle="text-caption-lg"
|
|
357
|
+
:leftIcon="item.leftIcon"
|
|
358
|
+
:positive="item.positive"
|
|
359
|
+
:rightIcon="item.rightIcon"
|
|
360
|
+
:selected="
|
|
361
|
+
item.value === selectedItem || item.label === selectedItem
|
|
362
|
+
"
|
|
363
|
+
@onClick="handleSheetItemClick(item, index)"
|
|
364
|
+
>
|
|
365
|
+
<template #leading_slot>
|
|
366
|
+
<slot name="leading_slot" />
|
|
367
|
+
<div v-if="!disableAvatar">
|
|
368
|
+
<UAvatar
|
|
369
|
+
v-if="item.avatarUrl"
|
|
370
|
+
:image="item.avatarUrl"
|
|
371
|
+
:name="item.label"
|
|
372
|
+
size="md"
|
|
373
|
+
/>
|
|
374
|
+
<UAvatar v-else :name="item.label" size="md" />
|
|
375
|
+
</div>
|
|
376
|
+
</template>
|
|
377
|
+
<template #trailing_slot>
|
|
378
|
+
<slot name="trailing_slot">
|
|
379
|
+
<q-icon
|
|
380
|
+
v-if="
|
|
381
|
+
item.value === selectedItem || item.label === selectedItem
|
|
382
|
+
"
|
|
383
|
+
class="fa-kit-duotone fa-circle-check"
|
|
384
|
+
color="primary"
|
|
385
|
+
size="1rem"
|
|
386
|
+
/>
|
|
387
|
+
</slot>
|
|
388
|
+
</template>
|
|
389
|
+
</UMenuItem>
|
|
390
|
+
</template>
|
|
391
|
+
</template>
|
|
392
|
+
<template v-else>
|
|
393
|
+
<q-item>
|
|
394
|
+
<q-item-section class="text-grey">
|
|
395
|
+
{{ noSearchText }}
|
|
396
|
+
</q-item-section>
|
|
397
|
+
</q-item>
|
|
398
|
+
</template>
|
|
399
|
+
</template>
|
|
400
|
+
<template #action_primary_one>
|
|
401
|
+
<UBtnStd
|
|
402
|
+
color="primary"
|
|
403
|
+
label="Cancel"
|
|
404
|
+
outline
|
|
405
|
+
size="md"
|
|
406
|
+
@onClick="handleClose"
|
|
407
|
+
/>
|
|
408
|
+
</template>
|
|
409
|
+
<template #action_primary_two>
|
|
410
|
+
<UBtnStd
|
|
411
|
+
color="primary"
|
|
412
|
+
label="Apply"
|
|
413
|
+
size="md"
|
|
414
|
+
@onClick="handleApply"
|
|
415
|
+
/>
|
|
416
|
+
</template>
|
|
417
|
+
</USheet>
|
|
238
418
|
</section>
|
|
239
419
|
</template>
|
|
240
420
|
|
|
@@ -290,4 +470,22 @@ watch(
|
|
|
290
470
|
.u-options-menu
|
|
291
471
|
.q-item:last-child
|
|
292
472
|
margin-bottom: $xxs
|
|
473
|
+
|
|
474
|
+
.sheet-card-wrapper .q-card__section .q-item
|
|
475
|
+
padding:$ba $ba !important
|
|
476
|
+
margin-bottom: $xs !important
|
|
477
|
+
border-radius: $sm !important
|
|
478
|
+
align-items: flex-start !important
|
|
479
|
+
.q-icon
|
|
480
|
+
font-size: $ms !important
|
|
481
|
+
.q-focus-helper
|
|
482
|
+
display: none
|
|
483
|
+
|
|
484
|
+
.sheet-action-wrapper .action-buttons
|
|
485
|
+
gap: $ba !important
|
|
486
|
+
padding: $ba !important
|
|
487
|
+
|
|
488
|
+
.sheet-card-wrapper .main-content-dialog
|
|
489
|
+
padding-top: $xs !important
|
|
490
|
+
padding-bottom: $xs !important
|
|
293
491
|
</style>
|
|
@@ -48,9 +48,10 @@ const props = defineProps({
|
|
|
48
48
|
})
|
|
49
49
|
|
|
50
50
|
// constants
|
|
51
|
+
|
|
52
|
+
let isDragging = false
|
|
51
53
|
const MAX_HEIGHT = 750
|
|
52
54
|
const MIN_HEIGHT = 40
|
|
53
|
-
let isDragging = false
|
|
54
55
|
let startHeight = 0
|
|
55
56
|
let startY = 0
|
|
56
57
|
|
|
@@ -193,62 +194,67 @@ watch(
|
|
|
193
194
|
</div>
|
|
194
195
|
|
|
195
196
|
<q-card-section
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
<div
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
<UBtnStd
|
|
203
|
-
v-if="isLeftIcon"
|
|
204
|
-
class="dialog-action-icons q-mr-xs"
|
|
205
|
-
:aria-label="leftIconLabel"
|
|
206
|
-
:flat="true"
|
|
207
|
-
tabindex="0"
|
|
208
|
-
@click="handleBackClick()"
|
|
197
|
+
class="column q-pt-none q-pb-xs q-px-ba q-mt-ba"
|
|
198
|
+
>
|
|
199
|
+
<div class="row items-start justify-between no-wrap">
|
|
200
|
+
<div class="heading-wrapper row">
|
|
201
|
+
<div
|
|
202
|
+
class="flex items-center justify-center dialog-heading-container"
|
|
209
203
|
>
|
|
210
|
-
<
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
204
|
+
<UBtnStd
|
|
205
|
+
v-if="isLeftIcon"
|
|
206
|
+
class="dialog-action-icons q-mr-xs"
|
|
207
|
+
:aria-label="leftIconLabel"
|
|
208
|
+
:flat="true"
|
|
209
|
+
tabindex="0"
|
|
210
|
+
@click="handleBackClick()"
|
|
211
|
+
>
|
|
212
|
+
<q-icon
|
|
213
|
+
:class="`icon-close ${leftIcon}`"
|
|
214
|
+
size="1.5rem"
|
|
215
|
+
tabindex="-1"
|
|
216
|
+
/>
|
|
217
|
+
</UBtnStd>
|
|
220
218
|
<div>
|
|
221
|
-
<
|
|
222
|
-
{{
|
|
223
|
-
</
|
|
219
|
+
<div class="text-heading-xs">
|
|
220
|
+
{{ heading }}
|
|
221
|
+
</div>
|
|
222
|
+
<div>
|
|
223
|
+
<span
|
|
224
|
+
v-if="headingCaption"
|
|
225
|
+
class="text-body-sm dialog-caption"
|
|
226
|
+
>
|
|
227
|
+
{{ headingCaption }}
|
|
228
|
+
</span>
|
|
229
|
+
</div>
|
|
224
230
|
</div>
|
|
225
231
|
</div>
|
|
226
232
|
</div>
|
|
227
|
-
|
|
233
|
+
<UBtnStd
|
|
234
|
+
class="dialog-action-icons"
|
|
235
|
+
:aria-label="closeIconLabel"
|
|
236
|
+
:flat="true"
|
|
237
|
+
tabindex="0"
|
|
238
|
+
@click="handleCloseDialog(key)"
|
|
239
|
+
>
|
|
240
|
+
<q-icon
|
|
241
|
+
:class="`icon-close ${closeIcon} icon-secondary-opacity`"
|
|
242
|
+
size="1.5rem"
|
|
243
|
+
tabindex="-1"
|
|
244
|
+
/>
|
|
245
|
+
</UBtnStd>
|
|
228
246
|
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
:flat="true"
|
|
233
|
-
tabindex="0"
|
|
234
|
-
@click="handleCloseDialog(key)"
|
|
235
|
-
>
|
|
236
|
-
<q-icon
|
|
237
|
-
:class="`icon-close ${closeIcon} icon-secondary-opacity`"
|
|
238
|
-
size="1.5rem"
|
|
239
|
-
tabindex="-1"
|
|
240
|
-
/>
|
|
241
|
-
</UBtnStd>
|
|
242
|
-
</q-card-section>
|
|
247
|
+
</div>
|
|
248
|
+
<slot name="header"></slot>
|
|
249
|
+
</q-card-section>
|
|
243
250
|
<q-card-section
|
|
244
|
-
class="main-content-dialog
|
|
245
|
-
:style="{ height: dialog.height - 84 + 'px !important' }"
|
|
251
|
+
class="main-content-dialog q-px-ba"
|
|
246
252
|
tabindex="-1"
|
|
247
253
|
>
|
|
248
254
|
<slot name="content"></slot>
|
|
249
255
|
</q-card-section>
|
|
250
256
|
</q-card>
|
|
251
|
-
<div v-if="showActionButtons && dialog.height > 70" class="action-wrapper">
|
|
257
|
+
<div v-if="showActionButtons && dialog.height > 70" class="sheet-action-wrapper">
|
|
252
258
|
<q-card-actions class="action-buttons q-px-sm q-py-ba" align="center">
|
|
253
259
|
<slot name="action_primary_one"></slot>
|
|
254
260
|
<slot name="action_primary_two"></slot>
|
|
@@ -259,9 +265,11 @@ watch(
|
|
|
259
265
|
|
|
260
266
|
<style lang="sass">
|
|
261
267
|
.sheet-card-wrapper
|
|
268
|
+
display: flex
|
|
269
|
+
flex-direction: column
|
|
262
270
|
position: relative
|
|
263
271
|
width: 100%
|
|
264
|
-
overflow: hidden
|
|
272
|
+
overflow: hidden !important
|
|
265
273
|
transition: height 0.02s ease-in-out
|
|
266
274
|
background: $neutral-1
|
|
267
275
|
border-radius: $sm $sm 0 0 !important
|
|
@@ -283,7 +291,7 @@ watch(
|
|
|
283
291
|
|
|
284
292
|
.drag-handle-wrapper
|
|
285
293
|
width: 100%
|
|
286
|
-
height:
|
|
294
|
+
height: 0.9rem !important
|
|
287
295
|
z-index: 9
|
|
288
296
|
display: flex
|
|
289
297
|
align-items: center
|
|
@@ -312,12 +320,15 @@ watch(
|
|
|
312
320
|
.q-item__section
|
|
313
321
|
color: red !important
|
|
314
322
|
|
|
315
|
-
.action-wrapper
|
|
323
|
+
.sheet-action-wrapper
|
|
316
324
|
background: $neutral-1
|
|
317
325
|
|
|
318
326
|
.main-content-dialog
|
|
319
|
-
margin-bottom:
|
|
327
|
+
margin-bottom: 0px !important
|
|
320
328
|
padding-bottom: 0
|
|
329
|
+
flex-grow: 1
|
|
330
|
+
overflow-y: auto !important
|
|
331
|
+
overflow-x: hidden
|
|
321
332
|
|
|
322
333
|
.dialog-caption
|
|
323
334
|
color: $neutral-9
|
|
@@ -329,4 +340,9 @@ watch(
|
|
|
329
340
|
|
|
330
341
|
.dialog-heading-container
|
|
331
342
|
gap: $xs
|
|
343
|
+
|
|
344
|
+
.action-wrapper
|
|
345
|
+
position: relative
|
|
346
|
+
width: 100%
|
|
347
|
+
background: $neutral-1
|
|
332
348
|
</style>
|