@dolanske/vui 0.3.4 → 0.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (114) hide show
  1. package/LICENSE +673 -673
  2. package/README.md +41 -40
  3. package/dist/components/Dropdown/DropdownItem.vue.d.ts +1 -0
  4. package/dist/components/Flex/Flex.vue.d.ts +3 -1
  5. package/dist/components/Grid/Grid.vue.d.ts +3 -1
  6. package/dist/components/Tabs/Tabs.vue.d.ts +4 -0
  7. package/dist/style.css +1 -1
  8. package/dist/vui.js +1547 -1534
  9. package/package.json +68 -68
  10. package/src/App.vue +176 -175
  11. package/src/components/Accordion/Accordion.vue +91 -91
  12. package/src/components/Accordion/AccordionGroup.vue +43 -43
  13. package/src/components/Accordion/accordion.scss +81 -80
  14. package/src/components/Alert/Alert.vue +53 -53
  15. package/src/components/Alert/alert.scss +80 -80
  16. package/src/components/Avatar/Avatar.vue +50 -50
  17. package/src/components/Avatar/avatar.scss +52 -52
  18. package/src/components/Badge/Badge.vue +21 -21
  19. package/src/components/Badge/badge.scss +89 -89
  20. package/src/components/Breadcrumbs/BreadcrumbItem.vue +26 -26
  21. package/src/components/Breadcrumbs/Breadcrumbs.vue +33 -33
  22. package/src/components/Breadcrumbs/breadcrumbs.scss +30 -30
  23. package/src/components/Button/Button.vue +90 -90
  24. package/src/components/Button/button.scss +178 -176
  25. package/src/components/ButtonGroup/ButtonGroup.vue +25 -25
  26. package/src/components/ButtonGroup/button-group.scss +51 -51
  27. package/src/components/Calendar/Calendar.vue +63 -60
  28. package/src/components/Calendar/calendar.scss +60 -56
  29. package/src/components/Card/Card.vue +48 -48
  30. package/src/components/Card/card.scss +53 -53
  31. package/src/components/Checkbox/Checkbox.vue +51 -52
  32. package/src/components/Checkbox/checkbox.scss +75 -66
  33. package/src/components/CopyClipboard/CopyClipboard.vue +82 -82
  34. package/src/components/CopyClipboard/copy-clipboard.scss +17 -17
  35. package/src/components/Divider/Divider.vue +44 -44
  36. package/src/components/Divider/divider.scss +35 -35
  37. package/src/components/Drawer/Drawer.vue +97 -97
  38. package/src/components/Drawer/drawer.scss +36 -36
  39. package/src/components/Dropdown/Dropdown.vue +111 -111
  40. package/src/components/Dropdown/DropdownItem.vue +33 -29
  41. package/src/components/Dropdown/DropdownTitle.vue +8 -8
  42. package/src/components/Dropdown/dropdown-item.scss +77 -0
  43. package/src/components/Dropdown/dropdown.scss +39 -117
  44. package/src/components/Flex/Flex.vue +113 -106
  45. package/src/components/Grid/Grid.vue +60 -54
  46. package/src/components/Input/Counter.vue +70 -70
  47. package/src/components/Input/Dropzone.vue +65 -65
  48. package/src/components/Input/File.vue +15 -15
  49. package/src/components/Input/Input.vue +121 -121
  50. package/src/components/Input/Password.vue +47 -47
  51. package/src/components/Input/Textarea.vue +76 -76
  52. package/src/components/Input/input.scss +208 -208
  53. package/src/components/Kbd/Kbd.vue +48 -48
  54. package/src/components/Kbd/KbdGroup.vue +31 -31
  55. package/src/components/Kbd/kbd.scss +18 -18
  56. package/src/components/Modal/Confirm.vue +56 -56
  57. package/src/components/Modal/Modal.vue +91 -91
  58. package/src/components/Modal/modal.scss +49 -49
  59. package/src/components/OTP/OTP.vue +133 -133
  60. package/src/components/OTP/OTPItem.vue +37 -37
  61. package/src/components/OTP/otp.scss +83 -83
  62. package/src/components/Pagination/Pagination.vue +74 -74
  63. package/src/components/Pagination/pagination.ts +78 -78
  64. package/src/components/Popout/Popout.vue +42 -42
  65. package/src/components/Popout/popout.scss +8 -8
  66. package/src/components/Progress/Progress.vue +90 -90
  67. package/src/components/Progress/progress.scss +41 -41
  68. package/src/components/Radio/Radio.vue +36 -36
  69. package/src/components/Radio/RadioGroup.vue +40 -40
  70. package/src/components/Radio/radio.scss +68 -59
  71. package/src/components/Select/Select.vue +180 -180
  72. package/src/components/Select/select.scss +44 -44
  73. package/src/components/Sheet/Sheet.vue +92 -92
  74. package/src/components/Sheet/sheet.scss +60 -60
  75. package/src/components/Sidebar/Sidebar.vue +102 -0
  76. package/src/components/Sidebar/sidebar.scss +123 -0
  77. package/src/components/Skeleton/Skeleton.vue +43 -43
  78. package/src/components/Skeleton/skeleton.scss +14 -14
  79. package/src/components/Spinner/Spinner.vue +42 -42
  80. package/src/components/Spinner/spinner.scss +46 -46
  81. package/src/components/Switch/Switch.vue +30 -30
  82. package/src/components/Switch/switch.scss +60 -52
  83. package/src/components/Table/Cell.vue +23 -23
  84. package/src/components/Table/Header.vue +59 -59
  85. package/src/components/Table/Row.vue +9 -9
  86. package/src/components/Table/SelectAll.vue +23 -23
  87. package/src/components/Table/SelectRow.vue +29 -29
  88. package/src/components/Table/Table.vue +66 -66
  89. package/src/components/Table/table.scss +134 -134
  90. package/src/components/Table/table.ts +244 -244
  91. package/src/components/Tabs/Tab.vue +27 -27
  92. package/src/components/Tabs/Tabs.vue +89 -82
  93. package/src/components/Tabs/tabs.scss +80 -79
  94. package/src/components/Toast/Toasts.vue +47 -47
  95. package/src/components/Toast/toast.scss +41 -41
  96. package/src/components/Toast/toast.ts +68 -68
  97. package/src/components/Tooltip/Tooltip.vue +86 -86
  98. package/src/components/Tooltip/tooltip.scss +4 -4
  99. package/src/index.scss +1 -1
  100. package/src/index.ts +119 -119
  101. package/src/internal/Backdrop/Backdrop.vue +22 -22
  102. package/src/internal/Backdrop/backdrop.scss +28 -28
  103. package/src/main.ts +5 -5
  104. package/src/shared/helpers.ts +74 -74
  105. package/src/shared/types.ts +29 -29
  106. package/src/style/animation.scss +21 -21
  107. package/src/style/core.scss +150 -148
  108. package/src/style/layout.scss +168 -136
  109. package/src/style/media-query.scss +29 -29
  110. package/src/style/reset.scss +135 -135
  111. package/src/style/{fonts.scss → text.scss} +74 -53
  112. package/src/style/tooltip.scss +128 -128
  113. package/src/style/typography.scss +338 -338
  114. package/src/style/utils.scss +36 -36
