mirror of
https://github.com/directus/directus.git
synced 2026-01-27 09:28:05 -05:00
Add progress circular (#32)
* made spinner more fancy * rebuild spinner to progress circular * update readme * cleaned code and style * clean readme * made spinner more fancy * rebuild spinner to progress circular * update readme * cleaned code and style * clean readme * Register circular progress * Fix broken import * Fix stylelint problems in v-progress-circular * Add some useful tests for circular progress * Delete package-lock.json * Update readme * Ignore package-lock Co-authored-by: Rijk van Zanten <rijkvanzanten@me.com>
This commit is contained in:
1
.gitignore
vendored
1
.gitignore
vendored
@@ -3,6 +3,7 @@ node_modules
|
||||
/dist
|
||||
storybook-static
|
||||
coverage
|
||||
package-lock.json
|
||||
|
||||
# local env files
|
||||
.env.local
|
||||
|
||||
@@ -9,9 +9,9 @@ import VIcon from './v-icon/';
|
||||
import VInput from './v-input/';
|
||||
import VOverlay from './v-overlay/';
|
||||
import VProgressLinear from './v-progress/linear/';
|
||||
import VProgressCircular from './v-progress/circular/';
|
||||
import VSheet from './v-sheet/';
|
||||
import VSlider from './v-slider/';
|
||||
import VSpinner from './v-spinner/';
|
||||
import VSwitch from './v-switch/';
|
||||
import VTable from './v-table/';
|
||||
|
||||
@@ -24,8 +24,8 @@ Vue.component('v-icon', VIcon);
|
||||
Vue.component('v-input', VInput);
|
||||
Vue.component('v-overlay', VOverlay);
|
||||
Vue.component('v-progress-linear', VProgressLinear);
|
||||
Vue.component('v-progress-circular', VProgressCircular);
|
||||
Vue.component('v-sheet', VSheet);
|
||||
Vue.component('v-slider', VSlider);
|
||||
Vue.component('v-spinner', VSpinner);
|
||||
Vue.component('v-switch', VSwitch);
|
||||
Vue.component('v-table', VTable);
|
||||
|
||||
@@ -1,12 +1,11 @@
|
||||
import { mount, createLocalVue } from '@vue/test-utils';
|
||||
import VueCompositionAPI from '@vue/composition-api';
|
||||
import VButton from './v-button.vue';
|
||||
import VProgressCircular from '../v-progress/circular/';
|
||||
|
||||
const localVue = createLocalVue();
|
||||
localVue.use(VueCompositionAPI);
|
||||
localVue.component('v-spinner', VSpinner);
|
||||
|
||||
import VButton from './v-button.vue';
|
||||
import VSpinner from '../v-spinner/';
|
||||
localVue.component('v-progress-circular', VProgressCircular);
|
||||
|
||||
describe('Button', () => {
|
||||
it('Renders the provided markup in the default slow', () => {
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
<span class="content" :class="{ invisible: loading }"><slot /></span>
|
||||
<div class="spinner">
|
||||
<slot v-if="loading" name="loading">
|
||||
<v-spinner :x-small="xSmall" :small="small" />
|
||||
<v-progress-circular :x-small="xSmall" :small="small" indeterminate />
|
||||
</slot>
|
||||
</div>
|
||||
</button>
|
||||
@@ -191,6 +191,11 @@ export default createComponent({
|
||||
top: 50%;
|
||||
left: 50%;
|
||||
transform: translate(-50%, -50%);
|
||||
|
||||
.v-progress-circular {
|
||||
--v-progress-circular-color: var(--v-button-color);
|
||||
--v-progress-circular-background-color: transparent;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
4
src/components/v-progress/circular/index.ts
Normal file
4
src/components/v-progress/circular/index.ts
Normal file
@@ -0,0 +1,4 @@
|
||||
import VProgressCircular from './v-progress-circular.vue';
|
||||
|
||||
export { VProgressCircular };
|
||||
export default VProgressCircular;
|
||||
@@ -0,0 +1,66 @@
|
||||
# Progress (circular)
|
||||
|
||||
```html
|
||||
<v-progress-circular />
|
||||
```
|
||||
|
||||
## Colors
|
||||
|
||||
The color of the circular progressbar can be changed through the `--v-progress-circular-color` and `--v-progress-circular-background-color` css variable.
|
||||
|
||||
```html
|
||||
<v-progress-circular/>
|
||||
<style>
|
||||
.v-progress-circular {
|
||||
--v-progress-circular-color: var(--red-100);
|
||||
--v-progress-circular-background-color: var(--red-600);
|
||||
}
|
||||
</style>
|
||||
```
|
||||
|
||||
|
||||
## Sizes
|
||||
|
||||
The circular progress component supports the following sizes through the use of props:
|
||||
|
||||
* x-small
|
||||
* small
|
||||
* (default)
|
||||
* large
|
||||
* x-large
|
||||
|
||||
```html
|
||||
<v-progress-circular x-small />
|
||||
<v-progress-circular small />
|
||||
<v-progress-circular />
|
||||
<v-progress-circular large />
|
||||
<v-progress-circular x-large />
|
||||
```
|
||||
|
||||
## Props
|
||||
| Prop | Description | Default |
|
||||
|----------------|-----------------------------------|-------------------------------------|
|
||||
| `value` | The percentage value | `0` |
|
||||
| `indeterminate`| Displays the loading animation | `false` |
|
||||
| `x-small` | Render extra small | `false` |
|
||||
| `small` | Render small | `false` |
|
||||
| `large` | Render large | `false` |
|
||||
| `x-large` | Render extra large | `false` |
|
||||
|
||||
## Slots
|
||||
| Slot | Description | Data |
|
||||
|-----------|--------------------------------------|------|
|
||||
| _default_ | Rendered in the center of the circle | -- |
|
||||
|
||||
## Events
|
||||
n/a
|
||||
|
||||
## CSS Variables
|
||||
| Variable | Default |
|
||||
|------------------------------------------|------------------------------------------|
|
||||
| `--v-progress-circular-color` | `var(--loading-background-color-accent)` |
|
||||
| `--v-progress-circular-background-color` | `var(--loading-background-color)` |
|
||||
| `--v-progress-circular-transition` | `400ms` |
|
||||
| `--v-progress-circular-speed` | `1s` |
|
||||
| `--v-progress-circular-size` | `28px` |
|
||||
| `--v-progress-circular-line-size` | `3px` |
|
||||
123
src/components/v-progress/circular/v-progress-circular.story.ts
Normal file
123
src/components/v-progress/circular/v-progress-circular.story.ts
Normal file
@@ -0,0 +1,123 @@
|
||||
import {
|
||||
withKnobs,
|
||||
color,
|
||||
optionsKnob as options,
|
||||
number,
|
||||
text,
|
||||
boolean
|
||||
} from '@storybook/addon-knobs';
|
||||
|
||||
import Vue from 'vue';
|
||||
import VProgressCircular from './v-progress-circular.vue';
|
||||
import markdown from './v-progress-circular.readme.md';
|
||||
import withPadding from '../../../../.storybook/decorators/with-padding';
|
||||
|
||||
Vue.component('v-progress-circular', VProgressCircular);
|
||||
|
||||
export default {
|
||||
title: 'Components / Progress (circular)',
|
||||
component: VProgressCircular,
|
||||
decorators: [withKnobs, withPadding],
|
||||
parameters: {
|
||||
notes: markdown
|
||||
}
|
||||
};
|
||||
|
||||
export const interactive = () => ({
|
||||
props: {
|
||||
value: {
|
||||
default: number('Value', 60)
|
||||
},
|
||||
indeterminate: {
|
||||
default: boolean('Indeterminate', false)
|
||||
},
|
||||
color: {
|
||||
default: color('Color', '#263238')
|
||||
},
|
||||
backgroundColor: {
|
||||
default: color('Background Color', '#cfd8dc')
|
||||
},
|
||||
size: {
|
||||
default: options(
|
||||
'Size',
|
||||
{
|
||||
'Extra Small': 'xSmall',
|
||||
Small: 'small',
|
||||
'(default)': 'default',
|
||||
Large: 'large',
|
||||
'Extra Large': 'xLarge'
|
||||
},
|
||||
'default',
|
||||
{
|
||||
display: 'select'
|
||||
}
|
||||
)
|
||||
},
|
||||
speed: {
|
||||
default: text('Speed (css, eg 200ms)', '2s')
|
||||
},
|
||||
customSize: {
|
||||
default: text('Size (in px)', '')
|
||||
},
|
||||
customLineSize: {
|
||||
default: text('Line Size (in px)', '')
|
||||
}
|
||||
},
|
||||
template: `
|
||||
<v-progress-circular
|
||||
:value="value"
|
||||
:indeterminate="indeterminate"
|
||||
:style="{
|
||||
'--v-progress-circular-color': color,
|
||||
'--v-progress-circular-background-color': backgroundColor,
|
||||
'--v-progress-circular-speed': speed,
|
||||
'--v-progress-circular-size': customSize,
|
||||
'--v-progress-circular-line-size': customLineSize
|
||||
}"
|
||||
:x-small="size === 'xSmall'"
|
||||
:small="size === 'small'"
|
||||
:large="size === 'large'"
|
||||
:x-large="size === 'xLarge'"
|
||||
/>`
|
||||
});
|
||||
|
||||
export const colors = () => `
|
||||
<div style="display: flex; justify-content: space-around">
|
||||
<v-progress-circular value="80" style="--v-progress-circular-color: var(--red)" />
|
||||
<v-progress-circular value="15" style="--v-progress-circular-color: var(--blue)" />
|
||||
<v-progress-circular indeterminate style="--v-progress-circular-color: var(--green)" />
|
||||
<v-progress-circular value="45" style="--v-progress-circular-color: var(--amber); --v-progress-circular-background-color: var(--red)" />
|
||||
<v-progress-circular value="65" style="--v-progress-circular-color: var(--purple)" />
|
||||
</div>
|
||||
`;
|
||||
|
||||
export const sizes = () => `
|
||||
<div style="display: flex; justify-content: space-around">
|
||||
<v-progress-circular value="45" x-small />
|
||||
<v-progress-circular value="45" small />
|
||||
<v-progress-circular value="45" />
|
||||
<v-progress-circular value="45" large />
|
||||
<v-progress-circular value="45" x-large />
|
||||
</div>
|
||||
`;
|
||||
|
||||
export const speed = () => `
|
||||
<div style="display: flex; justify-content: space-around">
|
||||
<v-progress-circular indeterminate style="--v-progress-circular-speed: 5s" />
|
||||
<v-progress-circular indeterminate style="--v-progress-circular-speed: 2.5s" />
|
||||
<v-progress-circular indeterminate />
|
||||
<v-progress-circular indeterminate style="--v-progress-circular-speed: 1.5s" />
|
||||
<v-progress-circular indeterminate style="--v-progress-circular-speed: 1.25s" />
|
||||
</div>
|
||||
`;
|
||||
|
||||
export const withSlot = () => `
|
||||
<div style="display: flex; gap: 20px;">
|
||||
<v-progress-circular value="60" large>
|
||||
60%
|
||||
</v-progress-circular>
|
||||
<v-progress-circular value="60" large>
|
||||
<v-icon name="add"/>
|
||||
</v-progress-circular>
|
||||
</div>
|
||||
`;
|
||||
@@ -0,0 +1,63 @@
|
||||
import { mount, createLocalVue, Wrapper } from '@vue/test-utils';
|
||||
import VueCompositionAPI from '@vue/composition-api';
|
||||
|
||||
const localVue = createLocalVue();
|
||||
localVue.use(VueCompositionAPI);
|
||||
|
||||
import VProgressCircular from './v-progress-circular.vue';
|
||||
|
||||
describe('Spinner', () => {
|
||||
let component: Wrapper<Vue>;
|
||||
|
||||
beforeEach(() => (component = mount(VProgressCircular, { localVue })));
|
||||
|
||||
it('Adds the correct classes based on props', async () => {
|
||||
component.setProps({
|
||||
indeterminate: true
|
||||
});
|
||||
await component.vm.$nextTick();
|
||||
expect(component.find('svg').classes()).toContain('indeterminate');
|
||||
});
|
||||
|
||||
it('Calculates the correct stroke-dasharray', async () => {
|
||||
component.setProps({
|
||||
value: 0
|
||||
});
|
||||
await component.vm.$nextTick();
|
||||
expect((component.vm as any).circleStyle).toEqual({
|
||||
'stroke-dasharray': '0, 78.5'
|
||||
});
|
||||
|
||||
component.setProps({
|
||||
value: 25
|
||||
});
|
||||
await component.vm.$nextTick();
|
||||
expect((component.vm as any).circleStyle).toEqual({
|
||||
'stroke-dasharray': '19.625, 78.5'
|
||||
});
|
||||
|
||||
component.setProps({
|
||||
value: 50
|
||||
});
|
||||
await component.vm.$nextTick();
|
||||
expect((component.vm as any).circleStyle).toEqual({
|
||||
'stroke-dasharray': '39.25, 78.5'
|
||||
});
|
||||
|
||||
component.setProps({
|
||||
value: 75
|
||||
});
|
||||
await component.vm.$nextTick();
|
||||
expect((component.vm as any).circleStyle).toEqual({
|
||||
'stroke-dasharray': '58.875, 78.5'
|
||||
});
|
||||
|
||||
component.setProps({
|
||||
value: 100
|
||||
});
|
||||
await component.vm.$nextTick();
|
||||
expect((component.vm as any).circleStyle).toEqual({
|
||||
'stroke-dasharray': '78.5, 78.5'
|
||||
});
|
||||
});
|
||||
});
|
||||
142
src/components/v-progress/circular/v-progress-circular.vue
Normal file
142
src/components/v-progress/circular/v-progress-circular.vue
Normal file
@@ -0,0 +1,142 @@
|
||||
<template>
|
||||
<div class="v-progress-circular" :class="sizeClass">
|
||||
<svg class="circle" viewBox="0 0 30 30" :class="{ indeterminate }">
|
||||
<path
|
||||
class="circle-background"
|
||||
d="M12.5,0A12.5,12.5,0,1,1,0,12.5,12.5,12.5,0,0,1,12.5,0Z"
|
||||
transform="translate(2.5 2.5)"
|
||||
/>
|
||||
<path
|
||||
class="circle-path"
|
||||
:style="circleStyle"
|
||||
d="M12.5,0A12.5,12.5,0,1,1,0,12.5,12.5,12.5,0,0,1,12.5,0Z"
|
||||
transform="translate(2.5 2.5)"
|
||||
/>
|
||||
</svg>
|
||||
<slot></slot>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import { createComponent, computed } from '@vue/composition-api';
|
||||
import parseCSSVar from '@/utils/parse-css-var';
|
||||
import useSizeClass, { sizeProps } from '@/compositions/size-class';
|
||||
|
||||
export default createComponent({
|
||||
props: {
|
||||
indeterminate: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
value: {
|
||||
type: Number,
|
||||
default: 0
|
||||
},
|
||||
...sizeProps
|
||||
},
|
||||
setup(props) {
|
||||
const sizeClass = useSizeClass(props);
|
||||
|
||||
const circleStyle = computed(() => ({
|
||||
'stroke-dasharray': (props.value / 100) * 78.5 + ', 78.5'
|
||||
}));
|
||||
|
||||
return { sizeClass, circleStyle };
|
||||
}
|
||||
});
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.v-progress-circular {
|
||||
--v-progress-circular-color: var(--input-foreground-color);
|
||||
--v-progress-circular-background-color: var(--input-border-color);
|
||||
--v-progress-circular-transition: 400ms;
|
||||
--v-progress-circular-speed: 2s;
|
||||
--v-progress-circular-size: 28px;
|
||||
--v-progress-circular-line-size: 3px;
|
||||
|
||||
position: relative;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
width: var(--v-progress-circular-size);
|
||||
height: var(--v-progress-circular-size);
|
||||
|
||||
&.x-small {
|
||||
--v-progress-circular-size: 12px;
|
||||
--v-progress-circular-line-size: 4px;
|
||||
}
|
||||
|
||||
&.small {
|
||||
--v-progress-circular-size: 16px;
|
||||
--v-progress-circular-line-size: 3px;
|
||||
}
|
||||
|
||||
&.large {
|
||||
--v-progress-circular-size: 48px;
|
||||
--v-progress-circular-line-size: 2.5px;
|
||||
}
|
||||
|
||||
&.x-large {
|
||||
--v-progress-circular-size: 64px;
|
||||
--v-progress-circular-line-size: 2px;
|
||||
}
|
||||
|
||||
.circle {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: var(--v-progress-circular-size);
|
||||
height: var(--v-progress-circular-size);
|
||||
|
||||
&-path {
|
||||
transition: stroke-dasharray var(--v-progress-circular-transition) ease-in-out;
|
||||
fill: transparent;
|
||||
stroke: var(--v-progress-circular-color);
|
||||
stroke-width: var(--v-progress-circular-line-size);
|
||||
}
|
||||
|
||||
&.indeterminate {
|
||||
animation: rotate var(--v-progress-circular-speed) infinite linear;
|
||||
|
||||
.circle-path {
|
||||
animation: stroke var(--v-progress-circular-speed) infinite linear;
|
||||
}
|
||||
}
|
||||
|
||||
&-background {
|
||||
fill: transparent;
|
||||
stroke: var(--v-progress-circular-background-color);
|
||||
stroke-width: var(--v-progress-circular-line-size);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes rotate {
|
||||
0% {
|
||||
transform: rotate(0deg);
|
||||
}
|
||||
|
||||
50% {
|
||||
transform: rotate(360deg);
|
||||
}
|
||||
|
||||
100% {
|
||||
transform: rotate(1080deg);
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes stroke {
|
||||
0% {
|
||||
stroke-dasharray: 0, 78.5px;
|
||||
}
|
||||
|
||||
50% {
|
||||
stroke-dasharray: 78.5px, 78.5px;
|
||||
}
|
||||
|
||||
100% {
|
||||
stroke-dasharray: 0, 78.5px;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -64,6 +64,7 @@ export default createComponent({
|
||||
--v-progress-linear-height: 4px;
|
||||
--v-progress-linear-color: var(--input-foreground-color);
|
||||
--v-progress-linear-background-color: var(--input-border-color);
|
||||
--v-progress-linear-transition: 400ms;
|
||||
|
||||
position: relative;
|
||||
display: flex;
|
||||
@@ -80,6 +81,7 @@ export default createComponent({
|
||||
left: 0;
|
||||
height: 100%;
|
||||
background-color: var(--v-progress-linear-color);
|
||||
transition: width var(--v-progress-linear-transition) ease-in-out;
|
||||
}
|
||||
|
||||
&.absolute {
|
||||
|
||||
@@ -1,4 +0,0 @@
|
||||
import VSpinner from './v-spinner.vue';
|
||||
|
||||
export { VSpinner };
|
||||
export default VSpinner;
|
||||
@@ -1,67 +0,0 @@
|
||||
# Spinner
|
||||
|
||||
```html
|
||||
<v-spinner />
|
||||
```
|
||||
|
||||
## Colors
|
||||
|
||||
The color of the spinner can be changed through the `--v-spinner-color` and `--v-spinner-background-color` css variable.
|
||||
|
||||
```html
|
||||
<v-spinner style="--v-spinner-color: var(--red-400); --v-spinner-background-color: transparent;" />
|
||||
```
|
||||
|
||||
The background color can be set in similar fashion:
|
||||
|
||||
```html
|
||||
<v-spinner/>
|
||||
<style>
|
||||
.v-spinner {
|
||||
--v-spinner-color: var(--red-100);
|
||||
--v-spinner-background-color: var(--red-600);
|
||||
}
|
||||
</style>
|
||||
```
|
||||
|
||||
|
||||
## Sizes
|
||||
|
||||
The spinner component supports the following sizes through the use of props:
|
||||
|
||||
* x-small
|
||||
* small
|
||||
* (default)
|
||||
* large
|
||||
* x-large
|
||||
|
||||
```html
|
||||
<v-spinner x-small />
|
||||
<v-spinner small />
|
||||
<v-spinner />
|
||||
<v-spinner large />
|
||||
<v-spinner x-large />
|
||||
```
|
||||
|
||||
## Props
|
||||
| Prop | Description | Default |
|
||||
|-------------|-----------------------------------|-------------------------------------|
|
||||
| `x-small` | Render extra small | `false` |
|
||||
| `small` | Render small | `false` |
|
||||
| `large` | Render large | `false` |
|
||||
| `x-large` | Render extra large | `false` |
|
||||
|
||||
## Slots
|
||||
n/a
|
||||
|
||||
## Events
|
||||
n/a
|
||||
|
||||
## CSS Variables
|
||||
| Variable | Default |
|
||||
|--------------------------------|-------------------------------|
|
||||
| `--v-spinner-color` | `var(--foreground-color)` |
|
||||
| `--v-spinner-background-color` | `var(--background-color-alt)` |
|
||||
| `--v-spinner-speed` | `1s` |
|
||||
| `--v-spinner-size` | `28px` |
|
||||
| `--v-spinner-line-size` | `3px` |
|
||||
@@ -1,97 +0,0 @@
|
||||
import { withKnobs, color, optionsKnob as options, number, text } from '@storybook/addon-knobs';
|
||||
|
||||
import Vue from 'vue';
|
||||
import VSpinner from './v-spinner.vue';
|
||||
import markdown from './v-spinner.readme.md';
|
||||
import withPadding from '../../../.storybook/decorators/with-padding';
|
||||
|
||||
Vue.component('v-spinner', VSpinner);
|
||||
|
||||
export default {
|
||||
title: 'Components / Spinner',
|
||||
component: VSpinner,
|
||||
decorators: [withKnobs, withPadding],
|
||||
parameters: {
|
||||
notes: markdown
|
||||
}
|
||||
};
|
||||
|
||||
export const interactive = () => ({
|
||||
props: {
|
||||
color: {
|
||||
default: color('Color', '#263238')
|
||||
},
|
||||
backgroundColor: {
|
||||
default: color('Background Color', '#cfd8dc')
|
||||
},
|
||||
size: {
|
||||
default: options(
|
||||
'Size',
|
||||
{
|
||||
'Extra Small': 'xSmall',
|
||||
Small: 'small',
|
||||
'(default)': 'default',
|
||||
Large: 'large',
|
||||
'Extra Large': 'xLarge'
|
||||
},
|
||||
'default',
|
||||
{
|
||||
display: 'select'
|
||||
}
|
||||
)
|
||||
},
|
||||
speed: {
|
||||
default: text('Speed (css, eg 200ms)', '1s')
|
||||
},
|
||||
customSize: {
|
||||
default: text('Size (in px)', '28px')
|
||||
},
|
||||
customLineSize: {
|
||||
default: text('Line Size (in px)', '3px')
|
||||
}
|
||||
},
|
||||
template: `
|
||||
<v-spinner
|
||||
:style="{
|
||||
'--v-spinner-color': color,
|
||||
'--v-spinner-background-color': backgroundColor,
|
||||
'--v-spinner-speed': speed,
|
||||
'--v-spinner-size': customSize,
|
||||
'--v-spinner-line-size': customLineSize
|
||||
}"
|
||||
:x-small="size === 'xSmall'"
|
||||
:small="size === 'small'"
|
||||
:large="size === 'large'"
|
||||
:x-large="size === 'xLarge'"
|
||||
/>`
|
||||
});
|
||||
|
||||
export const colors = () => `
|
||||
<div style="display: flex; justify-content: space-around">
|
||||
<v-spinner style="--v-spinner-color: var(--red)" />
|
||||
<v-spinner style="--v-spinner-color: transparent; --v-spinner-background-color: var(--blue)" />
|
||||
<v-spinner style="--v-spinner-color: var(--green)" />
|
||||
<v-spinner style="--v-spinner-color: var(--amber); --v-spinner-background-color: var(--red)" />
|
||||
<v-spinner style="--v-spinner-color: var(--purple)" />
|
||||
</div>
|
||||
`;
|
||||
|
||||
export const sizes = () => `
|
||||
<div style="display: flex; justify-content: space-around">
|
||||
<v-spinner x-small />
|
||||
<v-spinner small />
|
||||
<v-spinner />
|
||||
<v-spinner large />
|
||||
<v-spinner x-large />
|
||||
</div>
|
||||
`;
|
||||
|
||||
export const speed = () => `
|
||||
<div style="display: flex; justify-content: space-around">
|
||||
<v-spinner style="--v-spinner-speed: 5s" />
|
||||
<v-spinner style="--v-spinner-speed: 2.5s" />
|
||||
<v-spinner />
|
||||
<v-spinner style="--v-spinner-speed: 500ms" />
|
||||
<v-spinner style="--v-spinner-speed: 250ms" />
|
||||
</div>
|
||||
`;
|
||||
@@ -1,17 +0,0 @@
|
||||
import { mount, createLocalVue, Wrapper } from '@vue/test-utils';
|
||||
import VueCompositionAPI from '@vue/composition-api';
|
||||
|
||||
const localVue = createLocalVue();
|
||||
localVue.use(VueCompositionAPI);
|
||||
|
||||
import VSpinner from './v-spinner.vue';
|
||||
|
||||
describe('Spinner', () => {
|
||||
let component: Wrapper<Vue>;
|
||||
|
||||
beforeEach(() => (component = mount(VSpinner, { localVue })));
|
||||
|
||||
it('Renders', () => {
|
||||
expect(component.exists()).toBe(true);
|
||||
});
|
||||
});
|
||||
@@ -1,66 +0,0 @@
|
||||
<template>
|
||||
<div class="v-spinner" :class="sizeClass"></div>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import { createComponent, computed } from '@vue/composition-api';
|
||||
import parseCSSVar from '@/utils/parse-css-var';
|
||||
import useSizeClass, { sizeProps } from '@/compositions/size-class';
|
||||
|
||||
export default createComponent({
|
||||
props: sizeProps,
|
||||
setup(props) {
|
||||
const sizeClass = useSizeClass(props);
|
||||
return { sizeClass };
|
||||
}
|
||||
});
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.v-spinner {
|
||||
--v-spinner-color: var(--foreground-color);
|
||||
--v-spinner-background-color: var(--background-color-alt);
|
||||
--v-spinner-speed: 1s;
|
||||
--v-spinner-size: 28px;
|
||||
--v-spinner-line-size: 3px;
|
||||
|
||||
position: relative;
|
||||
width: var(--v-spinner-size);
|
||||
height: var(--v-spinner-size);
|
||||
background-color: transparent;
|
||||
border: var(--v-spinner-line-size) solid var(--v-spinner-background-color);
|
||||
border-top: var(--v-spinner-line-size) solid var(--v-spinner-color);
|
||||
border-radius: 100%;
|
||||
animation: rotate var(--v-spinner-speed) infinite linear;
|
||||
|
||||
&.x-small {
|
||||
--v-spinner-size: 12px;
|
||||
--v-spinner-line-size: 2px;
|
||||
}
|
||||
|
||||
&.small {
|
||||
--v-spinner-size: 16px;
|
||||
--v-spinner-line-size: 3px;
|
||||
}
|
||||
|
||||
&.large {
|
||||
--v-spinner-size: 48px;
|
||||
--v-spinner-line-size: 4px;
|
||||
}
|
||||
|
||||
&.x-large {
|
||||
--v-spinner-size: 64px;
|
||||
--v-spinner-line-size: 5px;
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes rotate {
|
||||
from {
|
||||
transform: rotate(0deg);
|
||||
}
|
||||
|
||||
to {
|
||||
transform: rotate(360deg);
|
||||
}
|
||||
}
|
||||
</style>
|
||||
Reference in New Issue
Block a user