PluginProbe ʕ •ᴥ•ʔ
Booking for Appointments and Events Calendar – Amelia / 1.2.31
Booking for Appointments and Events Calendar – Amelia v1.2.31
2.4.9 2.4.8 2.4.7 2.4.6 2.4.5 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 / button / AmButton.vue
ameliabooking / v3 / src / views / _components / button Last commit date
AmAdvButton.vue 4 years ago AmButton.vue 1 year ago AmButtonGroup.vue 1 year ago
AmButton.vue
630 lines
1 <template>
2 <button
3 v-bind="bindProps"
4 class="am-button"
5 :disabled="disabled || loading"
6 :autofocus="autofocus"
7 :type="nativeType"
8 :class="[
9 type ? 'am-button--' + type : '',
10 size ? 'am-button--' + size : '',
11 category ? 'am-button--' + category : '',
12 {
13 'is-icon-only': iconOnly,
14 'is-disabled': disabled,
15 'is-loading': loading,
16 'is-round': round,
17 'is-circle': circle
18 },
19 customClass
20 ]"
21 :style="{...cssVars, ...style}"
22 @click="handleClick"
23 >
24 <!-- Loading slot -->
25 <slot v-if="(loadingIcon || Object.keys(loadingIcon).length) && loading" name="loading">
26 <component :is="loadingIcon" v-if="typeof loadingIcon === 'object'"></component>
27 <span v-if="typeof loadingIcon === 'string'" :class="`am-icon-${loadingIcon}`"></span>
28 </slot>
29
30 <!-- Icon slot -->
31 <slot v-if="(icon || Object.keys(icon).length) && iconOnly && !loading" name="icon">
32 <component :is="icon" v-if="typeof icon === 'object'"></component>
33 <span v-if="typeof icon === 'string'" :class="`am-icon-${icon}`"></span>
34 </slot>
35
36 <!-- Prefix slot -->
37 <slot v-if="(prefix || Object.keys(prefix).length) && !iconOnly && !loading" name="prefix">
38 <component :is="prefix" v-if="typeof prefix === 'object'"></component>
39 <span v-if="typeof prefix === 'string'" :class="`am-icon-${prefix}`"></span>
40 </slot>
41
42 <!-- Default slot -->
43 <span v-if="$slots.default && !iconOnly" class="am-button__inner" :class="innerClass">
44 <slot />
45 </span>
46
47 <!-- Suffix slot -->
48 <slot v-if="(suffix || Object.keys(suffix).length) && !iconOnly && !loading" name="suffix">
49 <component :is="suffix" v-if="typeof suffix === 'object'"></component>
50 <span v-if="typeof suffix === 'string'" :class="`am-icon-${suffix}`"></span>
51 </slot>
52 </button>
53 </template>
54
55 <script setup>
56 import { useColorTransparency } from '../../../assets/js/common/colorManipulation';
57
58 import { computed, ref, inject } from "vue";
59
60 /**
61 * Component props
62 */
63 const props = defineProps({
64 id: {
65 type: String
66 },
67 customClass: {
68 type: String,
69 default: ''
70 },
71 innerClass: {
72 type: String,
73 default: ''
74 },
75 iconOnly: {
76 type: Boolean,
77 default: false
78 },
79 size: {
80 // default / medium / small / mini / micro
81 type: String,
82 default: 'default',
83 validator(value) {
84 return ['default', 'medium', 'small', 'mini', 'micro'].includes(value)
85 }
86 },
87 category: {
88 // primary / secondary / success / warning / danger / error
89 type: String,
90 default: 'primary',
91 validator(value) {
92 return ['primary', 'secondary', 'success', 'warning', 'danger', 'error', 'waiting'].includes(value)
93 }
94 },
95 type: {
96 // filled / plain / text
97 type: String,
98 default: 'filled',
99 validator(value) {
100 return ['filled', 'plain', 'text'].includes(value)
101 }
102 },
103 nativeType: {
104 // button / submit / reset
105 type: String,
106 default: 'button',
107 validator(value) {
108 return ['button', 'submit', 'reset'].includes(value)
109 }
110 },
111 round: {
112 type: Boolean,
113 default: false
114 },
115 circle: {
116 type: Boolean,
117 default: false
118 },
119 loading: {
120 type: Boolean,
121 default: false
122 },
123 disabled: {
124 type: Boolean,
125 default: false
126 },
127 autofocus: {
128 type: Boolean,
129 default: false
130 },
131 prefix: {
132 type: [String, Object, Function],
133 default: ''
134 },
135 suffix: {
136 type: [String, Object, Function],
137 default: ''
138 },
139 icon: {
140 type: [String, Object, Function],
141 default: ''
142 },
143 loadingIcon: {
144 type: [String, Object, Function],
145 default: ''
146 },
147 style: {
148 type: Object,
149 default: () => {
150 return {}
151 }
152 }
153 })
154
155 // Create filtered properties
156 const bindProps = computed(() => {
157 const filterObj = {...props};
158 const arrayProp = ['id'];
159
160 return Object.fromEntries(Object.entries(filterObj).filter(([key]) => arrayProp.includes(key)));
161 });
162
163 /**
164 * Component emits
165 * @type {EmitFn<string[]>}
166 */
167 const emits = defineEmits(['click'])
168
169 /**
170 * Handle click function
171 * @param evt
172 */
173 function handleClick(evt) {
174 emits('click', evt)
175 }
176
177 // * Color Vars
178 let amColors = inject('amColors', ref({
179 colorPrimary: '#1246D6',
180 colorSuccess: '#019719',
181 colorError: '#B4190F',
182 colorWarning: '#CCA20C',
183 colorMainBgr: '#FFFFFF',
184 colorMainHeadingText: '#33434C',
185 colorMainText: '#1A2C37',
186 colorSbBgr: '#17295A',
187 colorSbText: '#FFFFFF',
188 colorInpBgr: '#FFFFFF',
189 colorInpBorder: '#D1D5D7',
190 colorInpText: '#1A2C37',
191 colorInpPlaceHolder: '#1A2C37',
192 colorDropBgr: '#FFFFFF',
193 colorDropBorder: '#D1D5D7',
194 colorDropText: '#0E1920',
195 colorBtnPrim: '#265CF2',
196 colorBtnPrimText: '#FFFFFF',
197 colorBtnSec: '#1A2C37',
198 colorBtnSecText: '#FFFFFF',
199 colorBtnWaiting: '#CCA20C',
200 colorBtnWaitingText: '#FFFFFF',
201 colorBtnDanger: '#B4190F',
202 colorBtnDangerText: '#FFFFFF',
203 }))
204
205 const cssVars = computed(() => {
206 let cssVariables = {}
207 if (props.category === 'primary') {
208 cssVariables = {
209 '--am-c-btn-first': amColors.value.colorBtnPrim,
210 '--am-c-btn-second': amColors.value.colorBtnPrimText,
211 '--am-c-btn-first-op80': useColorTransparency(amColors.value.colorBtnPrim, 0.8),
212 '--am-c-btn-first-op30': useColorTransparency(amColors.value.colorBtnPrim, 0.3),
213 '--am-c-btn-first-op20': useColorTransparency(amColors.value.colorBtnPrim, 0.1),
214 }
215 }
216
217 if (props.category === 'secondary') {
218 cssVariables = {
219 '--am-c-btn-first': amColors.value.colorBtnSec,
220 '--am-c-btn-second': amColors.value.colorBtnSecText,
221 '--am-c-btn-first-op80': useColorTransparency(amColors.value.colorBtnSec, 0.8),
222 '--am-c-btn-first-op30': useColorTransparency(amColors.value.colorBtnSec, 0.3),
223 '--am-c-btn-first-op20': useColorTransparency(amColors.value.colorBtnSec, 0.1),
224 }
225 }
226
227 if (props.category === 'waiting') {
228 let bgr = amColors.value?.colorBtnWaiting ?? '#CCA20C'
229 let text = amColors.value?.colorBtnWaitingText ?? '#FFFFFF'
230
231 cssVariables = {
232 '--am-c-btn-first': bgr,
233 '--am-c-btn-second': text,
234 '--am-c-btn-first-op80': useColorTransparency(bgr, 0.8),
235 '--am-c-btn-first-op30': useColorTransparency(bgr, 0.3),
236 '--am-c-btn-first-op20': useColorTransparency(bgr, 0.1),
237 }
238 }
239
240 if (props.category === 'warning') {
241 cssVariables = {
242 '--am-c-btn-first': amColors.value.colorWarning,
243 '--am-c-btn-second': amColors.value.colorMainBgr,
244 '--am-c-btn-first-op80': useColorTransparency(amColors.value.colorWarning, 0.8),
245 '--am-c-btn-first-op30': useColorTransparency(amColors.value.colorWarning, 0.3),
246 '--am-c-btn-first-op20': useColorTransparency(amColors.value.colorWarning, 0.1),
247 }
248 }
249
250 if (props.category === 'danger') {
251 cssVariables = {
252 '--am-c-btn-first': amColors.value.colorBtnDanger,
253 '--am-c-btn-second': amColors.value.colorBtnDangerText,
254 '--am-c-btn-first-op80': useColorTransparency(amColors.value.colorBtnDanger, 0.8),
255 '--am-c-btn-first-op30': useColorTransparency(amColors.value.colorBtnDanger, 0.3),
256 '--am-c-btn-first-op20': useColorTransparency(amColors.value.colorBtnDanger, 0.1),
257 }
258 }
259
260 return cssVariables
261 })
262 </script>
263
264 <style lang="scss">
265 @mixin am-button-block {
266 .am-button {
267 --am-h-btn: 40px;
268 --am-fs-btn: 15px;
269 --am-fw-btn: 500;
270 --am-lh-btn: 1.6;
271 --am-rad-btn: 6px;
272 --am-padd-btn: 8px 24px;
273
274 display: inline-flex;
275 align-items: center;
276 justify-content: center;
277 height: var(--am-h-btn);
278 font-size: var(--am-fs-btn);
279 font-weight: var(--am-fw-btn);
280 line-height: var(--am-lh-btn);
281 white-space: nowrap;
282 text-decoration: none;
283 text-transform: unset;
284 border-radius: var(--am-rad-btn);
285 outline: 0;
286 margin: 0;
287 padding: var(--am-padd-btn);
288 cursor: pointer;
289 transition: 0.3s all ease-in-out;
290
291 // Inner
292 span {
293 display: flex;
294 align-items: center;
295 justify-content: center;
296 overflow: hidden;
297 }
298
299 &.am-button {
300 // Type - filled / plain / text
301 &--filled {
302 --am-c-btn-bgr: var(--am-c-btn-first);
303 --am-c-btn-text: var(--am-c-btn-second);
304 --am-c-btn-border: var(--am-c-btn-first);
305 background-color: var(--am-c-btn-bgr);
306 color: var(--am-c-btn-text);
307 border: 1px solid var(--am-c-btn-border);
308
309 &:not(.is-disabled) {
310 &:hover {
311 --am-c-btn-bgr: var(--am-c-btn-first-op80);
312 }
313
314 &:focus:not(:active) {
315 --am-c-btn-border: var(--am-c-btn-first);
316 box-shadow: 0 0 0 3px var(--am-c-btn-first-op30);
317 }
318
319 &:active {
320 --am-c-btn-bgr: var(--am-c-btn-first);
321 }
322 }
323 }
324
325 &--plain {
326 --am-c-btn-bgr: transparent;
327 --am-c-btn-text: var(--am-c-btn-first);
328 --am-c-btn-border: var(--am-c-btn-first-op30);
329 --am-c-btn-shadow: var(--am-c-btn-first-op20);
330 background-color: var(--am-c-btn-bgr);
331 color: var(--am-c-btn-text);
332 border: 1px solid var(--am-c-btn-border);
333 box-shadow: 0 1px 3px var(--am-c-btn-shadow);
334
335 &:not(.is-disabled) {
336 &:hover {
337 --am-c-btn-bgr: var(--am-c-btn-first-op20);
338 box-shadow: none;
339 }
340
341 &:focus:not(:active) {
342 --am-c-btn-border: var(--am-c-btn-second);
343 box-shadow: 0 0 0 2px var(--am-c-btn-first-op20);
344
345 &.is-icon-only {
346 --am-c-btn-border: var(--am-c-btn-first);
347 }
348
349 &:hover {
350 --am-c-btn-border: var(--am-c-btn-first-op20);
351 }
352 }
353
354 &:active {
355 --am-c-btn-bgr: var(--am-c-btn-first-op30);
356 box-shadow: none;
357 }
358 }
359 }
360
361 &--text {
362 --am-c-btn-bgr: transparent;
363 --am-c-btn-text: var(--am-c-btn-first);
364 --am-c-btn-border: transparent;
365 --am-c-btn-shadow: transparent;
366 background-color: var(--am-c-btn-bgr);
367 color: var(--am-c-btn-text);
368 border: 1px solid var(--am-c-btn-border);
369
370 &:not(.is-disabled) {
371 &:hover {
372 --am-c-btn-bgr: var(--am-c-btn-first-op20);
373 }
374
375 &:focus:not(:active) {
376 box-shadow: 0 0 0 2px var(--am-c-btn-first);
377 }
378
379 &:active {
380 --am-c-btn-bgr: var(--am-c-btn-first-op30);
381 }
382 }
383 }
384
385 // Size - default / medium / small / mini / micro
386 &--default {
387 --am-h-btn: 40px;
388 --am-fs-btn: 15px;
389 --am-lh-btn: 1.6;
390 --am-padd-btn: 8px 24px;
391
392 &.is-icon-only {
393 --am-padd-btn: 8px;
394 width: 40px;
395 }
396 }
397 &--medium {
398 --am-h-btn: 36px;
399 --am-fs-btn: 14px;
400 --am-lh-btn: 1.42857;
401 --am-padd-btn: 8px 20px;
402
403 &.is-icon-only {
404 --am-padd-btn: 8px;
405 width: 36px;
406 }
407 }
408 &--small {
409 --am-h-btn: 32px;
410 --am-fs-btn: 14px;
411 --am-lh-btn: 1.42857;
412 --am-padd-btn: 6px 16px;
413
414 &.is-icon-only {
415 --am-padd-btn: 6px;
416 width: 32px;
417 }
418 }
419 &--mini {
420 --am-h-btn: 28px;
421 --am-fs-btn: 13px;
422 --am-lh-btn: 1.53846;
423 --am-padd-btn: 4px 12px;
424 &.is-icon-only {
425 --am-padd-btn: 4px;
426 width: 28px;
427 }
428 }
429 &--micro {
430 --am-h-btn: 24px;
431 --am-fs-btn: 12px;
432 --am-lh-btn: 1.66666;
433 --am-padd-btn: 2px 12px;
434
435 &.is-icon-only {
436 --am-padd-btn: 2px;
437 --am-fs-btn: 16px;
438 width: 24px;
439 }
440 }
441
442 // Category - primary / secondary / success / warning / danger / error
443 // classes usage to change css variables
444 &--primary {}
445 &--secondary {}
446 &--success {}
447 &--warning {}
448 &--danger {}
449 &--error {}
450
451 // Circle
452 &.is-circle {
453 border-radius: 50%;
454 }
455
456 // Round
457 &.is-round {
458 border-radius: 20px;
459 }
460
461 // Disabled
462 &.is-disabled {
463 opacity: 0.7;
464 }
465
466 &--waiting-list { // TODO
467 }
468 }
469
470 &.am- {
471 &w20 {
472 width: 20%;
473 }
474
475 &w25 {
476 width: 25%;
477 }
478
479 &w30 {
480 width: 30%;
481 }
482
483 &w35 {
484 width: 35%;
485 }
486
487 &w40 {
488 width: 40%;
489 }
490
491 &w45 {
492 width: 45%;
493 }
494
495 &w50 {
496 width: 50%;
497 }
498
499 &w55 {
500 width: 55%;
501 }
502
503 &w60 {
504 width: 60%;
505 }
506
507 &w65 {
508 width: 65%;
509 }
510
511 &w70 {
512 width: 70%;
513 }
514
515 &w75 {
516 width: 75%;
517 }
518
519 &w80 {
520 width: 80%;
521 }
522
523 &w85 {
524 width: 85%;
525 }
526
527 &w90 {
528 width: 90%;
529 }
530
531 &w95 {
532 width: 95%;
533 }
534
535 &w100 {
536 width: 100%;
537 }
538
539 &mw20 {
540 max-width: 20%;
541 }
542
543 &mw25 {
544 max-width: 25%;
545 }
546
547 &mw30 {
548 max-width: 30%;
549 }
550
551 &mw35 {
552 max-width: 35%;
553 }
554
555 &mw40 {
556 max-width: 40%;
557 }
558
559 &mw45 {
560 max-width: 45%;
561 }
562
563 &mw50 {
564 max-width: 50%;
565 }
566
567 &mw55 {
568 max-width: 55%;
569 }
570
571 &mw60 {
572 max-width: 60%;
573 }
574
575 &mw65 {
576 max-width: 65%;
577 }
578
579 &mw70 {
580 max-width: 70%;
581 }
582
583 &mw75 {
584 max-width: 75%;
585 }
586
587 &mw80 {
588 max-width: 80%;
589 }
590
591 &mw85 {
592 max-width: 85%;
593 }
594
595 &mw90 {
596 max-width: 90%;
597 }
598
599 &mw95 {
600 max-width: 95%;
601 }
602
603 &mw100 {
604 max-width: 100%;
605 }
606 }
607 }
608 }
609
610 // Public
611 .amelia-v2-booking #amelia-container {
612 @include am-button-block;
613 }
614
615 // Dropdown
616 .am-dialog {
617 @include am-button-block;
618 }
619
620 // Modal - Dialog
621 .am-dialog-popup {
622 @include am-button-block;
623 }
624
625 // Admin
626 #amelia-app-backend-new {
627 @include am-button-block;
628 }
629 </style>
630