PluginProbe ʕ •ᴥ•ʔ
Booking for Appointments and Events Calendar – Amelia / 1.2.20
Booking for Appointments and Events Calendar – Amelia v1.2.20
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 / datePicker / AmDatePicker.vue
ameliabooking / v3 / src / views / _components / datePicker Last commit date
AmDatePicker.vue 1 year ago
AmDatePicker.vue
536 lines
1 <template>
2
3 <!-- Date Picker -->
4 <div
5 class="am-date-picker-wrapper"
6 :class="`am-date-picker--${size}`"
7 >
8 <div
9 v-if="props.customInputDisplay && props.type === 'daterange' && model.length"
10 class="am-date-picker__input"
11 :class="`am-date-picker--${size}`"
12 @click="triggerCalendar"
13 >
14 <span class="am-icon-calendar"></span>
15 <div class="am-date-picker__input-inner">
16 <span class="am-date-picker__input-start">
17 {{ getFrontedFormattedDate(moment(model[0]).format('YYYY-MM-DD')) }}
18 </span>
19 <span class="am-date-picker__input-separator">
20 -
21 </span>
22 <span class="am-date-picker__input-end">
23 {{ getFrontedFormattedDate(moment(model[1]).format('YYYY-MM-DD')) }}
24 </span>
25 </div>
26 </div>
27 <el-config-provider :locale="elementPlusTranslations(props.lang)">
28 <el-date-picker
29 v-bind="filteredProps"
30 :id="id"
31 ref="amDatePicker"
32 v-model="model"
33 :type="type"
34 :value="value"
35 :prefix-icon="prefixIcon"
36 :popper-class="popperClass"
37 :placeholder="placeholder"
38 :clear-icon="clearIcon"
39 :default-value="defaultValue"
40 :clearable="clearable"
41 :disabled-date="disabledDate"
42 :disabled="disabled"
43 :value-format="valueFormat"
44 :format="format"
45 :editable="editable"
46 class="am-date-picker"
47 :popper-style="cssVars"
48 :style="cssVars"
49 :class="[`am-date-picker--${size}`, {'am-date-picker--disabled': disabled}, {'am-date-picker--custom': props.type === 'daterange' && props.customInputDisplay}]"
50 @input="(eventValue) => $emit('input', eventValue)"
51 @change="(eventValue) => $emit('change', eventValue)"
52 @blur="(e) => $emit('blur', e)"
53 @focus="(e) => $emit('focus', e)"
54 @calendar-change="(e) => $emit('calendar-change', e)"
55 @panel-change="(e) => $emit('panel-change', e)"
56 ></el-date-picker>
57 </el-config-provider>
58 </div>
59 <!-- /Date Picker -->
60
61 </template>
62
63 <script setup>
64 // * Import from Vue
65 import {
66 computed,
67 ref,
68 toRefs,
69 inject,
70 } from "vue";
71
72 // * Libraries
73 import moment from "moment";
74
75 // * components
76 import AmeliaIconClose from "../icons/IconClose";
77 import AmeliaIconCalendar from "../icons/IconCalendar";
78
79 // * Composables
80 import { useColorTransparency } from "../../../assets/js/common/colorManipulation";
81 import { elementPlusTranslations } from "../../../assets/js/common/translationsElementPlus";
82 import { getFrontedFormattedDate } from "../../../assets/js/common/date";
83
84 /**
85 * Component Props
86 */
87 const props = defineProps({
88 id: {
89 type: String
90 },
91 modelValue: {
92 type: [String, Array, Object, Number],
93 },
94 type: {
95 type: String,
96 default: 'date'
97 },
98 defaultValue: {
99 type: [String, Array, Object, Number],
100 },
101 valueFormat: {
102 type: String
103 },
104 value: {
105 type: [String, Array, Object, Number],
106 },
107 format: {
108 type: String
109 },
110 editable: {
111 type: Boolean,
112 default: true
113 },
114 disabled: {
115 type: Boolean,
116 default: false
117 },
118 size: {
119 // default / medium / small / mini / micro
120 type: String,
121 default: 'default',
122 validator(value) {
123 return ['default', 'medium', 'small', 'mini', 'micro'].includes(value)
124 }
125 },
126 clearable: {
127 type: Boolean,
128 default: false
129 },
130 name: {
131 type: String,
132 default: ''
133 },
134 placeholder: {
135 type: String,
136 default: 'Select Date'
137 },
138 popperClass: {
139 type: String,
140 default: ''
141 },
142 teleported: {
143 type: Boolean,
144 default: true
145 },
146 clearIcon: {
147 type: [String, Object],
148 default: AmeliaIconClose
149 },
150 prefixIcon: {
151 type: [String, Object],
152 default: AmeliaIconCalendar
153 },
154 disabledDate: {
155 type: Function,
156 default: () => {}
157 },
158 lang: {
159 type: String,
160 default: ''
161 },
162 customInputDisplay: {
163 type: Boolean,
164 default: false
165 }
166 })
167
168 const unrefProps = (props) => {
169 const unref = {};
170 for (const key in props) {
171 unref[key] = props[key].value; // Get the value of each ref
172 }
173 return unref;
174 };
175
176 const { size, ...filteredProps } = unrefProps(toRefs(props));
177
178 /**
179 * Component Emits
180 * */
181 const emits = defineEmits(['change', 'input', 'visible-change', 'remove-tag', 'clear', 'blur', 'focus', 'calendar-change', 'panel-change', 'update:modelValue'])
182
183 /**
184 * Component model
185 */
186 let { modelValue } = toRefs(props)
187 let model = computed({
188 get: () => modelValue.value,
189 set: (val) => {
190 emits('update:modelValue', val)
191 }
192 })
193
194 /**
195 * Component reference
196 */
197 const amDatePicker = ref(null)
198
199 function triggerCalendar () {
200 if (amDatePicker.value) {
201 amDatePicker.value.focus()
202 }
203 }
204
205 // * Colors block
206 let amColors = inject('amColors');
207
208 let cssVars = computed(() => {
209 return {
210 '--am-c-primary': amColors.value.colorPrimary,
211 '--am-c-success': amColors.value.colorSuccess,
212 '--am-c-error': amColors.value.colorError,
213 '--am-c-warning': amColors.value.colorWarning,
214 '--am-c-main-bgr': amColors.value.colorMainBgr,
215 '--am-c-main-heading-text': amColors.value.colorMainHeadingText,
216 '--am-c-main-text': amColors.value.colorMainText,
217 '--am-c-sb-bgr': amColors.value.colorSbBgr,
218 '--am-c-sb-text': amColors.value.colorSbText,
219 '--am-c-inp-bgr': amColors.value.colorInpBgr,
220 '--am-c-inp-border': amColors.value.colorInpBorder,
221 '--am-c-inp-text': amColors.value.colorInpText,
222 '--am-c-inp-text-op03': useColorTransparency(amColors.value.colorInpText, 0.03),
223 '--am-c-inp-text-op60': useColorTransparency(amColors.value.colorInpText, 0.6),
224 '--am-c-inp-placeholder': amColors.value.colorInpPlaceHolder,
225 '--am-c-drop-bgr': amColors.value.colorDropBgr,
226 '--am-c-drop-text': amColors.value.colorDropText,
227 '--am-c-drop-text-op03': useColorTransparency(amColors.value.colorDropText, 0.03),
228 '--am-c-drop-text-op10': useColorTransparency(amColors.value.colorDropText, 0.1),
229 '--am-c-drop-text-op30': useColorTransparency(amColors.value.colorDropText, 0.3),
230 '--am-c-drop-text-op50': useColorTransparency(amColors.value.colorDropText, 0.5),
231 '--am-c-drop-text-op70': useColorTransparency(amColors.value.colorDropText, 0.7),
232 '--am-c-drop-text-op80': useColorTransparency(amColors.value.colorDropText, 0.8),
233 '--am-c-drop-border': amColors.value.colorDropBorder,
234 '--am-c-btn-prim': amColors.value.colorBtnPrim,
235 '--am-c-btn-prim-text': amColors.value.colorBtnPrimText,
236 '--am-c-btn-sec': amColors.value.colorBtnSec,
237 '--am-c-btn-sec-text': amColors.value.colorBtnSecText,
238 '--am-c-btn-danger': amColors.value.colorBtnDanger,
239 '--am-c-btn-danger-text': amColors.value.colorBtnDangerText,
240 '--am-c-skeleton-op20': useColorTransparency(amColors.value.colorMainText, 0.2),
241 '--am-c-skeleton-op60': useColorTransparency(amColors.value.colorMainText, 0.6),
242 '--am-c-skeleton-sb-op20': useColorTransparency(amColors.value.colorSbText, 0.2),
243 '--am-c-skeleton-sb-op60': useColorTransparency(amColors.value.colorSbText, 0.6),
244 }
245 })
246 </script>
247
248 <style lang="scss">
249 @mixin am-datepicker-block {
250
251 // Date Picker Wrapper
252 .am-date-picker-wrapper {
253 text-align: center;
254 flex: 1;
255
256 &.am-date-picker {
257 &--default {
258 height: 40px;
259 }
260
261 &--small {
262 height: 32px;
263 }
264 }
265
266 &:last-child {
267 border-right: none;
268 }
269
270 .el-input {
271 width: 100%;
272 * {
273 color: var(--am-c-inp-text);
274 }
275
276 .el-input__inner {
277 outline: none;
278 border-radius: 6px;
279 background: var(--am-c-inp-bgr);
280 border-color: var(--am-c-inp-border);
281 color: var(--am-c-inp-text);
282 padding-left: 31px !important;
283
284 &:focus {
285 border-color: var(--am-c-btn-prim);
286 }
287
288 &::-webkit-input-placeholder {
289 color: var(--am-c-inp-placeholder);
290 }
291 }
292
293 &__inner {
294 background: var(--am-c-inp-bgr);
295 border: 1px solid var(--am-c-inp-border);
296 }
297
298 &.is-disabled {
299 .el-input__inner {
300 background: var(--am-c-inp-text-op03);
301 color: var(--am-c-inp-text-op60);
302 }
303 }
304
305 // Size - default / medium / small / mini / micro
306 &--default .el-input__inner {
307 height: 40px;
308 }
309 &--medium .el-input__inner {
310 height: 36px;
311 }
312 &--small .el-input__inner {
313 height: 32px;
314 }
315
316 &__prefix {
317 left: 10px;
318 line-height: 32px;
319
320 &-inner {
321 display: flex;
322 align-items: center;
323
324 .am-icon-calendar {
325 font-size: 20px;
326 }
327 }
328
329 .el-icon {
330 ::before {
331 color: var(--am-c-inp-placeholder);
332 }
333 }
334 }
335
336 &__suffix {
337 &-inner {
338 display: flex;
339 align-items: center;
340 }
341 }
342 }
343
344 .am-date-picker {
345 &--default {
346 height: 40px;
347 }
348
349 &__input {
350 display: flex;
351 align-items: center;
352 width: 100%;
353 outline: none;
354 border: 1px solid var(--am-c-inp-border);
355 border-radius: 6px;
356 background: var(--am-c-inp-bgr);
357 color: var(--am-c-inp-text);
358 padding-left: 10px;
359 cursor: pointer;
360
361 &-inner {
362 display: flex;
363 align-items: center;
364 justify-content: space-evenly;
365 width: 100%;
366 }
367
368 &-start, &-end, &-separator {
369 font-size: 14px;
370 font-weight: 500;
371 background-color: transparent;
372 }
373
374 .am-icon-calendar {
375 font-size: 20px;
376 color: var(--am-c-capf-text);
377 }
378
379 &.am-date-picker {
380 &--small {
381 min-height: 32px;
382 }
383 }
384 }
385
386 &--custom {
387 height: 0 !important;
388 overflow: hidden;
389 border: none;
390 position: relative;
391 top: -16px;
392 }
393 }
394
395 .el-range {
396 &-input {
397 background-color: transparent;
398 color: var(--am-c-inp-text);
399 font-size: var(--am-fs-input);
400 }
401
402 &__icon {
403 font-size: 24px;
404 color: var(--am-c-inp-text);
405 }
406 }
407 }
408 }
409
410 .el-picker-panel {
411 background-color: var(--am-c-drop-bgr);
412 color: var(--am-c-drop-text);
413 border: 1px solid var(--am-c-drop-border);
414
415 &__icon-btn {
416 color: var(--am-c-drop-text);
417
418 &:hover {
419 color: var(--am-c-btn-prim)
420 }
421 }
422
423 &__content {
424 &.is-left {
425 border-right: 1px solid var(--am-c-drop-text-op10);
426 }
427 table, table td, table tr, table tr:is(.el-date-table__row) {
428 border: none !important;
429 }
430 table tr:not(.el-date-table__row) th {
431 color: var(--am-c-drop-text-op70);
432 border: none !important;
433 border-bottom: 1px solid var(--am-c-drop-text-op10) !important;
434 }
435 table {
436 td.today .el-date-table-cell__text {
437 color: var(--am-c-drop-text);
438 }
439 td.current:not(.disabled) .el-date-table-cell__text {
440 background: var(--am-c-btn-prim);
441 }
442 td.available:hover > div > span {
443 background: var(--am-c-drop-text);
444 border-radius: 50%;
445 color: var(--am-c-drop-bgr);
446 }
447 td.in-range > .el-date-table-cell {
448 background-color: var(--am-c-drop-text-op10);
449 }
450 td.in-range:hover > .el-date-table-cell {
451 background-color: var(--am-c-drop-text-op50);
452 }
453 td.end-date .el-date-table-cell__text, td.start-date .el-date-table-cell__text {
454 color: var(--am-c-drop-bgr);
455 background-color: var(--am-c-drop-text-op80);
456 }
457 td.today.start-date .el-date-table-cell__text {
458 color: var(--am-c-drop-bgr);
459 }
460 td.prev-month, td.next-month {
461 color: var(--am-c-drop-text-op30);
462 }
463
464 td.disabled .el-date-table-cell {
465 color: var(--am-c-drop-text-op30);
466 background-color: var(--am-c-drop-text-op03);
467 }
468 }
469 }
470
471 .d-arrow-left, .d-arrow-right {
472 display: none;
473 }
474 }
475
476 .el-date-picker__header {
477 text-align: center;
478 margin: 12px;
479
480 .el-picker-panel__icon-btn {
481 padding: 0;
482 }
483
484 .el-date-picker {
485 padding: 0;
486 font-size: 12px;
487 color: #303133;
488 cursor: pointer;
489 margin-top: 8px;
490 border-width: 0;
491 border-style: initial;
492 border-color: initial;
493 border-image: initial;
494 //background: transparent;
495 outline: none;
496
497 &__prev-btn {
498 float: left;
499 }
500
501 &__next-btn {
502 float: right;
503 }
504 &__prev-btn:focus, &__next-btn:focus {
505 //background: transparent;
506 outline: none;
507 }
508 }
509 &-label:hover {
510 color: var(--am-c-btn-prim);
511 }
512 }
513
514 .el-popper {
515 &.el-picker__popper {
516 &[data-popper-placement^="top"]^="top""],
517 &[data-popper-placement^="bottom"]^="bottom""],
518 &[data-popper-placement^="left"]^="left""],
519 &[data-popper-placement^="right"]^="right""] {
520 .el-popper__arrow {
521 display: none;
522 }
523 }
524 }
525 }
526
527 // public
528 .amelia-v2-booking #amelia-container {
529 @include am-datepicker-block;
530 }
531
532 // admin
533 #amelia-app-backend-new #amelia-container {
534 @include am-datepicker-block;
535 }
536 </style>