@stachelock/ui 0.5.0 → 0.5.1
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.
- package/dist/android-chrome-192x192.png +0 -0
- package/dist/android-chrome-512x512.png +0 -0
- package/dist/apple-touch-icon.png +0 -0
- package/dist/components/CloudinaryImage.js +74 -52
- package/dist/components/CloudinaryImage.js.map +1 -1
- package/dist/favicon-16x16.png +0 -0
- package/dist/favicon-32x32.png +0 -0
- package/dist/favicon.ico +0 -0
- package/dist/site.webmanifest +19 -0
- package/dist/src/components/CloudinaryImage.d.ts +41 -0
- package/dist/src/types/core.d.ts +10 -0
- package/dist/src/views/components/LottiePage.d.ts +2 -0
- package/dist/src/views/components/index.d.ts +1 -0
- package/dist/style.css +1 -1
- package/dist/ui.css +1 -1
- package/package.json +1 -1
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
@@ -1,6 +1,7 @@
|
|
|
1
|
-
import { createElementBlock as d, openBlock as u, createElementVNode as
|
|
2
|
-
import
|
|
3
|
-
|
|
1
|
+
import { createElementBlock as d, openBlock as u, createElementVNode as r, defineComponent as U, inject as D, ref as v, computed as l, watch as F, onMounted as W, onUnmounted as z, normalizeClass as n, normalizeStyle as C, withDirectives as g, createCommentVNode as O, createBlock as x, resolveDynamicComponent as k, vShow as y } from "vue";
|
|
2
|
+
import P from "https://res.cloudinary.com/demo/image/upload/sample.jpg?vue&type=CloudinaryImage&index=0&src=true&alt=Sample%20image&lang.CloudinaryImage";
|
|
3
|
+
import { _ as V } from "../_plugin-vue_export-helper-CHgC5LLL.js";
|
|
4
|
+
function H(i, f) {
|
|
4
5
|
return u(), d("svg", {
|
|
5
6
|
xmlns: "http://www.w3.org/2000/svg",
|
|
6
7
|
viewBox: "0 0 20 20",
|
|
@@ -8,14 +9,14 @@ function z(i, f) {
|
|
|
8
9
|
"aria-hidden": "true",
|
|
9
10
|
"data-slot": "icon"
|
|
10
11
|
}, [
|
|
11
|
-
|
|
12
|
+
r("path", {
|
|
12
13
|
"fill-rule": "evenodd",
|
|
13
14
|
d: "M1 5.25A2.25 2.25 0 0 1 3.25 3h13.5A2.25 2.25 0 0 1 19 5.25v9.5A2.25 2.25 0 0 1 16.75 17H3.25A2.25 2.25 0 0 1 1 14.75v-9.5Zm1.5 5.81v3.69c0 .414.336.75.75.75h13.5a.75.75 0 0 0 .75-.75v-2.69l-2.22-2.219a.75.75 0 0 0-1.06 0l-1.91 1.909.47.47a.75.75 0 1 1-1.06 1.06L6.53 8.091a.75.75 0 0 0-1.06 0l-2.97 2.97ZM12 7a1 1 0 1 1-2 0 1 1 0 0 1 2 0Z",
|
|
14
15
|
"clip-rule": "evenodd"
|
|
15
16
|
})
|
|
16
17
|
]);
|
|
17
18
|
}
|
|
18
|
-
function
|
|
19
|
+
function G(i, f) {
|
|
19
20
|
return u(), d("svg", {
|
|
20
21
|
xmlns: "http://www.w3.org/2000/svg",
|
|
21
22
|
viewBox: "0 0 20 20",
|
|
@@ -23,24 +24,37 @@ function F(i, f) {
|
|
|
23
24
|
"aria-hidden": "true",
|
|
24
25
|
"data-slot": "icon"
|
|
25
26
|
}, [
|
|
26
|
-
|
|
27
|
+
r("path", {
|
|
27
28
|
"fill-rule": "evenodd",
|
|
28
29
|
d: "M18 10a8 8 0 1 1-16 0 8 8 0 0 1 16 0Zm-5.5-2.5a2.5 2.5 0 1 1-5 0 2.5 2.5 0 0 1 5 0ZM10 12a5.99 5.99 0 0 0-4.793 2.39A6.483 6.483 0 0 0 10 16.5a6.483 6.483 0 0 0 4.793-2.11A5.99 5.99 0 0 0 10 12Z",
|
|
29
30
|
"clip-rule": "evenodd"
|
|
30
31
|
})
|
|
31
32
|
]);
|
|
32
33
|
}
|
|
33
|
-
const
|
|
34
|
+
const J = { class: "sl-flex sl-h-full sl-w-full sl-items-center sl-justify-center" }, K = { class: "sl-flex sl-h-full sl-w-full sl-items-center sl-justify-center" }, Q = {
|
|
34
35
|
key: 0,
|
|
35
36
|
class: "sl-h-full sl-w-full"
|
|
36
|
-
},
|
|
37
|
+
}, T = ["src", "alt"], $ = /* @__PURE__ */ U({
|
|
37
38
|
__name: "CloudinaryImage",
|
|
38
39
|
props: {
|
|
40
|
+
/** Direct image URL - bypasses Cloudinary URL generation */
|
|
41
|
+
src: {
|
|
42
|
+
type: String,
|
|
43
|
+
required: !1,
|
|
44
|
+
default: null
|
|
45
|
+
},
|
|
46
|
+
/** Cloudinary public ID */
|
|
39
47
|
publicId: {
|
|
40
48
|
type: String,
|
|
41
49
|
required: !1,
|
|
42
50
|
default: null
|
|
43
51
|
},
|
|
52
|
+
/** Alias for publicId (for compatibility with different naming conventions) */
|
|
53
|
+
imagePublicId: {
|
|
54
|
+
type: String,
|
|
55
|
+
required: !1,
|
|
56
|
+
default: null
|
|
57
|
+
},
|
|
44
58
|
asset: {
|
|
45
59
|
type: Object,
|
|
46
60
|
default: null,
|
|
@@ -51,6 +65,12 @@ const O = { class: "sl-flex sl-h-full sl-w-full sl-items-center sl-justify-cente
|
|
|
51
65
|
required: !1,
|
|
52
66
|
default: null
|
|
53
67
|
},
|
|
68
|
+
/** Fallback URL to use if primary image fails */
|
|
69
|
+
fallbackSrc: {
|
|
70
|
+
type: String,
|
|
71
|
+
required: !1,
|
|
72
|
+
default: null
|
|
73
|
+
},
|
|
54
74
|
transformations: {
|
|
55
75
|
type: Array,
|
|
56
76
|
default: () => []
|
|
@@ -94,82 +114,84 @@ const O = { class: "sl-flex sl-h-full sl-w-full sl-items-center sl-justify-cente
|
|
|
94
114
|
},
|
|
95
115
|
emits: ["update:imageLoaded", "error"],
|
|
96
116
|
setup(i, { emit: f }) {
|
|
97
|
-
const
|
|
98
|
-
if (!
|
|
99
|
-
const t =
|
|
117
|
+
const b = D("cloudinary", {}), s = v(!1), o = v(!1), c = v(!0), w = f, e = i, m = (t) => t ? t.startsWith("http://") || t.startsWith("https://") || t.startsWith("//") : !1, p = l(() => e.src && m(e.src) ? e.src : e.asset?.secure_url ? e.asset.secure_url : e.asset?.url ? e.asset.url : e.publicId && m(e.publicId) ? e.publicId : e.imagePublicId && m(e.imagePublicId) ? e.imagePublicId : null), _ = l(() => p.value ? null : e.asset?.public_id ? e.asset.public_id : e.imagePublicId || e.publicId || e.fallbackPublicId || null), q = l(() => {
|
|
118
|
+
if (!_.value) return null;
|
|
119
|
+
const t = b?.cloudName || "demo", S = b?.baseUrl || `https://res.cloudinary.com/${t}/image/upload`, a = [];
|
|
100
120
|
e.width && e.width !== "auto" && a.push(`w_${e.width}`), e.height && e.height !== "auto" && a.push(`h_${e.height}`), e.quality && a.push(`q_${e.quality}`), e.devicePixelRatio && a.push(`dpr_${e.devicePixelRatio}`), a.push("f_auto"), a.push("c_fill");
|
|
101
|
-
const
|
|
102
|
-
return `${
|
|
103
|
-
}),
|
|
121
|
+
const E = a.join(",");
|
|
122
|
+
return `${S}/${E}/${_.value}`;
|
|
123
|
+
}), h = l(() => p.value ? p.value : q.value), I = l(() => e.skeleton === "user" ? G : H), j = l(() => {
|
|
104
124
|
const t = {};
|
|
105
125
|
return e.width && e.width !== "auto" && (t.width = typeof e.width == "number" ? `${e.width}px` : e.width), e.height && e.height !== "auto" && (t.height = typeof e.height == "number" ? `${e.height}px` : e.height), e.aspectRatio && (t.aspectRatio = String(e.aspectRatio)), t;
|
|
106
|
-
}),
|
|
126
|
+
}), N = l(() => ({
|
|
107
127
|
"sl-relative sl-overflow-hidden": !0,
|
|
108
128
|
...e.customClasses?.div
|
|
109
|
-
})),
|
|
129
|
+
})), A = l(() => ({
|
|
110
130
|
"sl-h-full sl-w-full sl-text-gray-200": !0,
|
|
111
131
|
...e.customClasses?.skeleton
|
|
112
|
-
})),
|
|
132
|
+
})), R = l(() => ({
|
|
113
133
|
"sl-h-full sl-w-full sl-text-gray-300": !0,
|
|
114
134
|
...e.customClasses?.fallback
|
|
115
|
-
})),
|
|
135
|
+
})), B = l(() => ({
|
|
116
136
|
"sl-h-full sl-w-full sl-object-cover": !0,
|
|
117
137
|
...e.customClasses?.image
|
|
118
|
-
})),
|
|
138
|
+
})), L = l(() => ({
|
|
119
139
|
objectFit: "cover"
|
|
120
|
-
})),
|
|
121
|
-
s.value = !0,
|
|
122
|
-
},
|
|
123
|
-
c.value && (
|
|
140
|
+
})), M = () => {
|
|
141
|
+
s.value = !0, o.value = !1, w("update:imageLoaded", !0);
|
|
142
|
+
}, Z = (t) => {
|
|
143
|
+
c.value && (o.value = !0, s.value = !1, w("error", t));
|
|
124
144
|
};
|
|
125
|
-
return
|
|
126
|
-
() =>
|
|
145
|
+
return F(
|
|
146
|
+
() => h.value,
|
|
127
147
|
() => {
|
|
128
|
-
s.value = !1,
|
|
148
|
+
s.value = !1, o.value = !1;
|
|
129
149
|
}
|
|
130
|
-
),
|
|
150
|
+
), W(() => {
|
|
131
151
|
c.value = !0;
|
|
132
|
-
}),
|
|
152
|
+
}), z(() => {
|
|
133
153
|
c.value = !1;
|
|
134
|
-
}), (t,
|
|
135
|
-
style: C(
|
|
136
|
-
class: n(
|
|
154
|
+
}), (t, S) => (u(), d("div", {
|
|
155
|
+
style: C(j.value),
|
|
156
|
+
class: n(N.value)
|
|
137
157
|
}, [
|
|
138
|
-
|
|
139
|
-
|
|
158
|
+
g(r("div", J, [
|
|
159
|
+
r("div", {
|
|
140
160
|
role: "status",
|
|
141
161
|
class: n([{ "sl-animate-pulse": i.pulse }])
|
|
142
162
|
}, [
|
|
143
|
-
(u(), x(
|
|
144
|
-
class: n(
|
|
163
|
+
(u(), x(k(I.value), {
|
|
164
|
+
class: n(A.value)
|
|
145
165
|
}, null, 8, ["class"]))
|
|
146
166
|
], 2)
|
|
147
167
|
], 512), [
|
|
148
|
-
[
|
|
168
|
+
[y, !s.value && !o.value]
|
|
149
169
|
]),
|
|
150
|
-
|
|
151
|
-
(u(), x(
|
|
152
|
-
class: n(
|
|
170
|
+
g(r("div", K, [
|
|
171
|
+
(u(), x(k(I.value), {
|
|
172
|
+
class: n(R.value)
|
|
153
173
|
}, null, 8, ["class"]))
|
|
154
174
|
], 512), [
|
|
155
|
-
[
|
|
175
|
+
[y, o.value && !s.value]
|
|
156
176
|
]),
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
src:
|
|
177
|
+
h.value && c.value ? g((u(), d("div", Q, [
|
|
178
|
+
r("img", {
|
|
179
|
+
src: h.value,
|
|
160
180
|
alt: i.alt,
|
|
161
|
-
onLoad:
|
|
162
|
-
onError:
|
|
163
|
-
class: n(
|
|
164
|
-
style: C(
|
|
165
|
-
}, null, 46,
|
|
181
|
+
onLoad: M,
|
|
182
|
+
onError: Z,
|
|
183
|
+
class: n(B.value),
|
|
184
|
+
style: C(L.value)
|
|
185
|
+
}, null, 46, T)
|
|
166
186
|
], 512)), [
|
|
167
|
-
[
|
|
168
|
-
]) :
|
|
187
|
+
[y, s.value]
|
|
188
|
+
]) : O("", !0)
|
|
169
189
|
], 6));
|
|
170
190
|
}
|
|
171
|
-
})
|
|
191
|
+
});
|
|
192
|
+
typeof P == "function" && P($);
|
|
193
|
+
const te = /* @__PURE__ */ V($, [["__scopeId", "data-v-18ba2d71"]]);
|
|
172
194
|
export {
|
|
173
|
-
|
|
195
|
+
te as default
|
|
174
196
|
};
|
|
175
197
|
//# sourceMappingURL=CloudinaryImage.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"CloudinaryImage.js","sources":["../../node_modules/@heroicons/vue/20/solid/esm/PhotoIcon.js","../../node_modules/@heroicons/vue/20/solid/esm/UserCircleIcon.js","../../src/components/CloudinaryImage.vue"],"sourcesContent":["import { createElementVNode as _createElementVNode, openBlock as _openBlock, createElementBlock as _createElementBlock } from \"vue\"\n\nexport default function render(_ctx, _cache) {\n return (_openBlock(), _createElementBlock(\"svg\", {\n xmlns: \"http://www.w3.org/2000/svg\",\n viewBox: \"0 0 20 20\",\n fill: \"currentColor\",\n \"aria-hidden\": \"true\",\n \"data-slot\": \"icon\"\n }, [\n _createElementVNode(\"path\", {\n \"fill-rule\": \"evenodd\",\n d: \"M1 5.25A2.25 2.25 0 0 1 3.25 3h13.5A2.25 2.25 0 0 1 19 5.25v9.5A2.25 2.25 0 0 1 16.75 17H3.25A2.25 2.25 0 0 1 1 14.75v-9.5Zm1.5 5.81v3.69c0 .414.336.75.75.75h13.5a.75.75 0 0 0 .75-.75v-2.69l-2.22-2.219a.75.75 0 0 0-1.06 0l-1.91 1.909.47.47a.75.75 0 1 1-1.06 1.06L6.53 8.091a.75.75 0 0 0-1.06 0l-2.97 2.97ZM12 7a1 1 0 1 1-2 0 1 1 0 0 1 2 0Z\",\n \"clip-rule\": \"evenodd\"\n })\n ]))\n}","import { createElementVNode as _createElementVNode, openBlock as _openBlock, createElementBlock as _createElementBlock } from \"vue\"\n\nexport default function render(_ctx, _cache) {\n return (_openBlock(), _createElementBlock(\"svg\", {\n xmlns: \"http://www.w3.org/2000/svg\",\n viewBox: \"0 0 20 20\",\n fill: \"currentColor\",\n \"aria-hidden\": \"true\",\n \"data-slot\": \"icon\"\n }, [\n _createElementVNode(\"path\", {\n \"fill-rule\": \"evenodd\",\n d: \"M18 10a8 8 0 1 1-16 0 8 8 0 0 1 16 0Zm-5.5-2.5a2.5 2.5 0 1 1-5 0 2.5 2.5 0 0 1 5 0ZM10 12a5.99 5.99 0 0 0-4.793 2.39A6.483 6.483 0 0 0 10 16.5a6.483 6.483 0 0 0 4.793-2.11A5.99 5.99 0 0 0 10 12Z\",\n \"clip-rule\": \"evenodd\"\n })\n ]))\n}","<!--\n @component CloudinaryImage\n @description Cloudinary image component with loading states and fallbacks.\n \n Displays images from Cloudinary with automatic transformations, loading\n skeleton, error fallback, and flexible sizing options.\n \n @props\n - publicId (string, optional): Cloudinary public ID\n - asset (CloudinaryAsset, optional): Full asset object with transformations\n - fallbackPublicId (string, optional): Fallback image public ID\n - transformations (array, optional): Additional Cloudinary transformations\n - alt (string, optional): Alt text for accessibility\n - aspectRatio (string|number, optional): Aspect ratio (e.g., '16/9')\n - width (string|number, optional): Width in pixels or 'auto'\n - height (string|number, optional): Height in pixels or 'auto'\n - quality (string|number, optional): Image quality (1-100 or 'auto')\n - skeleton (string, optional): Skeleton type - 'user' or 'photo'\n - pulse (boolean, optional): Animate skeleton\n \n @emits\n - update:imageLoaded: Emitted when image load state changes\n - error: Emitted on image load error\n \n @example\n <CloudinaryImage\n public-id=\"avatars/user123\"\n :width=\"200\"\n :height=\"200\"\n alt=\"User avatar\"\n skeleton=\"user\"\n />\n-->\n<template>\n <div :style=\"computedDivStyle\" :class=\"computedDivClass\">\n <!-- Loading skeleton -->\n <div v-show=\"!imageLoaded && !imageError\" class=\"sl-flex sl-h-full sl-w-full sl-items-center sl-justify-center\">\n <div role=\"status\" :class=\"[{ 'sl-animate-pulse': pulse }]\">\n <component :is=\"skeletonComponent\" :class=\"computedSkeletonClass\" />\n </div>\n </div>\n\n <!-- Error fallback -->\n <div v-show=\"imageError && !imageLoaded\" class=\"sl-flex sl-h-full sl-w-full sl-items-center sl-justify-center\">\n <component :is=\"skeletonComponent\" :class=\"computedFallbackClass\" />\n </div>\n\n <!-- Image -->\n <div v-if=\"computedImg && isMounted\" v-show=\"imageLoaded\" class=\"sl-h-full sl-w-full\">\n <img\n :src=\"computedImg\"\n :alt=\"alt\"\n @load=\"onImageLoad\"\n @error=\"onImageError\"\n :class=\"computedImageClass\"\n :style=\"computedImageStyle\"\n />\n </div>\n </div>\n</template>\n\n<script setup lang=\"ts\">\n/**\n * CloudinaryImage - Image component with Cloudinary CDN support\n * \n * Provides a comprehensive image component with loading states, error handling,\n * and Cloudinary transformations. Uses plugin configuration for Cloudinary setup.\n * \n * ## Features\n * - Automatic loading skeleton\n * - Error fallback display\n * - Cloudinary URL generation\n * - Responsive sizing\n * - Aspect ratio control\n * - Quality optimization\n * \n * ## Plugin Configuration\n * Configure Cloudinary in your app setup:\n * ```typescript\n * app.use(StachelockUI, {\n * cloudinary: {\n * cloudName: 'your-cloud-name',\n * defaultTransformations: [...]\n * }\n * })\n * ```\n * \n * @module components/CloudinaryImage\n * @see {@link CloudinaryImageProps} for prop interface\n */\nimport { UserCircleIcon, PhotoIcon } from '@heroicons/vue/20/solid';\nimport { computed, inject, onMounted, onUnmounted, ref, watch } from 'vue';\nimport type { PropType } from 'vue';\nimport type { CloudinaryAsset, CloudinaryTransformationStep } from '../types/core';\n\n// Plugin configuration injection\nconst cloudinaryConfig = inject<{\n cloudName?: string;\n baseUrl?: string;\n defaultTransformations?: CloudinaryTransformationStep[];\n}>('cloudinary', {});\n\ninterface CustomClasses {\n div?: Record<string, boolean>;\n skeleton?: Record<string, boolean>;\n image?: Record<string, boolean>;\n fallback?: Record<string, boolean>;\n}\n\n// State\nconst imageLoaded = ref(false);\nconst imageError = ref(false);\nconst isMounted = ref(true);\n\nconst emit = defineEmits<{\n 'update:imageLoaded': [value: boolean];\n 'error': [error: unknown];\n}>();\n\nconst props = defineProps({\n publicId: {\n type: String,\n required: false,\n default: null\n },\n asset: {\n type: Object as PropType<CloudinaryAsset | null>,\n default: null,\n required: false\n },\n fallbackPublicId: {\n type: String,\n required: false,\n default: null\n },\n transformations: {\n type: Array as PropType<Array<(image: unknown) => void>>,\n default: () => []\n },\n alt: {\n type: String,\n default: ''\n },\n aspectRatio: {\n type: [String, Number] as PropType<string | number>,\n default: null\n },\n width: {\n type: [String, Number] as PropType<string | number>,\n default: 64\n },\n height: {\n type: [String, Number] as PropType<string | number>,\n default: 64\n },\n quality: {\n type: [String, Number],\n default: '90'\n },\n devicePixelRatio: {\n type: String,\n default: '2.0'\n },\n skeleton: {\n type: String as PropType<'user' | 'photo'>,\n default: 'photo'\n },\n pulse: {\n type: Boolean,\n default: true\n },\n customClasses: {\n type: Object as PropType<CustomClasses>,\n default: () => ({})\n }\n});\n\n// Computed: Effective public ID\nconst effectivePublicId = computed(() => {\n if (props.asset?.public_id) {\n return props.asset.public_id;\n }\n return props.publicId || props.fallbackPublicId || null;\n});\n\n// Computed: Generate Cloudinary URL\nconst computedImg = computed(() => {\n if (!effectivePublicId.value) return null;\n \n const cloudName = cloudinaryConfig?.cloudName || 'demo';\n const baseUrl = cloudinaryConfig?.baseUrl || `https://res.cloudinary.com/${cloudName}/image/upload`;\n \n // Build transformation string\n const transformations: string[] = [];\n \n // Add width/height\n if (props.width && props.width !== 'auto') {\n transformations.push(`w_${props.width}`);\n }\n if (props.height && props.height !== 'auto') {\n transformations.push(`h_${props.height}`);\n }\n \n // Add quality\n if (props.quality) {\n transformations.push(`q_${props.quality}`);\n }\n \n // Add DPR\n if (props.devicePixelRatio) {\n transformations.push(`dpr_${props.devicePixelRatio}`);\n }\n \n // Auto format\n transformations.push('f_auto');\n \n // Crop mode\n transformations.push('c_fill');\n \n const transformString = transformations.join(',');\n \n return `${baseUrl}/${transformString}/${effectivePublicId.value}`;\n});\n\n// Skeleton component based on type\nconst skeletonComponent = computed(() => {\n return props.skeleton === 'user' ? UserCircleIcon : PhotoIcon;\n});\n\n// Style computations\nconst computedDivStyle = computed(() => {\n const style: Record<string, string> = {};\n \n if (props.width && props.width !== 'auto') {\n style.width = typeof props.width === 'number' ? `${props.width}px` : props.width;\n }\n if (props.height && props.height !== 'auto') {\n style.height = typeof props.height === 'number' ? `${props.height}px` : props.height;\n }\n if (props.aspectRatio) {\n style.aspectRatio = String(props.aspectRatio);\n }\n \n return style;\n});\n\nconst computedDivClass = computed(() => ({\n 'sl-relative sl-overflow-hidden': true,\n ...props.customClasses?.div\n}));\n\nconst computedSkeletonClass = computed(() => ({\n 'sl-h-full sl-w-full sl-text-gray-200': true,\n ...props.customClasses?.skeleton\n}));\n\nconst computedFallbackClass = computed(() => ({\n 'sl-h-full sl-w-full sl-text-gray-300': true,\n ...props.customClasses?.fallback\n}));\n\nconst computedImageClass = computed(() => ({\n 'sl-h-full sl-w-full sl-object-cover': true,\n ...props.customClasses?.image\n}));\n\nconst computedImageStyle = computed(() => ({\n objectFit: 'cover' as const,\n}));\n\n// Event handlers\nconst onImageLoad = () => {\n imageLoaded.value = true;\n imageError.value = false;\n emit('update:imageLoaded', true);\n};\n\nconst onImageError = (error: Event) => {\n if (!isMounted.value) return;\n \n imageError.value = true;\n imageLoaded.value = false;\n emit('error', error);\n};\n\n// Reset state when publicId changes\nwatch(\n () => effectivePublicId.value,\n () => {\n imageLoaded.value = false;\n imageError.value = false;\n }\n);\n\n// Lifecycle\nonMounted(() => {\n isMounted.value = true;\n});\n\nonUnmounted(() => {\n isMounted.value = false;\n});\n</script>\n\n<style scoped>\n/* Prevent layout shift */\n[data-loading=\"true\"] {\n min-height: 20px;\n}\n</style>\n\n"],"names":["render","_ctx","_cache","_openBlock","_createElementBlock","_createElementVNode","cloudinaryConfig","inject","imageLoaded","ref","imageError","isMounted","emit","__emit","props","__props","effectivePublicId","computed","computedImg","cloudName","baseUrl","transformations","transformString","skeletonComponent","UserCircleIcon","PhotoIcon","computedDivStyle","style","computedDivClass","computedSkeletonClass","computedFallbackClass","computedImageClass","computedImageStyle","onImageLoad","onImageError","error","watch","onMounted","onUnmounted","_withDirectives","_hoisted_1","_createBlock","_resolveDynamicComponent","_vShow","_hoisted_2","_hoisted_3"],"mappings":"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","x_google_ignoreList":[0,1]}
|
|
1
|
+
{"version":3,"file":"CloudinaryImage.js","sources":["../../node_modules/@heroicons/vue/20/solid/esm/PhotoIcon.js","../../node_modules/@heroicons/vue/20/solid/esm/UserCircleIcon.js","../../src/components/CloudinaryImage.vue"],"sourcesContent":["import { createElementVNode as _createElementVNode, openBlock as _openBlock, createElementBlock as _createElementBlock } from \"vue\"\n\nexport default function render(_ctx, _cache) {\n return (_openBlock(), _createElementBlock(\"svg\", {\n xmlns: \"http://www.w3.org/2000/svg\",\n viewBox: \"0 0 20 20\",\n fill: \"currentColor\",\n \"aria-hidden\": \"true\",\n \"data-slot\": \"icon\"\n }, [\n _createElementVNode(\"path\", {\n \"fill-rule\": \"evenodd\",\n d: \"M1 5.25A2.25 2.25 0 0 1 3.25 3h13.5A2.25 2.25 0 0 1 19 5.25v9.5A2.25 2.25 0 0 1 16.75 17H3.25A2.25 2.25 0 0 1 1 14.75v-9.5Zm1.5 5.81v3.69c0 .414.336.75.75.75h13.5a.75.75 0 0 0 .75-.75v-2.69l-2.22-2.219a.75.75 0 0 0-1.06 0l-1.91 1.909.47.47a.75.75 0 1 1-1.06 1.06L6.53 8.091a.75.75 0 0 0-1.06 0l-2.97 2.97ZM12 7a1 1 0 1 1-2 0 1 1 0 0 1 2 0Z\",\n \"clip-rule\": \"evenodd\"\n })\n ]))\n}","import { createElementVNode as _createElementVNode, openBlock as _openBlock, createElementBlock as _createElementBlock } from \"vue\"\n\nexport default function render(_ctx, _cache) {\n return (_openBlock(), _createElementBlock(\"svg\", {\n xmlns: \"http://www.w3.org/2000/svg\",\n viewBox: \"0 0 20 20\",\n fill: \"currentColor\",\n \"aria-hidden\": \"true\",\n \"data-slot\": \"icon\"\n }, [\n _createElementVNode(\"path\", {\n \"fill-rule\": \"evenodd\",\n d: \"M18 10a8 8 0 1 1-16 0 8 8 0 0 1 16 0Zm-5.5-2.5a2.5 2.5 0 1 1-5 0 2.5 2.5 0 0 1 5 0ZM10 12a5.99 5.99 0 0 0-4.793 2.39A6.483 6.483 0 0 0 10 16.5a6.483 6.483 0 0 0 4.793-2.11A5.99 5.99 0 0 0 10 12Z\",\n \"clip-rule\": \"evenodd\"\n })\n ]))\n}","<!--\n @component CloudinaryImage\n @description Cloudinary image component with loading states and fallbacks.\n \n Displays images from Cloudinary with automatic transformations, loading\n skeleton, error fallback, and flexible sizing options.\n \n @props\n - src (string, optional): Direct image URL (bypasses Cloudinary URL generation)\n - publicId (string, optional): Cloudinary public ID\n - imagePublicId (string, optional): Alias for publicId (for compatibility)\n - asset (CloudinaryAsset, optional): Full asset object with transformations\n - fallbackPublicId (string, optional): Fallback image public ID\n - transformations (array, optional): Additional Cloudinary transformations\n - alt (string, optional): Alt text for accessibility\n - aspectRatio (string|number, optional): Aspect ratio (e.g., '16/9')\n - width (string|number, optional): Width in pixels or 'auto'\n - height (string|number, optional): Height in pixels or 'auto'\n - quality (string|number, optional): Image quality (1-100 or 'auto')\n - skeleton (string, optional): Skeleton type - 'user' or 'photo'\n - pulse (boolean, optional): Animate skeleton\n \n @emits\n - update:imageLoaded: Emitted when image load state changes\n - error: Emitted on image load error\n \n @example\n <!-- Using direct URL -->\n <CloudinaryImage\n src=\"https://res.cloudinary.com/demo/image/upload/sample.jpg\"\n :width=\"200\"\n :height=\"200\"\n alt=\"Sample image\"\n />\n \n @example\n <!-- Using public ID with auto-generated URL -->\n <CloudinaryImage\n public-id=\"avatars/user123\"\n :width=\"200\"\n :height=\"200\"\n alt=\"User avatar\"\n skeleton=\"user\"\n />\n-->\n<template>\n <div :style=\"computedDivStyle\" :class=\"computedDivClass\">\n <!-- Loading skeleton -->\n <div v-show=\"!imageLoaded && !imageError\" class=\"sl-flex sl-h-full sl-w-full sl-items-center sl-justify-center\">\n <div role=\"status\" :class=\"[{ 'sl-animate-pulse': pulse }]\">\n <component :is=\"skeletonComponent\" :class=\"computedSkeletonClass\" />\n </div>\n </div>\n\n <!-- Error fallback -->\n <div v-show=\"imageError && !imageLoaded\" class=\"sl-flex sl-h-full sl-w-full sl-items-center sl-justify-center\">\n <component :is=\"skeletonComponent\" :class=\"computedFallbackClass\" />\n </div>\n\n <!-- Image -->\n <div v-if=\"computedImg && isMounted\" v-show=\"imageLoaded\" class=\"sl-h-full sl-w-full\">\n <img\n :src=\"computedImg\"\n :alt=\"alt\"\n @load=\"onImageLoad\"\n @error=\"onImageError\"\n :class=\"computedImageClass\"\n :style=\"computedImageStyle\"\n />\n </div>\n </div>\n</template>\n\n<script setup lang=\"ts\">\n/**\n * CloudinaryImage - Image component with Cloudinary CDN support\n * \n * Provides a comprehensive image component with loading states, error handling,\n * and Cloudinary transformations. Uses plugin configuration for Cloudinary setup.\n * \n * ## Features\n * - Automatic loading skeleton\n * - Error fallback display\n * - Cloudinary URL generation\n * - Responsive sizing\n * - Aspect ratio control\n * - Quality optimization\n * \n * ## Plugin Configuration\n * Configure Cloudinary in your app setup:\n * ```typescript\n * app.use(StachelockUI, {\n * cloudinary: {\n * cloudName: 'your-cloud-name',\n * defaultTransformations: [...]\n * }\n * })\n * ```\n * \n * @module components/CloudinaryImage\n * @see {@link CloudinaryImageProps} for prop interface\n */\nimport { UserCircleIcon, PhotoIcon } from '@heroicons/vue/20/solid';\nimport { computed, inject, onMounted, onUnmounted, ref, watch } from 'vue';\nimport type { PropType } from 'vue';\nimport type { CloudinaryAsset, CloudinaryTransformationStep } from '../types/core';\n\n// Plugin configuration injection\nconst cloudinaryConfig = inject<{\n cloudName?: string;\n baseUrl?: string;\n defaultTransformations?: CloudinaryTransformationStep[];\n}>('cloudinary', {});\n\ninterface CustomClasses {\n div?: Record<string, boolean>;\n skeleton?: Record<string, boolean>;\n image?: Record<string, boolean>;\n fallback?: Record<string, boolean>;\n}\n\n// State\nconst imageLoaded = ref(false);\nconst imageError = ref(false);\nconst isMounted = ref(true);\n\nconst emit = defineEmits<{\n 'update:imageLoaded': [value: boolean];\n 'error': [error: unknown];\n}>();\n\nconst props = defineProps({\n /** Direct image URL - bypasses Cloudinary URL generation */\n src: {\n type: String,\n required: false,\n default: null\n },\n /** Cloudinary public ID */\n publicId: {\n type: String,\n required: false,\n default: null\n },\n /** Alias for publicId (for compatibility with different naming conventions) */\n imagePublicId: {\n type: String,\n required: false,\n default: null\n },\n asset: {\n type: Object as PropType<CloudinaryAsset | null>,\n default: null,\n required: false\n },\n fallbackPublicId: {\n type: String,\n required: false,\n default: null\n },\n /** Fallback URL to use if primary image fails */\n fallbackSrc: {\n type: String,\n required: false,\n default: null\n },\n transformations: {\n type: Array as PropType<Array<(image: unknown) => void>>,\n default: () => []\n },\n alt: {\n type: String,\n default: ''\n },\n aspectRatio: {\n type: [String, Number] as PropType<string | number>,\n default: null\n },\n width: {\n type: [String, Number] as PropType<string | number>,\n default: 64\n },\n height: {\n type: [String, Number] as PropType<string | number>,\n default: 64\n },\n quality: {\n type: [String, Number],\n default: '90'\n },\n devicePixelRatio: {\n type: String,\n default: '2.0'\n },\n skeleton: {\n type: String as PropType<'user' | 'photo'>,\n default: 'photo'\n },\n pulse: {\n type: Boolean,\n default: true\n },\n customClasses: {\n type: Object as PropType<CustomClasses>,\n default: () => ({})\n }\n});\n\n/**\n * Helper to check if a string is a full URL\n */\nconst isFullUrl = (value: string | null | undefined): boolean => {\n if (!value) return false;\n return value.startsWith('http://') || value.startsWith('https://') || value.startsWith('//');\n};\n\n// Computed: Direct URL source (if provided)\nconst directSrc = computed(() => {\n // Check src prop first\n if (props.src && isFullUrl(props.src)) {\n return props.src;\n }\n \n // Check if asset has secure_url or url\n if (props.asset?.secure_url) {\n return props.asset.secure_url;\n }\n if ((props.asset as any)?.url) {\n return (props.asset as any).url;\n }\n \n // Check if publicId or imagePublicId is actually a full URL\n if (props.publicId && isFullUrl(props.publicId)) {\n return props.publicId;\n }\n if (props.imagePublicId && isFullUrl(props.imagePublicId)) {\n return props.imagePublicId;\n }\n \n return null;\n});\n\n// Computed: Effective public ID (when not using direct URL)\nconst effectivePublicId = computed(() => {\n // If we have a direct URL, we don't need a public ID\n if (directSrc.value) return null;\n \n if (props.asset?.public_id) {\n return props.asset.public_id;\n }\n return props.imagePublicId || props.publicId || props.fallbackPublicId || null;\n});\n\n// Computed: Generate Cloudinary URL from public ID\nconst generatedCloudinaryUrl = computed(() => {\n if (!effectivePublicId.value) return null;\n \n const cloudName = cloudinaryConfig?.cloudName || 'demo';\n const baseUrl = cloudinaryConfig?.baseUrl || `https://res.cloudinary.com/${cloudName}/image/upload`;\n \n // Build transformation string\n const transformations: string[] = [];\n \n // Add width/height\n if (props.width && props.width !== 'auto') {\n transformations.push(`w_${props.width}`);\n }\n if (props.height && props.height !== 'auto') {\n transformations.push(`h_${props.height}`);\n }\n \n // Add quality\n if (props.quality) {\n transformations.push(`q_${props.quality}`);\n }\n \n // Add DPR\n if (props.devicePixelRatio) {\n transformations.push(`dpr_${props.devicePixelRatio}`);\n }\n \n // Auto format\n transformations.push('f_auto');\n \n // Crop mode\n transformations.push('c_fill');\n \n const transformString = transformations.join(',');\n \n return `${baseUrl}/${transformString}/${effectivePublicId.value}`;\n});\n\n// Computed: Final image URL (prefers direct URL over generated)\nconst computedImg = computed(() => {\n // Use direct URL if available\n if (directSrc.value) {\n return directSrc.value;\n }\n \n // Otherwise use generated Cloudinary URL\n return generatedCloudinaryUrl.value;\n});\n\n// Skeleton component based on type\nconst skeletonComponent = computed(() => {\n return props.skeleton === 'user' ? UserCircleIcon : PhotoIcon;\n});\n\n// Style computations\nconst computedDivStyle = computed(() => {\n const style: Record<string, string> = {};\n \n if (props.width && props.width !== 'auto') {\n style.width = typeof props.width === 'number' ? `${props.width}px` : props.width;\n }\n if (props.height && props.height !== 'auto') {\n style.height = typeof props.height === 'number' ? `${props.height}px` : props.height;\n }\n if (props.aspectRatio) {\n style.aspectRatio = String(props.aspectRatio);\n }\n \n return style;\n});\n\nconst computedDivClass = computed(() => ({\n 'sl-relative sl-overflow-hidden': true,\n ...props.customClasses?.div\n}));\n\nconst computedSkeletonClass = computed(() => ({\n 'sl-h-full sl-w-full sl-text-gray-200': true,\n ...props.customClasses?.skeleton\n}));\n\nconst computedFallbackClass = computed(() => ({\n 'sl-h-full sl-w-full sl-text-gray-300': true,\n ...props.customClasses?.fallback\n}));\n\nconst computedImageClass = computed(() => ({\n 'sl-h-full sl-w-full sl-object-cover': true,\n ...props.customClasses?.image\n}));\n\nconst computedImageStyle = computed(() => ({\n objectFit: 'cover' as const,\n}));\n\n// Event handlers\nconst onImageLoad = () => {\n imageLoaded.value = true;\n imageError.value = false;\n emit('update:imageLoaded', true);\n};\n\nconst onImageError = (error: Event) => {\n if (!isMounted.value) return;\n \n imageError.value = true;\n imageLoaded.value = false;\n emit('error', error);\n};\n\n// Reset state when source changes\nwatch(\n () => computedImg.value,\n () => {\n imageLoaded.value = false;\n imageError.value = false;\n }\n);\n\n// Lifecycle\nonMounted(() => {\n isMounted.value = true;\n});\n\nonUnmounted(() => {\n isMounted.value = false;\n});\n</script>\n\n<style scoped>\n/* Prevent layout shift */\n[data-loading=\"true\"] {\n min-height: 20px;\n}\n</style>\n\n"],"names":["render","_ctx","_cache","_openBlock","_createElementBlock","_createElementVNode","cloudinaryConfig","inject","imageLoaded","ref","imageError","isMounted","emit","__emit","props","__props","isFullUrl","value","directSrc","computed","effectivePublicId","generatedCloudinaryUrl","cloudName","baseUrl","transformations","transformString","computedImg","skeletonComponent","UserCircleIcon","PhotoIcon","computedDivStyle","style","computedDivClass","computedSkeletonClass","computedFallbackClass","computedImageClass","computedImageStyle","onImageLoad","onImageError","error","watch","onMounted","onUnmounted","_withDirectives","_hoisted_1","_createBlock","_resolveDynamicComponent","_vShow","_hoisted_2","_hoisted_3"],"mappings":"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","x_google_ignoreList":[0,1]}
|
|
Binary file
|
|
Binary file
|
package/dist/favicon.ico
ADDED
|
Binary file
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "Stachelock UI",
|
|
3
|
+
"short_name": "Stachelock UI",
|
|
4
|
+
"icons": [
|
|
5
|
+
{
|
|
6
|
+
"src": "/android-chrome-192x192.png",
|
|
7
|
+
"sizes": "192x192",
|
|
8
|
+
"type": "image/png"
|
|
9
|
+
},
|
|
10
|
+
{
|
|
11
|
+
"src": "/android-chrome-512x512.png",
|
|
12
|
+
"sizes": "512x512",
|
|
13
|
+
"type": "image/png"
|
|
14
|
+
}
|
|
15
|
+
],
|
|
16
|
+
"theme_color": "#ffffff",
|
|
17
|
+
"background_color": "#ffffff",
|
|
18
|
+
"display": "standalone"
|
|
19
|
+
}
|
|
@@ -7,11 +7,24 @@ interface CustomClasses {
|
|
|
7
7
|
fallback?: Record<string, boolean>;
|
|
8
8
|
}
|
|
9
9
|
declare const _default: import('vue').DefineComponent<import('vue').ExtractPropTypes<{
|
|
10
|
+
/** Direct image URL - bypasses Cloudinary URL generation */
|
|
11
|
+
src: {
|
|
12
|
+
type: StringConstructor;
|
|
13
|
+
required: false;
|
|
14
|
+
default: null;
|
|
15
|
+
};
|
|
16
|
+
/** Cloudinary public ID */
|
|
10
17
|
publicId: {
|
|
11
18
|
type: StringConstructor;
|
|
12
19
|
required: false;
|
|
13
20
|
default: null;
|
|
14
21
|
};
|
|
22
|
+
/** Alias for publicId (for compatibility with different naming conventions) */
|
|
23
|
+
imagePublicId: {
|
|
24
|
+
type: StringConstructor;
|
|
25
|
+
required: false;
|
|
26
|
+
default: null;
|
|
27
|
+
};
|
|
15
28
|
asset: {
|
|
16
29
|
type: PropType<CloudinaryAsset | null>;
|
|
17
30
|
default: null;
|
|
@@ -22,6 +35,12 @@ declare const _default: import('vue').DefineComponent<import('vue').ExtractPropT
|
|
|
22
35
|
required: false;
|
|
23
36
|
default: null;
|
|
24
37
|
};
|
|
38
|
+
/** Fallback URL to use if primary image fails */
|
|
39
|
+
fallbackSrc: {
|
|
40
|
+
type: StringConstructor;
|
|
41
|
+
required: false;
|
|
42
|
+
default: null;
|
|
43
|
+
};
|
|
25
44
|
transformations: {
|
|
26
45
|
type: PropType<((image: unknown) => void)[]>;
|
|
27
46
|
default: () => never[];
|
|
@@ -66,11 +85,24 @@ declare const _default: import('vue').DefineComponent<import('vue').ExtractPropT
|
|
|
66
85
|
error: (error: unknown) => any;
|
|
67
86
|
"update:imageLoaded": (value: boolean) => any;
|
|
68
87
|
}, string, import('vue').PublicProps, Readonly<import('vue').ExtractPropTypes<{
|
|
88
|
+
/** Direct image URL - bypasses Cloudinary URL generation */
|
|
89
|
+
src: {
|
|
90
|
+
type: StringConstructor;
|
|
91
|
+
required: false;
|
|
92
|
+
default: null;
|
|
93
|
+
};
|
|
94
|
+
/** Cloudinary public ID */
|
|
69
95
|
publicId: {
|
|
70
96
|
type: StringConstructor;
|
|
71
97
|
required: false;
|
|
72
98
|
default: null;
|
|
73
99
|
};
|
|
100
|
+
/** Alias for publicId (for compatibility with different naming conventions) */
|
|
101
|
+
imagePublicId: {
|
|
102
|
+
type: StringConstructor;
|
|
103
|
+
required: false;
|
|
104
|
+
default: null;
|
|
105
|
+
};
|
|
74
106
|
asset: {
|
|
75
107
|
type: PropType<CloudinaryAsset | null>;
|
|
76
108
|
default: null;
|
|
@@ -81,6 +113,12 @@ declare const _default: import('vue').DefineComponent<import('vue').ExtractPropT
|
|
|
81
113
|
required: false;
|
|
82
114
|
default: null;
|
|
83
115
|
};
|
|
116
|
+
/** Fallback URL to use if primary image fails */
|
|
117
|
+
fallbackSrc: {
|
|
118
|
+
type: StringConstructor;
|
|
119
|
+
required: false;
|
|
120
|
+
default: null;
|
|
121
|
+
};
|
|
84
122
|
transformations: {
|
|
85
123
|
type: PropType<((image: unknown) => void)[]>;
|
|
86
124
|
default: () => never[];
|
|
@@ -127,9 +165,12 @@ declare const _default: import('vue').DefineComponent<import('vue').ExtractPropT
|
|
|
127
165
|
}>, {
|
|
128
166
|
width: string | number;
|
|
129
167
|
height: string | number;
|
|
168
|
+
src: string;
|
|
130
169
|
publicId: string;
|
|
170
|
+
imagePublicId: string;
|
|
131
171
|
asset: CloudinaryAsset | null;
|
|
132
172
|
fallbackPublicId: string;
|
|
173
|
+
fallbackSrc: string;
|
|
133
174
|
transformations: ((image: unknown) => void)[];
|
|
134
175
|
alt: string;
|
|
135
176
|
aspectRatio: string | number;
|
package/dist/src/types/core.d.ts
CHANGED
|
@@ -536,6 +536,10 @@ export interface CloudinaryTransformationStep {
|
|
|
536
536
|
export interface CloudinaryAsset {
|
|
537
537
|
/** Cloudinary public ID */
|
|
538
538
|
public_id: string;
|
|
539
|
+
/** Secure URL (from Cloudinary API response) */
|
|
540
|
+
secure_url?: string;
|
|
541
|
+
/** URL (from Cloudinary API response) */
|
|
542
|
+
url?: string;
|
|
539
543
|
/** Asset transformations */
|
|
540
544
|
transformations?: CloudinaryTransformationStep[];
|
|
541
545
|
/** Asset format */
|
|
@@ -547,12 +551,18 @@ export interface CloudinaryAsset {
|
|
|
547
551
|
* Props for CloudinaryImage component.
|
|
548
552
|
*/
|
|
549
553
|
export interface CloudinaryImageProps {
|
|
554
|
+
/** Direct image URL - bypasses Cloudinary URL generation */
|
|
555
|
+
src?: string;
|
|
550
556
|
/** Cloudinary public ID */
|
|
551
557
|
publicId?: string;
|
|
558
|
+
/** Alias for publicId (for compatibility with different naming conventions) */
|
|
559
|
+
imagePublicId?: string;
|
|
552
560
|
/** Full asset object with transformations */
|
|
553
561
|
asset?: CloudinaryAsset | null;
|
|
554
562
|
/** Fallback public ID if primary fails */
|
|
555
563
|
fallbackPublicId?: string;
|
|
564
|
+
/** Fallback URL to use if primary image fails */
|
|
565
|
+
fallbackSrc?: string;
|
|
556
566
|
/** Additional transformations to apply */
|
|
557
567
|
transformations?: Array<(image: CloudinaryAsset) => void>;
|
|
558
568
|
/** Alt text for accessibility */
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
declare const _default: import('vue').DefineComponent<{}, {}, {}, {}, {}, import('vue').ComponentOptionsMixin, import('vue').ComponentOptionsMixin, {}, string, import('vue').PublicProps, Readonly<{}> & Readonly<{}>, {}, {}, {}, {}, string, import('vue').ComponentProvideOptions, true, {}, HTMLDivElement>;
|
|
2
|
+
export default _default;
|
|
@@ -5,6 +5,7 @@ export { default as BreadcrumbPage } from './BreadcrumbPage';
|
|
|
5
5
|
export { default as ButtonPage } from './ButtonPage';
|
|
6
6
|
export { default as CloudinaryImagePage } from './CloudinaryImagePage';
|
|
7
7
|
export { default as LoadingPage } from './LoadingPage';
|
|
8
|
+
export { default as LottiePage } from './LottiePage';
|
|
8
9
|
export { default as MenuPage } from './MenuPage';
|
|
9
10
|
export { default as ModalPage } from './ModalPage';
|
|
10
11
|
export { default as ProgressPage } from './ProgressPage';
|