@speckle/ui-components 2.25.9 → 2.26.1

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.
@@ -0,0 +1,147 @@
1
+ ---
2
+ description: Component library patterns and Storybook conventions for ui-components
3
+ globs: ['**/*.vue', '**/*.ts', '**/*.js', '**/*.stories.*', '**/lib.ts']
4
+ alwaysApply: false
5
+ ---
6
+
7
+ # Component Library Patterns
8
+
9
+ ## File Structure
10
+
11
+ ```
12
+ packages/ui-components/
13
+ ├── src/
14
+ │ ├── components/ # Reusable UI components
15
+ │ ├── helpers/ # Component utilities
16
+ │ └── lib.ts # Main export file
17
+ ```
18
+
19
+ ## Component Development
20
+
21
+ ### Reusable Components
22
+
23
+ - **Focus on reusability** - components should work in multiple contexts
24
+ - **Minimal external dependencies** - keep the library lightweight
25
+ - **Props-driven** - all variations should be controllable via props
26
+ - **No business logic** - components should be presentational
27
+
28
+ ### Component Composition
29
+
30
+ - **Compound components** for complex UI patterns
31
+ - **Render props** or slots for customizable content
32
+ - **Headless patterns** where appropriate for maximum flexibility
33
+
34
+ ```vue
35
+ <!-- Good: Flexible and reusable -->
36
+ <template>
37
+ <button :class="buttonClasses" :disabled="disabled" @click="$emit('click', $event)">
38
+ <Icon v-if="icon" :name="icon" />
39
+ <slot />
40
+ </button>
41
+ </template>
42
+
43
+ <script setup lang="ts">
44
+ interface Props {
45
+ variant?: 'primary' | 'secondary' | 'danger'
46
+ size?: 'sm' | 'md' | 'lg'
47
+ icon?: string
48
+ disabled?: boolean
49
+ }
50
+
51
+ const props = withDefaults(defineProps<Props>(), {
52
+ variant: 'primary',
53
+ size: 'md'
54
+ })
55
+
56
+ const emit = defineEmits<{
57
+ click: [event: MouseEvent]
58
+ }>()
59
+ </script>
60
+ ```
61
+
62
+ ## Storybook Development
63
+
64
+ ### Story Organization
65
+
66
+ - **One story file per component**
67
+ - **Multiple variants** to showcase all component states
68
+ - **Interactive controls** for all props
69
+ - **Documentation** with usage examples
70
+
71
+ ```typescript
72
+ // Button.stories.ts
73
+ import type { Meta, StoryObj } from '@storybook/vue3'
74
+ import Button from './Button.vue'
75
+
76
+ const meta: Meta<typeof Button> = {
77
+ title: 'Form/Button',
78
+ component: Button,
79
+ parameters: {
80
+ docs: {
81
+ description: {
82
+ component: 'Primary button component with multiple variants'
83
+ }
84
+ }
85
+ },
86
+ argTypes: {
87
+ variant: {
88
+ control: { type: 'select' },
89
+ options: ['primary', 'secondary', 'danger']
90
+ }
91
+ }
92
+ }
93
+
94
+ export default meta
95
+ type Story = StoryObj<typeof meta>
96
+
97
+ export const Primary: Story = {
98
+ args: {
99
+ variant: 'primary'
100
+ }
101
+ }
102
+
103
+ export const AllVariants: Story = {
104
+ render: () => ({
105
+ components: { Button },
106
+ template: `
107
+ <div class="space-x-4">
108
+ <Button variant="primary">Primary</Button>
109
+ <Button variant="secondary">Secondary</Button>
110
+ <Button variant="danger">Danger</Button>
111
+ </div>
112
+ `
113
+ })
114
+ }
115
+ ```
116
+
117
+ ### Story Best Practices
118
+
119
+ - **Show all states** (default, hover, disabled, loading, etc.)
120
+ - **Responsive examples** for components that adapt to screen size
121
+ - **Accessibility testing** with a11y addon
122
+ - **Performance testing** for complex components
123
+
124
+ ## Library Exports
125
+
126
+ ### Main Export File
127
+
128
+ ```typescript
129
+ // src/lib.ts
130
+ export { default as Button } from './components/Button.vue'
131
+ export { default as Input } from './components/Input.vue'
132
+ export { default as Modal } from './components/Modal.vue'
133
+
134
+ // Export types
135
+ export type { ButtonProps } from './components/Button.vue'
136
+ export type { InputProps } from './components/Input.vue'
137
+
138
+ // Export utilities
139
+ export * from './helpers/validation'
140
+ export * from './helpers/formatting'
141
+ ```
142
+
143
+ ### Tree-Shakeable Exports
144
+
145
+ - **Named exports only** - no default exports for the library
146
+ - **Separate type exports** - allow importing types without importing components
147
+ - **Utility separation** - helpers should be importable independently
@@ -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("@heroicons/vue/20/solid");require("@speckle/shared");require("vee-validate");require("nanoid");require("lucide-vue-next");require("@vueuse/core");require("@headlessui/vue");require("@heroicons/vue/24/solid");require("v3-infinite-loading");const B={class:"flex flex-col space-y-2"},F={class:"flex"},z={class:"flex mx-14 space-x-2"},D=e.defineComponent({__name:"AvatarEditor",props:{user:{},disabled:{type:Boolean},size:{}},emits:["cancel","save"],setup(v,{emit:p}){const m=p,u=v,i=e.ref(null),d=e.ref(null),a=e.ref(null),l=e.ref(null),s=e.computed(()=>{switch(u.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}}}),h=t=>{l.value&&URL.revokeObjectURL(l.value),l.value=t},x=t=>{const r=t.files[0];r&&(a.value=r)},g=t=>{var r;return t?"border-primary":(r=a.value)!=null&&r.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=d.value)==null?void 0:t.triggerPicker()},b=()=>{a.value=null,l.value=null},y=()=>{var r;const t=((r=i.value)==null?void 0:r.getResult().canvas.toDataURL("image/jpeg",.85))||null;m("save",t)};return e.onUnmounted(()=>{h(null)}),e.watch(()=>u.user.avatar,t=>{l.value=t||null},{immediate:!0}),e.watch(a,t=>{l.value=t!=null&&t.file&&!t.error?URL.createObjectURL(t.file):null},{deep:!0}),(t,r)=>(e.openBlock(),e.createElementBlock("div",B,[e.createElementVNode("div",F,[e.createElementVNode("div",{class:e.normalizeClass(["flex flex-col px-2 space-y-1",{invisible:!l.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),l.value?(e.openBlock(),e.createBlock(e.unref(R.Cropper),{key:0,ref_key:"cropper",ref:i,class:"cropper",src:l.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:d,class:e.normalizeClass(["cropper flex items-center justify-center",{hidden:l.value}]),accept:"image/*","size-limit":5*1024*1024,onFilesSelected:x},{default:e.withCtx(({isDraggingFiles:f,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(f)]]},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:!l.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",z,[r[3]||(r[3]=e.createElementVNode("div",{class:"grow"},null,-1)),e.createVNode(o.FormButton,{color:"outline",onClick:r[0]||(r[0]=f=>t.$emit("cancel"))},{default:e.withCtx(()=>[...r[1]||(r[1]=[e.createTextVNode("Close",-1)])]),_:1}),e.createVNode(o.FormButton,{disabled:t.disabled,onClick:y},{default:e.withCtx(()=>[...r[2]||(r[2]=[e.createTextVNode("Save",-1)])]),_:1},8,["disabled"])])]))}});exports.default=D;
2
+ //# sourceMappingURL=AvatarEditor-00037f6e.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"AvatarEditor-504f96fb.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<{\n (e: 'cancel'): void\n (e: 'save', val: Nullable<string>): void\n}>()\n\nconst props = defineProps<{\n user: AvatarUser\n disabled?: boolean\n size?: UserAvatarSize\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":"itBA2GA,MAAMA,EAAOC,EAKPC,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"}
1
+ {"version":3,"file":"AvatarEditor-00037f6e.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<{\n (e: 'cancel'): void\n (e: 'save', val: Nullable<string>): void\n}>()\n\nconst props = defineProps<{\n user: AvatarUser\n disabled?: boolean\n size?: UserAvatarSize\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","_openBlock","_createElementBlock","_hoisted_1","_createElementVNode","_hoisted_2","_normalizeClass","_createVNode","FormButton","_unref","ArrowUturnLeftIcon","ArrowUturnRightIcon","ArrowUpOnSquareIcon","ArrowLeftOnRectangleIcon","_createBlock","Cropper","FormFileUploadZone","activatorOn","_mergeProps","_toHandlers","PhotoIcon","XMarkIcon","_hoisted_3","$emit","_cache","disabled"],"mappings":"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"}
@@ -8,11 +8,12 @@ import "@heroicons/vue/20/solid";
8
8
  import "@speckle/shared";
9
9
  import "vee-validate";
10
10
  import "nanoid";
11
+ import "lucide-vue-next";
11
12
  import "@vueuse/core";
12
13
  import "@headlessui/vue";
13
14
  import "@heroicons/vue/24/solid";
14
15
  import "v3-infinite-loading";
15
- const W = { class: "flex flex-col space-y-2" }, Y = { class: "flex" }, ee = { class: "flex mx-14 space-x-2" }, ve = /* @__PURE__ */ j({
16
+ const W = { class: "flex flex-col space-y-2" }, Y = { class: "flex" }, ee = { class: "flex mx-14 space-x-2" }, he = /* @__PURE__ */ j({
16
17
  __name: "AvatarEditor",
17
18
  props: {
18
19
  user: {},
@@ -174,18 +175,18 @@ const W = { class: "flex flex-col space-y-2" }, Y = { class: "flex" }, ee = { cl
174
175
  color: "outline",
175
176
  onClick: t[0] || (t[0] = (x) => e.$emit("cancel"))
176
177
  }, {
177
- default: m(() => t[1] || (t[1] = [
178
- C("Close")
179
- ])),
178
+ default: m(() => [...t[1] || (t[1] = [
179
+ C("Close", -1)
180
+ ])]),
180
181
  _: 1
181
182
  }),
182
183
  r(i, {
183
184
  disabled: e.disabled,
184
185
  onClick: S
185
186
  }, {
186
- default: m(() => t[2] || (t[2] = [
187
- C("Save")
188
- ])),
187
+ default: m(() => [...t[2] || (t[2] = [
188
+ C("Save", -1)
189
+ ])]),
189
190
  _: 1
190
191
  }, 8, ["disabled"])
191
192
  ])
@@ -193,6 +194,6 @@ const W = { class: "flex flex-col space-y-2" }, Y = { class: "flex" }, ee = { cl
193
194
  }
194
195
  });
195
196
  export {
196
- ve as default
197
+ he as default
197
198
  };
198
- //# sourceMappingURL=AvatarEditor-edb34575.js.map
199
+ //# sourceMappingURL=AvatarEditor-fc5c4df2.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"AvatarEditor-edb34575.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<{\n (e: 'cancel'): void\n (e: 'save', val: Nullable<string>): void\n}>()\n\nconst props = defineProps<{\n user: AvatarUser\n disabled?: boolean\n size?: UserAvatarSize\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,GAKPC,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;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
1
+ {"version":3,"file":"AvatarEditor-fc5c4df2.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<{\n (e: 'cancel'): void\n (e: 'save', val: Nullable<string>): void\n}>()\n\nconst props = defineProps<{\n user: AvatarUser\n disabled?: boolean\n size?: UserAvatarSize\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","_openBlock","_createElementBlock","_hoisted_1","_createElementVNode","_hoisted_2","_normalizeClass","_createVNode","FormButton","_unref","ArrowUturnLeftIcon","ArrowUturnRightIcon","ArrowUpOnSquareIcon","ArrowLeftOnRectangleIcon","_createBlock","Cropper","FormFileUploadZone","activatorOn","_mergeProps","_toHandlers","PhotoIcon","XMarkIcon","_hoisted_3","$emit","_cache","disabled"],"mappings":"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"}
@@ -0,0 +1,17 @@
1
+ type __VLS_Props = {
2
+ title?: string;
3
+ text?: string;
4
+ button?: {
5
+ to?: string;
6
+ title: string;
7
+ };
8
+ showCloser?: boolean;
9
+ };
10
+ declare const _default: import('vue').DefineComponent<__VLS_Props, {}, {}, {}, {}, import('vue').ComponentOptionsMixin, import('vue').ComponentOptionsMixin, {
11
+ click: (e: MouseEvent) => any;
12
+ close: (e: MouseEvent) => any;
13
+ }, string, import('vue').PublicProps, Readonly<__VLS_Props> & Readonly<{
14
+ onClick?: ((e: MouseEvent) => any) | undefined;
15
+ onClose?: ((e: MouseEvent) => any) | undefined;
16
+ }>, {}, {}, {}, {}, string, import('vue').ComponentProvideOptions, false, {}, HTMLDivElement>;
17
+ export default _default;
@@ -105,6 +105,10 @@ declare const _default: import('vue').DefineComponent<import('vue').ExtractPropT
105
105
  type: PropType<LabelPosition>;
106
106
  default: string;
107
107
  };
108
+ indeterminate: {
109
+ type: BooleanConstructor;
110
+ default: boolean;
111
+ };
108
112
  }>, {}, {}, {}, {}, import('vue').ComponentOptionsMixin, import('vue').ComponentOptionsMixin, {} & {
109
113
  "update:modelValue": (val: ValueType) => any;
110
114
  }, string, import('vue').PublicProps, Readonly<import('vue').ExtractPropTypes<{
@@ -201,6 +205,10 @@ declare const _default: import('vue').DefineComponent<import('vue').ExtractPropT
201
205
  type: PropType<LabelPosition>;
202
206
  default: string;
203
207
  };
208
+ indeterminate: {
209
+ type: BooleanConstructor;
210
+ default: boolean;
211
+ };
204
212
  }>> & Readonly<{
205
213
  "onUpdate:modelValue"?: ((val: ValueType) => any) | undefined;
206
214
  }>, {
@@ -217,5 +225,6 @@ declare const _default: import('vue').DefineComponent<import('vue').ExtractPropT
217
225
  id: Optional<string>;
218
226
  hideLabel: boolean;
219
227
  labelPosition: LabelPosition;
228
+ indeterminate: boolean;
220
229
  }, {}, {}, {}, string, import('vue').ComponentProvideOptions, true, {}, any>;
221
230
  export default _default;
@@ -25,6 +25,8 @@ declare const _default: import('vue').DefineComponent<__VLS_Props, {}, {}, {}, {
25
25
  disabled: boolean;
26
26
  loading: boolean;
27
27
  type: string;
28
+ iconClasses: string;
29
+ placeholder: import('../../../../shared/dist/esm/index').Optional<string>;
28
30
  label: import('../../../../shared/dist/esm/index').Optional<string>;
29
31
  modelValue: string;
30
32
  rules: import('vee-validate').RuleExpression<string>;
@@ -40,7 +42,6 @@ declare const _default: import('vue').DefineComponent<__VLS_Props, {}, {}, {}, {
40
42
  customErrorMessage: string;
41
43
  hideErrorMessage: boolean;
42
44
  customHelpClass: string;
43
- placeholder: import('../../../../shared/dist/esm/index').Optional<string>;
44
45
  showOptional: boolean;
45
46
  wrapperClasses: string;
46
47
  readOnly: boolean;
@@ -56,6 +57,7 @@ declare const _default: import('vue').DefineComponent<__VLS_Props, {}, {}, {}, {
56
57
  readonly disabled: boolean;
57
58
  readonly loading: boolean;
58
59
  readonly type: string;
60
+ readonly iconClasses: string;
59
61
  readonly name: string;
60
62
  readonly modelValue: string;
61
63
  readonly validateOnMount: boolean;
@@ -72,11 +74,11 @@ declare const _default: import('vue').DefineComponent<__VLS_Props, {}, {}, {}, {
72
74
  readonly wrapperClasses: string;
73
75
  readonly readOnly: boolean;
74
76
  readonly inputClasses: string;
77
+ readonly placeholder?: import('../../../../shared/dist/esm/index').Optional<string>;
75
78
  readonly label?: import('../../../../shared/dist/esm/index').Optional<string>;
76
79
  readonly rules?: import('vee-validate').RuleExpression<string>;
77
80
  readonly help?: import('../../../../shared/dist/esm/index').Optional<string>;
78
81
  readonly customHelpClass?: string | undefined;
79
- readonly placeholder?: import('../../../../shared/dist/esm/index').Optional<string>;
80
82
  readonly customIcon?: import('../../../../shared/dist/esm/index').Optional<import('../../lib').PropAnyComponent>;
81
83
  readonly rightIcon?: import('../../../../shared/dist/esm/index').Optional<import('../../lib').PropAnyComponent>;
82
84
  readonly rightIconTitle?: string | undefined;
@@ -94,7 +96,7 @@ declare const _default: import('vue').DefineComponent<__VLS_Props, {}, {}, {}, {
94
96
  readonly onFocus?: (() => any) | undefined;
95
97
  readonly onBlur?: (() => any) | undefined;
96
98
  readonly onRightIconClick?: (() => any) | undefined;
97
- } & import('vue').VNodeProps & import('vue').AllowedComponentProps & import('vue').ComponentCustomProps, "size" | "fullWidth" | "color" | "disabled" | "loading" | "type" | "label" | "modelValue" | "rules" | "validateOnMount" | "showRequired" | "labelPosition" | "validateOnValueUpdate" | "help" | "showLabel" | "autoFocus" | "showClear" | "useLabelInErrors" | "customErrorMessage" | "hideErrorMessage" | "customHelpClass" | "placeholder" | "showOptional" | "wrapperClasses" | "readOnly" | "customIcon" | "inputClasses" | "rightIcon" | "rightIconTitle" | "tooltipText">;
99
+ } & import('vue').VNodeProps & import('vue').AllowedComponentProps & import('vue').ComponentCustomProps, "size" | "fullWidth" | "color" | "disabled" | "loading" | "type" | "iconClasses" | "placeholder" | "label" | "modelValue" | "rules" | "validateOnMount" | "showRequired" | "labelPosition" | "validateOnValueUpdate" | "help" | "showLabel" | "autoFocus" | "showClear" | "useLabelInErrors" | "customErrorMessage" | "hideErrorMessage" | "customHelpClass" | "showOptional" | "wrapperClasses" | "readOnly" | "customIcon" | "inputClasses" | "rightIcon" | "rightIconTitle" | "tooltipText">;
98
100
  $attrs: {
99
101
  [x: string]: unknown;
100
102
  };
@@ -178,6 +180,10 @@ declare const _default: import('vue').DefineComponent<__VLS_Props, {}, {}, {}, {
178
180
  type: import('vue').PropType<import('../../../../shared/dist/esm/index').Optional<import('../../lib').PropAnyComponent>>;
179
181
  default: undefined;
180
182
  };
183
+ iconClasses: {
184
+ type: StringConstructor;
185
+ default: null;
186
+ };
181
187
  autoFocus: {
182
188
  type: BooleanConstructor;
183
189
  default: boolean;
@@ -279,6 +285,8 @@ declare const _default: import('vue').DefineComponent<__VLS_Props, {}, {}, {}, {
279
285
  disabled: boolean;
280
286
  loading: boolean;
281
287
  type: string;
288
+ iconClasses: string;
289
+ placeholder: import('../../../../shared/dist/esm/index').Optional<string>;
282
290
  label: import('../../../../shared/dist/esm/index').Optional<string>;
283
291
  modelValue: string;
284
292
  rules: import('vee-validate').RuleExpression<string>;
@@ -294,7 +302,6 @@ declare const _default: import('vue').DefineComponent<__VLS_Props, {}, {}, {}, {
294
302
  customErrorMessage: string;
295
303
  hideErrorMessage: boolean;
296
304
  customHelpClass: string;
297
- placeholder: import('../../../../shared/dist/esm/index').Optional<string>;
298
305
  showOptional: boolean;
299
306
  wrapperClasses: string;
300
307
  readOnly: boolean;
@@ -330,6 +337,8 @@ declare const _default: import('vue').DefineComponent<__VLS_Props, {}, {}, {}, {
330
337
  disabled: boolean;
331
338
  loading: boolean;
332
339
  type: string;
340
+ iconClasses: string;
341
+ placeholder: import('../../../../shared/dist/esm/index').Optional<string>;
333
342
  label: import('../../../../shared/dist/esm/index').Optional<string>;
334
343
  modelValue: string;
335
344
  rules: import('vee-validate').RuleExpression<string>;
@@ -345,7 +354,6 @@ declare const _default: import('vue').DefineComponent<__VLS_Props, {}, {}, {}, {
345
354
  customErrorMessage: string;
346
355
  hideErrorMessage: boolean;
347
356
  customHelpClass: string;
348
- placeholder: import('../../../../shared/dist/esm/index').Optional<string>;
349
357
  showOptional: boolean;
350
358
  wrapperClasses: string;
351
359
  readOnly: boolean;
@@ -415,6 +423,10 @@ declare const _default: import('vue').DefineComponent<__VLS_Props, {}, {}, {}, {
415
423
  type: import('vue').PropType<import('../../../../shared/dist/esm/index').Optional<import('../../lib').PropAnyComponent>>;
416
424
  default: undefined;
417
425
  };
426
+ iconClasses: {
427
+ type: StringConstructor;
428
+ default: null;
429
+ };
418
430
  autoFocus: {
419
431
  type: BooleanConstructor;
420
432
  default: boolean;
@@ -493,7 +505,7 @@ declare const _default: import('vue').DefineComponent<__VLS_Props, {}, {}, {}, {
493
505
  onFocus?: (() => any) | undefined;
494
506
  onBlur?: (() => any) | undefined;
495
507
  onRightIconClick?: (() => any) | undefined;
496
- }>, "focus" | ("size" | "fullWidth" | "color" | "disabled" | "loading" | "type" | "label" | "modelValue" | "rules" | "validateOnMount" | "showRequired" | "labelPosition" | "validateOnValueUpdate" | "help" | "showLabel" | "autoFocus" | "showClear" | "useLabelInErrors" | "customErrorMessage" | "hideErrorMessage" | "customHelpClass" | "placeholder" | "showOptional" | "wrapperClasses" | "readOnly" | "customIcon" | "inputClasses" | "rightIcon" | "rightIconTitle" | "tooltipText")> & import('vue').ShallowUnwrapRef<{
508
+ }>, "focus" | ("size" | "fullWidth" | "color" | "disabled" | "loading" | "type" | "iconClasses" | "placeholder" | "label" | "modelValue" | "rules" | "validateOnMount" | "showRequired" | "labelPosition" | "validateOnValueUpdate" | "help" | "showLabel" | "autoFocus" | "showClear" | "useLabelInErrors" | "customErrorMessage" | "hideErrorMessage" | "customHelpClass" | "showOptional" | "wrapperClasses" | "readOnly" | "customIcon" | "inputClasses" | "rightIcon" | "rightIconTitle" | "tooltipText")> & import('vue').ShallowUnwrapRef<{
497
509
  focus: () => void;
498
510
  }> & {} & import('vue').ComponentCustomProperties & {} & {
499
511
  $slots: {
@@ -0,0 +1,27 @@
1
+ type __VLS_Props = {
2
+ min: number;
3
+ max: number;
4
+ step: number;
5
+ name: string;
6
+ disabled?: boolean;
7
+ showFields?: boolean;
8
+ style?: Record<string, string | number>;
9
+ };
10
+ type __VLS_PublicProps = {
11
+ modelValue?: {
12
+ min: number;
13
+ max: number;
14
+ };
15
+ } & __VLS_Props;
16
+ declare const _default: import('vue').DefineComponent<__VLS_PublicProps, {}, {}, {}, {}, import('vue').ComponentOptionsMixin, import('vue').ComponentOptionsMixin, {
17
+ "update:modelValue": (value: {
18
+ min: number;
19
+ max: number;
20
+ }) => any;
21
+ }, string, import('vue').PublicProps, Readonly<__VLS_PublicProps> & Readonly<{
22
+ "onUpdate:modelValue"?: ((value: {
23
+ min: number;
24
+ max: number;
25
+ }) => any) | undefined;
26
+ }>, {}, {}, {}, {}, string, import('vue').ComponentProvideOptions, false, {}, HTMLDivElement>;
27
+ export default _default;
@@ -6,6 +6,8 @@ type __VLS_Props = {
6
6
  label: string;
7
7
  disabled?: boolean;
8
8
  hideHeader?: boolean;
9
+ inputBelowSlider?: boolean;
10
+ style?: Record<string, string | number>;
9
11
  };
10
12
  declare const currentValue: import('vue').ModelRef<number, string, number, number>;
11
13
  type __VLS_PublicProps = {
@@ -123,6 +123,10 @@ declare const __VLS_component: import('vue').DefineComponent<import('vue').Extra
123
123
  type: PropType<Optional<PropAnyComponent>>;
124
124
  default: undefined;
125
125
  };
126
+ iconClasses: {
127
+ type: StringConstructor;
128
+ default: null;
129
+ };
126
130
  /**
127
131
  * Whether to focus on the input when component is mounted
128
132
  */
@@ -312,6 +316,10 @@ declare const __VLS_component: import('vue').DefineComponent<import('vue').Extra
312
316
  type: PropType<Optional<PropAnyComponent>>;
313
317
  default: undefined;
314
318
  };
319
+ iconClasses: {
320
+ type: StringConstructor;
321
+ default: null;
322
+ };
315
323
  /**
316
324
  * Whether to focus on the input when component is mounted
317
325
  */
@@ -400,6 +408,8 @@ declare const __VLS_component: import('vue').DefineComponent<import('vue').Extra
400
408
  disabled: boolean;
401
409
  loading: boolean;
402
410
  type: string;
411
+ iconClasses: string;
412
+ placeholder: Optional<string>;
403
413
  label: Optional<string>;
404
414
  modelValue: string;
405
415
  rules: RuleExpression<string>;
@@ -415,7 +425,6 @@ declare const __VLS_component: import('vue').DefineComponent<import('vue').Extra
415
425
  customErrorMessage: string;
416
426
  hideErrorMessage: boolean;
417
427
  customHelpClass: string;
418
- placeholder: Optional<string>;
419
428
  showOptional: boolean;
420
429
  wrapperClasses: string;
421
430
  readOnly: boolean;
@@ -43,7 +43,7 @@ declare const _default: <SingleItem extends Record<string, unknown> | string | n
43
43
  menuOpenDirection: "left" | "right";
44
44
  menuMaxHeightClasses: string;
45
45
  }> & Omit<{
46
- readonly disabled: Optional<boolean>;
46
+ readonly disabled: boolean;
47
47
  readonly label: string;
48
48
  readonly name: string;
49
49
  readonly search: boolean;
@@ -57,15 +57,16 @@ declare const _default: <SingleItem extends Record<string, unknown> | string | n
57
57
  readonly multiple: boolean;
58
58
  readonly items: SingleItem[];
59
59
  readonly searchPlaceholder: string;
60
- readonly buttonStyle: Optional<"base" | "simple" | "tinted">;
61
- readonly hideCheckmarks: Optional<boolean>;
62
- readonly allowUnset: Optional<boolean>;
60
+ readonly buttonStyle: "base" | "simple" | "tinted";
61
+ readonly hideCheckmarks: boolean;
62
+ readonly allowUnset: boolean;
63
63
  readonly clearable: boolean;
64
64
  readonly fixedHeight: boolean;
65
65
  readonly fullyControlValue: boolean;
66
66
  readonly mountMenuOnBody: boolean;
67
67
  readonly menuOpenDirection: "left" | "right";
68
68
  readonly size?: Optional<"sm" | "base" | "lg" | "xl">;
69
+ readonly placeholder?: string | undefined;
69
70
  readonly modelValue?: ([{
70
71
  type: PropType<SingleItem | SingleItem[] | undefined>;
71
72
  default: undefined;
@@ -74,20 +75,19 @@ declare const _default: <SingleItem extends Record<string, unknown> | string | n
74
75
  default: undefined;
75
76
  }) | undefined;
76
77
  readonly rules?: RuleExpression<SingleItem | SingleItem[] | undefined>;
78
+ readonly by?: string | undefined;
77
79
  readonly help?: Optional<string>;
78
- readonly placeholder?: string | undefined;
79
80
  readonly tooltipText?: string | undefined;
80
81
  readonly filterPredicate?: Optional<(item: SingleItem, searchString: string) => boolean>;
81
82
  readonly disabledItemPredicate?: Optional<(item: SingleItem) => boolean>;
82
83
  readonly getSearchResults?: Optional<(searchString: string) => MaybeAsync<SingleItem[]>>;
83
- readonly by?: string | undefined;
84
84
  readonly labelId?: string | undefined;
85
85
  readonly buttonId?: string | undefined;
86
86
  readonly disabledItemTooltip?: string | undefined;
87
87
  readonly menuMaxWidth?: number | undefined;
88
88
  readonly menuMaxHeightClasses?: string | undefined;
89
89
  readonly "onUpdate:modelValue"?: ((v: SingleItem | SingleItem[] | undefined) => any) | undefined;
90
- } & import('vue').VNodeProps & import('vue').AllowedComponentProps & import('vue').ComponentCustomProps, "size" | "disabled" | "search" | "modelValue" | "rules" | "validateOnMount" | "showRequired" | "labelPosition" | "validateOnValueUpdate" | "help" | "showLabel" | "useLabelInErrors" | "showOptional" | "tooltipText" | "multiple" | "items" | "filterPredicate" | "disabledItemPredicate" | "getSearchResults" | "searchPlaceholder" | "buttonStyle" | "hideCheckmarks" | "allowUnset" | "clearable" | "fixedHeight" | "fullyControlValue" | "mountMenuOnBody" | "labelId" | "buttonId" | "menuMaxWidth" | "menuOpenDirection" | "menuMaxHeightClasses">, "label" | "name" | "onUpdate:modelValue" | "placeholder" | "by" | "disabledItemTooltip" | ("size" | "disabled" | "search" | "modelValue" | "rules" | "validateOnMount" | "showRequired" | "labelPosition" | "validateOnValueUpdate" | "help" | "showLabel" | "useLabelInErrors" | "showOptional" | "tooltipText" | "multiple" | "items" | "filterPredicate" | "disabledItemPredicate" | "getSearchResults" | "searchPlaceholder" | "buttonStyle" | "hideCheckmarks" | "allowUnset" | "clearable" | "fixedHeight" | "fullyControlValue" | "mountMenuOnBody" | "labelId" | "buttonId" | "menuMaxWidth" | "menuOpenDirection" | "menuMaxHeightClasses")> & {} & Partial<{}>> & import('vue').PublicProps;
90
+ } & import('vue').VNodeProps & import('vue').AllowedComponentProps & import('vue').ComponentCustomProps, "size" | "disabled" | "search" | "modelValue" | "rules" | "validateOnMount" | "showRequired" | "labelPosition" | "validateOnValueUpdate" | "help" | "showLabel" | "useLabelInErrors" | "showOptional" | "tooltipText" | "multiple" | "items" | "filterPredicate" | "disabledItemPredicate" | "getSearchResults" | "searchPlaceholder" | "buttonStyle" | "hideCheckmarks" | "allowUnset" | "clearable" | "fixedHeight" | "fullyControlValue" | "mountMenuOnBody" | "labelId" | "buttonId" | "menuMaxWidth" | "menuOpenDirection" | "menuMaxHeightClasses">, "placeholder" | "label" | "name" | "onUpdate:modelValue" | "by" | "disabledItemTooltip" | ("size" | "disabled" | "search" | "modelValue" | "rules" | "validateOnMount" | "showRequired" | "labelPosition" | "validateOnValueUpdate" | "help" | "showLabel" | "useLabelInErrors" | "showOptional" | "tooltipText" | "multiple" | "items" | "filterPredicate" | "disabledItemPredicate" | "getSearchResults" | "searchPlaceholder" | "buttonStyle" | "hideCheckmarks" | "allowUnset" | "clearable" | "fixedHeight" | "fullyControlValue" | "mountMenuOnBody" | "labelId" | "buttonId" | "menuMaxWidth" | "menuOpenDirection" | "menuMaxHeightClasses")> & {} & Partial<{}>> & import('vue').PublicProps;
91
91
  expose(exposed: import('vue').ShallowUnwrapRef<{
92
92
  triggerSearch: () => Promise<void>;
93
93
  }>): void;