@mekari/pixel3-image 0.0.7-dev.5

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.
@@ -0,0 +1,77 @@
1
+ // src/modules/image.props.ts
2
+ var imageProps = {
3
+ id: {
4
+ type: String,
5
+ default: ""
6
+ },
7
+ src: {
8
+ type: String,
9
+ default: ""
10
+ },
11
+ alt: {
12
+ type: String,
13
+ default: ""
14
+ },
15
+ layout: {
16
+ type: String,
17
+ default: "intrinsic"
18
+ },
19
+ width: {
20
+ type: Number,
21
+ default: 0
22
+ },
23
+ height: {
24
+ type: Number,
25
+ default: 0
26
+ },
27
+ sizes: {
28
+ type: String,
29
+ default: ""
30
+ },
31
+ srcPlaceholder: {
32
+ type: String,
33
+ default: "data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7"
34
+ },
35
+ srcset: {
36
+ type: String,
37
+ default: ""
38
+ },
39
+ typeSrcset: {
40
+ type: String,
41
+ default: ""
42
+ },
43
+ mediaSrcset: {
44
+ type: String,
45
+ default: ""
46
+ },
47
+ maxSrcset: {
48
+ type: Number,
49
+ default: 5
50
+ },
51
+ objectFit: {
52
+ type: String,
53
+ default: "fill"
54
+ },
55
+ objectPosition: {
56
+ type: String,
57
+ default: ""
58
+ },
59
+ errorText: {
60
+ type: String,
61
+ default: "Failed load image"
62
+ },
63
+ isLazy: {
64
+ type: Boolean,
65
+ default: true
66
+ },
67
+ isShowLoading: {
68
+ type: Boolean,
69
+ default: true
70
+ }
71
+ };
72
+ var imageEmit = ["intersect", "load", "error"];
73
+
74
+ export {
75
+ imageProps,
76
+ imageEmit
77
+ };
@@ -0,0 +1,48 @@
1
+ import {
2
+ useImage
3
+ } from "./chunk-MC3PU33I.mjs";
4
+ import {
5
+ imageProps
6
+ } from "./chunk-DPFH2SO2.mjs";
7
+
8
+ // src/image.tsx
9
+ import { createVNode as _createVNode } from "vue";
10
+ import { defineComponent } from "vue";
11
+ import { MpSpinner } from "@mekari/pixel3-spinner";
12
+ import { flex } from "@mekari/pixel3-styled-system/patterns";
13
+ var MpImage = defineComponent({
14
+ name: "MpImage",
15
+ props: imageProps,
16
+ emits: ["intersect", "load", "error"],
17
+ setup(props, {
18
+ slots,
19
+ emit
20
+ }) {
21
+ const {
22
+ rootAttrs,
23
+ sizerAttrs,
24
+ imgSizerAttrs,
25
+ sourceAttrs,
26
+ imgAttrs,
27
+ isLoading,
28
+ sizerStyle
29
+ } = useImage(props, emit);
30
+ return () => {
31
+ const children = slots.default && slots.default();
32
+ return _createVNode("div", rootAttrs.value, [isLoading.value && _createVNode("div", {
33
+ "class": flex({
34
+ alignItems: "center",
35
+ justifyContent: "center",
36
+ zIndex: "1",
37
+ position: "absolute",
38
+ width: "full",
39
+ height: "full"
40
+ })
41
+ }, [children ? children : _createVNode(MpSpinner, null, null)]), sizerStyle.value && _createVNode("div", sizerAttrs.value, [_createVNode("img", imgSizerAttrs.value, null)]), _createVNode("picture", null, [_createVNode("source", sourceAttrs.value, null), _createVNode("img", imgAttrs.value, null)])]);
42
+ };
43
+ }
44
+ });
45
+
46
+ export {
47
+ MpImage
48
+ };
@@ -0,0 +1,240 @@
1
+ import {
2
+ __name
3
+ } from "./chunk-QZ7VFGWC.mjs";
4
+
5
+ // src/modules/image.hooks.ts
6
+ import { computed, onUnmounted, ref, toRefs } from "vue";
7
+ import { getUniqueId, useIntersectionObserver } from "@mekari/pixel3-utils";
8
+ function useImage(props, emit) {
9
+ const {
10
+ id,
11
+ src,
12
+ alt,
13
+ srcPlaceholder,
14
+ srcset,
15
+ typeSrcset,
16
+ mediaSrcset,
17
+ layout,
18
+ width,
19
+ height,
20
+ sizes,
21
+ objectFit,
22
+ objectPosition,
23
+ errorText,
24
+ isLazy,
25
+ isShowLoading
26
+ } = toRefs(props);
27
+ const intersected = ref(false);
28
+ const loaded = ref(false);
29
+ const failed = ref(false);
30
+ const imageWrapperNode = ref();
31
+ const imgNode = ref();
32
+ const {
33
+ stop: disableIntersectionObserver
34
+ } = useIntersectionObserver(imageWrapperNode, ([{
35
+ isIntersecting
36
+ }]) => {
37
+ if (isIntersecting) {
38
+ intersected.value = true;
39
+ emit("intersect", getId);
40
+ }
41
+ });
42
+ const getId = id.value || getUniqueId("", "image").value;
43
+ const isVisible = computed(() => {
44
+ return intersected.value || !isLazy.value;
45
+ });
46
+ const isLoading = computed(() => {
47
+ return isShowLoading.value && isVisible.value && !loaded.value && !failed.value;
48
+ });
49
+ const srcImage = computed(() => {
50
+ return isVisible.value && src.value ? src.value : srcPlaceholder.value;
51
+ });
52
+ const srcsetImage = computed(() => {
53
+ return isVisible.value && srcset.value ? srcset.value : void 0;
54
+ });
55
+ const sizerSvg = computed(() => {
56
+ if (layout.value !== "intrinsic") {
57
+ return "";
58
+ }
59
+ const backgroundColor = !intersected.value ? "background-color:#ffffff;" : "";
60
+ return `<svg
61
+ width="${width.value}"
62
+ height="${height.value}"
63
+ xmlns="http://www.w3.org/2000/svg"
64
+ style="${backgroundColor}"
65
+ >
66
+ <text x="50%" y="50%" dominant-baseline="middle" text-anchor="middle">${errorText.value}</text>
67
+ </svg>`;
68
+ });
69
+ const sizerStyle = computed(() => {
70
+ let style;
71
+ if (layout.value === "responsive") {
72
+ const quotient = height.value / width.value;
73
+ const paddingTop = isNaN(quotient) ? "100%" : `${quotient * 100}%`;
74
+ style = {
75
+ display: "block",
76
+ boxSizing: "border-box",
77
+ paddingTop
78
+ };
79
+ } else if (layout.value === "intrinsic") {
80
+ style = {
81
+ boxSizing: "border-box",
82
+ display: "block",
83
+ maxWidth: "100%"
84
+ };
85
+ }
86
+ return style;
87
+ });
88
+ const wrapperStyle = computed(() => {
89
+ let style = {};
90
+ if (layout.value === "responsive") {
91
+ style = {
92
+ position: "relative",
93
+ display: "block",
94
+ overflow: "hidden",
95
+ boxSizing: "border-box",
96
+ margin: 0
97
+ };
98
+ } else if (layout.value === "intrinsic") {
99
+ style = {
100
+ position: "relative",
101
+ display: "inline-block",
102
+ overflow: "hidden",
103
+ boxSizing: "border-box",
104
+ maxWidth: "100%",
105
+ margin: 0
106
+ };
107
+ } else if (layout.value === "fixed") {
108
+ style = {
109
+ position: "relative",
110
+ display: "inline-block",
111
+ overflow: "hidden",
112
+ boxSizing: "border-box",
113
+ width: `${width.value}px`,
114
+ height: `${height.value}px`
115
+ };
116
+ } else if (layout.value === "fill") {
117
+ style = {
118
+ position: "absolute",
119
+ display: "block",
120
+ overflow: "hidden",
121
+ boxSizing: "border-box",
122
+ top: 0,
123
+ left: 0,
124
+ bottom: 0,
125
+ right: 0,
126
+ margin: 0
127
+ };
128
+ }
129
+ return style;
130
+ });
131
+ const rootAttrs = computed(() => {
132
+ return {
133
+ "data-pixel-component": "MpImage",
134
+ ref: imageWrapperNode,
135
+ id: getId,
136
+ style: {
137
+ ...wrapperStyle.value
138
+ }
139
+ };
140
+ });
141
+ const sizerAttrs = computed(() => {
142
+ return {
143
+ style: {
144
+ ...sizerStyle.value
145
+ }
146
+ };
147
+ });
148
+ const imgSizerAttrs = computed(() => {
149
+ return {
150
+ src: `data:image/svg+xml;base64,${toBase64(sizerSvg.value)}`,
151
+ alt: "",
152
+ ariaHidden: true,
153
+ style: {
154
+ maxWidth: "100%",
155
+ display: "block",
156
+ border: "none",
157
+ margin: 0,
158
+ padding: 0
159
+ }
160
+ };
161
+ });
162
+ const sourceAttrs = computed(() => {
163
+ return {
164
+ srcset: srcsetImage.value,
165
+ type: typeSrcset.value,
166
+ media: mediaSrcset.value
167
+ };
168
+ });
169
+ const imgAttrs = computed(() => {
170
+ return {
171
+ ref: imgNode,
172
+ alt: alt.value ? alt.value : void 0,
173
+ src: srcImage.value ? srcImage.value : void 0,
174
+ sizes: sizes.value ? sizes.value : void 0,
175
+ decoding: "async",
176
+ // eslint-disable-next-line
177
+ style: {
178
+ position: "absolute",
179
+ display: "block",
180
+ top: 0,
181
+ left: 0,
182
+ bottom: 0,
183
+ right: 0,
184
+ boxSizing: "border-box",
185
+ padding: 0,
186
+ border: "none",
187
+ margin: "auto",
188
+ width: "0",
189
+ height: "0",
190
+ minWidth: "100%",
191
+ maxWidth: "100%",
192
+ minHeight: "100%",
193
+ maxHeight: "100%",
194
+ objectFit: objectFit.value ? objectFit.value : void 0,
195
+ objectPosition: objectPosition.value ? objectPosition.value : void 0
196
+ },
197
+ onLoad: handleLoad,
198
+ onError: handleError
199
+ };
200
+ });
201
+ function toBase64(str) {
202
+ console.log("STR", str);
203
+ if (typeof window === "undefined") {
204
+ return Buffer.from(str).toString("base64");
205
+ } else {
206
+ return window.btoa(str);
207
+ }
208
+ }
209
+ __name(toBase64, "toBase64");
210
+ function handleLoad() {
211
+ if (imgNode.value && imgNode.value.getAttribute("src") !== srcPlaceholder.value && !loaded.value) {
212
+ loaded.value = true;
213
+ emit("load", getId);
214
+ }
215
+ }
216
+ __name(handleLoad, "handleLoad");
217
+ function handleError(e) {
218
+ emit("error", getId, e);
219
+ failed.value = true;
220
+ }
221
+ __name(handleError, "handleError");
222
+ onUnmounted(() => {
223
+ disableIntersectionObserver();
224
+ });
225
+ return {
226
+ rootAttrs,
227
+ sizerAttrs,
228
+ imgSizerAttrs,
229
+ sourceAttrs,
230
+ imgAttrs,
231
+ isLoading,
232
+ sizerStyle,
233
+ sizerSvg
234
+ };
235
+ }
236
+ __name(useImage, "useImage");
237
+
238
+ export {
239
+ useImage
240
+ };
@@ -0,0 +1,6 @@
1
+ var __defProp = Object.defineProperty;
2
+ var __name = (target, value) => __defProp(target, "name", { value, configurable: true });
3
+
4
+ export {
5
+ __name
6
+ };
@@ -0,0 +1,167 @@
1
+ import * as vue_jsx_runtime from 'vue/jsx-runtime';
2
+ import { ImageLayout, ImageObjectFit } from './modules/image.type.mjs';
3
+ import * as vue from 'vue';
4
+
5
+ declare const MpImage: vue.DefineComponent<{
6
+ id: {
7
+ type: vue.PropType<string>;
8
+ default: string;
9
+ };
10
+ src: {
11
+ type: vue.PropType<string>;
12
+ default: string;
13
+ };
14
+ alt: {
15
+ type: vue.PropType<string>;
16
+ default: string;
17
+ };
18
+ layout: {
19
+ type: vue.PropType<ImageLayout>;
20
+ default: string;
21
+ };
22
+ width: {
23
+ type: vue.PropType<number>;
24
+ default: number;
25
+ };
26
+ height: {
27
+ type: vue.PropType<number>;
28
+ default: number;
29
+ };
30
+ sizes: {
31
+ type: vue.PropType<string>;
32
+ default: string;
33
+ };
34
+ srcPlaceholder: {
35
+ type: vue.PropType<string>;
36
+ default: string;
37
+ };
38
+ srcset: {
39
+ type: vue.PropType<string>;
40
+ default: string;
41
+ };
42
+ typeSrcset: {
43
+ type: vue.PropType<string>;
44
+ default: string;
45
+ };
46
+ mediaSrcset: {
47
+ type: vue.PropType<string>;
48
+ default: string;
49
+ };
50
+ maxSrcset: {
51
+ type: vue.PropType<number>;
52
+ default: number;
53
+ };
54
+ objectFit: {
55
+ type: vue.PropType<ImageObjectFit>;
56
+ default: string;
57
+ };
58
+ objectPosition: {
59
+ type: vue.PropType<string>;
60
+ default: string;
61
+ };
62
+ errorText: {
63
+ type: vue.PropType<string>;
64
+ default: string;
65
+ };
66
+ isLazy: {
67
+ type: vue.PropType<boolean>;
68
+ default: boolean;
69
+ };
70
+ isShowLoading: {
71
+ type: vue.PropType<boolean>;
72
+ default: boolean;
73
+ };
74
+ }, () => vue_jsx_runtime.JSX.Element, unknown, {}, {}, vue.ComponentOptionsMixin, vue.ComponentOptionsMixin, ("intersect" | "load" | "error")[], "intersect" | "load" | "error", vue.PublicProps, Readonly<vue.ExtractPropTypes<{
75
+ id: {
76
+ type: vue.PropType<string>;
77
+ default: string;
78
+ };
79
+ src: {
80
+ type: vue.PropType<string>;
81
+ default: string;
82
+ };
83
+ alt: {
84
+ type: vue.PropType<string>;
85
+ default: string;
86
+ };
87
+ layout: {
88
+ type: vue.PropType<ImageLayout>;
89
+ default: string;
90
+ };
91
+ width: {
92
+ type: vue.PropType<number>;
93
+ default: number;
94
+ };
95
+ height: {
96
+ type: vue.PropType<number>;
97
+ default: number;
98
+ };
99
+ sizes: {
100
+ type: vue.PropType<string>;
101
+ default: string;
102
+ };
103
+ srcPlaceholder: {
104
+ type: vue.PropType<string>;
105
+ default: string;
106
+ };
107
+ srcset: {
108
+ type: vue.PropType<string>;
109
+ default: string;
110
+ };
111
+ typeSrcset: {
112
+ type: vue.PropType<string>;
113
+ default: string;
114
+ };
115
+ mediaSrcset: {
116
+ type: vue.PropType<string>;
117
+ default: string;
118
+ };
119
+ maxSrcset: {
120
+ type: vue.PropType<number>;
121
+ default: number;
122
+ };
123
+ objectFit: {
124
+ type: vue.PropType<ImageObjectFit>;
125
+ default: string;
126
+ };
127
+ objectPosition: {
128
+ type: vue.PropType<string>;
129
+ default: string;
130
+ };
131
+ errorText: {
132
+ type: vue.PropType<string>;
133
+ default: string;
134
+ };
135
+ isLazy: {
136
+ type: vue.PropType<boolean>;
137
+ default: boolean;
138
+ };
139
+ isShowLoading: {
140
+ type: vue.PropType<boolean>;
141
+ default: boolean;
142
+ };
143
+ }>> & {
144
+ onIntersect?: ((...args: any[]) => any) | undefined;
145
+ onLoad?: ((...args: any[]) => any) | undefined;
146
+ onError?: ((...args: any[]) => any) | undefined;
147
+ }, {
148
+ id: string;
149
+ src: string;
150
+ alt: string;
151
+ layout: ImageLayout;
152
+ width: number;
153
+ height: number;
154
+ sizes: string;
155
+ srcPlaceholder: string;
156
+ srcset: string;
157
+ typeSrcset: string;
158
+ mediaSrcset: string;
159
+ maxSrcset: number;
160
+ objectFit: ImageObjectFit;
161
+ objectPosition: string;
162
+ errorText: string;
163
+ isLazy: boolean;
164
+ isShowLoading: boolean;
165
+ }, {}>;
166
+
167
+ export { MpImage };
@@ -0,0 +1,167 @@
1
+ import * as vue_jsx_runtime from 'vue/jsx-runtime';
2
+ import { ImageLayout, ImageObjectFit } from './modules/image.type.js';
3
+ import * as vue from 'vue';
4
+
5
+ declare const MpImage: vue.DefineComponent<{
6
+ id: {
7
+ type: vue.PropType<string>;
8
+ default: string;
9
+ };
10
+ src: {
11
+ type: vue.PropType<string>;
12
+ default: string;
13
+ };
14
+ alt: {
15
+ type: vue.PropType<string>;
16
+ default: string;
17
+ };
18
+ layout: {
19
+ type: vue.PropType<ImageLayout>;
20
+ default: string;
21
+ };
22
+ width: {
23
+ type: vue.PropType<number>;
24
+ default: number;
25
+ };
26
+ height: {
27
+ type: vue.PropType<number>;
28
+ default: number;
29
+ };
30
+ sizes: {
31
+ type: vue.PropType<string>;
32
+ default: string;
33
+ };
34
+ srcPlaceholder: {
35
+ type: vue.PropType<string>;
36
+ default: string;
37
+ };
38
+ srcset: {
39
+ type: vue.PropType<string>;
40
+ default: string;
41
+ };
42
+ typeSrcset: {
43
+ type: vue.PropType<string>;
44
+ default: string;
45
+ };
46
+ mediaSrcset: {
47
+ type: vue.PropType<string>;
48
+ default: string;
49
+ };
50
+ maxSrcset: {
51
+ type: vue.PropType<number>;
52
+ default: number;
53
+ };
54
+ objectFit: {
55
+ type: vue.PropType<ImageObjectFit>;
56
+ default: string;
57
+ };
58
+ objectPosition: {
59
+ type: vue.PropType<string>;
60
+ default: string;
61
+ };
62
+ errorText: {
63
+ type: vue.PropType<string>;
64
+ default: string;
65
+ };
66
+ isLazy: {
67
+ type: vue.PropType<boolean>;
68
+ default: boolean;
69
+ };
70
+ isShowLoading: {
71
+ type: vue.PropType<boolean>;
72
+ default: boolean;
73
+ };
74
+ }, () => vue_jsx_runtime.JSX.Element, unknown, {}, {}, vue.ComponentOptionsMixin, vue.ComponentOptionsMixin, ("intersect" | "load" | "error")[], "intersect" | "load" | "error", vue.PublicProps, Readonly<vue.ExtractPropTypes<{
75
+ id: {
76
+ type: vue.PropType<string>;
77
+ default: string;
78
+ };
79
+ src: {
80
+ type: vue.PropType<string>;
81
+ default: string;
82
+ };
83
+ alt: {
84
+ type: vue.PropType<string>;
85
+ default: string;
86
+ };
87
+ layout: {
88
+ type: vue.PropType<ImageLayout>;
89
+ default: string;
90
+ };
91
+ width: {
92
+ type: vue.PropType<number>;
93
+ default: number;
94
+ };
95
+ height: {
96
+ type: vue.PropType<number>;
97
+ default: number;
98
+ };
99
+ sizes: {
100
+ type: vue.PropType<string>;
101
+ default: string;
102
+ };
103
+ srcPlaceholder: {
104
+ type: vue.PropType<string>;
105
+ default: string;
106
+ };
107
+ srcset: {
108
+ type: vue.PropType<string>;
109
+ default: string;
110
+ };
111
+ typeSrcset: {
112
+ type: vue.PropType<string>;
113
+ default: string;
114
+ };
115
+ mediaSrcset: {
116
+ type: vue.PropType<string>;
117
+ default: string;
118
+ };
119
+ maxSrcset: {
120
+ type: vue.PropType<number>;
121
+ default: number;
122
+ };
123
+ objectFit: {
124
+ type: vue.PropType<ImageObjectFit>;
125
+ default: string;
126
+ };
127
+ objectPosition: {
128
+ type: vue.PropType<string>;
129
+ default: string;
130
+ };
131
+ errorText: {
132
+ type: vue.PropType<string>;
133
+ default: string;
134
+ };
135
+ isLazy: {
136
+ type: vue.PropType<boolean>;
137
+ default: boolean;
138
+ };
139
+ isShowLoading: {
140
+ type: vue.PropType<boolean>;
141
+ default: boolean;
142
+ };
143
+ }>> & {
144
+ onIntersect?: ((...args: any[]) => any) | undefined;
145
+ onLoad?: ((...args: any[]) => any) | undefined;
146
+ onError?: ((...args: any[]) => any) | undefined;
147
+ }, {
148
+ id: string;
149
+ src: string;
150
+ alt: string;
151
+ layout: ImageLayout;
152
+ width: number;
153
+ height: number;
154
+ sizes: string;
155
+ srcPlaceholder: string;
156
+ srcset: string;
157
+ typeSrcset: string;
158
+ mediaSrcset: string;
159
+ maxSrcset: number;
160
+ objectFit: ImageObjectFit;
161
+ objectPosition: string;
162
+ errorText: string;
163
+ isLazy: boolean;
164
+ isShowLoading: boolean;
165
+ }, {}>;
166
+
167
+ export { MpImage };