PluginProbe
The Innovative Form Builder – IvyForms / 1.1
The Innovative Form Builder – IvyForms v1.1
1.5.1 1.5 1.4.1 1.4 trunk 0.1.2 0.2 0.2.1 0.3 0.3.1 0.4 0.5 0.6 0.6.1 0.6.1-backup 0.6.1.1 0.7 0.8 0.8.1 0.8.2 0.9 0.9.1 1.0 1.1 1.1.1 All 27 releases
ivyforms / frontend / src / views / _components / loader / IvyCircleLoader.vue

IvyCircleLoader.vue in The Innovative Form Builder – IvyForms 1.1, at frontend/src/views/_components/loader/IvyCircleLoader.vue

165 lines 3.3 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <template>
2 <span
3 class="ivyforms-circle-loader ivyforms-align-items-center ivyforms-justify-content-center"
4 :class="[`ivyforms-circle-loader--${size}`, { 'ivyforms-circle-loader--completed': completed }]"
5 >
6 <svg viewBox="0 0 24 24" class="ivyforms-circle-loader__svg ivyforms-width-100">>
7 <circle class="ivyforms-circle-loader__bg" cx="12" cy="12" r="10" />
8 <circle class="ivyforms-circle-loader__track" cx="12" cy="12" r="10" />
9 <circle class="ivyforms-circle-loader__progress" cx="12" cy="12" r="10" />
10 </svg>
11 <span
12 class="ivyforms-circle-loader__check ivyforms-flex ivyforms-align-items-center ivyforms-justify-content-center ivyforms-width-100"
13 >
14 <CheckLoaderIcon />
15 </span>
16 </span>
17 </template>
18
19 <script setup lang="ts">
20 import CheckLoaderIcon from '@/assets/icons/global/outline/check-loader.svg?component'
21
22 interface Props {
23 size?: 's' | 'd' | 'l'
24 completed?: boolean
25 }
26
27 withDefaults(defineProps<Props>(), {
28 size: 'd',
29 completed: false,
30 })
31 </script>
32
33 <style lang="scss" scoped>
34 .ivyforms-circle-loader {
35 display: inline-flex;
36 position: relative;
37
38 // Size variants
39 &--s {
40 width: 16px;
41 height: 16px;
42 }
43
44 &--d {
45 width: 24px;
46 height: 24px;
47 }
48
49 &--l {
50 width: 32px;
51 height: 32px;
52 }
53
54 &__svg {
55 height: 100%;
56 position: absolute;
57 top: 0;
58 left: 0;
59 }
60
61 &__bg {
62 fill: transparent;
63 }
64
65 &__track {
66 fill: none;
67 stroke: var(--map-base-dusk-stroke-1, #707883);
68 stroke-width: 2;
69 opacity: 0;
70 }
71
72 &__progress {
73 fill: none;
74 stroke: var(--map-base-dusk-symbol-2, #394452);
75 stroke-width: 2;
76 stroke-linecap: round;
77 stroke-dasharray: 62.83;
78 stroke-dashoffset: 62.83;
79 transform-origin: center;
80 transform: rotate(-90deg);
81 animation: ivyforms-circle-loader-spin 1.2s linear infinite;
82 }
83
84 &__check {
85 position: absolute;
86 top: 0;
87 left: 0;
88 height: 100%;
89 z-index: 1;
90
91 :deep(path) {
92 fill: var(--map-base-dusk-symbol-2, #394452);
93 }
94 }
95
96 // Completed state - show final appearance
97 &--completed {
98 .ivyforms-circle-loader__bg {
99 fill: var(--map-base-dusk-symbol-2, #394452);
100 animation: ivyforms-circle-loader-bg-appear 0.3s ease-out forwards;
101 }
102
103 .ivyforms-circle-loader__track {
104 opacity: 1;
105 animation: ivyforms-circle-loader-track-appear 0.3s ease-out forwards;
106 }
107
108 .ivyforms-circle-loader__progress {
109 stroke-dashoffset: 0;
110 animation: none;
111 }
112
113 .ivyforms-circle-loader__check {
114 :deep(path) {
115 fill: #ffffff;
116 animation: ivyforms-circle-loader-check-appear 0.3s ease-out forwards;
117 }
118 }
119 }
120 }
121
122 // Loading animation - spinning circle
123 @keyframes ivyforms-circle-loader-spin {
124 0% {
125 stroke-dashoffset: 62.83;
126 transform: rotate(-90deg);
127 }
128 50% {
129 stroke-dashoffset: 15;
130 }
131 100% {
132 stroke-dashoffset: 62.83;
133 transform: rotate(270deg);
134 }
135 }
136
137 // Completed state animations
138 @keyframes ivyforms-circle-loader-bg-appear {
139 from {
140 fill: transparent;
141 }
142 to {
143 fill: var(--map-base-dusk-symbol-2, #394452);
144 }
145 }
146
147 @keyframes ivyforms-circle-loader-track-appear {
148 from {
149 opacity: 0;
150 }
151 to {
152 opacity: 1;
153 }
154 }
155
156 @keyframes ivyforms-circle-loader-check-appear {
157 from {
158 fill: var(--map-base-dusk-symbol-2, #394452);
159 }
160 to {
161 fill: #ffffff;
162 }
163 }
164 </style>
165