@speckle/ui-components 2.17.3 → 2.17.4
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-e223a145.cjs +2 -0
- package/dist/AvatarEditor-e223a145.cjs.map +1 -0
- package/dist/{AvatarEditor-8531c565.js → AvatarEditor-fda5ba41.js} +52 -52
- package/dist/AvatarEditor-fda5ba41.js.map +1 -0
- package/dist/components/InfiniteLoading.vue.d.ts +42 -29
- package/dist/components/SourceAppBadge.vue.d.ts +14 -11
- package/dist/components/common/Alert.vue.d.ts +48 -49
- package/dist/components/common/Badge.vue.d.ts +64 -47
- package/dist/components/common/loading/Bar.vue.d.ts +13 -10
- package/dist/components/common/loading/Icon.vue.d.ts +30 -19
- package/dist/components/common/steps/Bullet.vue.d.ts +31 -56
- package/dist/components/common/steps/Number.vue.d.ts +29 -50
- package/dist/components/common/text/Link.vue.d.ts +9 -9
- package/dist/components/form/Button.vue.d.ts +12 -11
- package/dist/components/form/CardButton.vue.d.ts +17 -16
- package/dist/components/form/Checkbox.vue.d.ts +3 -3
- package/dist/components/form/ClipboardInput.vue.d.ts +28 -26
- package/dist/components/form/Tags.vue.d.ts +69 -126
- package/dist/components/form/TextArea.vue.d.ts +71 -119
- package/dist/components/form/TextInput.vue.d.ts +7 -6
- package/dist/components/form/file-upload/Zone.vue.d.ts +60 -37
- package/dist/components/form/select/Badges.vue.d.ts +30 -60
- package/dist/components/form/select/Base.vue.d.ts +31 -244
- package/dist/components/form/select/SourceApps.vue.d.ts +4 -4
- package/dist/components/global/ToastRenderer.vue.d.ts +17 -14
- package/dist/components/layout/Dialog.vue.d.ts +51 -60
- package/dist/components/layout/DialogSection.vue.d.ts +3 -3
- package/dist/components/layout/Disclosure.vue.d.ts +37 -26
- package/dist/components/layout/GridListToggle.vue.d.ts +15 -10
- package/dist/components/layout/Menu.vue.d.ts +24 -19
- package/dist/components/layout/Table.vue.d.ts +8 -16
- package/dist/components/layout/Tabs.vue.d.ts +15 -12
- package/dist/components/user/Avatar.vue.d.ts +42 -46
- package/dist/components/user/AvatarEditable.vue.d.ts +2 -2
- package/dist/components/user/AvatarEditor.vue.d.ts +21 -26
- package/dist/components/user/AvatarGroup.vue.d.ts +39 -38
- package/dist/composables/common/async.d.ts +3 -3
- package/dist/composables/common/steps.d.ts +2 -2
- package/dist/composables/common/window.d.ts +2 -2
- package/dist/composables/form/fileUpload.d.ts +3 -3
- package/dist/composables/form/input.d.ts +1 -1
- package/dist/composables/form/select.d.ts +2 -2
- package/dist/composables/form/textInput.d.ts +3 -3
- package/dist/composables/layout/resize.d.ts +2 -2
- package/dist/composables/user/avatar.d.ts +1 -1
- package/dist/helpers/common/components.d.ts +2 -2
- package/dist/helpers/common/validation.d.ts +1 -1
- package/dist/helpers/form/file.d.ts +1 -1
- package/dist/lib.cjs +1 -1
- package/dist/lib.cjs.map +1 -1
- package/dist/lib.d.ts +12 -8
- package/dist/lib.js +1714 -1720
- package/dist/lib.js.map +1 -1
- package/dist/stories/composables/toast.d.ts +1 -1
- package/dist/style.css +1 -1
- package/package.json +9 -9
- package/tsconfig.json +1 -0
- package/dist/AvatarEditor-0cf61750.cjs +0 -2
- package/dist/AvatarEditor-0cf61750.cjs.map +0 -1
- package/dist/AvatarEditor-8531c565.js.map +0 -1
package/dist/style.css
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
.tippy-box[data-animation=fade][data-state=hidden]{opacity:0}[data-tippy-root]{max-width:calc(100vw - 10px)}.tippy-box{position:relative;background-color:#333;color:#fff;border-radius:4px;font-size:14px;line-height:1.4;white-space:normal;outline:0;transition-property:transform,visibility,opacity}.tippy-box[data-placement^=top]>.tippy-arrow{bottom:0}.tippy-box[data-placement^=top]>.tippy-arrow:before{bottom:-7px;left:0;border-width:8px 8px 0;border-top-color:initial;transform-origin:center top}.tippy-box[data-placement^=bottom]>.tippy-arrow{top:0}.tippy-box[data-placement^=bottom]>.tippy-arrow:before{top:-7px;left:0;border-width:0 8px 8px;border-bottom-color:initial;transform-origin:center bottom}.tippy-box[data-placement^=left]>.tippy-arrow{right:0}.tippy-box[data-placement^=left]>.tippy-arrow:before{border-width:8px 0 8px 8px;border-left-color:initial;right:-7px;transform-origin:center left}.tippy-box[data-placement^=right]>.tippy-arrow{left:0}.tippy-box[data-placement^=right]>.tippy-arrow:before{left:-7px;border-width:8px 8px 8px 0;border-right-color:initial;transform-origin:center right}.tippy-box[data-inertia][data-state=visible]{transition-timing-function:cubic-bezier(.54,1.5,.38,1.11)}.tippy-arrow{width:16px;height:16px;color:#333}.tippy-arrow:before{content:"";position:absolute;border-color:transparent;border-style:solid}.tippy-content{position:relative;padding:5px 9px;z-index:1}.icon-slot[data-v-
|
|
1
|
+
.tippy-box[data-animation=fade][data-state=hidden]{opacity:0}[data-tippy-root]{max-width:calc(100vw - 10px)}.tippy-box{position:relative;background-color:#333;color:#fff;border-radius:4px;font-size:14px;line-height:1.4;white-space:normal;outline:0;transition-property:transform,visibility,opacity}.tippy-box[data-placement^=top]>.tippy-arrow{bottom:0}.tippy-box[data-placement^=top]>.tippy-arrow:before{bottom:-7px;left:0;border-width:8px 8px 0;border-top-color:initial;transform-origin:center top}.tippy-box[data-placement^=bottom]>.tippy-arrow{top:0}.tippy-box[data-placement^=bottom]>.tippy-arrow:before{top:-7px;left:0;border-width:0 8px 8px;border-bottom-color:initial;transform-origin:center bottom}.tippy-box[data-placement^=left]>.tippy-arrow{right:0}.tippy-box[data-placement^=left]>.tippy-arrow:before{border-width:8px 0 8px 8px;border-left-color:initial;right:-7px;transform-origin:center left}.tippy-box[data-placement^=right]>.tippy-arrow{left:0}.tippy-box[data-placement^=right]>.tippy-arrow:before{left:-7px;border-width:8px 8px 8px 0;border-right-color:initial;transform-origin:center right}.tippy-box[data-inertia][data-state=visible]{transition-timing-function:cubic-bezier(.54,1.5,.38,1.11)}.tippy-arrow{width:16px;height:16px;color:#333}.tippy-arrow:before{content:"";position:absolute;border-color:transparent;border-style:solid}.tippy-content{position:relative;padding:5px 9px;z-index:1}.icon-slot[data-v-facc4a03]:empty{display:none}.swoosher[data-v-89e77cae]{width:100%;height:100%;animation:swoosh-89e77cae 1s infinite linear;transform-origin:0% 30%}@keyframes swoosh-89e77cae{0%{transform:translate(0) scaleX(0)}40%{transform:translate(0) scaleX(.4)}to{transform:translate(100%) scaleX(.5)}}
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@speckle/ui-components",
|
|
3
3
|
"description": "Speckle theme UI components built with Vue 3 & Tailwind",
|
|
4
|
-
"version": "2.17.
|
|
4
|
+
"version": "2.17.4",
|
|
5
5
|
"scripts": {
|
|
6
6
|
"dev": "vite",
|
|
7
7
|
"build": "vue-tsc && vite build",
|
|
@@ -40,7 +40,7 @@
|
|
|
40
40
|
"dependencies": {
|
|
41
41
|
"@headlessui/vue": "^1.7.13",
|
|
42
42
|
"@heroicons/vue": "^2.0.12",
|
|
43
|
-
"@speckle/shared": "^2.17.
|
|
43
|
+
"@speckle/shared": "^2.17.4",
|
|
44
44
|
"@vueuse/core": "^9.13.0",
|
|
45
45
|
"lodash": "^4.0.0",
|
|
46
46
|
"lodash-es": "^4.0.0",
|
|
@@ -54,7 +54,7 @@
|
|
|
54
54
|
"@babel/preset-env": "^7.21.5",
|
|
55
55
|
"@babel/preset-react": "^7.18.6",
|
|
56
56
|
"@rollup/plugin-typescript": "^11.1.0",
|
|
57
|
-
"@speckle/tailwind-theme": "^2.17.
|
|
57
|
+
"@speckle/tailwind-theme": "^2.17.4",
|
|
58
58
|
"@storybook/addon-essentials": "^7.3.2",
|
|
59
59
|
"@storybook/addon-interactions": "^7.3.2",
|
|
60
60
|
"@storybook/addon-links": "^7.3.2",
|
|
@@ -68,7 +68,7 @@
|
|
|
68
68
|
"@types/lodash": "^4.0.0",
|
|
69
69
|
"@typescript-eslint/eslint-plugin": "^5.38.1",
|
|
70
70
|
"@typescript-eslint/parser": "^5.38.1",
|
|
71
|
-
"@vitejs/plugin-vue": "^4.
|
|
71
|
+
"@vitejs/plugin-vue": "^4.5.0",
|
|
72
72
|
"autoprefixer": "^10.4.14",
|
|
73
73
|
"browserify-zlib": "^0.2.0",
|
|
74
74
|
"chromatic": "^6.17.4",
|
|
@@ -88,11 +88,11 @@
|
|
|
88
88
|
"tailwindcss": "^3.3.2",
|
|
89
89
|
"type-fest": "^2.13.1",
|
|
90
90
|
"typescript": "^5.0.4",
|
|
91
|
-
"unplugin-vue-macros": "^2.
|
|
92
|
-
"vite": "^4.
|
|
93
|
-
"vite-plugin-dts": "^3.
|
|
94
|
-
"vue": "^3.3.
|
|
95
|
-
"vue-tsc": "^1.
|
|
91
|
+
"unplugin-vue-macros": "^2.7.0",
|
|
92
|
+
"vite": "^4.5.0",
|
|
93
|
+
"vite-plugin-dts": "^3.6.3",
|
|
94
|
+
"vue": "^3.3.8",
|
|
95
|
+
"vue-tsc": "^1.8.22",
|
|
96
96
|
"wait-on": "^6.0.1"
|
|
97
97
|
},
|
|
98
98
|
"installConfig": {
|
package/tsconfig.json
CHANGED
|
@@ -1,2 +0,0 @@
|
|
|
1
|
-
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const e=require("vue"),n=require("@heroicons/vue/24/outline"),z=require("vue-advanced-cropper");require("vue-advanced-cropper/dist/style.css");const i=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 q={class:"flex flex-col space-y-2"},R={class:"flex"},B={class:"flex mx-14 space-x-2"},_=e.createElementVNode("div",{class:"grow"},null,-1),F=e.defineComponent({__name:"AvatarEditor",props:{user:null,disabled:{type:Boolean},size:null},emits:["cancel","save"],setup(u,{emit:m}){const d=u,o=e.ref(null),f=e.ref(null),a=e.ref(null),r=e.ref(null),s=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}}}),h=t=>{r.value&&URL.revokeObjectURL(r.value),r.value=t},p=t=>{const l=t.files[0];l&&(a.value=l)},x=t=>{var l;return t?"border-primary":(l=a.value)!=null&&l.error?"border-danger":"border-outline-2"},g=()=>{var t;return(t=o.value)==null?void 0:t.rotate(-90)},C=()=>{var t;return(t=o.value)==null?void 0:t.rotate(90)},w=()=>{var t;return(t=o.value)==null?void 0:t.flip(1,0)},k=()=>{var t;return(t=o.value)==null?void 0:t.flip(0,1)},y=()=>{var t;return(t=f.value)==null?void 0:t.triggerPicker()},N=()=>{a.value=null,r.value=null},V=()=>{var l;const t=((l=o.value)==null?void 0:l.getResult().canvas.toDataURL("image/jpeg",.85))||null;m("save",t)};return e.onUnmounted(()=>{h(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",q,[e.createElementVNode("div",R,[e.createElementVNode("div",{class:e.normalizeClass(["flex flex-col px-2 space-y-1",{invisible:!r.value}])},[e.withDirectives(e.createVNode(i.FormButton,{"icon-left":e.unref(n.ArrowUturnLeftIcon),"hide-text":"",size:"sm",outlined:"",onClick:g},null,8,["icon-left"]),[[e.unref(c.directive),"Rotate left"]]),e.withDirectives(e.createVNode(i.FormButton,{"icon-left":e.unref(n.ArrowUturnRightIcon),"hide-text":"",size:"sm",outlined:"",onClick:C},null,8,["icon-left"]),[[e.unref(c.directive),"Rotate right"]]),e.withDirectives(e.createVNode(i.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(i.FormButton,{"icon-left":e.unref(n.ArrowLeftOnRectangleIcon),"hide-text":"",size:"sm",outlined:"",onClick:w},null,8,["icon-left"]),[[e.unref(c.directive),"Flip horizontally"]])],2),r.value?(e.openBlock(),e.createBlock(e.unref(z.Cropper),{key:0,ref_key:"cropper",ref:o,class:"cropper",src:r.value,"stencil-props":{aspectRatio:1/1},canvas:s.value,style:e.normalizeStyle(`width: ${s.value.width}px; height: ${s.value.height}px`)},null,8,["src","canvas","style"])):e.createCommentVNode("",!0),e.createVNode(i.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:p},{default:e.withCtx(({isDraggingFiles:v,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",[x(v)]]},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(i.FormButton,{"icon-left":e.unref(n.PhotoIcon),"hide-text":"",size:"sm",onClick:y},null,8,["icon-left"]),[[e.unref(c.directive),"Replace image"]]),e.withDirectives(e.createVNode(i.FormButton,{"icon-left":e.unref(n.XMarkIcon),"hide-text":"",size:"sm",color:"danger",onClick:N},null,8,["icon-left"]),[[e.unref(c.directive),"Remove"]])],2)]),e.createElementVNode("div",B,[_,e.createVNode(i.FormButton,{color:"secondary",size:"sm",onClick:l[0]||(l[0]=v=>t.$emit("cancel"))},{default:e.withCtx(()=>[e.createTextVNode(" Close ")]),_:1}),e.createVNode(i.FormButton,{size:"sm",disabled:u.disabled,onClick:V},{default:e.withCtx(()=>[e.createTextVNode("Save")]),_:1},8,["disabled"])])]))}});exports.default=F;
|
|
2
|
-
//# sourceMappingURL=AvatarEditor-0cf61750.cjs.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"AvatarEditor-0cf61750.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=\"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 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, 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 { UploadableFileItem } from '~~/src/composables/form/fileUpload'\nimport { 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":["cropper","ref","uploadZone","selectedUpload","activeImageUrl","canvasSize","computed","props","setNewActiveUrl","url","onFilesSelected","params","file","getDashedBorderClasses","isDraggingFiles","_a","rotateLeft","rotateRight","flipHorizontal","flipVertical","onReplace","onRemove","onSave","newUrl","emit","onUnmounted","watch","newAvatar","newUpload"],"mappings":"syBA2HMA,EAAUC,EAAA,IACd,IAAA,EAMIC,EAAaD,MAAI,IAA+C,EAChEE,EAAiBF,MAAI,IAAoC,EACzDG,EAAiBH,MAAI,IAAwB,EAE7CI,EAAaC,EAAAA,SAAS,IAAM,CAChC,OAAQC,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,EAEKC,EAAmBC,GAA0B,CAC7CL,EAAe,OACb,IAAA,gBAAgBA,EAAe,KAAK,EAG1CA,EAAe,MAAQK,CAAA,EAGnBC,EAAmBC,GAA4C,CAC7D,MAAAC,EAAOD,EAAO,MAAM,CAAC,EACtBC,IACLT,EAAe,MAAQS,EAAA,EAGnBC,EAA0BC,GAA6B,OACvD,OAAAA,EAAwB,kBACxBC,EAAAZ,EAAe,QAAf,MAAAY,EAAsB,MAAc,gBAEjC,kBAAA,EAGHC,EAAa,IAAA,OAAM,OAAAD,EAAAf,EAAQ,QAAR,YAAAe,EAAe,OAAO,MACzCE,EAAc,IAAA,OAAM,OAAAF,EAAAf,EAAQ,QAAR,YAAAe,EAAe,OAAO,KAC1CG,EAAiB,IAAA,OAAM,OAAAH,EAAAf,EAAQ,QAAR,YAAAe,EAAe,KAAK,EAAG,IAC9CI,EAAe,IAAA,OAAM,OAAAJ,EAAAf,EAAQ,QAAR,YAAAe,EAAe,KAAK,EAAG,IAE5CK,EAAY,IAAM,OAAA,OAAAL,EAAAb,EAAW,QAAX,YAAAa,EAAkB,iBACpCM,EAAW,IAAM,CACrBlB,EAAe,MAAQ,KACvBC,EAAe,MAAQ,IAAA,EAEnBkB,EAAS,IAAM,OACb,MAAAC,IAASR,EAAAf,EAAQ,QAAR,YAAAe,EAAe,YAAY,OAAO,UAAU,aAAc,OAAS,KAClFS,EAAK,OAAQD,CAAM,CAAA,EAGrBE,OAAAA,EAAAA,YAAY,IAAM,CAChBjB,EAAgB,IAAI,CAAA,CACrB,EAEDkB,EAAA,MACE,IAAMnB,EAAM,KAAK,OAChBoB,GAAc,CACbvB,EAAe,MAAQuB,GAAa,IACtC,EACA,CAAE,UAAW,EAAK,CAAA,EAGpBD,EAAA,MACEvB,EACCyB,GAAc,CACExB,EAAA,MACbwB,GAAA,MAAAA,EAAW,MAAQ,CAACA,EAAU,MAAQ,IAAI,gBAAgBA,EAAU,IAAI,EAAI,IAChF,EACA,CAAE,KAAM,EAAK,CAAA"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"AvatarEditor-8531c565.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=\"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 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, 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 { UploadableFileItem } from '~~/src/composables/form/fileUpload'\nimport { 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":["cropper","ref","uploadZone","selectedUpload","activeImageUrl","canvasSize","computed","props","setNewActiveUrl","url","onFilesSelected","params","file","getDashedBorderClasses","isDraggingFiles","_a","rotateLeft","rotateRight","flipHorizontal","flipVertical","onReplace","onRemove","onSave","newUrl","emit","onUnmounted","watch","newAvatar","newUpload"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;iBA2HMA,IAAUC;AAAA,MACd;AAAA,IAAA,GAMIC,IAAaD,EAAI,IAA+C,GAChEE,IAAiBF,EAAI,IAAoC,GACzDG,IAAiBH,EAAI,IAAwB,GAE7CI,IAAaC,EAAS,MAAM;AAChC,cAAQC,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,GAEKC,IAAkB,CAACC,MAA0B;AACjD,MAAIL,EAAe,SACb,IAAA,gBAAgBA,EAAe,KAAK,GAG1CA,EAAe,QAAQK;AAAA,IAAA,GAGnBC,IAAkB,CAACC,MAA4C;AAC7D,YAAAC,IAAOD,EAAO,MAAM,CAAC;AAC3B,MAAKC,MACLT,EAAe,QAAQS;AAAA,IAAA,GAGnBC,IAAyB,CAACC,MAA6B;;AACvD,aAAAA,IAAwB,oBACxBC,IAAAZ,EAAe,UAAf,QAAAY,EAAsB,QAAc,kBAEjC;AAAA,IAAA,GAGHC,IAAa,MAAA;;AAAM,cAAAD,IAAAf,EAAQ,UAAR,gBAAAe,EAAe,OAAO;AAAA,OACzCE,IAAc,MAAA;;AAAM,cAAAF,IAAAf,EAAQ,UAAR,gBAAAe,EAAe,OAAO;AAAA,OAC1CG,IAAiB,MAAA;;AAAM,cAAAH,IAAAf,EAAQ,UAAR,gBAAAe,EAAe,KAAK,GAAG;AAAA,OAC9CI,IAAe,MAAA;;AAAM,cAAAJ,IAAAf,EAAQ,UAAR,gBAAAe,EAAe,KAAK,GAAG;AAAA,OAE5CK,IAAY,MAAM;;AAAA,cAAAL,IAAAb,EAAW,UAAX,gBAAAa,EAAkB;AAAA,OACpCM,IAAW,MAAM;AACrB,MAAAlB,EAAe,QAAQ,MACvBC,EAAe,QAAQ;AAAA,IAAA,GAEnBkB,IAAS,MAAM;;AACb,YAAAC,MAASR,IAAAf,EAAQ,UAAR,gBAAAe,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,MAAMnB,EAAM,KAAK;AAAA,MACjB,CAACoB,MAAc;AACb,QAAAvB,EAAe,QAAQuB,KAAa;AAAA,MACtC;AAAA,MACA,EAAE,WAAW,GAAK;AAAA,IAAA,GAGpBD;AAAA,MACEvB;AAAA,MACA,CAACyB,MAAc;AACE,QAAAxB,EAAA,QACbwB,KAAA,QAAAA,EAAW,QAAQ,CAACA,EAAU,QAAQ,IAAI,gBAAgBA,EAAU,IAAI,IAAI;AAAA,MAChF;AAAA,MACA,EAAE,MAAM,GAAK;AAAA,IAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
|