diff --git a/.gitignore b/.gitignore
index 4a107b156c..0e8028e1e4 100644
--- a/.gitignore
+++ b/.gitignore
@@ -3,6 +3,7 @@ node_modules
/dist
storybook-static
coverage
+package-lock.json
# local env files
.env.local
diff --git a/src/components/register.ts b/src/components/register.ts
index a0449afa45..fcf97839fa 100644
--- a/src/components/register.ts
+++ b/src/components/register.ts
@@ -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);
diff --git a/src/components/v-button/v-button.test.ts b/src/components/v-button/v-button.test.ts
index 7247951dc4..becc194bec 100644
--- a/src/components/v-button/v-button.test.ts
+++ b/src/components/v-button/v-button.test.ts
@@ -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', () => {
diff --git a/src/components/v-button/v-button.vue b/src/components/v-button/v-button.vue
index 061d9b85e1..f78bb5ad2b 100644
--- a/src/components/v-button/v-button.vue
+++ b/src/components/v-button/v-button.vue
@@ -9,7 +9,7 @@
-
+
@@ -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;
+ }
}
}
diff --git a/src/components/v-progress/circular/index.ts b/src/components/v-progress/circular/index.ts
new file mode 100644
index 0000000000..05cdb5a79e
--- /dev/null
+++ b/src/components/v-progress/circular/index.ts
@@ -0,0 +1,4 @@
+import VProgressCircular from './v-progress-circular.vue';
+
+export { VProgressCircular };
+export default VProgressCircular;
diff --git a/src/components/v-progress/circular/v-progress-circular.readme.md b/src/components/v-progress/circular/v-progress-circular.readme.md
new file mode 100644
index 0000000000..5efb8a20bf
--- /dev/null
+++ b/src/components/v-progress/circular/v-progress-circular.readme.md
@@ -0,0 +1,66 @@
+# Progress (circular)
+
+```html
+
+```
+
+## 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
+
+
+```
+
+
+## Sizes
+
+The circular progress component supports the following sizes through the use of props:
+
+* x-small
+* small
+* (default)
+* large
+* x-large
+
+```html
+
+
+
+
+
+```
+
+## 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` |
diff --git a/src/components/v-progress/circular/v-progress-circular.story.ts b/src/components/v-progress/circular/v-progress-circular.story.ts
new file mode 100644
index 0000000000..5069b99569
--- /dev/null
+++ b/src/components/v-progress/circular/v-progress-circular.story.ts
@@ -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: `
+ `
+});
+
+export const colors = () => `
+
+
+
+
+
+
+
+`;
+
+export const sizes = () => `
+
+
+
+
+
+
+
+`;
+
+export const speed = () => `
+
+
+
+
+
+
+
+`;
+
+export const withSlot = () => `
+
+
+ 60%
+
+
+
+
+
+`;
diff --git a/src/components/v-progress/circular/v-progress-circular.test.ts b/src/components/v-progress/circular/v-progress-circular.test.ts
new file mode 100644
index 0000000000..b7f3f883bc
--- /dev/null
+++ b/src/components/v-progress/circular/v-progress-circular.test.ts
@@ -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;
+
+ 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'
+ });
+ });
+});
diff --git a/src/components/v-progress/circular/v-progress-circular.vue b/src/components/v-progress/circular/v-progress-circular.vue
new file mode 100644
index 0000000000..cbd24c6aa7
--- /dev/null
+++ b/src/components/v-progress/circular/v-progress-circular.vue
@@ -0,0 +1,142 @@
+
+
+
+
+
+
+
diff --git a/src/components/v-progress/linear/v-progress.linear.story.ts b/src/components/v-progress/linear/v-progress-linear.story.ts
similarity index 100%
rename from src/components/v-progress/linear/v-progress.linear.story.ts
rename to src/components/v-progress/linear/v-progress-linear.story.ts
diff --git a/src/components/v-progress/linear/v-progress-linear.vue b/src/components/v-progress/linear/v-progress-linear.vue
index cb46357701..baac237695 100644
--- a/src/components/v-progress/linear/v-progress-linear.vue
+++ b/src/components/v-progress/linear/v-progress-linear.vue
@@ -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 {
diff --git a/src/components/v-spinner/index.ts b/src/components/v-spinner/index.ts
deleted file mode 100644
index d87fa3d1e9..0000000000
--- a/src/components/v-spinner/index.ts
+++ /dev/null
@@ -1,4 +0,0 @@
-import VSpinner from './v-spinner.vue';
-
-export { VSpinner };
-export default VSpinner;
diff --git a/src/components/v-spinner/v-spinner.readme.md b/src/components/v-spinner/v-spinner.readme.md
deleted file mode 100644
index 290bfd6985..0000000000
--- a/src/components/v-spinner/v-spinner.readme.md
+++ /dev/null
@@ -1,67 +0,0 @@
-# Spinner
-
-```html
-
-```
-
-## Colors
-
-The color of the spinner can be changed through the `--v-spinner-color` and `--v-spinner-background-color` css variable.
-
-```html
-
-```
-
-The background color can be set in similar fashion:
-
-```html
-
-
-```
-
-
-## Sizes
-
-The spinner component supports the following sizes through the use of props:
-
-* x-small
-* small
-* (default)
-* large
-* x-large
-
-```html
-
-
-
-
-
-```
-
-## 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` |
diff --git a/src/components/v-spinner/v-spinner.story.ts b/src/components/v-spinner/v-spinner.story.ts
deleted file mode 100644
index 2a4bc68305..0000000000
--- a/src/components/v-spinner/v-spinner.story.ts
+++ /dev/null
@@ -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: `
- `
-});
-
-export const colors = () => `
-
-
-
-
-
-
-
-`;
-
-export const sizes = () => `
-
-
-
-
-
-
-
-`;
-
-export const speed = () => `
-
-
-
-
-
-
-
-`;
diff --git a/src/components/v-spinner/v-spinner.test.ts b/src/components/v-spinner/v-spinner.test.ts
deleted file mode 100644
index e10d3f5176..0000000000
--- a/src/components/v-spinner/v-spinner.test.ts
+++ /dev/null
@@ -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;
-
- beforeEach(() => (component = mount(VSpinner, { localVue })));
-
- it('Renders', () => {
- expect(component.exists()).toBe(true);
- });
-});
diff --git a/src/components/v-spinner/v-spinner.vue b/src/components/v-spinner/v-spinner.vue
deleted file mode 100644
index f9d7f88c8e..0000000000
--- a/src/components/v-spinner/v-spinner.vue
+++ /dev/null
@@ -1,66 +0,0 @@
-
-
-
-
-
-
-