@speckle/ui-components 2.20.1 → 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.
@@ -1,9 +1,9 @@
1
- import { defineComponent as N, ref as d, computed as V, onUnmounted as $, watch as k, openBlock as y, createElementBlock as O, createElementVNode as a, normalizeClass as f, withDirectives as s, createVNode as r, unref as t, createBlock as D, normalizeStyle as E, createCommentVNode as P, withCtx as p, mergeProps as Z, toHandlers as H, createTextVNode as z } from "vue";
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 c } from "vue-tippy";
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__ */ a("div", { class: "grow" }, null, -1), xe = /* @__PURE__ */ N({
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: C }) {
25
- const R = C, h = v, n = d(
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), m = V(() => {
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
- }), _ = (e) => {
39
+ }), y = (e) => {
40
40
  l.value && URL.revokeObjectURL(l.value), l.value = e;
41
- }, b = (e) => {
41
+ }, w = (e) => {
42
42
  const o = e.files[0];
43
43
  o && (u.value = o);
44
- }, w = (e) => {
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
- R("save", e);
67
+ b("save", e);
68
68
  };
69
- return $(() => {
70
- _(null);
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) => (y(), O("div", W, [
84
- a("div", Y, [
85
- a("div", {
86
- class: f(["flex flex-col px-2 space-y-1", { invisible: !l.value }])
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
- s(r(i, {
88
+ c(r(i, {
89
89
  "icon-left": t(q),
90
90
  "hide-text": "",
91
- size: "sm",
92
- outlined: "",
91
+ color: "outline",
93
92
  onClick: L
94
93
  }, null, 8, ["icon-left"]), [
95
- [t(c), "Rotate left"]
94
+ [t(a), "Rotate left"]
96
95
  ]),
97
- s(r(i, {
96
+ c(r(i, {
98
97
  "icon-left": t(M),
99
98
  "hide-text": "",
100
- size: "sm",
101
- outlined: "",
99
+ color: "outline",
102
100
  onClick: U
103
101
  }, null, 8, ["icon-left"]), [
104
- [t(c), "Rotate right"]
102
+ [t(a), "Rotate right"]
105
103
  ]),
106
- s(r(i, {
104
+ c(r(i, {
107
105
  "icon-left": t(T),
108
106
  "hide-text": "",
109
- size: "sm",
110
- outlined: "",
107
+ color: "outline",
111
108
  onClick: A
112
109
  }, null, 8, ["icon-left"]), [
113
- [t(c), "Flip vertically"]
110
+ [t(a), "Flip vertically"]
114
111
  ]),
115
- s(r(i, {
112
+ c(r(i, {
116
113
  "icon-left": t(X),
117
114
  "hide-text": "",
118
- size: "sm",
119
- outlined: "",
115
+ color: "outline",
120
116
  onClick: I
121
117
  }, null, 8, ["icon-left"]), [
122
- [t(c), "Flip horizontally"]
118
+ [t(a), "Flip horizontally"]
123
119
  ])
124
120
  ], 2),
125
- l.value ? (y(), D(t(K), {
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: m.value,
135
- style: E(`width: ${m.value.width}px; height: ${m.value.height}px`)
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: f(["cropper flex items-center justify-center", { hidden: l.value }]),
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: b
139
+ onFilesSelected: w
144
140
  }, {
145
- default: p(({ isDraggingFiles: g, activatorOn: j }) => [
146
- a("div", Z({
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", [w(g)]]
148
- }, H(j, !0)), " Click here or drag and drop an image ", 16)
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
- a("div", {
153
- class: f(["flex flex-col px-2 space-y-1", { invisible: !l.value }])
148
+ s("div", {
149
+ class: p(["flex flex-col px-2 space-y-1", { invisible: !l.value }])
154
150
  }, [
155
- s(r(i, {
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(c), "Replace image"]
156
+ [t(a), "Replace image"]
162
157
  ]),
163
- s(r(i, {
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(c), "Remove"]
164
+ [t(a), "Remove"]
171
165
  ])
172
166
  ], 2)
173
167
  ]),
174
- a("div", ee, [
168
+ s("div", ee, [
175
169
  te,
176
170
  r(i, {
177
- color: "secondary",
178
- size: "sm",
171
+ color: "outline",
179
172
  onClick: o[0] || (o[0] = (g) => e.$emit("cancel"))
180
173
  }, {
181
- default: p(() => [
182
- z(" Close ")
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: p(() => [
192
- z("Save")
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-ce4e7960.js.map
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 = 'xs' | 'sm' | 'base' | 'lg' | 'xl';
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
- noUnderline: {
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
- noUnderline: {
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
- noUnderline: boolean;
116
+ underline: boolean;
117
117
  }, {}>, {
118
118
  default?(_: {}): any;
119
119
  }>;