@speckle/ui-components 2.16.1-alpha8 → 2.16.1-alpha9

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.
@@ -169,7 +169,7 @@ const G = { class: "flex flex-col space-y-2" }, J = { class: "flex" }, K = { cla
169
169
  onClick: o[0] || (o[0] = (h) => e.$emit("cancel"))
170
170
  }, {
171
171
  default: m(() => [
172
- k(" Cancel ")
172
+ k(" Close ")
173
173
  ]),
174
174
  _: 1
175
175
  }),
@@ -190,4 +190,4 @@ const G = { class: "flex flex-col space-y-2" }, J = { class: "flex" }, K = { cla
190
190
  export {
191
191
  me as default
192
192
  };
193
- //# sourceMappingURL=AvatarEditor-1bbae637.js.map
193
+ //# sourceMappingURL=AvatarEditor-594c4e0d.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"AvatarEditor-594c4e0d.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 size=\"sm\"\n outlined\n @click=\"rotateLeft\"\n />\n <FormButton\n v-tippy=\"'Rotate right'\"\n :icon-left=\"ArrowUturnRightIcon\"\n hide-text\n size=\"sm\"\n outlined\n @click=\"rotateRight\"\n />\n <FormButton\n v-tippy=\"'Flip vertically'\"\n :icon-left=\"ArrowUpOnSquareIcon\"\n hide-text\n size=\"sm\"\n outlined\n @click=\"flipVertical\"\n />\n <FormButton\n v-tippy=\"'Flip horizontally'\"\n :icon-left=\"ArrowLeftOnRectangleIcon\"\n hide-text\n size=\"sm\"\n outlined\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=\"{\n width: 250,\n height: 250\n }\"\n style=\"width: 250px; height: 250px\"\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 size=\"sm\"\n @click=\"onReplace\"\n />\n <FormButton\n v-tippy=\"'Remove'\"\n :icon-left=\"XMarkIcon\"\n hide-text\n size=\"sm\"\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=\"secondary\" size=\"sm\" @click=\"$emit('cancel')\">\n Close\n </FormButton>\n <FormButton size=\"sm\" :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 { Nullable } from '@speckle/shared'\nimport { onUnmounted, ref, watch } 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 { UploadableFileItem } from '~~/src/composables/form/fileUpload'\nimport { AvatarUser } 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})\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 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":["cropper","ref","uploadZone","selectedUpload","activeImageUrl","setNewActiveUrl","url","onFilesSelected","params","file","getDashedBorderClasses","isDraggingFiles","_a","rotateLeft","rotateRight","flipHorizontal","flipVertical","onReplace","onRemove","onSave","newUrl","emit","onUnmounted","watch","props","newAvatar","newUpload"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;iBA6HMA,IAAUC;AAAA,MACd;AAAA,IAAA,GAMIC,IAAaD,EAAI,IAA+C,GAChEE,IAAiBF,EAAI,IAAoC,GACzDG,IAAiBH,EAAI,IAAwB,GAE7CI,IAAkB,CAACC,MAA0B;AACjD,MAAIF,EAAe,SACb,IAAA,gBAAgBA,EAAe,KAAK,GAG1CA,EAAe,QAAQE;AAAA,IAAA,GAGnBC,IAAkB,CAACC,MAA4C;AAC7D,YAAAC,IAAOD,EAAO,MAAM,CAAC;AAC3B,MAAKC,MACLN,EAAe,QAAQM;AAAA,IAAA,GAGnBC,IAAyB,CAACC,MAA6B;;AACvD,aAAAA,IAAwB,oBACxBC,IAAAT,EAAe,UAAf,QAAAS,EAAsB,QAAc,kBAEjC;AAAA,IAAA,GAGHC,IAAa,MAAA;;AAAM,cAAAD,IAAAZ,EAAQ,UAAR,gBAAAY,EAAe,OAAO;AAAA,OACzCE,IAAc,MAAA;;AAAM,cAAAF,IAAAZ,EAAQ,UAAR,gBAAAY,EAAe,OAAO;AAAA,OAC1CG,IAAiB,MAAA;;AAAM,cAAAH,IAAAZ,EAAQ,UAAR,gBAAAY,EAAe,KAAK,GAAG;AAAA,OAC9CI,IAAe,MAAA;;AAAM,cAAAJ,IAAAZ,EAAQ,UAAR,gBAAAY,EAAe,KAAK,GAAG;AAAA,OAE5CK,IAAY,MAAM;;AAAA,cAAAL,IAAAV,EAAW,UAAX,gBAAAU,EAAkB;AAAA,OACpCM,IAAW,MAAM;AACrB,MAAAf,EAAe,QAAQ,MACvBC,EAAe,QAAQ;AAAA,IAAA,GAEnBe,IAAS,MAAM;;AACb,YAAAC,MAASR,IAAAZ,EAAQ,UAAR,gBAAAY,EAAe,YAAY,OAAO,UAAU,cAAc,UAAS;AAClF,MAAAS,EAAK,QAAQD,CAAM;AAAA,IAAA;AAGrB,WAAAE,EAAY,MAAM;AAChB,MAAAjB,EAAgB,IAAI;AAAA,IAAA,CACrB,GAEDkB;AAAA,MACE,MAAMC,EAAM,KAAK;AAAA,MACjB,CAACC,MAAc;AACb,QAAArB,EAAe,QAAQqB,KAAa;AAAA,MACtC;AAAA,MACA,EAAE,WAAW,GAAK;AAAA,IAAA,GAGpBF;AAAA,MACEpB;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;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
@@ -1,2 +1,2 @@
1
- "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const e=require("vue"),n=require("@heroicons/vue/24/outline"),q=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("vee-validate");require("nanoid");require("@speckle/shared");require("@vueuse/core");require("@headlessui/vue");require("v3-infinite-loading");const R={class:"flex flex-col space-y-2"},w={class:"flex"},z={class:"flex mx-14 space-x-2"},B=e.createElementVNode("div",{class:"grow"},null,-1),_=e.defineComponent({__name:"AvatarEditor",props:{user:null,disabled:{type:Boolean}},emits:["cancel","save"],setup(s,{emit:f}){const v=s,i=e.ref(null),u=e.ref(null),a=e.ref(null),r=e.ref(null),m=t=>{r.value&&URL.revokeObjectURL(r.value),r.value=t},p=t=>{const l=t.files[0];l&&(a.value=l)},h=t=>{var l;return t?"border-primary":(l=a.value)!=null&&l.error?"border-danger":"border-outline-2"},x=()=>{var t;return(t=i.value)==null?void 0:t.rotate(-90)},g=()=>{var t;return(t=i.value)==null?void 0:t.rotate(90)},C=()=>{var t;return(t=i.value)==null?void 0:t.flip(1,0)},k=()=>{var t;return(t=i.value)==null?void 0:t.flip(0,1)},N=()=>{var t;return(t=u.value)==null?void 0:t.triggerPicker()},V=()=>{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;f("save",t)};return e.onUnmounted(()=>{m(null)}),e.watch(()=>v.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",R,[e.createElementVNode("div",w,[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":"",size:"sm",outlined:"",onClick:x},null,8,["icon-left"]),[[e.unref(c.directive),"Rotate left"]]),e.withDirectives(e.createVNode(o.FormButton,{"icon-left":e.unref(n.ArrowUturnRightIcon),"hide-text":"",size:"sm",outlined:"",onClick:g},null,8,["icon-left"]),[[e.unref(c.directive),"Rotate right"]]),e.withDirectives(e.createVNode(o.FormButton,{"icon-left":e.unref(n.ArrowUpOnSquareIcon),"hide-text":"",size:"sm",outlined:"",onClick:k},null,8,["icon-left"]),[[e.unref(c.directive),"Flip vertically"]]),e.withDirectives(e.createVNode(o.FormButton,{"icon-left":e.unref(n.ArrowLeftOnRectangleIcon),"hide-text":"",size:"sm",outlined:"",onClick:C},null,8,["icon-left"]),[[e.unref(c.directive),"Flip horizontally"]])],2),r.value?(e.openBlock(),e.createBlock(e.unref(q.Cropper),{key:0,ref_key:"cropper",ref:i,class:"cropper",src:r.value,"stencil-props":{aspectRatio:1/1},canvas:{width:250,height:250},style:{width:"250px",height:"250px"}},null,8,["src"])):e.createCommentVNode("",!0),e.createVNode(o.FormFileUploadZone,{ref_key:"uploadZone",ref:u,class:e.normalizeClass(["cropper flex items-center justify-center",{hidden:r.value}]),accept:"image/*","size-limit":5*1024*1024,onFilesSelected:p},{default:e.withCtx(({isDraggingFiles:d,activatorOn:b})=>[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",[h(d)]]},e.toHandlers(b,!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":"",size:"sm",onClick:N},null,8,["icon-left"]),[[e.unref(c.directive),"Replace image"]]),e.withDirectives(e.createVNode(o.FormButton,{"icon-left":e.unref(n.XMarkIcon),"hide-text":"",size:"sm",color:"danger",onClick:V},null,8,["icon-left"]),[[e.unref(c.directive),"Remove"]])],2)]),e.createElementVNode("div",z,[B,e.createVNode(o.FormButton,{color:"secondary",size:"sm",onClick:l[0]||(l[0]=d=>t.$emit("cancel"))},{default:e.withCtx(()=>[e.createTextVNode(" Cancel ")]),_:1}),e.createVNode(o.FormButton,{size:"sm",disabled:s.disabled,onClick:y},{default:e.withCtx(()=>[e.createTextVNode("Save")]),_:1},8,["disabled"])])]))}});exports.default=_;
2
- //# sourceMappingURL=AvatarEditor-f4b16291.cjs.map
1
+ "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const e=require("vue"),n=require("@heroicons/vue/24/outline"),q=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("vee-validate");require("nanoid");require("@speckle/shared");require("@vueuse/core");require("@headlessui/vue");require("v3-infinite-loading");const R={class:"flex flex-col space-y-2"},w={class:"flex"},z={class:"flex mx-14 space-x-2"},B=e.createElementVNode("div",{class:"grow"},null,-1),_=e.defineComponent({__name:"AvatarEditor",props:{user:null,disabled:{type:Boolean}},emits:["cancel","save"],setup(a,{emit:f}){const v=a,i=e.ref(null),u=e.ref(null),s=e.ref(null),r=e.ref(null),m=t=>{r.value&&URL.revokeObjectURL(r.value),r.value=t},p=t=>{const l=t.files[0];l&&(s.value=l)},h=t=>{var l;return t?"border-primary":(l=s.value)!=null&&l.error?"border-danger":"border-outline-2"},x=()=>{var t;return(t=i.value)==null?void 0:t.rotate(-90)},g=()=>{var t;return(t=i.value)==null?void 0:t.rotate(90)},C=()=>{var t;return(t=i.value)==null?void 0:t.flip(1,0)},k=()=>{var t;return(t=i.value)==null?void 0:t.flip(0,1)},N=()=>{var t;return(t=u.value)==null?void 0:t.triggerPicker()},V=()=>{s.value=null,r.value=null},y=()=>{var l;const t=((l=i.value)==null?void 0:l.getResult().canvas.toDataURL("image/jpeg",.85))||null;f("save",t)};return e.onUnmounted(()=>{m(null)}),e.watch(()=>v.user.avatar,t=>{r.value=t||null},{immediate:!0}),e.watch(s,t=>{r.value=t!=null&&t.file&&!t.error?URL.createObjectURL(t.file):null},{deep:!0}),(t,l)=>(e.openBlock(),e.createElementBlock("div",R,[e.createElementVNode("div",w,[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":"",size:"sm",outlined:"",onClick:x},null,8,["icon-left"]),[[e.unref(c.directive),"Rotate left"]]),e.withDirectives(e.createVNode(o.FormButton,{"icon-left":e.unref(n.ArrowUturnRightIcon),"hide-text":"",size:"sm",outlined:"",onClick:g},null,8,["icon-left"]),[[e.unref(c.directive),"Rotate right"]]),e.withDirectives(e.createVNode(o.FormButton,{"icon-left":e.unref(n.ArrowUpOnSquareIcon),"hide-text":"",size:"sm",outlined:"",onClick:k},null,8,["icon-left"]),[[e.unref(c.directive),"Flip vertically"]]),e.withDirectives(e.createVNode(o.FormButton,{"icon-left":e.unref(n.ArrowLeftOnRectangleIcon),"hide-text":"",size:"sm",outlined:"",onClick:C},null,8,["icon-left"]),[[e.unref(c.directive),"Flip horizontally"]])],2),r.value?(e.openBlock(),e.createBlock(e.unref(q.Cropper),{key:0,ref_key:"cropper",ref:i,class:"cropper",src:r.value,"stencil-props":{aspectRatio:1/1},canvas:{width:250,height:250},style:{width:"250px",height:"250px"}},null,8,["src"])):e.createCommentVNode("",!0),e.createVNode(o.FormFileUploadZone,{ref_key:"uploadZone",ref:u,class:e.normalizeClass(["cropper flex items-center justify-center",{hidden:r.value}]),accept:"image/*","size-limit":5*1024*1024,onFilesSelected:p},{default:e.withCtx(({isDraggingFiles:d,activatorOn:b})=>[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",[h(d)]]},e.toHandlers(b,!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":"",size:"sm",onClick:N},null,8,["icon-left"]),[[e.unref(c.directive),"Replace image"]]),e.withDirectives(e.createVNode(o.FormButton,{"icon-left":e.unref(n.XMarkIcon),"hide-text":"",size:"sm",color:"danger",onClick:V},null,8,["icon-left"]),[[e.unref(c.directive),"Remove"]])],2)]),e.createElementVNode("div",z,[B,e.createVNode(o.FormButton,{color:"secondary",size:"sm",onClick:l[0]||(l[0]=d=>t.$emit("cancel"))},{default:e.withCtx(()=>[e.createTextVNode(" Close ")]),_:1}),e.createVNode(o.FormButton,{size:"sm",disabled:a.disabled,onClick:y},{default:e.withCtx(()=>[e.createTextVNode("Save")]),_:1},8,["disabled"])])]))}});exports.default=_;
2
+ //# sourceMappingURL=AvatarEditor-92ea4e16.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"AvatarEditor-92ea4e16.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 size=\"sm\"\n outlined\n @click=\"rotateLeft\"\n />\n <FormButton\n v-tippy=\"'Rotate right'\"\n :icon-left=\"ArrowUturnRightIcon\"\n hide-text\n size=\"sm\"\n outlined\n @click=\"rotateRight\"\n />\n <FormButton\n v-tippy=\"'Flip vertically'\"\n :icon-left=\"ArrowUpOnSquareIcon\"\n hide-text\n size=\"sm\"\n outlined\n @click=\"flipVertical\"\n />\n <FormButton\n v-tippy=\"'Flip horizontally'\"\n :icon-left=\"ArrowLeftOnRectangleIcon\"\n hide-text\n size=\"sm\"\n outlined\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=\"{\n width: 250,\n height: 250\n }\"\n style=\"width: 250px; height: 250px\"\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 size=\"sm\"\n @click=\"onReplace\"\n />\n <FormButton\n v-tippy=\"'Remove'\"\n :icon-left=\"XMarkIcon\"\n hide-text\n size=\"sm\"\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=\"secondary\" size=\"sm\" @click=\"$emit('cancel')\">\n Close\n </FormButton>\n <FormButton size=\"sm\" :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 { Nullable } from '@speckle/shared'\nimport { onUnmounted, ref, watch } 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 { UploadableFileItem } from '~~/src/composables/form/fileUpload'\nimport { AvatarUser } 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})\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 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":["cropper","ref","uploadZone","selectedUpload","activeImageUrl","setNewActiveUrl","url","onFilesSelected","params","file","getDashedBorderClasses","isDraggingFiles","_a","rotateLeft","rotateRight","flipHorizontal","flipVertical","onReplace","onRemove","onSave","newUrl","emit","onUnmounted","watch","props","newAvatar","newUpload"],"mappings":"4xBA6HMA,EAAUC,EAAA,IACd,IAAA,EAMIC,EAAaD,MAAI,IAA+C,EAChEE,EAAiBF,MAAI,IAAoC,EACzDG,EAAiBH,MAAI,IAAwB,EAE7CI,EAAmBC,GAA0B,CAC7CF,EAAe,OACb,IAAA,gBAAgBA,EAAe,KAAK,EAG1CA,EAAe,MAAQE,CAAA,EAGnBC,EAAmBC,GAA4C,CAC7D,MAAAC,EAAOD,EAAO,MAAM,CAAC,EACtBC,IACLN,EAAe,MAAQM,EAAA,EAGnBC,EAA0BC,GAA6B,OACvD,OAAAA,EAAwB,kBACxBC,EAAAT,EAAe,QAAf,MAAAS,EAAsB,MAAc,gBAEjC,kBAAA,EAGHC,EAAa,IAAA,OAAM,OAAAD,EAAAZ,EAAQ,QAAR,YAAAY,EAAe,OAAO,MACzCE,EAAc,IAAA,OAAM,OAAAF,EAAAZ,EAAQ,QAAR,YAAAY,EAAe,OAAO,KAC1CG,EAAiB,IAAA,OAAM,OAAAH,EAAAZ,EAAQ,QAAR,YAAAY,EAAe,KAAK,EAAG,IAC9CI,EAAe,IAAA,OAAM,OAAAJ,EAAAZ,EAAQ,QAAR,YAAAY,EAAe,KAAK,EAAG,IAE5CK,EAAY,IAAM,OAAA,OAAAL,EAAAV,EAAW,QAAX,YAAAU,EAAkB,iBACpCM,EAAW,IAAM,CACrBf,EAAe,MAAQ,KACvBC,EAAe,MAAQ,IAAA,EAEnBe,EAAS,IAAM,OACb,MAAAC,IAASR,EAAAZ,EAAQ,QAAR,YAAAY,EAAe,YAAY,OAAO,UAAU,aAAc,OAAS,KAClFS,EAAK,OAAQD,CAAM,CAAA,EAGrBE,OAAAA,EAAAA,YAAY,IAAM,CAChBjB,EAAgB,IAAI,CAAA,CACrB,EAEDkB,EAAA,MACE,IAAMC,EAAM,KAAK,OAChBC,GAAc,CACbrB,EAAe,MAAQqB,GAAa,IACtC,EACA,CAAE,UAAW,EAAK,CAAA,EAGpBF,EAAA,MACEpB,EACCuB,GAAc,CACEtB,EAAA,MACbsB,GAAA,MAAAA,EAAW,MAAQ,CAACA,EAAU,MAAQ,IAAI,gBAAgBA,EAAU,IAAI,EAAI,IAChF,EACA,CAAE,KAAM,EAAK,CAAA"}
@@ -49,6 +49,7 @@ declare const _default: __VLS_WithTemplateSlots<import("vue").DefineComponent<{
49
49
  hoverEffect: boolean;
50
50
  }, {}>, {
51
51
  default?(_: {}): any;
52
+ "absolute-anchor"?(_: {}): any;
52
53
  }>;
53
54
  export default _default;
54
55
  type __VLS_WithTemplateSlots<T, S> = T & {
@@ -1,21 +1,69 @@
1
- import { Nullable } from '@speckle/shared';
2
- import { AvatarUser } from '../../composables/user/avatar';
1
+ import { MaybeNullOrUndefined } from '@speckle/shared';
2
+ type ModelType = MaybeNullOrUndefined<string>;
3
3
  declare const _default: import("vue").DefineComponent<{
4
- user: {
5
- type: import("vue").PropType<AvatarUser>;
4
+ editMode: import("vue").PropType<boolean>;
5
+ modelValue: {
6
+ type: import("vue").PropType<ModelType>;
6
7
  required: true;
7
8
  };
9
+ placeholder: {
10
+ type: import("vue").PropType<string>;
11
+ required: true;
12
+ };
13
+ name: {
14
+ type: import("vue").PropType<string>;
15
+ required: true;
16
+ };
17
+ rules: {
18
+ type: import("vue").PropType<string | Record<string, unknown> | import("vee-validate").GenericValidateFunction<ModelType> | import("vee-validate").GenericValidateFunction<ModelType>[] | {
19
+ validate(value: ModelType, options: Record<string, any>): Promise<ModelType>;
20
+ }>;
21
+ };
22
+ validateOnMount: {
23
+ type: import("vue").PropType<boolean>;
24
+ };
25
+ validateOnValueUpdate: {
26
+ type: import("vue").PropType<boolean>;
27
+ };
28
+ disabled: {
29
+ type: import("vue").PropType<boolean>;
30
+ };
8
31
  }, {
9
32
  open: () => boolean;
10
33
  close: () => boolean;
11
34
  }, unknown, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
12
- save: (newUrl: Nullable<string>) => void;
35
+ save: (newUrl: ModelType) => void;
36
+ "update:modelValue": (value: ModelType) => void;
13
37
  }, string, import("vue").VNodeProps & import("vue").AllowedComponentProps & import("vue").ComponentCustomProps, Readonly<import("vue").ExtractPropTypes<{
14
- user: {
15
- type: import("vue").PropType<AvatarUser>;
38
+ editMode: import("vue").PropType<boolean>;
39
+ modelValue: {
40
+ type: import("vue").PropType<ModelType>;
16
41
  required: true;
17
42
  };
43
+ placeholder: {
44
+ type: import("vue").PropType<string>;
45
+ required: true;
46
+ };
47
+ name: {
48
+ type: import("vue").PropType<string>;
49
+ required: true;
50
+ };
51
+ rules: {
52
+ type: import("vue").PropType<string | Record<string, unknown> | import("vee-validate").GenericValidateFunction<ModelType> | import("vee-validate").GenericValidateFunction<ModelType>[] | {
53
+ validate(value: ModelType, options: Record<string, any>): Promise<ModelType>;
54
+ }>;
55
+ };
56
+ validateOnMount: {
57
+ type: import("vue").PropType<boolean>;
58
+ };
59
+ validateOnValueUpdate: {
60
+ type: import("vue").PropType<boolean>;
61
+ };
62
+ disabled: {
63
+ type: import("vue").PropType<boolean>;
64
+ };
18
65
  }>> & {
19
- onSave?: ((newUrl: Nullable<string>) => any) | undefined;
66
+ "onUpdate:modelValue"?: ((value: ModelType) => any) | undefined;
67
+ onSave?: ((newUrl: ModelType) => any) | undefined;
20
68
  }, {}, {}>;
21
69
  export default _default;