@@ -1,60 +1,60 @@
1
- .vui-sheet {
2
- display: flex;
3
- flex-direction: column;
4
- position: absolute;
5
- background-color: var(--color-bg);
6
- border-color: var(--color-border);
7
- height: 100dvh;
8
-
9
- &.vui-sheet-position-top {
10
- top: 0;
11
- border-bottom: 1px solid var(--color-border);
12
- height: auto;
13
- }
14
-
15
- &.vui-sheet-position-bottom {
16
- bottom: 0;
17
- border-top: 1px solid var(--color-border);
18
- height: auto;
19
- }
20
-
21
- &.vui-sheet-position-right {
22
- right: 0;
23
- top: 0;
24
- border-left: 1px solid var(--color-border);
25
- }
26
-
27
- &.vui-sheet-position-left {
28
- left: 0;
29
- top: 0;
30
- border-right: 1px solid var(--color-border);
31
- }
32
-
33
- &.vui-sheet-position-top,
34
- &.vui-sheet-position-bottom {
35
- max-height: 35dvh;
36
- width: 100%;
37
- }
38
-
39
- .vui-sheet-header,
40
- .vui-sheet-content {
41
- width: 100%;
42
- padding: var(--space-m);
43
- }
44
-
45
- .vui-sheet-content {
46
- flex: 1 1 0%;
47
- overflow-y: auto;
48
- height: 100%;
49
- }
50
-
51
- .vui-sheet-header {
52
- display: flex;
53
- gap: var(--space-m);
54
- align-self: flex-start;
55
-
56
- & + .vui-sheet-content {
57
- padding-top: var(--space-s);
58
- }
59
- }
60
- }
1
+ .vui-sheet {
2
+ display: flex;
3
+ flex-direction: column;
4
+ position: absolute;
5
+ background-color: var(--color-bg);
6
+ border-color: var(--color-border);
7
+ height: 100dvh;
8
+
9
+ &.vui-sheet-position-top {
10
+ top: 0;
11
+ border-bottom: 1px solid var(--color-border);
12
+ height: auto;
13
+ }
14
+
15
+ &.vui-sheet-position-bottom {
16
+ bottom: 0;
17
+ border-top: 1px solid var(--color-border);
18
+ height: auto;
19
+ }
20
+
21
+ &.vui-sheet-position-right {
22
+ right: 0;
23
+ top: 0;
24
+ border-left: 1px solid var(--color-border);
25
+ }
26
+
27
+ &.vui-sheet-position-left {
28
+ left: 0;
29
+ top: 0;
30
+ border-right: 1px solid var(--color-border);
31
+ }
32
+
33
+ &.vui-sheet-position-top,
34
+ &.vui-sheet-position-bottom {
35
+ max-height: 35dvh;
36
+ width: 100%;
37
+ }
38
+
39
+ .vui-sheet-header,
40
+ .vui-sheet-content {
41
+ width: 100%;
42
+ padding: var(--space-m);
43
+ }
44
+
45
+ .vui-sheet-content {
46
+ flex: 1 1 0%;
47
+ overflow-y: auto;
48
+ height: 100%;
49
+ }
50
+
51
+ .vui-sheet-header {
52
+ display: flex;
53
+ gap: var(--space-m);
54
+ align-self: flex-start;
55
+
56
+ & + .vui-sheet-content {
57
+ padding-top: var(--space-s);
58
+ }
59
+ }
60
+ }
@@ -0,0 +1,102 @@
1
+ <script setup lang='ts'>
2
+ import { useCssVar, useMouse, useTimeoutFn, watchThrottled } from '@vueuse/core'
3
+ import { computed, useSlots, useTemplateRef } from 'vue'
4
+ import { isNil } from '../../shared/helpers'
5
+ import './sidebar.scss'
6
+
7
+ const props = withDefaults(defineProps<Props>(), {
8
+ width: 224,
9
+ mini: false,
10
+ })
11
+
12
+ interface Props {
13
+ width?: number
14
+ /**
15
+ * Controls wether the sidebar is displayed in full size, or a small version
16
+ */
17
+ mini?: boolean
18
+ /**
19
+ * Allow sidebar showing up, when user hovers at very left of the screen. The
20
+ * sidebar will apear over content, not pushing anything over
21
+ */
22
+ appear?: boolean
23
+ /**
24
+ * Add edges of background around sidebar
25
+ */
26
+ floaty?: boolean
27
+ }
28
+
29
+ const sidebar = useTemplateRef('sidebar')
30
+ const open = defineModel<boolean>()
31
+ const slots = useSlots()
32
+ const offset = useCssVar('--vui-sidebar-float-offset', sidebar, {
33
+ initialValue: '8px',
34
+ })
35
+
36
+ const width = computed(() => {
37
+ if (props.mini)
38
+ return `65px`
39
+ if (!props.floaty)
40
+ return `${props.width}px`
41
+ return `calc(${props.width}px - ${offset.value})`
42
+ })
43
+
44
+ const slotProps = computed(() => ({
45
+ mini: props.mini,
46
+ floaty: props.floaty,
47
+ width: props.width,
48
+ open,
49
+ }))
50
+
51
+ // Sidebar `appear` implementation
52
+ const { start, stop, isPending } = useTimeoutFn(() => {
53
+ open.value = true
54
+ }, 250)
55
+
56
+ const APPEAR_OFFSET = 32
57
+
58
+ const { x } = useMouse()
59
+
60
+ watchThrottled(x, (pos) => {
61
+ if (!props.appear)
62
+ return
63
+
64
+ if (pos <= APPEAR_OFFSET && pos >= 0 && !open.value && !isPending.value) {
65
+ start()
66
+ }
67
+ else if (isPending.value) {
68
+ stop()
69
+ }
70
+
71
+ const openWidth = props.mini
72
+ ? 65
73
+ : props.floaty
74
+ ? props.width
75
+ : props.width - (isNil(offset.value) ? 0 : Number(offset.value?.replace('px', '')))
76
+
77
+ if ((pos > APPEAR_OFFSET + openWidth || pos < 0) && open.value) {
78
+ open.value = false
79
+ }
80
+ }, {
81
+ throttle: 100,
82
+ })
83
+ </script>
84
+
85
+ <template>
86
+ <div class="vui-sidebar-outer" :style="{ width }" :class="{ open }">
87
+ <aside ref="sidebar" class="vui-sidebar" :class="{ open, floaty: props.floaty, mini: props.mini }" :style="{ width: `${props.mini ? 65 : props.width}px` }">
88
+ <div v-if="slots.header" class="vui-sidebar-header">
89
+ <slot name="header" v-bind="slotProps" />
90
+ </div>
91
+ <div class="vui-sidebar-content">
92
+ <div class="vui-sidebar-content-wrap">
93
+ <slot v-bind="slotProps" />
94
+ </div>
95
+ </div>
96
+
97
+ <div v-if="slots.footer" class="vui-sidebar-footer">
98
+ <slot name="footer" v-bind="slotProps" />
99
+ </div>
100
+ </aside>
101
+ </div>
102
+ </template>
@@ -0,0 +1,123 @@
1
+ // TODO: flesh out better
2
+ .vui-sidebar-layout {
3
+ display: flex;
4
+ flex-wrap: nowrap;
5
+ gap: 32px;
6
+ position: relative;
7
+
8
+ main {
9
+ flex: 1;
10
+ padding: 2rem;
11
+ }
12
+
13
+ .vui-sidebar-outer {
14
+ transition: var(--transition-slow);
15
+
16
+ &:not(.open) {
17
+ width: 0px !important;
18
+ }
19
+ }
20
+ }
21
+
22
+ .vui-sidebar {
23
+ --vui-sidebar-float-offset: 8px;
24
+ display: flex;
25
+ flex-direction: column;
26
+ gap: var(--space-sm);
27
+ height: 100vh;
28
+ width: 224px;
29
+ position: fixed;
30
+ top: 0;
31
+ z-index: 50;
32
+ background-color: var(--color-bg);
33
+ border-right: 1px solid var(--color-border);
34
+ transition: var(--transition-slow);
35
+ transform: translateX(-100%);
36
+ will-change: transform;
37
+
38
+ &.open {
39
+ transform: translateX(0);
40
+
41
+ &.floaty {
42
+ transform: translateX(0);
43
+ }
44
+ }
45
+
46
+ &.floaty {
47
+ top: var(--vui-sidebar-float-offset);
48
+ left: var(--vui-sidebar-float-offset);
49
+ bottom: var(--vui-sidebar-float-offset);
50
+ height: calc(100vh - calc(var(--vui-sidebar-float-offset) * 2));
51
+ border-radius: var(--border-radius-m);
52
+ border: 1px solid var(--color-border);
53
+ transform: translateX(calc(-100% - calc(var(--vui-sidebar-float-offset) * 2)));
54
+ box-shadow: var(--box-shadow);
55
+ }
56
+
57
+ .vui-sidebar-header,
58
+ .vui-sidebar-footer,
59
+ .vui-sidebar-content .vui-sidebar-content-wrap {
60
+ padding: var(--space-s);
61
+ }
62
+
63
+ .vui-sidebar-header:not(:only-child) {
64
+ padding-bottom: 0;
65
+ }
66
+
67
+ .vui-sidebar-footer:not(:only-child) {
68
+ padding-top: 0;
69
+ }
70
+
71
+ .vui-sidebar-content {
72
+ flex: 1;
73
+ position: relative;
74
+
75
+ .vui-sidebar-content-wrap {
76
+ position: absolute;
77
+ inset: 0;
78
+ overflow-y: auto;
79
+ }
80
+ }
81
+
82
+ // Note: elements in sidebar (& mini) should have a slight modification
83
+
84
+ // Accordion
85
+ // Does not have a border under content
86
+ .vui-accordion {
87
+ border-bottom: 0;
88
+ }
89
+
90
+ // DropdownItems (sidebar items
91
+ // Should have a bit less spacing between slots
92
+ .vui-dropdown-item {
93
+ padding-inline: var(--space-xs);
94
+ }
95
+
96
+ &.mini {
97
+ .vui-dropdown-item .vui-dropdown-item-icon {
98
+ width: 20px;
99
+ height: 20px;
100
+ }
101
+
102
+ .vui-dropdown-item,
103
+ .vui-button {
104
+ --button-height: 40px;
105
+ width: var(--button-height) !important;
106
+ height: var(--button-height) !important;
107
+ justify-content: center;
108
+ align-items: center;
109
+
110
+ svg {
111
+ width: 20px;
112
+ height: 20px;
113
+ }
114
+
115
+ .vui-dropdown-item-slot,
116
+ .vui-dropdown-item-hint,
117
+ .vui-button-slot-end,
118
+ .vui-button-slot-start {
119
+ display: none;
120
+ }
121
+ }
122
+ }
123
+ }
@@ -1,43 +1,43 @@
1
- <!-- eslint-disable ts/no-use-before-define -->
2
- <script setup lang='ts'>
3
- import { computed } from 'vue'
4
- import { formatUnitValue } from '../../shared/helpers'
5
- import './skeleton.scss'
6
-
7
- interface Props {
8
- radius?: string | number
9
- width?: string | number
10
- height?: string | number
11
- circle?: boolean
12
- }
13
-
14
- const {
15
- // @ts-expect-error I can't get ESLint to STOP moving DEFAULT_RADIUS below
16
- // this props declaration wtf
17
- radius = DEFAULT_RADIUS,
18
- width = '100%',
19
- height = '32px',
20
- circle,
21
- } = defineProps<Props>()
22
-
23
- const DEFAULT_RADIUS = 'var(--border-radius-s)'
24
-
25
- // Give priority to radius, if it is NOT set to default
26
- const bR = computed(() => formatUnitValue(circle && radius === DEFAULT_RADIUS ? 9999 : radius))
27
-
28
- // When using `circle` prop, we want to use the same
29
- // value for both height and width, but we can't
30
- // know which one will be defined
31
- const w = computed(() => formatUnitValue(circle ? (width || height) : width))
32
- const h = computed(() => formatUnitValue(circle ? (width || height) : height))
33
- </script>
34
-
35
- <template>
36
- <div
37
- class="vui-skeleton" :style="{
38
- borderRadius: bR,
39
- width: w,
40
- height: h,
41
- }"
42
- />
43
- </template>
1
+ <!-- eslint-disable ts/no-use-before-define -->
2
+ <script setup lang='ts'>
3
+ import { computed } from 'vue'
4
+ import { formatUnitValue } from '../../shared/helpers'
5
+ import './skeleton.scss'
6
+
7
+ interface Props {
8
+ radius?: string | number
9
+ width?: string | number
10
+ height?: string | number
11
+ circle?: boolean
12
+ }
13
+
14
+ const {
15
+ // @ts-expect-error I can't get ESLint to STOP moving DEFAULT_RADIUS below
16
+ // this props declaration wtf
17
+ radius = DEFAULT_RADIUS,
18
+ width = '100%',
19
+ height = '32px',
20
+ circle,
21
+ } = defineProps<Props>()
22
+
23
+ const DEFAULT_RADIUS = 'var(--border-radius-s)'
24
+
25
+ // Give priority to radius, if it is NOT set to default
26
+ const bR = computed(() => formatUnitValue(circle && radius === DEFAULT_RADIUS ? 9999 : radius))
27
+
28
+ // When using `circle` prop, we want to use the same
29
+ // value for both height and width, but we can't
30
+ // know which one will be defined
31
+ const w = computed(() => formatUnitValue(circle ? (width || height) : width))
32
+ const h = computed(() => formatUnitValue(circle ? (width || height) : height))
33
+ </script>
34
+
35
+ <template>
36
+ <div
37
+ class="vui-skeleton" :style="{
38
+ borderRadius: bR,
39
+ width: w,
40
+ height: h,
41
+ }"
42
+ />
43
+ </template>
@@ -1,14 +1,14 @@
1
- .vui-skeleton {
2
- animation: pulse 2.5s cubic-bezier(0.4, 0, 0.6, 1) infinite;
3
- background-color: var(--color-border);
4
-
5
- @keyframes pulse {
6
- 0%,
7
- 100% {
8
- opacity: 1;
9
- }
10
- 50% {
11
- opacity: 0.5;
12
- }
13
- }
14
- }
1
+ .vui-skeleton {
2
+ animation: pulse 2.5s cubic-bezier(0.4, 0, 0.6, 1) infinite;
3
+ background-color: var(--color-border);
4
+
5
+ @keyframes pulse {
6
+ 0%,
7
+ 100% {
8
+ opacity: 1;
9
+ }
10
+ 50% {
11
+ opacity: 0.5;
12
+ }
13
+ }
14
+ }
@@ -1,42 +1,42 @@
1
- <script setup lang="ts">
2
- import type { Sizes } from '../../shared/types'
3
- import { computed } from 'vue'
4
- import { Size } from '../../shared/types'
5
- import './spinner.scss'
6
-
7
- interface Props {
8
- size?: Sizes
9
- }
10
-
11
- const {
12
- size = 's',
13
- } = defineProps<Props>()
14
-
15
- const w = computed(() => {
16
- switch (size) {
17
- case Size.s: return '16px'
18
- case Size.l: return '38px'
19
- case Size.m:
20
- default: return '26px'
21
- }
22
- })
23
-
24
- const bW = computed(() => {
25
- switch (size) {
26
- case Size.s: return '3px'
27
- case Size.l: return '5px'
28
- case Size.m:
29
- default: return '4px'
30
- }
31
- })
32
- </script>
33
-
34
- <template>
35
- <div
36
- :class="{ size }" class="vui-spinner" :style="{
37
- width: w,
38
- height: w,
39
- borderWidth: bW,
40
- }"
41
- />
42
- </template>
1
+ <script setup lang="ts">
2
+ import type { Sizes } from '../../shared/types'
3
+ import { computed } from 'vue'
4
+ import { Size } from '../../shared/types'
5
+ import './spinner.scss'
6
+
7
+ interface Props {
8
+ size?: Sizes
9
+ }
10
+
11
+ const {
12
+ size = 's',
13
+ } = defineProps<Props>()
14
+
15
+ const w = computed(() => {
16
+ switch (size) {
17
+ case Size.s: return '16px'
18
+ case Size.l: return '38px'
19
+ case Size.m:
20
+ default: return '26px'
21
+ }
22
+ })
23
+
24
+ const bW = computed(() => {
25
+ switch (size) {
26
+ case Size.s: return '3px'
27
+ case Size.l: return '5px'
28
+ case Size.m:
29
+ default: return '4px'
30
+ }
31
+ })
32
+ </script>
33
+
34
+ <template>
35
+ <div
36
+ :class="{ size }" class="vui-spinner" :style="{
37
+ width: w,
38
+ height: w,
39
+ borderWidth: bW,
40
+ }"
41
+ />
42
+ </template>
@@ -1,46 +1,46 @@
1
- .vui-spinner {
2
- --spinner-color: var(--color-text);
3
- aspect-ratio: 1;
4
- border-radius: 50%;
5
- border: 3px solid var(--spinner-color);
6
- animation:
7
- l20-1 0.8s infinite linear alternate,
8
- l20-2 1.6s infinite linear;
9
- }
10
- @keyframes l20-1 {
11
- 0% {
12
- clip-path: polygon(50% 50%, 0 0, 50% 0%, 50% 0%, 50% 0%, 50% 0%, 50% 0%);
13
- }
14
- 12.5% {
15
- clip-path: polygon(50% 50%, 0 0, 50% 0%, 100% 0%, 100% 0%, 100% 0%, 100% 0%);
16
- }
17
- 25% {
18
- clip-path: polygon(50% 50%, 0 0, 50% 0%, 100% 0%, 100% 100%, 100% 100%, 100% 100%);
19
- }
20
- 50% {
21
- clip-path: polygon(50% 50%, 0 0, 50% 0%, 100% 0%, 100% 100%, 50% 100%, 0% 100%);
22
- }
23
- 62.5% {
24
- clip-path: polygon(50% 50%, 100% 0, 100% 0%, 100% 0%, 100% 100%, 50% 100%, 0% 100%);
25
- }
26
- 75% {
27
- clip-path: polygon(50% 50%, 100% 100%, 100% 100%, 100% 100%, 100% 100%, 50% 100%, 0% 100%);
28
- }
29
- 100% {
30
- clip-path: polygon(50% 50%, 50% 100%, 50% 100%, 50% 100%, 50% 100%, 50% 100%, 0% 100%);
31
- }
32
- }
33
- @keyframes l20-2 {
34
- 0% {
35
- transform: scaleY(1) rotate(0deg);
36
- }
37
- 49.99% {
38
- transform: scaleY(1) rotate(135deg);
39
- }
40
- 50% {
41
- transform: scaleY(-1) rotate(0deg);
42
- }
43
- 100% {
44
- transform: scaleY(-1) rotate(-135deg);
45
- }
46
- }
1
+ .vui-spinner {
2
+ --spinner-color: var(--color-text);
3
+ aspect-ratio: 1;
4
+ border-radius: 50%;
5
+ border: 3px solid var(--spinner-color);
6
+ animation:
7
+ l20-1 0.8s infinite linear alternate,
8
+ l20-2 1.6s infinite linear;
9
+ }
10
+ @keyframes l20-1 {
11
+ 0% {
12
+ clip-path: polygon(50% 50%, 0 0, 50% 0%, 50% 0%, 50% 0%, 50% 0%, 50% 0%);
13
+ }
14
+ 12.5% {
15
+ clip-path: polygon(50% 50%, 0 0, 50% 0%, 100% 0%, 100% 0%, 100% 0%, 100% 0%);
16
+ }
17
+ 25% {
18
+ clip-path: polygon(50% 50%, 0 0, 50% 0%, 100% 0%, 100% 100%, 100% 100%, 100% 100%);
19
+ }
20
+ 50% {
21
+ clip-path: polygon(50% 50%, 0 0, 50% 0%, 100% 0%, 100% 100%, 50% 100%, 0% 100%);
22
+ }
23
+ 62.5% {
24
+ clip-path: polygon(50% 50%, 100% 0, 100% 0%, 100% 0%, 100% 100%, 50% 100%, 0% 100%);
25
+ }
26
+ 75% {
27
+ clip-path: polygon(50% 50%, 100% 100%, 100% 100%, 100% 100%, 100% 100%, 50% 100%, 0% 100%);
28
+ }
29
+ 100% {
30
+ clip-path: polygon(50% 50%, 50% 100%, 50% 100%, 50% 100%, 50% 100%, 50% 100%, 0% 100%);
31
+ }
32
+ }
33
+ @keyframes l20-2 {
34
+ 0% {
35
+ transform: scaleY(1) rotate(0deg);
36
+ }
37
+ 49.99% {
38
+ transform: scaleY(1) rotate(135deg);
39
+ }
40
+ 50% {
41
+ transform: scaleY(-1) rotate(0deg);
42
+ }
43
+ 100% {
44
+ transform: scaleY(-1) rotate(-135deg);
45
+ }
46
+ }