@speckle/ui-components 2.19.6 → 2.20.2
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/{AvatarEditor-ce4e7960.js → AvatarEditor-911ee3da.js} +50 -58
- package/dist/AvatarEditor-911ee3da.js.map +1 -0
- package/dist/AvatarEditor-f04b220d.cjs +2 -0
- package/dist/AvatarEditor-f04b220d.cjs.map +1 -0
- package/dist/components/common/Alert.vue.d.ts +2 -0
- package/dist/components/common/text/Link.vue.d.ts +4 -4
- package/dist/components/form/Button.vue.d.ts +58 -195
- package/dist/components/form/Checkbox.vue.d.ts +1 -1
- package/dist/components/form/Radio.vue.d.ts +1 -1
- package/dist/components/form/TextInput.vue.d.ts +19 -9
- package/dist/components/form/select/Base.vue.d.ts +3 -3
- package/dist/components/layout/Dialog.vue.d.ts +24 -3
- package/dist/components/layout/DialogSection.vue.d.ts +3 -3
- package/dist/components/layout/Table.vue.d.ts +0 -2
- package/dist/components/layout/sidebar/menu/group/Item.vue.d.ts +6 -2
- package/dist/composables/user/avatar.d.ts +2 -2
- package/dist/helpers/form/button.d.ts +2 -2
- package/dist/helpers/layout/components.d.ts +1 -0
- package/dist/helpers/tailwind.d.ts +1 -1
- package/dist/lib.cjs +1 -1
- package/dist/lib.cjs.map +1 -1
- package/dist/lib.d.ts +2 -2
- package/dist/lib.js +2298 -2468
- package/dist/lib.js.map +1 -1
- package/dist/style.css +1 -1
- package/package.json +6 -4
- package/dist/AvatarEditor-25bff065.cjs +0 -2
- package/dist/AvatarEditor-25bff065.cjs.map +0 -1
- package/dist/AvatarEditor-ce4e7960.js.map +0 -1
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import { defineComponent as
|
|
1
|
+
import { defineComponent as j, ref as d, computed as N, onUnmounted as V, watch as k, openBlock as _, createElementBlock as O, createElementVNode as s, normalizeClass as p, withDirectives as c, createVNode as r, unref as t, createBlock as D, normalizeStyle as E, createCommentVNode as P, withCtx as m, mergeProps as Z, toHandlers as H, createTextVNode as C } from "vue";
|
|
2
2
|
import { ArrowUturnLeftIcon as q, ArrowUturnRightIcon as M, ArrowUpOnSquareIcon as T, ArrowLeftOnRectangleIcon as X, PhotoIcon as G, XMarkIcon as J } from "@heroicons/vue/24/outline";
|
|
3
3
|
import { Cropper as K } from "vue-advanced-cropper";
|
|
4
4
|
import "vue-advanced-cropper/dist/style.css";
|
|
5
5
|
import { FormButton as i, FormFileUploadZone as Q } from "./lib.js";
|
|
6
|
-
import { directive as
|
|
6
|
+
import { directive as a } from "vue-tippy";
|
|
7
7
|
import "lodash";
|
|
8
8
|
import "@heroicons/vue/24/solid";
|
|
9
9
|
import "@heroicons/vue/20/solid";
|
|
@@ -13,7 +13,7 @@ import "nanoid";
|
|
|
13
13
|
import "@vueuse/core";
|
|
14
14
|
import "@headlessui/vue";
|
|
15
15
|
import "v3-infinite-loading";
|
|
16
|
-
const W = { class: "flex flex-col space-y-2" }, Y = { class: "flex" }, ee = { class: "flex mx-14 space-x-2" }, te = /* @__PURE__ */
|
|
16
|
+
const W = { class: "flex flex-col space-y-2" }, Y = { class: "flex" }, ee = { class: "flex mx-14 space-x-2" }, te = /* @__PURE__ */ s("div", { class: "grow" }, null, -1), xe = /* @__PURE__ */ j({
|
|
17
17
|
__name: "AvatarEditor",
|
|
18
18
|
props: {
|
|
19
19
|
user: null,
|
|
@@ -21,10 +21,10 @@ const W = { class: "flex flex-col space-y-2" }, Y = { class: "flex" }, ee = { cl
|
|
|
21
21
|
size: null
|
|
22
22
|
},
|
|
23
23
|
emits: ["cancel", "save"],
|
|
24
|
-
setup(v, { emit:
|
|
25
|
-
const
|
|
24
|
+
setup(v, { emit: R }) {
|
|
25
|
+
const b = R, h = v, n = d(
|
|
26
26
|
null
|
|
27
|
-
), x = d(null), u = d(null), l = d(null),
|
|
27
|
+
), x = d(null), u = d(null), l = d(null), f = N(() => {
|
|
28
28
|
switch (h.size) {
|
|
29
29
|
case "xs":
|
|
30
30
|
return { width: 64, height: 64 };
|
|
@@ -36,12 +36,12 @@ const W = { class: "flex flex-col space-y-2" }, Y = { class: "flex" }, ee = { cl
|
|
|
36
36
|
default:
|
|
37
37
|
return { width: 32, height: 32 };
|
|
38
38
|
}
|
|
39
|
-
}),
|
|
39
|
+
}), y = (e) => {
|
|
40
40
|
l.value && URL.revokeObjectURL(l.value), l.value = e;
|
|
41
|
-
},
|
|
41
|
+
}, w = (e) => {
|
|
42
42
|
const o = e.files[0];
|
|
43
43
|
o && (u.value = o);
|
|
44
|
-
},
|
|
44
|
+
}, z = (e) => {
|
|
45
45
|
var o;
|
|
46
46
|
return e ? "border-primary" : (o = u.value) != null && o.error ? "border-danger" : "border-outline-2";
|
|
47
47
|
}, L = () => {
|
|
@@ -64,10 +64,10 @@ const W = { class: "flex flex-col space-y-2" }, Y = { class: "flex" }, ee = { cl
|
|
|
64
64
|
}, S = () => {
|
|
65
65
|
var o;
|
|
66
66
|
const e = ((o = n.value) == null ? void 0 : o.getResult().canvas.toDataURL("image/jpeg", 0.85)) || null;
|
|
67
|
-
|
|
67
|
+
b("save", e);
|
|
68
68
|
};
|
|
69
|
-
return
|
|
70
|
-
|
|
69
|
+
return V(() => {
|
|
70
|
+
y(null);
|
|
71
71
|
}), k(
|
|
72
72
|
() => h.user.avatar,
|
|
73
73
|
(e) => {
|
|
@@ -80,49 +80,45 @@ const W = { class: "flex flex-col space-y-2" }, Y = { class: "flex" }, ee = { cl
|
|
|
80
80
|
l.value = e != null && e.file && !e.error ? URL.createObjectURL(e.file) : null;
|
|
81
81
|
},
|
|
82
82
|
{ deep: !0 }
|
|
83
|
-
), (e, o) => (
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
class:
|
|
83
|
+
), (e, o) => (_(), O("div", W, [
|
|
84
|
+
s("div", Y, [
|
|
85
|
+
s("div", {
|
|
86
|
+
class: p(["flex flex-col px-2 space-y-1", { invisible: !l.value }])
|
|
87
87
|
}, [
|
|
88
|
-
|
|
88
|
+
c(r(i, {
|
|
89
89
|
"icon-left": t(q),
|
|
90
90
|
"hide-text": "",
|
|
91
|
-
|
|
92
|
-
outlined: "",
|
|
91
|
+
color: "outline",
|
|
93
92
|
onClick: L
|
|
94
93
|
}, null, 8, ["icon-left"]), [
|
|
95
|
-
[t(
|
|
94
|
+
[t(a), "Rotate left"]
|
|
96
95
|
]),
|
|
97
|
-
|
|
96
|
+
c(r(i, {
|
|
98
97
|
"icon-left": t(M),
|
|
99
98
|
"hide-text": "",
|
|
100
|
-
|
|
101
|
-
outlined: "",
|
|
99
|
+
color: "outline",
|
|
102
100
|
onClick: U
|
|
103
101
|
}, null, 8, ["icon-left"]), [
|
|
104
|
-
[t(
|
|
102
|
+
[t(a), "Rotate right"]
|
|
105
103
|
]),
|
|
106
|
-
|
|
104
|
+
c(r(i, {
|
|
107
105
|
"icon-left": t(T),
|
|
108
106
|
"hide-text": "",
|
|
109
|
-
|
|
110
|
-
outlined: "",
|
|
107
|
+
color: "outline",
|
|
111
108
|
onClick: A
|
|
112
109
|
}, null, 8, ["icon-left"]), [
|
|
113
|
-
[t(
|
|
110
|
+
[t(a), "Flip vertically"]
|
|
114
111
|
]),
|
|
115
|
-
|
|
112
|
+
c(r(i, {
|
|
116
113
|
"icon-left": t(X),
|
|
117
114
|
"hide-text": "",
|
|
118
|
-
|
|
119
|
-
outlined: "",
|
|
115
|
+
color: "outline",
|
|
120
116
|
onClick: I
|
|
121
117
|
}, null, 8, ["icon-left"]), [
|
|
122
|
-
[t(
|
|
118
|
+
[t(a), "Flip horizontally"]
|
|
123
119
|
])
|
|
124
120
|
], 2),
|
|
125
|
-
l.value ? (
|
|
121
|
+
l.value ? (_(), D(t(K), {
|
|
126
122
|
key: 0,
|
|
127
123
|
ref_key: "cropper",
|
|
128
124
|
ref: n,
|
|
@@ -131,65 +127,61 @@ const W = { class: "flex flex-col space-y-2" }, Y = { class: "flex" }, ee = { cl
|
|
|
131
127
|
"stencil-props": {
|
|
132
128
|
aspectRatio: 1 / 1
|
|
133
129
|
},
|
|
134
|
-
canvas:
|
|
135
|
-
style: E(`width: ${
|
|
130
|
+
canvas: f.value,
|
|
131
|
+
style: E(`width: ${f.value.width}px; height: ${f.value.height}px`)
|
|
136
132
|
}, null, 8, ["src", "canvas", "style"])) : P("", !0),
|
|
137
133
|
r(Q, {
|
|
138
134
|
ref_key: "uploadZone",
|
|
139
135
|
ref: x,
|
|
140
|
-
class:
|
|
136
|
+
class: p(["cropper flex items-center justify-center", { hidden: l.value }]),
|
|
141
137
|
accept: "image/*",
|
|
142
138
|
"size-limit": 5 * 1024 * 1024,
|
|
143
|
-
onFilesSelected:
|
|
139
|
+
onFilesSelected: w
|
|
144
140
|
}, {
|
|
145
|
-
default:
|
|
146
|
-
|
|
147
|
-
class: ["cursor-pointer text-center w-full h-full border-dashed border-2 rounded-md p-4 flex items-center justify-center text-sm text-foreground-2", [
|
|
148
|
-
}, H(
|
|
141
|
+
default: m(({ isDraggingFiles: g, activatorOn: $ }) => [
|
|
142
|
+
s("div", Z({
|
|
143
|
+
class: ["cursor-pointer text-center w-full h-full border-dashed border-2 rounded-md p-4 flex items-center justify-center text-sm text-foreground-2", [z(g)]]
|
|
144
|
+
}, H($, !0)), " Click here or drag and drop an image ", 16)
|
|
149
145
|
]),
|
|
150
146
|
_: 1
|
|
151
147
|
}, 8, ["class"]),
|
|
152
|
-
|
|
153
|
-
class:
|
|
148
|
+
s("div", {
|
|
149
|
+
class: p(["flex flex-col px-2 space-y-1", { invisible: !l.value }])
|
|
154
150
|
}, [
|
|
155
|
-
|
|
151
|
+
c(r(i, {
|
|
156
152
|
"icon-left": t(G),
|
|
157
153
|
"hide-text": "",
|
|
158
|
-
size: "sm",
|
|
159
154
|
onClick: B
|
|
160
155
|
}, null, 8, ["icon-left"]), [
|
|
161
|
-
[t(
|
|
156
|
+
[t(a), "Replace image"]
|
|
162
157
|
]),
|
|
163
|
-
|
|
158
|
+
c(r(i, {
|
|
164
159
|
"icon-left": t(J),
|
|
165
160
|
"hide-text": "",
|
|
166
|
-
size: "sm",
|
|
167
161
|
color: "danger",
|
|
168
162
|
onClick: F
|
|
169
163
|
}, null, 8, ["icon-left"]), [
|
|
170
|
-
[t(
|
|
164
|
+
[t(a), "Remove"]
|
|
171
165
|
])
|
|
172
166
|
], 2)
|
|
173
167
|
]),
|
|
174
|
-
|
|
168
|
+
s("div", ee, [
|
|
175
169
|
te,
|
|
176
170
|
r(i, {
|
|
177
|
-
color: "
|
|
178
|
-
size: "sm",
|
|
171
|
+
color: "outline",
|
|
179
172
|
onClick: o[0] || (o[0] = (g) => e.$emit("cancel"))
|
|
180
173
|
}, {
|
|
181
|
-
default:
|
|
182
|
-
|
|
174
|
+
default: m(() => [
|
|
175
|
+
C("Close")
|
|
183
176
|
]),
|
|
184
177
|
_: 1
|
|
185
178
|
}),
|
|
186
179
|
r(i, {
|
|
187
|
-
size: "sm",
|
|
188
180
|
disabled: v.disabled,
|
|
189
181
|
onClick: S
|
|
190
182
|
}, {
|
|
191
|
-
default:
|
|
192
|
-
|
|
183
|
+
default: m(() => [
|
|
184
|
+
C("Save")
|
|
193
185
|
]),
|
|
194
186
|
_: 1
|
|
195
187
|
}, 8, ["disabled"])
|
|
@@ -200,4 +192,4 @@ const W = { class: "flex flex-col space-y-2" }, Y = { class: "flex" }, ee = { cl
|
|
|
200
192
|
export {
|
|
201
193
|
xe as default
|
|
202
194
|
};
|
|
203
|
-
//# sourceMappingURL=AvatarEditor-
|
|
195
|
+
//# sourceMappingURL=AvatarEditor-911ee3da.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"AvatarEditor-911ee3da.js","sources":["../src/components/user/AvatarEditor.vue"],"sourcesContent":["<template>\n <div class=\"flex flex-col space-y-2\">\n <div class=\"flex\">\n <div class=\"flex flex-col px-2 space-y-1\" :class=\"{ invisible: !activeImageUrl }\">\n <FormButton\n v-tippy=\"'Rotate left'\"\n :icon-left=\"ArrowUturnLeftIcon\"\n hide-text\n color=\"outline\"\n @click=\"rotateLeft\"\n />\n <FormButton\n v-tippy=\"'Rotate right'\"\n :icon-left=\"ArrowUturnRightIcon\"\n hide-text\n color=\"outline\"\n @click=\"rotateRight\"\n />\n <FormButton\n v-tippy=\"'Flip vertically'\"\n :icon-left=\"ArrowUpOnSquareIcon\"\n hide-text\n color=\"outline\"\n @click=\"flipVertical\"\n />\n <FormButton\n v-tippy=\"'Flip horizontally'\"\n :icon-left=\"ArrowLeftOnRectangleIcon\"\n hide-text\n color=\"outline\"\n @click=\"flipHorizontal\"\n />\n </div>\n <Cropper\n v-if=\"activeImageUrl\"\n ref=\"cropper\"\n class=\"cropper\"\n :src=\"activeImageUrl\"\n :stencil-props=\"{\n aspectRatio: 1 / 1\n }\"\n :canvas=\"canvasSize\"\n :style=\"`width: ${canvasSize.width}px; height: ${canvasSize.height}px`\"\n />\n <FormFileUploadZone\n ref=\"uploadZone\"\n v-slot=\"{ isDraggingFiles, activatorOn }\"\n class=\"cropper flex items-center justify-center\"\n :class=\"{ hidden: activeImageUrl }\"\n accept=\"image/*\"\n :size-limit=\"5 * 1024 * 1024\"\n @files-selected=\"onFilesSelected\"\n >\n <div\n class=\"cursor-pointer text-center w-full h-full border-dashed border-2 rounded-md p-4 flex items-center justify-center text-sm text-foreground-2\"\n :class=\"[getDashedBorderClasses(isDraggingFiles)]\"\n v-on=\"activatorOn\"\n >\n Click here or drag and drop an image\n </div>\n </FormFileUploadZone>\n <div class=\"flex flex-col px-2 space-y-1\" :class=\"{ invisible: !activeImageUrl }\">\n <FormButton\n v-tippy=\"'Replace image'\"\n :icon-left=\"PhotoIcon\"\n hide-text\n @click=\"onReplace\"\n />\n <FormButton\n v-tippy=\"'Remove'\"\n :icon-left=\"XMarkIcon\"\n hide-text\n color=\"danger\"\n @click=\"onRemove\"\n />\n </div>\n </div>\n <div class=\"flex mx-14 space-x-2\">\n <div class=\"grow\" />\n <FormButton color=\"outline\" @click=\"$emit('cancel')\">Close</FormButton>\n <FormButton :disabled=\"disabled\" @click=\"onSave\">Save</FormButton>\n </div>\n </div>\n</template>\n<script setup lang=\"ts\">\nimport {\n ArrowUturnLeftIcon,\n ArrowUturnRightIcon,\n ArrowLeftOnRectangleIcon,\n ArrowUpOnSquareIcon,\n XMarkIcon,\n PhotoIcon\n} from '@heroicons/vue/24/outline'\nimport type { Nullable } from '@speckle/shared'\nimport { onUnmounted, ref, watch, computed } from 'vue'\nimport { Cropper } from 'vue-advanced-cropper'\nimport 'vue-advanced-cropper/dist/style.css'\nimport FormButton from '~~/src/components/form/Button.vue'\nimport FormFileUploadZone from '~~/src/components/form/file-upload/Zone.vue'\nimport type { UploadableFileItem } from '~~/src/composables/form/fileUpload'\nimport type { AvatarUser, UserAvatarSize } from '~~/src/composables/user/avatar'\nimport { directive as vTippy } from 'vue-tippy'\n\n/**\n * Always try to lazy load this, as it's quite heavy\n */\n\nconst emit = defineEmits([\"cancel\", \"save\"])\n\nconst props = defineProps({\n user: null,\n disabled: { type: Boolean },\n size: null\n})\n\nconst cropper = ref(\n null as Nullable<{\n flip: (x: number, y: number) => void\n rotate: (angle: number) => void\n getResult: () => { canvas: HTMLCanvasElement }\n }>\n)\nconst uploadZone = ref(null as Nullable<{ triggerPicker: () => void }>)\nconst selectedUpload = ref(null as Nullable<UploadableFileItem>)\nconst activeImageUrl = ref(null as Nullable<string>)\n\nconst canvasSize = computed(() => {\n switch (props.size) {\n case 'xs' || 'sm' || 'lg' || 'xl':\n return { width: 64, height: 64 }\n case 'xxl':\n return { width: 140, height: 140 }\n case 'editable':\n return { width: 240, height: 240 }\n case 'base':\n default:\n return { width: 32, height: 32 }\n }\n})\n\nconst setNewActiveUrl = (url: Nullable<string>) => {\n if (activeImageUrl.value) {\n URL.revokeObjectURL(activeImageUrl.value)\n }\n\n activeImageUrl.value = url\n}\n\nconst onFilesSelected = (params: { files: UploadableFileItem[] }) => {\n const file = params.files[0]\n if (!file) return\n selectedUpload.value = file\n}\n\nconst getDashedBorderClasses = (isDraggingFiles: boolean) => {\n if (isDraggingFiles) return 'border-primary'\n if (selectedUpload.value?.error) return 'border-danger'\n\n return 'border-outline-2'\n}\n\nconst rotateLeft = () => cropper.value?.rotate(-90)\nconst rotateRight = () => cropper.value?.rotate(90)\nconst flipHorizontal = () => cropper.value?.flip(1, 0)\nconst flipVertical = () => cropper.value?.flip(0, 1)\n\nconst onReplace = () => uploadZone.value?.triggerPicker()\nconst onRemove = () => {\n selectedUpload.value = null\n activeImageUrl.value = null\n}\nconst onSave = () => {\n const newUrl = cropper.value?.getResult().canvas.toDataURL('image/jpeg', 0.85) || null\n emit('save', newUrl)\n}\n\nonUnmounted(() => {\n setNewActiveUrl(null)\n})\n\nwatch(\n () => props.user.avatar,\n (newAvatar) => {\n activeImageUrl.value = newAvatar || null\n },\n { immediate: true }\n)\n\nwatch(\n selectedUpload,\n (newUpload) => {\n activeImageUrl.value =\n newUpload?.file && !newUpload.error ? URL.createObjectURL(newUpload.file) : null\n },\n { deep: true }\n)\n</script>\n"],"names":["emit","__emit","props","__props","cropper","ref","uploadZone","selectedUpload","activeImageUrl","canvasSize","computed","setNewActiveUrl","url","onFilesSelected","params","file","getDashedBorderClasses","isDraggingFiles","_a","rotateLeft","rotateRight","flipHorizontal","flipVertical","onReplace","onRemove","onSave","newUrl","onUnmounted","watch","newAvatar","newUpload"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;AA2GA,UAAMA,IAAOC,GAEPC,IAAQC,GAMRC,IAAUC;AAAA,MACd;AAAA,IAAA,GAMIC,IAAaD,EAAI,IAA+C,GAChEE,IAAiBF,EAAI,IAAoC,GACzDG,IAAiBH,EAAI,IAAwB,GAE7CI,IAAaC,EAAS,MAAM;AAChC,cAAQR,EAAM,MAAM;AAAA,QAClB,KAAK;AACH,iBAAO,EAAE,OAAO,IAAI,QAAQ,GAAG;AAAA,QACjC,KAAK;AACH,iBAAO,EAAE,OAAO,KAAK,QAAQ,IAAI;AAAA,QACnC,KAAK;AACH,iBAAO,EAAE,OAAO,KAAK,QAAQ,IAAI;AAAA,QACnC,KAAK;AAAA,QACL;AACE,iBAAO,EAAE,OAAO,IAAI,QAAQ,GAAG;AAAA,MACnC;AAAA,IAAA,CACD,GAEKS,IAAkB,CAACC,MAA0B;AACjD,MAAIJ,EAAe,SACb,IAAA,gBAAgBA,EAAe,KAAK,GAG1CA,EAAe,QAAQI;AAAA,IAAA,GAGnBC,IAAkB,CAACC,MAA4C;AAC7D,YAAAC,IAAOD,EAAO,MAAM,CAAC;AAC3B,MAAKC,MACLR,EAAe,QAAQQ;AAAA,IAAA,GAGnBC,IAAyB,CAACC,MAA6B;;AACvD,aAAAA,IAAwB,oBACxBC,IAAAX,EAAe,UAAf,QAAAW,EAAsB,QAAc,kBAEjC;AAAA,IAAA,GAGHC,IAAa,MAAA;;AAAM,cAAAD,IAAAd,EAAQ,UAAR,gBAAAc,EAAe,OAAO;AAAA,OACzCE,IAAc,MAAA;;AAAM,cAAAF,IAAAd,EAAQ,UAAR,gBAAAc,EAAe,OAAO;AAAA,OAC1CG,IAAiB,MAAA;;AAAM,cAAAH,IAAAd,EAAQ,UAAR,gBAAAc,EAAe,KAAK,GAAG;AAAA,OAC9CI,IAAe,MAAA;;AAAM,cAAAJ,IAAAd,EAAQ,UAAR,gBAAAc,EAAe,KAAK,GAAG;AAAA,OAE5CK,IAAY,MAAM;;AAAA,cAAAL,IAAAZ,EAAW,UAAX,gBAAAY,EAAkB;AAAA,OACpCM,IAAW,MAAM;AACrB,MAAAjB,EAAe,QAAQ,MACvBC,EAAe,QAAQ;AAAA,IAAA,GAEnBiB,IAAS,MAAM;;AACb,YAAAC,MAASR,IAAAd,EAAQ,UAAR,gBAAAc,EAAe,YAAY,OAAO,UAAU,cAAc,UAAS;AAClF,MAAAlB,EAAK,QAAQ0B,CAAM;AAAA,IAAA;AAGrB,WAAAC,EAAY,MAAM;AAChB,MAAAhB,EAAgB,IAAI;AAAA,IAAA,CACrB,GAEDiB;AAAA,MACE,MAAM1B,EAAM,KAAK;AAAA,MACjB,CAAC2B,MAAc;AACb,QAAArB,EAAe,QAAQqB,KAAa;AAAA,MACtC;AAAA,MACA,EAAE,WAAW,GAAK;AAAA,IAAA,GAGpBD;AAAA,MACErB;AAAA,MACA,CAACuB,MAAc;AACE,QAAAtB,EAAA,QACbsB,KAAA,QAAAA,EAAW,QAAQ,CAACA,EAAU,QAAQ,IAAI,gBAAgBA,EAAU,IAAI,IAAI;AAAA,MAChF;AAAA,MACA,EAAE,MAAM,GAAK;AAAA,IAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const e=require("vue"),n=require("@heroicons/vue/24/outline"),R=require("vue-advanced-cropper");require("vue-advanced-cropper/dist/style.css");const o=require("./lib.cjs"),c=require("vue-tippy");require("lodash");require("@heroicons/vue/24/solid");require("@heroicons/vue/20/solid");require("@speckle/shared");require("vee-validate");require("nanoid");require("@vueuse/core");require("@headlessui/vue");require("v3-infinite-loading");const B={class:"flex flex-col space-y-2"},_={class:"flex"},F={class:"flex mx-14 space-x-2"},z=e.createElementVNode("div",{class:"grow"},null,-1),D=e.defineComponent({__name:"AvatarEditor",props:{user:null,disabled:{type:Boolean},size:null},emits:["cancel","save"],setup(s,{emit:h}){const m=h,d=s,i=e.ref(null),f=e.ref(null),a=e.ref(null),r=e.ref(null),u=e.computed(()=>{switch(d.size){case"xs":return{width:64,height:64};case"xxl":return{width:140,height:140};case"editable":return{width:240,height:240};case"base":default:return{width:32,height:32}}}),p=t=>{r.value&&URL.revokeObjectURL(r.value),r.value=t},x=t=>{const l=t.files[0];l&&(a.value=l)},g=t=>{var l;return t?"border-primary":(l=a.value)!=null&&l.error?"border-danger":"border-outline-2"},C=()=>{var t;return(t=i.value)==null?void 0:t.rotate(-90)},w=()=>{var t;return(t=i.value)==null?void 0:t.rotate(90)},k=()=>{var t;return(t=i.value)==null?void 0:t.flip(1,0)},N=()=>{var t;return(t=i.value)==null?void 0:t.flip(0,1)},V=()=>{var t;return(t=f.value)==null?void 0:t.triggerPicker()},b=()=>{a.value=null,r.value=null},y=()=>{var l;const t=((l=i.value)==null?void 0:l.getResult().canvas.toDataURL("image/jpeg",.85))||null;m("save",t)};return e.onUnmounted(()=>{p(null)}),e.watch(()=>d.user.avatar,t=>{r.value=t||null},{immediate:!0}),e.watch(a,t=>{r.value=t!=null&&t.file&&!t.error?URL.createObjectURL(t.file):null},{deep:!0}),(t,l)=>(e.openBlock(),e.createElementBlock("div",B,[e.createElementVNode("div",_,[e.createElementVNode("div",{class:e.normalizeClass(["flex flex-col px-2 space-y-1",{invisible:!r.value}])},[e.withDirectives(e.createVNode(o.FormButton,{"icon-left":e.unref(n.ArrowUturnLeftIcon),"hide-text":"",color:"outline",onClick:C},null,8,["icon-left"]),[[e.unref(c.directive),"Rotate left"]]),e.withDirectives(e.createVNode(o.FormButton,{"icon-left":e.unref(n.ArrowUturnRightIcon),"hide-text":"",color:"outline",onClick:w},null,8,["icon-left"]),[[e.unref(c.directive),"Rotate right"]]),e.withDirectives(e.createVNode(o.FormButton,{"icon-left":e.unref(n.ArrowUpOnSquareIcon),"hide-text":"",color:"outline",onClick:N},null,8,["icon-left"]),[[e.unref(c.directive),"Flip vertically"]]),e.withDirectives(e.createVNode(o.FormButton,{"icon-left":e.unref(n.ArrowLeftOnRectangleIcon),"hide-text":"",color:"outline",onClick:k},null,8,["icon-left"]),[[e.unref(c.directive),"Flip horizontally"]])],2),r.value?(e.openBlock(),e.createBlock(e.unref(R.Cropper),{key:0,ref_key:"cropper",ref:i,class:"cropper",src:r.value,"stencil-props":{aspectRatio:1/1},canvas:u.value,style:e.normalizeStyle(`width: ${u.value.width}px; height: ${u.value.height}px`)},null,8,["src","canvas","style"])):e.createCommentVNode("",!0),e.createVNode(o.FormFileUploadZone,{ref_key:"uploadZone",ref:f,class:e.normalizeClass(["cropper flex items-center justify-center",{hidden:r.value}]),accept:"image/*","size-limit":5*1024*1024,onFilesSelected:x},{default:e.withCtx(({isDraggingFiles:v,activatorOn:q})=>[e.createElementVNode("div",e.mergeProps({class:["cursor-pointer text-center w-full h-full border-dashed border-2 rounded-md p-4 flex items-center justify-center text-sm text-foreground-2",[g(v)]]},e.toHandlers(q,!0))," Click here or drag and drop an image ",16)]),_:1},8,["class"]),e.createElementVNode("div",{class:e.normalizeClass(["flex flex-col px-2 space-y-1",{invisible:!r.value}])},[e.withDirectives(e.createVNode(o.FormButton,{"icon-left":e.unref(n.PhotoIcon),"hide-text":"",onClick:V},null,8,["icon-left"]),[[e.unref(c.directive),"Replace image"]]),e.withDirectives(e.createVNode(o.FormButton,{"icon-left":e.unref(n.XMarkIcon),"hide-text":"",color:"danger",onClick:b},null,8,["icon-left"]),[[e.unref(c.directive),"Remove"]])],2)]),e.createElementVNode("div",F,[z,e.createVNode(o.FormButton,{color:"outline",onClick:l[0]||(l[0]=v=>t.$emit("cancel"))},{default:e.withCtx(()=>[e.createTextVNode("Close")]),_:1}),e.createVNode(o.FormButton,{disabled:s.disabled,onClick:y},{default:e.withCtx(()=>[e.createTextVNode("Save")]),_:1},8,["disabled"])])]))}});exports.default=D;
|
|
2
|
+
//# sourceMappingURL=AvatarEditor-f04b220d.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"AvatarEditor-f04b220d.cjs","sources":["../src/components/user/AvatarEditor.vue"],"sourcesContent":["<template>\n <div class=\"flex flex-col space-y-2\">\n <div class=\"flex\">\n <div class=\"flex flex-col px-2 space-y-1\" :class=\"{ invisible: !activeImageUrl }\">\n <FormButton\n v-tippy=\"'Rotate left'\"\n :icon-left=\"ArrowUturnLeftIcon\"\n hide-text\n color=\"outline\"\n @click=\"rotateLeft\"\n />\n <FormButton\n v-tippy=\"'Rotate right'\"\n :icon-left=\"ArrowUturnRightIcon\"\n hide-text\n color=\"outline\"\n @click=\"rotateRight\"\n />\n <FormButton\n v-tippy=\"'Flip vertically'\"\n :icon-left=\"ArrowUpOnSquareIcon\"\n hide-text\n color=\"outline\"\n @click=\"flipVertical\"\n />\n <FormButton\n v-tippy=\"'Flip horizontally'\"\n :icon-left=\"ArrowLeftOnRectangleIcon\"\n hide-text\n color=\"outline\"\n @click=\"flipHorizontal\"\n />\n </div>\n <Cropper\n v-if=\"activeImageUrl\"\n ref=\"cropper\"\n class=\"cropper\"\n :src=\"activeImageUrl\"\n :stencil-props=\"{\n aspectRatio: 1 / 1\n }\"\n :canvas=\"canvasSize\"\n :style=\"`width: ${canvasSize.width}px; height: ${canvasSize.height}px`\"\n />\n <FormFileUploadZone\n ref=\"uploadZone\"\n v-slot=\"{ isDraggingFiles, activatorOn }\"\n class=\"cropper flex items-center justify-center\"\n :class=\"{ hidden: activeImageUrl }\"\n accept=\"image/*\"\n :size-limit=\"5 * 1024 * 1024\"\n @files-selected=\"onFilesSelected\"\n >\n <div\n class=\"cursor-pointer text-center w-full h-full border-dashed border-2 rounded-md p-4 flex items-center justify-center text-sm text-foreground-2\"\n :class=\"[getDashedBorderClasses(isDraggingFiles)]\"\n v-on=\"activatorOn\"\n >\n Click here or drag and drop an image\n </div>\n </FormFileUploadZone>\n <div class=\"flex flex-col px-2 space-y-1\" :class=\"{ invisible: !activeImageUrl }\">\n <FormButton\n v-tippy=\"'Replace image'\"\n :icon-left=\"PhotoIcon\"\n hide-text\n @click=\"onReplace\"\n />\n <FormButton\n v-tippy=\"'Remove'\"\n :icon-left=\"XMarkIcon\"\n hide-text\n color=\"danger\"\n @click=\"onRemove\"\n />\n </div>\n </div>\n <div class=\"flex mx-14 space-x-2\">\n <div class=\"grow\" />\n <FormButton color=\"outline\" @click=\"$emit('cancel')\">Close</FormButton>\n <FormButton :disabled=\"disabled\" @click=\"onSave\">Save</FormButton>\n </div>\n </div>\n</template>\n<script setup lang=\"ts\">\nimport {\n ArrowUturnLeftIcon,\n ArrowUturnRightIcon,\n ArrowLeftOnRectangleIcon,\n ArrowUpOnSquareIcon,\n XMarkIcon,\n PhotoIcon\n} from '@heroicons/vue/24/outline'\nimport type { Nullable } from '@speckle/shared'\nimport { onUnmounted, ref, watch, computed } from 'vue'\nimport { Cropper } from 'vue-advanced-cropper'\nimport 'vue-advanced-cropper/dist/style.css'\nimport FormButton from '~~/src/components/form/Button.vue'\nimport FormFileUploadZone from '~~/src/components/form/file-upload/Zone.vue'\nimport type { UploadableFileItem } from '~~/src/composables/form/fileUpload'\nimport type { AvatarUser, UserAvatarSize } from '~~/src/composables/user/avatar'\nimport { directive as vTippy } from 'vue-tippy'\n\n/**\n * Always try to lazy load this, as it's quite heavy\n */\n\nconst emit = defineEmits([\"cancel\", \"save\"])\n\nconst props = defineProps({\n user: null,\n disabled: { type: Boolean },\n size: null\n})\n\nconst cropper = ref(\n null as Nullable<{\n flip: (x: number, y: number) => void\n rotate: (angle: number) => void\n getResult: () => { canvas: HTMLCanvasElement }\n }>\n)\nconst uploadZone = ref(null as Nullable<{ triggerPicker: () => void }>)\nconst selectedUpload = ref(null as Nullable<UploadableFileItem>)\nconst activeImageUrl = ref(null as Nullable<string>)\n\nconst canvasSize = computed(() => {\n switch (props.size) {\n case 'xs' || 'sm' || 'lg' || 'xl':\n return { width: 64, height: 64 }\n case 'xxl':\n return { width: 140, height: 140 }\n case 'editable':\n return { width: 240, height: 240 }\n case 'base':\n default:\n return { width: 32, height: 32 }\n }\n})\n\nconst setNewActiveUrl = (url: Nullable<string>) => {\n if (activeImageUrl.value) {\n URL.revokeObjectURL(activeImageUrl.value)\n }\n\n activeImageUrl.value = url\n}\n\nconst onFilesSelected = (params: { files: UploadableFileItem[] }) => {\n const file = params.files[0]\n if (!file) return\n selectedUpload.value = file\n}\n\nconst getDashedBorderClasses = (isDraggingFiles: boolean) => {\n if (isDraggingFiles) return 'border-primary'\n if (selectedUpload.value?.error) return 'border-danger'\n\n return 'border-outline-2'\n}\n\nconst rotateLeft = () => cropper.value?.rotate(-90)\nconst rotateRight = () => cropper.value?.rotate(90)\nconst flipHorizontal = () => cropper.value?.flip(1, 0)\nconst flipVertical = () => cropper.value?.flip(0, 1)\n\nconst onReplace = () => uploadZone.value?.triggerPicker()\nconst onRemove = () => {\n selectedUpload.value = null\n activeImageUrl.value = null\n}\nconst onSave = () => {\n const newUrl = cropper.value?.getResult().canvas.toDataURL('image/jpeg', 0.85) || null\n emit('save', newUrl)\n}\n\nonUnmounted(() => {\n setNewActiveUrl(null)\n})\n\nwatch(\n () => props.user.avatar,\n (newAvatar) => {\n activeImageUrl.value = newAvatar || null\n },\n { immediate: true }\n)\n\nwatch(\n selectedUpload,\n (newUpload) => {\n activeImageUrl.value =\n newUpload?.file && !newUpload.error ? URL.createObjectURL(newUpload.file) : null\n },\n { deep: true }\n)\n</script>\n"],"names":["emit","__emit","props","__props","cropper","ref","uploadZone","selectedUpload","activeImageUrl","canvasSize","computed","setNewActiveUrl","url","onFilesSelected","params","file","getDashedBorderClasses","isDraggingFiles","_a","rotateLeft","rotateRight","flipHorizontal","flipVertical","onReplace","onRemove","onSave","newUrl","onUnmounted","watch","newAvatar","newUpload"],"mappings":"4xBA2GA,MAAMA,EAAOC,EAEPC,EAAQC,EAMRC,EAAUC,EAAA,IACd,IAAA,EAMIC,EAAaD,MAAI,IAA+C,EAChEE,EAAiBF,MAAI,IAAoC,EACzDG,EAAiBH,MAAI,IAAwB,EAE7CI,EAAaC,EAAAA,SAAS,IAAM,CAChC,OAAQR,EAAM,KAAM,CAClB,IAAK,KACH,MAAO,CAAE,MAAO,GAAI,OAAQ,EAAG,EACjC,IAAK,MACH,MAAO,CAAE,MAAO,IAAK,OAAQ,GAAI,EACnC,IAAK,WACH,MAAO,CAAE,MAAO,IAAK,OAAQ,GAAI,EACnC,IAAK,OACL,QACE,MAAO,CAAE,MAAO,GAAI,OAAQ,EAAG,CACnC,CAAA,CACD,EAEKS,EAAmBC,GAA0B,CAC7CJ,EAAe,OACb,IAAA,gBAAgBA,EAAe,KAAK,EAG1CA,EAAe,MAAQI,CAAA,EAGnBC,EAAmBC,GAA4C,CAC7D,MAAAC,EAAOD,EAAO,MAAM,CAAC,EACtBC,IACLR,EAAe,MAAQQ,EAAA,EAGnBC,EAA0BC,GAA6B,OACvD,OAAAA,EAAwB,kBACxBC,EAAAX,EAAe,QAAf,MAAAW,EAAsB,MAAc,gBAEjC,kBAAA,EAGHC,EAAa,IAAA,OAAM,OAAAD,EAAAd,EAAQ,QAAR,YAAAc,EAAe,OAAO,MACzCE,EAAc,IAAA,OAAM,OAAAF,EAAAd,EAAQ,QAAR,YAAAc,EAAe,OAAO,KAC1CG,EAAiB,IAAA,OAAM,OAAAH,EAAAd,EAAQ,QAAR,YAAAc,EAAe,KAAK,EAAG,IAC9CI,EAAe,IAAA,OAAM,OAAAJ,EAAAd,EAAQ,QAAR,YAAAc,EAAe,KAAK,EAAG,IAE5CK,EAAY,IAAM,OAAA,OAAAL,EAAAZ,EAAW,QAAX,YAAAY,EAAkB,iBACpCM,EAAW,IAAM,CACrBjB,EAAe,MAAQ,KACvBC,EAAe,MAAQ,IAAA,EAEnBiB,EAAS,IAAM,OACb,MAAAC,IAASR,EAAAd,EAAQ,QAAR,YAAAc,EAAe,YAAY,OAAO,UAAU,aAAc,OAAS,KAClFlB,EAAK,OAAQ0B,CAAM,CAAA,EAGrBC,OAAAA,EAAAA,YAAY,IAAM,CAChBhB,EAAgB,IAAI,CAAA,CACrB,EAEDiB,EAAA,MACE,IAAM1B,EAAM,KAAK,OAChB2B,GAAc,CACbrB,EAAe,MAAQqB,GAAa,IACtC,EACA,CAAE,UAAW,EAAK,CAAA,EAGpBD,EAAA,MACErB,EACCuB,GAAc,CACEtB,EAAA,MACbsB,GAAA,MAAAA,EAAW,MAAQ,CAACA,EAAU,MAAQ,IAAI,gBAAgBA,EAAU,IAAI,EAAI,IAChF,EACA,CAAE,KAAM,EAAK,CAAA"}
|
|
@@ -11,6 +11,7 @@ declare const _default: __VLS_WithTemplateSlots<import("vue").DefineComponent<__
|
|
|
11
11
|
externalUrl?: boolean | undefined;
|
|
12
12
|
}[] | undefined;
|
|
13
13
|
customIcon?: PropAnyComponent | undefined;
|
|
14
|
+
hideIcon?: boolean | undefined;
|
|
14
15
|
size?: Size | undefined;
|
|
15
16
|
}>, {
|
|
16
17
|
color: string;
|
|
@@ -27,6 +28,7 @@ declare const _default: __VLS_WithTemplateSlots<import("vue").DefineComponent<__
|
|
|
27
28
|
externalUrl?: boolean | undefined;
|
|
28
29
|
}[] | undefined;
|
|
29
30
|
customIcon?: PropAnyComponent | undefined;
|
|
31
|
+
hideIcon?: boolean | undefined;
|
|
30
32
|
size?: Size | undefined;
|
|
31
33
|
}>, {
|
|
32
34
|
color: string;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import type { PropType } from 'vue';
|
|
2
2
|
import type { Nullable, Optional } from '@speckle/shared';
|
|
3
3
|
import type { PropAnyComponent } from '../../../helpers/common/components';
|
|
4
|
-
type LinkSize = '
|
|
4
|
+
type LinkSize = 'sm' | 'base' | 'lg';
|
|
5
5
|
declare const _default: __VLS_WithTemplateSlots<import("vue").DefineComponent<{
|
|
6
6
|
to: {
|
|
7
7
|
type: PropType<Optional<string>>;
|
|
@@ -47,7 +47,7 @@ declare const _default: __VLS_WithTemplateSlots<import("vue").DefineComponent<{
|
|
|
47
47
|
type: BooleanConstructor;
|
|
48
48
|
default: boolean;
|
|
49
49
|
};
|
|
50
|
-
|
|
50
|
+
underline: {
|
|
51
51
|
type: BooleanConstructor;
|
|
52
52
|
default: boolean;
|
|
53
53
|
};
|
|
@@ -98,7 +98,7 @@ declare const _default: __VLS_WithTemplateSlots<import("vue").DefineComponent<{
|
|
|
98
98
|
type: BooleanConstructor;
|
|
99
99
|
default: boolean;
|
|
100
100
|
};
|
|
101
|
-
|
|
101
|
+
underline: {
|
|
102
102
|
type: BooleanConstructor;
|
|
103
103
|
default: boolean;
|
|
104
104
|
};
|
|
@@ -113,7 +113,7 @@ declare const _default: __VLS_WithTemplateSlots<import("vue").DefineComponent<{
|
|
|
113
113
|
iconRight: Nullable<PropAnyComponent>;
|
|
114
114
|
hideText: boolean;
|
|
115
115
|
foregroundLink: boolean;
|
|
116
|
-
|
|
116
|
+
underline: boolean;
|
|
117
117
|
}, {}>, {
|
|
118
118
|
default?(_: {}): any;
|
|
119
119
|
}>;
|