@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 CHANGED
@@ -1,4 +1,4 @@
1
- # Component Library v1.0.0-alpha.133
1
+ # Component Library v1.0.0-alpha.136
2
2
 
3
3
  **This library provides custom UI components for USSSA applications.**
4
4
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@usssa/component-library",
3
- "version": "1.0.0-alpha.134",
3
+ "version": "1.0.0-alpha.136",
4
4
  "description": "A Quasar component library project",
5
5
  "productName": "Quasar component library App",
6
6
  "author": "Troy Moreland <troy.moreland@usssa.com>",
@@ -1,5 +1,5 @@
1
1
  <script setup>
2
- import { computed, ref } from 'vue'
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} text-body-sm label`">
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 v-bind="scope.itemProps" class="items-center u-custom-options">
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 v-if="scope.opt.description" caption>
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="perPageOptions"
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
- type: String,
16
- default: 'select-std'
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 class="column q-gutter-y-xs" :dataTestId="dataTestId">
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
- class="row items-start justify-between no-wrap q-pt-none q-pb-xs q-px-ba q-mt-ba"
197
- >
198
- <div class="heading-wrapper row">
199
- <div
200
- class="flex items-center justify-center dialog-heading-container"
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
- <q-icon
211
- :class="`icon-close ${leftIcon}`"
212
- size="1.5rem"
213
- tabindex="-1"
214
- />
215
- </UBtnStd>
216
- <div>
217
- <div class="text-heading-xs">
218
- {{ heading }}
219
- </div>
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
- <span v-if="headingCaption" class="text-body-sm dialog-caption">
222
- {{ headingCaption }}
223
- </span>
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
- </div>
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
- <UBtnStd
230
- class="dialog-action-icons"
231
- :aria-label="closeIconLabel"
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 scroll q-px-ba"
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: 1rem
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: $ba
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>