diff --git a/README.md b/README.md
index cad5385..07a6e73 100644
--- a/README.md
+++ b/README.md
@@ -20,12 +20,18 @@ This is a Vue port for [react-content-loader](https://github.com/danilowoz/react
## Install
-Note: For Vue 2, use `vue-content-loader@^0.2` instead.
+⚠️ For Vue 2, use `vue-content-loader@^0.2` instead.
+
+With npm:
+
+```bash
+npm i vue-content-loader
+```
+
+Or with yarn:
```bash
yarn add vue-content-loader
-# For Vue 2
-# yarn add vue-content-loader@^0.2
```
CDN: [UNPKG](https://unpkg.com/vue-content-loader/) | [jsDelivr](https://cdn.jsdelivr.net/npm/vue-content-loader/) (available as `window.contentLoaders`)
@@ -66,7 +72,7 @@ import {
`ContentLoader` is a meta loader while other loaders are just higher-order components of it. By default `ContentLoader` only displays a simple rectangle, here's how you can use it to create custom loaders:
```vue
-
+
@@ -84,19 +90,42 @@ You can also use the [online tool](http://danilowoz.com/create-vue-content-loade
### Props
-| Prop | Type | Default | Description |
-| ------------------- | ------- | ----------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
-| width | number | `400` | |
-| height | number | `130` | |
-| speed | number | `2` | |
-| preserveAspectRatio | string | `'xMidYMid meet'` | |
-| primaryColor | string | `'#f9f9f9'` | |
-| secondaryColor | string | `'#ecebeb'` | |
-| uniqueKey | string | `randomId()` | Unique ID, you need to make it consistent for SSR |
-| animate | boolean | `true` | |
-| baseUrl | string | empty string | Required if you're using `` in your ``. Defaults to an empty string. This prop is common used as: `` which will fill the SVG attribute with the relative path. Related [#14](https://github.com/egoist/vue-content-loader/issues/14). |
-| primaryOpacity | number | `1` | Background opacity (0 = transparent, 1 = opaque) used to solve an issue in Safari |
-| secondaryOpacity | number | `1` | Background opacity (0 = transparent, 1 = opaque) used to solve an issue in Safari |
+| Prop | Type | Default | Description |
+| ------------------- | -------------- | ---------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
+| width | number, string | | SVG width in pixels without unit |
+| height | number, string | | SVG height in pixels without unit |
+| viewBox | string | `'0 0 ${width || 400} ${height || 130}'` | See [SVG viewBox](https://developer.mozilla.org/en-US/docs/Web/SVG/Attribute/viewBox) attribute |
+| preserveAspectRatio | string | `'xMidYMid meet'` | See [SVG preserveAspectRatio](https://developer.mozilla.org/en-US/docs/Web/SVG/Attribute/preserveAspectRatio) attribute |
+| speed | number | `2` | Animation speed |
+| primaryColor | string | `'#f9f9f9'` | Background color |
+| secondaryColor | string | `'#ecebeb'` | Highlight color |
+| uniqueKey | string | `randomId()` | Unique ID, you need to make it consistent for SSR |
+| animate | boolean | `true` | |
+| baseUrl | string | empty string | Required if you're using `` in your ``. Defaults to an empty string. This prop is common used as: `` which will fill the SVG attribute with the relative path. Related [#14](https://github.com/egoist/vue-content-loader/issues/14). |
+| primaryOpacity | number | `1` | Background opacity (0 = transparent, 1 = opaque) used to solve an issue in Safari |
+| secondaryOpacity | number | `1` | Background opacity (0 = transparent, 1 = opaque) used to solve an issue in Safari |
+
+## Examples
+
+### Responsiveness
+
+To create a responsive loader that will follow its parent container width, use only the `viewBox` attribute to set the ratio:
+
+```vue
+
+
+
+```
+
+To create a loader with fixed dimensions, use `width` and `height` attributes:
+
+```vue
+
+
+
+```
+
+Note: the exact behavior might be different depending on the CSS you apply to SVG elements.
## Credits
diff --git a/bili.config.js b/bili.config.js
index fe810a8..3269627 100644
--- a/bili.config.js
+++ b/bili.config.js
@@ -1,6 +1,7 @@
/** @type {import('bili').Config} */
module.exports = {
externals: ['vue'],
+ input: 'src/index.ts',
output: {
format: ['cjs', 'es', 'umd', 'umd-min'],
fileName: 'vue-content-loader.[format][min][ext]',
diff --git a/package.json b/package.json
index 98b4951..533ec04 100644
--- a/package.json
+++ b/package.json
@@ -14,6 +14,7 @@
"files": [
"dist"
],
+ "types": "dist/index.d.ts",
"sideEffects": false,
"scripts": {
"prepublishOnly": "npm run build",
@@ -39,6 +40,8 @@
"bili": "^5.0.5",
"jest": "^26.6.3",
"poi": "12.10.3",
+ "rollup-plugin-typescript2": "^0.29.0",
+ "typescript": "^4.1.3",
"vue": "^3.0.5",
"vue-loader": "^16.1.2",
"vue-router": "^4.0.3"
diff --git a/src/BulletListLoader.js b/src/BulletListLoader.tsx
similarity index 81%
rename from src/BulletListLoader.js
rename to src/BulletListLoader.tsx
index 6474f88..7bf10dd 100644
--- a/src/BulletListLoader.js
+++ b/src/BulletListLoader.tsx
@@ -1,7 +1,8 @@
+import { defineComponent } from 'vue'
import ContentLoader from './ContentLoader'
-const BulletListLoader = (props, { attrs }) => {
- return (
+const BulletListLoader = defineComponent((props, { attrs }) => {
+ return () => (
@@ -13,6 +14,6 @@ const BulletListLoader = (props, { attrs }) => {
)
-}
+})
export default BulletListLoader
diff --git a/src/CodeLoader.js b/src/CodeLoader.tsx
similarity index 86%
rename from src/CodeLoader.js
rename to src/CodeLoader.tsx
index 6baae3a..164ddf8 100644
--- a/src/CodeLoader.js
+++ b/src/CodeLoader.tsx
@@ -1,7 +1,8 @@
+import { defineComponent } from 'vue'
import ContentLoader from './ContentLoader'
-const CodeLoader = (props, { attrs }) => {
- return (
+const CodeLoader = defineComponent((props, { attrs }) => {
+ return () => (
@@ -17,6 +18,6 @@ const CodeLoader = (props, { attrs }) => {
)
-}
+})
export default CodeLoader
diff --git a/src/ContentLoader.spec.js b/src/ContentLoader.spec.js
index d8ea7db..bdb63c7 100644
--- a/src/ContentLoader.spec.js
+++ b/src/ContentLoader.spec.js
@@ -5,8 +5,8 @@ describe('ContentLoader', () => {
it('has default values for props', () => {
const wrapper = mount(ContentLoader)
- expect(wrapper.vm.width).toBe(400)
- expect(wrapper.vm.height).toBe(130)
+ expect(wrapper.vm.width).toBe(undefined)
+ expect(wrapper.vm.height).toBe(undefined)
expect(wrapper.vm.speed).toBe(2)
expect(wrapper.vm.preserveAspectRatio).toBe('xMidYMid meet')
expect(wrapper.vm.baseUrl).toBe('')
@@ -14,6 +14,7 @@ describe('ContentLoader', () => {
expect(wrapper.vm.secondaryColor).toBe('#ecebeb')
expect(wrapper.vm.primaryOpacity).toBe(1)
expect(wrapper.vm.secondaryOpacity).toBe(1)
+ expect(wrapper.vm.uniqueKey).toBe(undefined)
expect(wrapper.vm.animate).toBe(true)
})
@@ -27,6 +28,8 @@ describe('ContentLoader', () => {
})
expect(wrapper.find('svg').attributes()).toEqual({
+ width: '300',
+ height: '200',
preserveAspectRatio: 'xMaxYMid slice',
version: '1.1',
viewBox: '0 0 300 200'
@@ -43,6 +46,8 @@ describe('ContentLoader', () => {
})
expect(wrapper.find('svg').attributes()).toEqual({
+ width: '300',
+ height: '200',
preserveAspectRatio: 'xMaxYMid slice',
version: '1.1',
viewBox: '0 0 300 200'
@@ -57,8 +62,8 @@ describe('ContentLoader', () => {
'clip-path': `url(#${wrapper.vm.idClip})`,
x: '0',
y: '0',
- width: '400',
- height: '130'
+ width: '100%',
+ height: '100%'
})
})
@@ -143,8 +148,8 @@ describe('ContentLoader', () => {
y: '0',
rx: '5',
ry: '5',
- width: '400',
- height: '130'
+ width: '100%',
+ height: '100%'
})
})
diff --git a/src/ContentLoader.js b/src/ContentLoader.tsx
similarity index 85%
rename from src/ContentLoader.js
rename to src/ContentLoader.tsx
index 9c01de1..e594922 100644
--- a/src/ContentLoader.js
+++ b/src/ContentLoader.tsx
@@ -6,21 +6,22 @@ export default defineComponent({
props: {
width: {
- type: [Number, String],
- default: 400
+ type: [Number, String]
},
height: {
- type: [Number, String],
- default: 130
+ type: [Number, String]
},
- speed: {
- type: Number,
- default: 2
+ viewBox: {
+ type: String
},
preserveAspectRatio: {
type: String,
default: 'xMidYMid meet'
},
+ speed: {
+ type: Number,
+ default: 2
+ },
baseUrl: {
type: String,
default: ''
@@ -53,17 +54,23 @@ export default defineComponent({
setup(props) {
const idClip = props.uniqueKey ? `${props.uniqueKey}-idClip` : uid()
const idGradient = props.uniqueKey ? `${props.uniqueKey}-idGradient` : uid()
+ const width = props.width ?? 400
+ const height = props.height ?? 130
+ const computedViewBox = props.viewBox ?? `0 0 ${width} ${height}`
return {
idClip,
- idGradient
+ idGradient,
+ computedViewBox
}
},
render() {
return (