| 
 | 1 | +import { defineComponent } from 'vue'  | 
1 | 2 | import uid from './uid'  | 
2 | 3 | 
 
  | 
3 |  | -const ContentLoader = (props, { attrs, slots }) => {  | 
4 |  | -  const idClip = props.uniqueKey ? `${props.uniqueKey}-idClip` : uid()  | 
5 |  | -  const idGradient = props.uniqueKey ? `${props.uniqueKey}-idGradient` : uid()  | 
 | 4 | +export default defineComponent({  | 
 | 5 | +  name: 'ContentLoader',  | 
6 | 6 | 
 
  | 
7 |  | -  return (  | 
8 |  | -    <svg  | 
9 |  | -      {...attrs}  | 
10 |  | -      viewBox={`0 0 ${props.width} ${props.height}`}  | 
11 |  | -      version="1.1"  | 
12 |  | -      preserveAspectRatio={props.preserveAspectRatio}  | 
13 |  | -    >  | 
14 |  | -      <rect  | 
15 |  | -        style={{ fill: `url(${props.baseUrl}#${idGradient})` }}  | 
16 |  | -        clip-path={`url(${props.baseUrl}#${idClip})`}  | 
17 |  | -        x="0"  | 
18 |  | -        y="0"  | 
19 |  | -        width={props.width}  | 
20 |  | -        height={props.height}  | 
21 |  | -      />  | 
 | 7 | +  props: {  | 
 | 8 | +    width: {  | 
 | 9 | +      type: [Number, String],  | 
 | 10 | +      default: 400  | 
 | 11 | +    },  | 
 | 12 | +    height: {  | 
 | 13 | +      type: [Number, String],  | 
 | 14 | +      default: 130  | 
 | 15 | +    },  | 
 | 16 | +    speed: {  | 
 | 17 | +      type: Number,  | 
 | 18 | +      default: 2  | 
 | 19 | +    },  | 
 | 20 | +    preserveAspectRatio: {  | 
 | 21 | +      type: String,  | 
 | 22 | +      default: 'xMidYMid meet'  | 
 | 23 | +    },  | 
 | 24 | +    baseUrl: {  | 
 | 25 | +      type: String,  | 
 | 26 | +      default: ''  | 
 | 27 | +    },  | 
 | 28 | +    primaryColor: {  | 
 | 29 | +      type: String,  | 
 | 30 | +      default: '#f9f9f9'  | 
 | 31 | +    },  | 
 | 32 | +    secondaryColor: {  | 
 | 33 | +      type: String,  | 
 | 34 | +      default: '#ecebeb'  | 
 | 35 | +    },  | 
 | 36 | +    primaryOpacity: {  | 
 | 37 | +      type: Number,  | 
 | 38 | +      default: 1  | 
 | 39 | +    },  | 
 | 40 | +    secondaryOpacity: {  | 
 | 41 | +      type: Number,  | 
 | 42 | +      default: 1  | 
 | 43 | +    },  | 
 | 44 | +    uniqueKey: {  | 
 | 45 | +      type: String  | 
 | 46 | +    },  | 
 | 47 | +    animate: {  | 
 | 48 | +      type: Boolean,  | 
 | 49 | +      default: true  | 
 | 50 | +    }  | 
 | 51 | +  },  | 
22 | 52 | 
 
  | 
23 |  | -      <defs>  | 
24 |  | -        <clipPath id={idClip}>  | 
25 |  | -          {slots.default ? (  | 
26 |  | -            slots.default()  | 
27 |  | -          ) : (  | 
28 |  | -            <rect  | 
29 |  | -              x="0"  | 
30 |  | -              y="0"  | 
31 |  | -              rx="5"  | 
32 |  | -              ry="5"  | 
33 |  | -              width={props.width}  | 
34 |  | -              height={props.height}  | 
35 |  | -            />  | 
36 |  | -          )}  | 
37 |  | -        </clipPath>  | 
 | 53 | +  setup(props) {  | 
 | 54 | +    const idClip = props.uniqueKey ? `${props.uniqueKey}-idClip` : uid()  | 
 | 55 | +    const idGradient = props.uniqueKey ? `${props.uniqueKey}-idGradient` : uid()  | 
38 | 56 | 
 
  | 
39 |  | -        <linearGradient id={idGradient}>  | 
40 |  | -          <stop  | 
41 |  | -            offset="0%"  | 
42 |  | -            stop-color={props.primaryColor}  | 
43 |  | -            stop-opacity={props.primaryOpacity}  | 
44 |  | -          >  | 
45 |  | -            {props.animate ? (  | 
46 |  | -              <animate  | 
47 |  | -                attributeName="offset"  | 
48 |  | -                values="-2; 1"  | 
49 |  | -                dur={`${props.speed}s`}  | 
50 |  | -                repeatCount="indefinite"  | 
51 |  | -              />  | 
52 |  | -            ) : null}  | 
53 |  | -          </stop>  | 
54 |  | -          <stop  | 
55 |  | -            offset="50%"  | 
56 |  | -            stop-color={props.secondaryColor}  | 
57 |  | -            stop-opacity={props.secondaryOpacity}  | 
58 |  | -          >  | 
59 |  | -            {props.animate ? (  | 
60 |  | -              <animate  | 
61 |  | -                attributeName="offset"  | 
62 |  | -                values="-1.5; 1.5"  | 
63 |  | -                dur={`${props.speed}s`}  | 
64 |  | -                repeatCount="indefinite"  | 
65 |  | -              />  | 
66 |  | -            ) : null}  | 
67 |  | -          </stop>  | 
68 |  | -          <stop  | 
69 |  | -            offset="100%"  | 
70 |  | -            stop-color={props.primaryColor}  | 
71 |  | -            stop-opacity={props.primaryOpacity}  | 
72 |  | -          >  | 
73 |  | -            {props.animate ? (  | 
74 |  | -              <animate  | 
75 |  | -                attributeName="offset"  | 
76 |  | -                values="-1; 2"  | 
77 |  | -                dur={`${props.speed}s`}  | 
78 |  | -                repeatCount="indefinite"  | 
 | 57 | +    return {  | 
 | 58 | +      idClip,  | 
 | 59 | +      idGradient  | 
 | 60 | +    }  | 
 | 61 | +  },  | 
 | 62 | + | 
 | 63 | +  render() {  | 
 | 64 | +    return (  | 
 | 65 | +      <svg  | 
 | 66 | +        viewBox={`0 0 ${this.width} ${this.height}`}  | 
 | 67 | +        version="1.1"  | 
 | 68 | +        preserveAspectRatio={this.preserveAspectRatio}  | 
 | 69 | +      >  | 
 | 70 | +        <rect  | 
 | 71 | +          style={{ fill: `url(${this.baseUrl}#${this.idGradient})` }}  | 
 | 72 | +          clip-path={`url(${this.baseUrl}#${this.idClip})`}  | 
 | 73 | +          x="0"  | 
 | 74 | +          y="0"  | 
 | 75 | +          width={this.width}  | 
 | 76 | +          height={this.height}  | 
 | 77 | +        />  | 
 | 78 | + | 
 | 79 | +        <defs>  | 
 | 80 | +          <clipPath id={this.idClip}>  | 
 | 81 | +            {this.$slots.default ? (  | 
 | 82 | +              this.$slots.default()  | 
 | 83 | +            ) : (  | 
 | 84 | +              <rect  | 
 | 85 | +                x="0"  | 
 | 86 | +                y="0"  | 
 | 87 | +                rx="5"  | 
 | 88 | +                ry="5"  | 
 | 89 | +                width={this.width}  | 
 | 90 | +                height={this.height}  | 
79 | 91 |               />  | 
80 |  | -            ) : null}  | 
81 |  | -          </stop>  | 
82 |  | -        </linearGradient>  | 
83 |  | -      </defs>  | 
84 |  | -    </svg>  | 
85 |  | -  )  | 
86 |  | -}  | 
 | 92 | +            )}  | 
 | 93 | +          </clipPath>  | 
87 | 94 | 
 
  | 
88 |  | -ContentLoader.props = {  | 
89 |  | -  width: {  | 
90 |  | -    type: [Number, String],  | 
91 |  | -    default: 400  | 
92 |  | -  },  | 
93 |  | -  height: {  | 
94 |  | -    type: [Number, String],  | 
95 |  | -    default: 130  | 
96 |  | -  },  | 
97 |  | -  speed: {  | 
98 |  | -    type: Number,  | 
99 |  | -    default: 2  | 
100 |  | -  },  | 
101 |  | -  preserveAspectRatio: {  | 
102 |  | -    type: String,  | 
103 |  | -    default: 'xMidYMid meet'  | 
104 |  | -  },  | 
105 |  | -  baseUrl: {  | 
106 |  | -    type: String,  | 
107 |  | -    default: ''  | 
108 |  | -  },  | 
109 |  | -  primaryColor: {  | 
110 |  | -    type: String,  | 
111 |  | -    default: '#f9f9f9'  | 
112 |  | -  },  | 
113 |  | -  secondaryColor: {  | 
114 |  | -    type: String,  | 
115 |  | -    default: '#ecebeb'  | 
116 |  | -  },  | 
117 |  | -  primaryOpacity: {  | 
118 |  | -    type: Number,  | 
119 |  | -    default: 1  | 
120 |  | -  },  | 
121 |  | -  secondaryOpacity: {  | 
122 |  | -    type: Number,  | 
123 |  | -    default: 1  | 
124 |  | -  },  | 
125 |  | -  uniqueKey: {  | 
126 |  | -    type: String  | 
127 |  | -  },  | 
128 |  | -  animate: {  | 
129 |  | -    type: Boolean,  | 
130 |  | -    default: true  | 
 | 95 | +          <linearGradient id={this.idGradient}>  | 
 | 96 | +            <stop  | 
 | 97 | +              offset="0%"  | 
 | 98 | +              stop-color={this.primaryColor}  | 
 | 99 | +              stop-opacity={this.primaryOpacity}  | 
 | 100 | +            >  | 
 | 101 | +              {this.animate ? (  | 
 | 102 | +                <animate  | 
 | 103 | +                  attributeName="offset"  | 
 | 104 | +                  values="-2; 1"  | 
 | 105 | +                  dur={`${this.speed}s`}  | 
 | 106 | +                  repeatCount="indefinite"  | 
 | 107 | +                />  | 
 | 108 | +              ) : null}  | 
 | 109 | +            </stop>  | 
 | 110 | +            <stop  | 
 | 111 | +              offset="50%"  | 
 | 112 | +              stop-color={this.secondaryColor}  | 
 | 113 | +              stop-opacity={this.secondaryOpacity}  | 
 | 114 | +            >  | 
 | 115 | +              {this.animate ? (  | 
 | 116 | +                <animate  | 
 | 117 | +                  attributeName="offset"  | 
 | 118 | +                  values="-1.5; 1.5"  | 
 | 119 | +                  dur={`${this.speed}s`}  | 
 | 120 | +                  repeatCount="indefinite"  | 
 | 121 | +                />  | 
 | 122 | +              ) : null}  | 
 | 123 | +            </stop>  | 
 | 124 | +            <stop  | 
 | 125 | +              offset="100%"  | 
 | 126 | +              stop-color={this.primaryColor}  | 
 | 127 | +              stop-opacity={this.primaryOpacity}  | 
 | 128 | +            >  | 
 | 129 | +              {this.animate ? (  | 
 | 130 | +                <animate  | 
 | 131 | +                  attributeName="offset"  | 
 | 132 | +                  values="-1; 2"  | 
 | 133 | +                  dur={`${this.speed}s`}  | 
 | 134 | +                  repeatCount="indefinite"  | 
 | 135 | +                />  | 
 | 136 | +              ) : null}  | 
 | 137 | +            </stop>  | 
 | 138 | +          </linearGradient>  | 
 | 139 | +        </defs>  | 
 | 140 | +      </svg>  | 
 | 141 | +    )  | 
131 | 142 |   }  | 
132 |  | -}  | 
133 |  | - | 
134 |  | -export default ContentLoader  | 
 | 143 | +})  | 
0 commit comments