Button
10 months ago
HostingerTools
10 months ago
Icon
10 months ago
Loaders
10 months ago
Modals
10 months ago
AccordionCard.vue
10 months ago
Card.vue
10 months ago
CircleLoader.vue
10 months ago
CopyField.vue
10 months ago
Label.vue
10 months ago
NoResults.vue
10 months ago
Notice.vue
1 year ago
OverheadButton.vue
10 months ago
PluginSplitNotice.vue
10 months ago
Stepper.vue
10 months ago
Toggle.vue
10 months ago
CircleLoader.vue
81 lines
| 1 | <script lang="ts" setup> |
| 2 | import { computed } from "vue"; |
| 3 | |
| 4 | import { Color } from "@/types"; |
| 5 | import { wrapInCssVar } from "@/utils/helpers"; |
| 6 | |
| 7 | const props = withDefaults(defineProps<Props>(), { |
| 8 | color: "primary", |
| 9 | size: "medium", |
| 10 | dimensions: undefined, |
| 11 | borderSize: undefined, |
| 12 | borderColor: undefined |
| 13 | }); |
| 14 | |
| 15 | const DIMENSION_MAP = { |
| 16 | small: "24px", |
| 17 | medium: "40px", |
| 18 | large: "72px" |
| 19 | } as const; |
| 20 | |
| 21 | type HCircleLoaderSize = keyof typeof DIMENSION_MAP; |
| 22 | |
| 23 | interface Props { |
| 24 | color?: Color; |
| 25 | size?: HCircleLoaderSize; |
| 26 | dimensions?: string; |
| 27 | borderSize?: string; |
| 28 | borderColor?: Color; |
| 29 | } |
| 30 | |
| 31 | const getDimensions = () => { |
| 32 | if (props.dimensions) { |
| 33 | return props.dimensions; |
| 34 | } |
| 35 | |
| 36 | return DIMENSION_MAP[props.size]; |
| 37 | }; |
| 38 | |
| 39 | const getBorder = () => props.borderSize || "4px"; |
| 40 | |
| 41 | const getBorderColor = (): string => { |
| 42 | if (props.borderColor) { |
| 43 | return wrapInCssVar(props.borderColor); |
| 44 | } |
| 45 | |
| 46 | return wrapInCssVar(`${props.color}-light`); |
| 47 | }; |
| 48 | |
| 49 | const style = computed(() => ({ |
| 50 | color: wrapInCssVar(props.color), |
| 51 | borderColor: getBorderColor(), |
| 52 | width: getDimensions(), |
| 53 | borderSize: getBorder(), |
| 54 | height: getDimensions() |
| 55 | })); |
| 56 | </script> |
| 57 | |
| 58 | <template> |
| 59 | <div class="loader" /> |
| 60 | </template> |
| 61 | |
| 62 | <style lang="scss" scoped> |
| 63 | .loader { |
| 64 | border: v-bind("style.borderSize") solid v-bind("style.borderColor"); |
| 65 | border-top: v-bind("style.borderSize") solid v-bind("style.color"); |
| 66 | width: v-bind("style.width"); |
| 67 | height: v-bind("style.height"); |
| 68 | border-radius: 50%; |
| 69 | animation: spin 1s linear infinite; |
| 70 | } |
| 71 | |
| 72 | @keyframes spin { |
| 73 | 0% { |
| 74 | transform: rotate(0deg); |
| 75 | } |
| 76 | 100% { |
| 77 | transform: rotate(360deg); |
| 78 | } |
| 79 | } |
| 80 | </style> |
| 81 |