@speckle/ui-components 2.23.5 → 2.23.7

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/README.md CHANGED
@@ -6,7 +6,7 @@ Speckle UI component library built with Vue 3 and relying on the Speckle Tailwin
6
6
 
7
7
  1. Make sure you have `@speckle/tailwind-theme` installed and set up with Tailwind
8
8
  1. Install `@speckle/ui-components`
9
- 1. In your tailwind config import `tailwindContentEntry` from `@speckle/ui-components/tailwind-configure` and invoke it in the `contents` field to ensure PurgeCSS is configured correctly. It requires the CJS `require` object as its only parameter. If it isn't available (in an ESM environment), you can use node's `createRequire()`.
9
+ 1. In your tailwind config import `tailwindContentEntries` from `@speckle/ui-components/tailwind-configure` and invoke it in the `contents` field to ensure PurgeCSS is configured correctly. It requires the CJS `require` object as its only parameter. If it isn't available (in an ESM environment), you can use node's `createRequire()`.
10
10
  1. Import `@speckle/ui-components/style.css` in your app. If `exports` map isn't supported you can also import from `@speckle/ui-components/dist/style.css`
11
11
 
12
12
  ### Usage in Nuxt v3
@@ -27,8 +27,12 @@ const W = { class: "flex flex-col space-y-2" }, Y = { class: "flex" }, ee = { cl
27
27
  ), x = d(null), u = d(null), l = d(null), f = N(() => {
28
28
  switch (h.size) {
29
29
  case "xs":
30
+ case "sm":
31
+ case "lg":
32
+ case "xl":
30
33
  return { width: 64, height: 64 };
31
34
  case "xxl":
35
+ case "3xl":
32
36
  return { width: 140, height: 140 };
33
37
  case "editable":
34
38
  return { width: 240, height: 240 };
@@ -192,4 +196,4 @@ const W = { class: "flex flex-col space-y-2" }, Y = { class: "flex" }, ee = { cl
192
196
  export {
193
197
  xe as default
194
198
  };
195
- //# sourceMappingURL=AvatarEditor-664d2235.js.map
199
+ //# sourceMappingURL=AvatarEditor-25fde016.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"AvatarEditor-664d2235.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;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
1
+ {"version":3,"file":"AvatarEditor-25fde016.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':\n case 'sm':\n case 'lg':\n case 'xl':\n return { width: 64, height: 64 }\n case 'xxl':\n case '3xl':\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;AAAA,QACL,KAAK;AAAA,QACL,KAAK;AAAA,QACL,KAAK;AACH,iBAAO,EAAE,OAAO,IAAI,QAAQ,GAAG;AAAA,QACjC,KAAK;AAAA,QACL,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/20/solid");require("@speckle/shared");require("vee-validate");require("nanoid");require("@vueuse/core");require("@headlessui/vue");require("@heroicons/vue/24/solid");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(u,{emit:m}){const h=m,d=u,i=e.ref(null),f=e.ref(null),a=e.ref(null),r=e.ref(null),s=e.computed(()=>{switch(d.size){case"xs":case"sm":case"lg":case"xl":return{width:64,height:64};case"xxl":case"3xl":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;h("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: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(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:u.disabled,onClick:y},{default:e.withCtx(()=>[e.createTextVNode("Save")]),_:1},8,["disabled"])])]))}});exports.default=D;
2
+ //# sourceMappingURL=AvatarEditor-a33fb9ec.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"AvatarEditor-1b6423eb.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"}
1
+ {"version":3,"file":"AvatarEditor-a33fb9ec.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':\n case 'sm':\n case 'lg':\n case 'xl':\n return { width: 64, height: 64 }\n case 'xxl':\n case '3xl':\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,KACL,IAAK,KACL,IAAK,KACL,IAAK,KACH,MAAO,CAAE,MAAO,GAAI,OAAQ,EAAG,EACjC,IAAK,MACL,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"}
@@ -14,6 +14,7 @@ declare const _default: import("vue").DefineComponent<__VLS_WithDefaults<__VLS_T
14
14
  autoFocus?: boolean | undefined;
15
15
  showClear?: boolean | undefined;
16
16
  showRequired?: boolean | undefined;
17
+ showOptional?: boolean | undefined;
17
18
  color?: InputColor | undefined;
18
19
  wrapperClasses?: string | undefined;
19
20
  size?: InputSize | undefined;
@@ -46,6 +47,7 @@ declare const _default: import("vue").DefineComponent<__VLS_WithDefaults<__VLS_T
46
47
  autoFocus?: boolean | undefined;
47
48
  showClear?: boolean | undefined;
48
49
  showRequired?: boolean | undefined;
50
+ showOptional?: boolean | undefined;
49
51
  color?: InputColor | undefined;
50
52
  wrapperClasses?: string | undefined;
51
53
  size?: InputSize | undefined;
@@ -0,0 +1,191 @@
1
+ import type { PropType } from 'vue';
2
+ import type { MaybeAsync, Optional } from '@speckle/shared';
3
+ import type { RuleExpression } from 'vee-validate';
4
+ import type { LabelPosition } from '../../../composables/form/input';
5
+ declare const _default: <SingleItem extends string | number | Record<string, unknown>>(__VLS_props: {
6
+ size?: Optional<"sm" | "base" | "lg" | "xl">;
7
+ readonly label: string;
8
+ modelValue?: ([{
9
+ type: PropType<SingleItem | SingleItem[] | undefined>;
10
+ default: undefined;
11
+ }] extends [import("vue").Prop<infer V, infer D>] ? unknown extends V ? import("@vue/shared").IfAny<V, V, D> : V : {
12
+ type: PropType<SingleItem | SingleItem[] | undefined>;
13
+ default: undefined;
14
+ }) | undefined;
15
+ "onUpdate:modelValue"?: ((v: SingleItem | SingleItem[] | undefined) => any) | undefined;
16
+ readonly name: string;
17
+ disabled?: Optional<boolean>;
18
+ rules?: RuleExpression<SingleItem | SingleItem[] | undefined>;
19
+ validateOnMount?: boolean | undefined;
20
+ showRequired?: boolean | undefined;
21
+ labelPosition?: LabelPosition | undefined;
22
+ validateOnValueUpdate?: boolean | undefined;
23
+ search?: boolean | undefined;
24
+ help?: Optional<string>;
25
+ showLabel?: boolean | undefined;
26
+ useLabelInErrors?: boolean | undefined;
27
+ readonly placeholder?: string | undefined;
28
+ showOptional?: boolean | undefined;
29
+ tooltipText?: string | undefined;
30
+ items?: SingleItem[] | undefined;
31
+ filterPredicate?: Optional<(item: SingleItem, searchString: string) => boolean>;
32
+ disabledItemPredicate?: Optional<(item: SingleItem) => boolean>;
33
+ getSearchResults?: Optional<(searchString: string) => MaybeAsync<SingleItem[]>>;
34
+ searchPlaceholder?: string | undefined;
35
+ readonly by?: string | undefined;
36
+ buttonStyle?: Optional<"base" | "simple" | "tinted">;
37
+ hideCheckmarks?: Optional<boolean>;
38
+ allowUnset?: Optional<boolean>;
39
+ clearable?: boolean | undefined;
40
+ fixedHeight?: boolean | undefined;
41
+ fullyControlValue?: boolean | undefined;
42
+ mountMenuOnBody?: boolean | undefined;
43
+ labelId?: string | undefined;
44
+ buttonId?: string | undefined;
45
+ readonly disabledItemTooltip?: string | undefined;
46
+ } & import("vue").VNodeProps & import("vue").AllowedComponentProps & import("vue").ComponentCustomProps, __VLS_ctx?: {
47
+ attrs: any;
48
+ slots: {
49
+ "nothing-selected"?(_: {}): any;
50
+ "something-selected"?(_: {
51
+ value: SingleItem[];
52
+ }): any;
53
+ "nothing-found"?(_: {}): any;
54
+ option?(_: {
55
+ class: string;
56
+ item: SingleItem;
57
+ selected: boolean;
58
+ disabled: boolean;
59
+ }): any;
60
+ };
61
+ emit: (e: 'update:modelValue', v: SingleItem | SingleItem[] | undefined) => void;
62
+ } | undefined, __VLS_expose?: ((exposed: import("vue").ShallowUnwrapRef<{
63
+ triggerSearch: () => Promise<void>;
64
+ }>) => void) | undefined, __VLS_setup?: Promise<{
65
+ props: {
66
+ size?: Optional<"sm" | "base" | "lg" | "xl">;
67
+ readonly label: string;
68
+ modelValue?: ([{
69
+ type: PropType<SingleItem | SingleItem[] | undefined>;
70
+ default: undefined;
71
+ }] extends [import("vue").Prop<infer V, infer D>] ? unknown extends V ? import("@vue/shared").IfAny<V, V, D> : V : {
72
+ type: PropType<SingleItem | SingleItem[] | undefined>;
73
+ default: undefined;
74
+ }) | undefined;
75
+ "onUpdate:modelValue"?: ((v: SingleItem | SingleItem[] | undefined) => any) | undefined;
76
+ readonly name: string;
77
+ disabled?: Optional<boolean>;
78
+ rules?: RuleExpression<SingleItem | SingleItem[] | undefined>;
79
+ validateOnMount?: boolean | undefined;
80
+ showRequired?: boolean | undefined;
81
+ labelPosition?: LabelPosition | undefined;
82
+ validateOnValueUpdate?: boolean | undefined;
83
+ search?: boolean | undefined;
84
+ help?: Optional<string>;
85
+ showLabel?: boolean | undefined;
86
+ useLabelInErrors?: boolean | undefined;
87
+ readonly placeholder?: string | undefined;
88
+ showOptional?: boolean | undefined;
89
+ tooltipText?: string | undefined;
90
+ items?: SingleItem[] | undefined;
91
+ filterPredicate?: Optional<(item: SingleItem, searchString: string) => boolean>;
92
+ disabledItemPredicate?: Optional<(item: SingleItem) => boolean>;
93
+ getSearchResults?: Optional<(searchString: string) => MaybeAsync<SingleItem[]>>;
94
+ searchPlaceholder?: string | undefined;
95
+ readonly by?: string | undefined;
96
+ buttonStyle?: Optional<"base" | "simple" | "tinted">;
97
+ hideCheckmarks?: Optional<boolean>;
98
+ allowUnset?: Optional<boolean>;
99
+ clearable?: boolean | undefined;
100
+ fixedHeight?: boolean | undefined;
101
+ fullyControlValue?: boolean | undefined;
102
+ mountMenuOnBody?: boolean | undefined;
103
+ labelId?: string | undefined;
104
+ buttonId?: string | undefined;
105
+ readonly disabledItemTooltip?: string | undefined;
106
+ } & import("vue").VNodeProps & import("vue").AllowedComponentProps & import("vue").ComponentCustomProps;
107
+ expose(exposed: import("vue").ShallowUnwrapRef<{
108
+ triggerSearch: () => Promise<void>;
109
+ }>): void;
110
+ attrs: any;
111
+ slots: {
112
+ "nothing-selected"?(_: {}): any;
113
+ "something-selected"?(_: {
114
+ value: SingleItem[];
115
+ }): any;
116
+ "nothing-found"?(_: {}): any;
117
+ option?(_: {
118
+ class: string;
119
+ item: SingleItem;
120
+ selected: boolean;
121
+ disabled: boolean;
122
+ }): any;
123
+ };
124
+ emit: (e: 'update:modelValue', v: SingleItem | SingleItem[] | undefined) => void;
125
+ }>) => import("vue").VNode<import("vue").RendererNode, import("vue").RendererElement, {
126
+ [key: string]: any;
127
+ }> & {
128
+ __ctx?: {
129
+ props: {
130
+ size?: Optional<"sm" | "base" | "lg" | "xl">;
131
+ readonly label: string;
132
+ modelValue?: ([{
133
+ type: PropType<SingleItem | SingleItem[] | undefined>;
134
+ default: undefined;
135
+ }] extends [import("vue").Prop<infer V, infer D>] ? unknown extends V ? import("@vue/shared").IfAny<V, V, D> : V : {
136
+ type: PropType<SingleItem | SingleItem[] | undefined>;
137
+ default: undefined;
138
+ }) | undefined;
139
+ "onUpdate:modelValue"?: ((v: SingleItem | SingleItem[] | undefined) => any) | undefined;
140
+ readonly name: string;
141
+ disabled?: Optional<boolean>;
142
+ rules?: RuleExpression<SingleItem | SingleItem[] | undefined>;
143
+ validateOnMount?: boolean | undefined;
144
+ showRequired?: boolean | undefined;
145
+ labelPosition?: LabelPosition | undefined;
146
+ validateOnValueUpdate?: boolean | undefined;
147
+ search?: boolean | undefined;
148
+ help?: Optional<string>;
149
+ showLabel?: boolean | undefined;
150
+ useLabelInErrors?: boolean | undefined;
151
+ readonly placeholder?: string | undefined;
152
+ showOptional?: boolean | undefined;
153
+ tooltipText?: string | undefined;
154
+ items?: SingleItem[] | undefined;
155
+ filterPredicate?: Optional<(item: SingleItem, searchString: string) => boolean>;
156
+ disabledItemPredicate?: Optional<(item: SingleItem) => boolean>;
157
+ getSearchResults?: Optional<(searchString: string) => MaybeAsync<SingleItem[]>>;
158
+ searchPlaceholder?: string | undefined;
159
+ readonly by?: string | undefined;
160
+ buttonStyle?: Optional<"base" | "simple" | "tinted">;
161
+ hideCheckmarks?: Optional<boolean>;
162
+ allowUnset?: Optional<boolean>;
163
+ clearable?: boolean | undefined;
164
+ fixedHeight?: boolean | undefined;
165
+ fullyControlValue?: boolean | undefined;
166
+ mountMenuOnBody?: boolean | undefined;
167
+ labelId?: string | undefined;
168
+ buttonId?: string | undefined;
169
+ readonly disabledItemTooltip?: string | undefined;
170
+ } & import("vue").VNodeProps & import("vue").AllowedComponentProps & import("vue").ComponentCustomProps;
171
+ expose(exposed: import("vue").ShallowUnwrapRef<{
172
+ triggerSearch: () => Promise<void>;
173
+ }>): void;
174
+ attrs: any;
175
+ slots: {
176
+ "nothing-selected"?(_: {}): any;
177
+ "something-selected"?(_: {
178
+ value: SingleItem[];
179
+ }): any;
180
+ "nothing-found"?(_: {}): any;
181
+ option?(_: {
182
+ class: string;
183
+ item: SingleItem;
184
+ selected: boolean;
185
+ disabled: boolean;
186
+ }): any;
187
+ };
188
+ emit: (e: 'update:modelValue', v: SingleItem | SingleItem[] | undefined) => void;
189
+ } | undefined;
190
+ };
191
+ export default _default;
@@ -6,14 +6,14 @@ export type AvatarUser = {
6
6
  export type AvatarUserWithId = AvatarUser & {
7
7
  id: string;
8
8
  };
9
- export type UserAvatarSize = '2xs' | 'xs' | 'sm' | 'base' | 'lg' | 'xl' | 'xxl' | 'editable';
9
+ export type UserAvatarSize = '2xs' | 'xs' | 'sm' | 'base' | 'lg' | 'xl' | 'xxl' | '3xl' | 'editable';
10
10
  export declare function useAvatarSizeClasses(params: {
11
11
  props: ToRefs<{
12
12
  size?: UserAvatarSize;
13
13
  }>;
14
14
  }): {
15
- heightClasses: import("vue").ComputedRef<"h-8" | "h-6" | "h-10" | "h-14" | "h-4" | "h-5" | "h-32" | "h-60">;
16
- widthClasses: import("vue").ComputedRef<"w-4" | "w-5" | "w-6" | "w-10" | "w-14" | "w-32" | "w-60" | "w-8">;
15
+ heightClasses: import("vue").ComputedRef<"h-8" | "h-6" | "h-10" | "h-14" | "h-4" | "h-5" | "h-24" | "h-32" | "h-60">;
16
+ widthClasses: import("vue").ComputedRef<"w-4" | "w-5" | "w-6" | "w-10" | "w-14" | "w-24" | "w-32" | "w-60" | "w-8">;
17
17
  sizeClasses: import("vue").ComputedRef<string>;
18
- iconClasses: import("vue").ComputedRef<"w-5 h-5" | "w-3 h-3" | "w-8 h-8" | "w-10 h-10" | "w-20 h-20" | "w-4 h-4">;
18
+ iconClasses: import("vue").ComputedRef<"w-4 h-4" | "w-3 h-3" | "w-5 h-5" | "w-8 h-8" | "w-10 h-10" | "w-20 h-20">;
19
19
  };
@@ -27,3 +27,4 @@ export declare const stringContains: (params: {
27
27
  }) => GenericValidateFunction<string>;
28
28
  export declare const isUrl: GenericValidateFunction<string>;
29
29
  export declare const isItemSelected: GenericValidateFunction<unknown[]>;
30
+ export declare const isMultiItemSelected: <T>(val: unknown) => true | string;