PluginProbe ʕ •ᴥ•ʔ
Booking for Appointments and Events Calendar – Amelia / trunk
Booking for Appointments and Events Calendar – Amelia vtrunk
2.4.4 2.4.3 2.4.2 2.4.1 2.4 trunk 1.2.1 1.2.10 1.2.11 1.2.12 1.2.13 1.2.14 1.2.15 1.2.16 1.2.17 1.2.18 1.2.19 1.2.2 1.2.20 1.2.21 1.2.22 1.2.23 1.2.24 1.2.25 1.2.26 1.2.27 1.2.28 1.2.29 1.2.3 1.2.30 1.2.31 1.2.32 1.2.33 1.2.34 1.2.35 1.2.36 1.2.37 1.2.38 1.2.4 1.2.5 1.2.6 1.2.7 1.2.8 1.2.9 2.0 2.0.1 2.0.2 2.1 2.1.1 2.1.2 2.1.3 2.2 2.2.1 2.3
ameliabooking / v3 / src / views / _components / time-select / AmTimeSelect.vue
ameliabooking / v3 / src / views / _components / time-select Last commit date
AmTimeSelect.vue 5 days ago
AmTimeSelect.vue
496 lines
1 <template>
2 <div class="am-time-select__wrapper" :class="parentClass" :style="cssVars">
3 <el-time-select
4 :id="props.id"
5 ref="amTimeSelect"
6 v-model="model"
7 class="am-time-select"
8 :class="[
9 `am-time-select--${size}`,
10 { 'am-time-select--disabled': disabled },
11 { 'am-time-select--prefix': props.prefixIcon },
12 { 'am-time-select--suffix': props.suffixIcon || (props.clearIcon && pross.clearable) },
13 props.class,
14 ]"
15 :disabled="props.disabled"
16 :placeholder="props.placeholder"
17 :clear-icon="props.clearIcon"
18 :clearable="props.clearable"
19 :editable="props.editable"
20 :name="props.name"
21 :popper-class="`am-time-select__popper${
22 props.popperClass ? ' ' + props.popperClass : props.popperClass
23 }`"
24 :prefix-icon="props.prefixIcon"
25 :suffix-icon="props.suffixIcon"
26 :end="props.end"
27 :max-time="props.maxTime"
28 :min-time="props.minTime"
29 :start="props.start"
30 :step="props.step"
31 :format="props.format"
32 :include-end-time="props.includeEndTime"
33 :effect="props.effect"
34 />
35 </div>
36 </template>
37
38 <script setup>
39 // * Import from Vue
40 import { ref, toRefs, computed, markRaw, inject, onMounted } from 'vue'
41
42 // * Dedicated components
43 import IconComponent from '../icons/IconComponent.vue'
44
45 // * Composables
46 import { useColorTransparency } from '../../../assets/js/common/colorManipulation'
47
48 /**
49 * Component Props
50 * */
51 const props = defineProps({
52 modelValue: {
53 type: String,
54 },
55 id: {
56 type: String,
57 default: '',
58 },
59 disabled: {
60 type: Boolean,
61 default: false,
62 },
63 editable: {
64 type: Boolean,
65 default: true,
66 },
67 clearable: {
68 type: Boolean,
69 default: true,
70 },
71 includeEndTime: {
72 type: Boolean,
73 default: false,
74 },
75 size: {
76 // default / medium / small / mini / micro
77 type: String,
78 default: 'default',
79 validator(value) {
80 return ['default', 'medium', 'small', 'mini', 'micro'].includes(value)
81 },
82 },
83 placeholder: {
84 type: String,
85 default: '',
86 },
87 name: {
88 type: String,
89 },
90 effect: {
91 type: String,
92 default: 'light',
93 validator(value) {
94 return ['dark', 'light'].includes(value)
95 },
96 },
97 prefixIcon: {
98 type: [String, Object, Function],
99 default: markRaw({
100 components: { IconComponent },
101 template: `<IconComponent icon="clock"/>`,
102 }),
103 },
104 suffixIcon: {
105 type: [String, Object, Function],
106 default: markRaw({
107 components: { IconComponent },
108 template: `<IconComponent icon="arrow-up"/>`,
109 }),
110 },
111 clearIcon: {
112 type: [String, Object, Function],
113 default: markRaw({
114 components: { IconComponent },
115 template: `<IconComponent icon="close"/>`,
116 }),
117 },
118 start: {
119 type: String,
120 default: '',
121 },
122 end: {
123 type: String,
124 default: '',
125 },
126 step: {
127 type: String,
128 default: '',
129 },
130 minTime: {
131 type: String,
132 default: '',
133 },
134 maxTime: {
135 type: String,
136 default: '',
137 },
138 format: {
139 type: String,
140 default: 'HH:mm',
141 },
142 popperClass: {
143 type: String,
144 default: '',
145 },
146 class: {
147 type: String,
148 default: '',
149 },
150 parentClass: {
151 type: String,
152 default: '',
153 },
154 })
155
156 /**
157 * Component Emits
158 * */
159 const emits = defineEmits(['update:modelValue'])
160
161 /**
162 * Component Model
163 * */
164 const { modelValue } = toRefs(props)
165
166 const model = computed({
167 get: () => modelValue.value,
168 set: (value) => {
169 emits('update:modelValue', value)
170 },
171 })
172
173 /**
174 * Component Refs
175 * */
176 const amTimeSelect = ref(null)
177
178 // * Font Vars
179 let amFonts = inject(
180 'amFonts',
181 ref({
182 fontFamily: 'Amelia Roboto, sans-serif',
183 fontUrl: '',
184 customFontFamily: '',
185 fontFormat: '',
186 customFontSelected: false,
187 }),
188 )
189
190 // * Color Vars
191 let amColors = inject(
192 'amColors',
193 ref({
194 colorPrimary: '#1246D6',
195 colorSuccess: '#019719',
196 colorError: '#B4190F',
197 colorWarning: '#CCA20C',
198 colorMainBgr: '#FFFFFF',
199 colorMainHeadingText: '#33434C',
200 colorMainText: '#1A2C37',
201 colorSbBgr: '#17295A',
202 colorSbText: '#FFFFFF',
203 colorInpBgr: '#FFFFFF',
204 colorInpBorder: '#D1D5D7',
205 colorInpText: '#1A2C37',
206 colorInpPlaceHolder: '#808A90',
207 colorDropBgr: '#FFFFFF',
208 colorDropBorder: '#D1D5D7',
209 colorDropText: '#0E1920',
210 colorBtnPrim: '#265CF2',
211 colorBtnPrimText: '#FFFFFF',
212 colorBtnSec: '#1A2C37',
213 colorBtnSecText: '#FFFFFF',
214 }),
215 )
216
217 // * Css Variables
218 let cssVars = computed(() => {
219 return {
220 '--am-c-timeselect-shadow': useColorTransparency(amColors.value.colorInpText, 0.05),
221 '--am-c-timeselect-text-op60': useColorTransparency(amColors.value.colorInpText, 0.6),
222 '--am-c-timeselect-text-op40': useColorTransparency(amColors.value.colorInpText, 0.4),
223 '--am-c-timeselect-text-op10': useColorTransparency(amColors.value.colorInpText, 0.03),
224 '--am-font-family': amFonts.value.fontFamily,
225 }
226 })
227
228 onMounted(() => {
229 const popperWrapper = document.querySelector("[id^='el-popper-container']")
230 popperWrapper.style.setProperty('--am-c-option-bgr', amColors.value.colorDropBgr)
231 popperWrapper.style.setProperty('--am-c-option-border', amColors.value.colorDropBorder)
232 popperWrapper.style.setProperty('--am-c-option-text', amColors.value.colorDropText)
233 popperWrapper.style.setProperty(
234 '--am-c-option-text-op65',
235 useColorTransparency(amColors.value.colorDropText, 0.65),
236 )
237 popperWrapper.style.setProperty(
238 '--am-c-option-text-op50',
239 useColorTransparency(amColors.value.colorDropText, 0.5),
240 )
241 popperWrapper.style.setProperty(
242 '--am-c-option-hover',
243 useColorTransparency(amColors.value.colorDropText, 0.1),
244 )
245 popperWrapper.style.setProperty('--am-c-option-selected', amColors.value.colorPrimary)
246 popperWrapper.style.setProperty(
247 '--am-c-option-selected-op10',
248 useColorTransparency(amColors.value.colorPrimary, 0.1),
249 )
250 popperWrapper.style.setProperty('--am-c-option-img-bgr', amColors.value.colorSuccess)
251 popperWrapper.style.setProperty('--am-c-option-img-text', amColors.value.colorMainBgr)
252 popperWrapper.style.setProperty('--am-font-family', amFonts.value.fontFamily)
253 })
254 </script>
255
256 <style lang="scss">
257 @mixin am-time-select-block {
258 .am-time-select {
259 // -c- color
260 // -rad- border radius
261 // -h- height
262 // -fs- font size
263 // -padd- padding
264 // -bgr background
265 --am-c-timeselect-bgr: var(--am-c-inp-bgr);
266 --am-c-timeselect-border: var(--am-c-inp-border);
267 --am-c-timeselect-text: var(--am-c-inp-text);
268 --am-c-timeselect-placeholder: var(--am-c-inp-placeholder);
269 --am-rad-timeselect: var(--am-rad-inp);
270 --am-fs-timeselect: var(--am-fs-inp);
271 --am-h-timeselect: var(--am-h-inp);
272 --am-padd-timeselect: 8px 12px;
273 width: 100%;
274
275 // Select Wrapper
276 &__wrapper {
277 width: 100%;
278 }
279
280 // Size - default / medium / small / mini / micro
281 &--default {
282 --am-h-timeselect: 40px;
283 }
284 &--medium {
285 --am-h-timeselect: 36px;
286 }
287 &--small {
288 --am-h-timeselect: 32px;
289 }
290 &--mini {
291 --am-h-timeselect: 28px;
292 }
293 &--micro {
294 --am-h-timeselect: 24px;
295 }
296
297 // Disabled
298 &--disabled {
299 --am-c-timeselect-bgr: var(--am-c-timeselect-text-op10);
300 --am-c-timeselect-text: var(--am-c-timeselect-text-op60);
301 cursor: not-allowed;
302 }
303
304 // Prefix / Suffix
305 &--prefix {
306 --am-padd-timeselect: 0 12px 0 8px;
307
308 &.am-time-select--suffix {
309 --am-padd-timeselect: 0 8px;
310 }
311 }
312
313 &--suffix {
314 --am-padd-timeselect: 0 8px 0 12px;
315 }
316
317 // Input
318 .el-select {
319 // Visual presentation of input
320 &__wrapper {
321 display: flex;
322 align-items: center;
323 gap: 0 6px;
324 height: var(--am-h-timeselect);
325 min-height: 24px;
326 background-color: var(--am-c-timeselect-bgr);
327 border-radius: var(--am-rad-timeselect);
328 border: none;
329 box-shadow: 0 0 0 1px var(--am-c-timeselect-border);
330 padding: var(--am-padd-timeselect);
331 }
332
333 // Input
334 &__input {
335 width: 100%;
336 height: 100%;
337 min-height: 24px;
338 font-size: var(--am-fs-timeselect);
339 font-weight: 400;
340 line-height: 24px;
341 text-overflow: ellipsis;
342 white-space: nowrap;
343 overflow: hidden;
344 color: var(--am-c-timeselect-text);
345 border: none;
346 border-radius: 0;
347 background: none;
348 padding: 0;
349 box-shadow: none;
350
351 // Placeholder
352 &::placeholder {
353 color: var(--am-c-timeselect-placeholder);
354 opacity: 1; /* Ensures it’s not transparent */
355 }
356 &::-webkit-input-placeholder {
357 /* Chrome, Safari */
358 color: var(--am-c-timeselect-placeholder);
359 }
360 &:-moz-placeholder {
361 /* Firefox 4-18 */
362 color: var(--am-c-timeselect-placeholder);
363 opacity: 1;
364 }
365 &::-moz-placeholder {
366 /* Firefox 19+ */
367 color: var(--am-c-timeselect-placeholder);
368 opacity: 1;
369 }
370 &:-ms-input-placeholder {
371 /* IE 10-11 */
372 color: var(--am-c-timeselect-placeholder);
373 }
374 }
375
376 // Visual presentation of input value
377 &__selected-item {
378 &.is-transparent {
379 --am-c-timeselect-text: var(--am-c-timeselect-text-placeholder);
380 }
381
382 span {
383 font-size: var(--am-fs-timeselect);
384 line-height: 24px;
385 font-weight: 400;
386 color: var(--am-c-timeselect-text);
387 }
388 }
389
390 // Prefix and Suffix icon
391 &__prefix,
392 &__suffix {
393 .el-icon {
394 width: auto;
395 height: auto;
396 }
397
398 [class^='am-icon']^='am-icon'] {
399 font-size: 24px;
400 line-height: 1;
401 color: var(--am-c-timeselect-text);
402 }
403
404 .am-icon-arrow-up,
405 .am-icon-close {
406 font-size: 18px;
407 }
408 }
409 }
410 }
411 }
412
413 // Time Select Popper
414 .am-time-select__popper {
415 --am-hmin-timeselect-option: 32px;
416 --am-h-timeselect-option: auto;
417 --am-flh-timeselect-option: 1.4;
418 --am-c-timeselect-option-text: var(--am-c-option-text);
419 --am-c-timeselect-option-bgr: transparent;
420 --am-pad-timeselect-option: 8px;
421 --am-mar-timeselect-option: 0px;
422 --am-fs-timeselect-option: 14px;
423 --am-fw-timeselect-option: 400;
424 --am-ff-timeselect-option: var(--am-font-family);
425 background-color: var(--am-c-option-bgr) !important;
426
427 &.el-select__popper.el-popper[role='tooltip']='tooltip'] {
428 background-color: transparent;
429 border-color: var(--am-c-option-border);
430 overflow: hidden;
431 }
432
433 &.el-select-dropdown {
434 margin: 0;
435 position: static;
436 border: none;
437 }
438
439 * {
440 font-family: var(--am-font-family), sans-serif;
441 border-radius: unset;
442 }
443
444 .el-select-dropdown {
445 &__list {
446 padding: 0;
447 }
448
449 &__item {
450 min-height: var(--am-hmin-timeselect-option) !important;
451 height: var(--am-h-timeselect-option) !important;
452 font-family: var(--am-ff-timeselect-option), sans-serif !important;
453 font-size: var(--am-fs-timeselect-option) !important;
454 font-weight: var(--am-fw-timeselect-option) !important;
455 line-height: var(--am-flh-timeselect-option) !important;
456 color: var(--am-c-timeselect-option-text) !important;
457 background-color: var(--am-c-timeselect-option-bgr) !important;
458 padding: var(--am-pad-timeselect-option) !important;
459 margin: var(--am-mar-timeselect-option) !important;
460 white-space: normal;
461
462 &:hover,
463 &.hover {
464 --am-c-timeselect-option-bgr: var(--am-c-option-hover);
465 }
466
467 &.selected {
468 --am-c-timeselect-option-text: var(--am-c-option-selected);
469 }
470
471 &.is-disabled {
472 --am-c-timeselect-option-text: var(--am-c-option-text-op50) !important;
473 }
474
475 &:last-child {
476 border-bottom: none;
477 }
478 }
479
480 &__empty {
481 color: var(--am-c-option-text-op65);
482 }
483 }
484 }
485
486 // public
487 .amelia-v2-booking #amelia-container {
488 @include am-time-select-block;
489 }
490
491 // admin
492 #amelia-app-backend-new {
493 @include am-time-select-block;
494 }
495 </style>
496