@speckle/ui-components 2.16.0 → 2.16.1-alpha2

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 @@
1
+ {"version":3,"file":"lib.cjs","sources":["../src/components/form/Button.vue","../src/components/common/text/Link.vue","../src/helpers/global/toast.ts","../src/components/global/ToastRenderer.vue","../src/components/common/Badge.vue","../src/helpers/tailwind.ts","../src/composables/common/steps.ts","../src/components/common/steps/Number.vue","../src/components/common/steps/Bullet.vue","../src/components/form/CardButton.vue","../src/components/form/Checkbox.vue","../src/composables/form/textInput.ts","../src/components/form/TextArea.vue","../src/components/form/TextInput.vue","../src/helpers/common/validation.ts","../src/composables/layout/resize.ts","../src/composables/form/select.ts","../src/components/form/select/Base.vue","../src/components/form/select/SourceApps.vue","../src/components/form/select/Badges.vue","../src/components/form/Switch.vue","../src/helpers/form/input.ts","../src/composables/form/input.ts","../src/components/layout/Dialog.vue","../src/components/layout/Disclosure.vue","../src/helpers/layout/components.ts","../src/components/layout/GridListToggle.vue","../src/composables/common/window.ts","../src/components/layout/Menu.vue","../src/components/layout/Tabs.vue","../src/components/layout/Table.vue","../src/components/InfiniteLoading.vue","../src/components/layout/Panel.vue","../src/components/common/Alert.vue","../src/composables/common/async.ts"],"sourcesContent":["<template>\n <Component\n :is=\"to ? linkComponent : 'button'\"\n :href=\"to\"\n :to=\"to\"\n :type=\"buttonType\"\n :external=\"external\"\n :class=\"buttonClasses\"\n :disabled=\"isDisabled\"\n role=\"button\"\n @click=\"onClick\"\n >\n <Component\n :is=\"finalLeftIcon\"\n v-if=\"finalLeftIcon\"\n :class=\"`${iconClasses} ${hideText ? '' : 'mr-2'}`\"\n />\n <slot v-if=\"!hideText\">Button</slot>\n <div v-else style=\"margin: 0 !important; width: 0.01px\">\n &nbsp;\n <!-- The point of this is to ensure text & no-text buttons have the same height -->\n </div>\n <Component\n :is=\"iconRight\"\n v-if=\"iconRight || !loading\"\n :class=\"`${iconClasses} ${hideText ? '' : 'ml-2'}`\"\n />\n </Component>\n</template>\n<script setup lang=\"ts\">\nimport { isObjectLike } from 'lodash'\nimport { ConcreteComponent, PropType, computed, resolveDynamicComponent } from 'vue'\nimport { Nullable, Optional } from '@speckle/shared'\nimport { ArrowPathIcon } from '@heroicons/vue/24/solid'\n\ntype FormButtonSize = 'xs' | 'sm' | 'base' | 'lg' | 'xl'\ntype FormButtonColor =\n | 'default'\n | 'invert'\n | 'danger'\n | 'warning'\n | 'success'\n | 'card'\n | 'secondary'\n | 'info'\n\nconst emit = defineEmits([\"click\"])\n\nconst props = defineProps({\n /**\n * URL to which to navigate - can be a relative (app) path or an absolute link for an external URL\n */\n to: {\n type: String as PropType<Optional<string>>,\n required: false,\n default: undefined\n },\n /**\n * Choose from one of many button sizes\n */\n size: {\n type: String as PropType<FormButtonSize>,\n default: 'base'\n },\n /**\n * If set, will make the button take up all available space horizontally\n */\n fullWidth: {\n type: Boolean,\n default: false\n },\n /**\n * Will outline the button.\n */\n outlined: {\n type: Boolean,\n default: false\n },\n /**\n * Will apply a rounded class.\n */\n rounded: {\n type: Boolean,\n default: false\n },\n /**\n * Similar to \"link\", but without an underline and possibly in different colors\n */\n text: {\n type: Boolean,\n default: false\n },\n /**\n * Will remove paddings and background. Use for links.\n */\n link: {\n type: Boolean,\n default: false\n },\n /**\n * Colors:\n * default: the default primary blue.\n * invert: for when you want to use this button on a primary background.\n * danger: for dangerous actions (e.g. deletions).\n * warning: for less dangerous actions (e.g. archival).\n */\n color: {\n type: String as PropType<FormButtonColor>,\n default: 'default'\n },\n /**\n * Whether the target location should be forcefully treated as an external URL\n * (for relative paths this will likely cause a redirect)\n */\n external: {\n type: Boolean as PropType<Optional<boolean>>,\n required: false,\n default: undefined\n },\n /**\n * Whether to disable the button so that it can't be pressed\n */\n disabled: {\n type: Boolean as PropType<Optional<boolean>>,\n required: false,\n default: undefined\n },\n /**\n * If set, will have type set to \"submit\" to enable it to submit any parent forms\n */\n submit: {\n type: Boolean,\n default: false\n },\n /**\n * Add icon to the left from the text\n */\n iconLeft: {\n type: [Object, Function] as PropType<Nullable<ConcreteComponent>>,\n default: null\n },\n /**\n * Add icon to the right from the text\n */\n iconRight: {\n type: [Object, Function] as PropType<Nullable<ConcreteComponent>>,\n default: null\n },\n /**\n * Hide default slot (when you want to show icons only)\n */\n hideText: {\n type: Boolean,\n default: false\n },\n /**\n * Customize component to be used when rendering links.\n *\n * The component will try to dynamically resolve NuxtLink and RouterLink and use those, if this is set to null.\n */\n linkComponent: {\n type: [Object, Function] as PropType<Nullable<ConcreteComponent>>,\n default: null\n },\n /**\n * Disables the button and shows a spinning loader\n */\n loading: {\n type: Boolean,\n default: false\n }\n})\n\nconst NuxtLink = resolveDynamicComponent('NuxtLink')\nconst RouterLink = resolveDynamicComponent('RouterLink')\n\nconst linkComponent = computed(() => {\n if (props.linkComponent) return props.linkComponent\n if (props.external) return 'a'\n if (isObjectLike(NuxtLink)) return NuxtLink\n if (isObjectLike(RouterLink)) return RouterLink\n return 'a'\n})\n\nconst buttonType = computed(() => {\n if (props.to) return undefined\n if (props.submit) return 'submit'\n return 'button'\n})\n\nconst isDisabled = computed(() => props.disabled || props.loading)\nconst finalLeftIcon = computed(() => (props.loading ? ArrowPathIcon : props.iconLeft))\n\nconst bgAndBorderClasses = computed(() => {\n const classParts: string[] = []\n\n classParts.push('border-2')\n if (isDisabled.value) {\n classParts.push(\n props.outlined\n ? 'border-foreground-disabled'\n : 'bg-foundation-disabled border-transparent'\n )\n } else {\n switch (props.color) {\n case 'invert':\n classParts.push(\n props.outlined\n ? 'border-foundation dark:border-foreground'\n : 'bg-foundation dark:bg-foreground border-transparent'\n )\n break\n case 'card':\n classParts.push(\n props.outlined\n ? 'border-foundation-2 shadow'\n : 'bg-foundation-2 dark:bg-foundation-2 border-foundation shadow'\n )\n break\n case 'danger':\n classParts.push(props.outlined ? 'border-danger' : 'bg-danger border-danger')\n break\n case 'secondary':\n classParts.push(\n props.outlined ? 'border-foundation' : 'bg-foundation border-foundation-2'\n )\n break\n case 'warning':\n classParts.push(props.outlined ? 'border-warning' : 'bg-warning border-warning')\n break\n case 'info':\n classParts.push(props.outlined ? 'border-info' : 'bg-info border-info')\n break\n case 'success':\n classParts.push(props.outlined ? 'border-success' : 'bg-success border-success')\n break\n case 'default':\n default:\n classParts.push(\n props.outlined\n ? 'border-primary hover:border-primary-focus'\n : 'bg-primary hover:bg-primary-focus border-transparent'\n )\n break\n }\n }\n\n return classParts.join(' ')\n})\n\nconst foregroundClasses = computed(() => {\n const classParts: string[] = []\n if (!props.text && !props.link) {\n if (isDisabled.value) {\n classParts.push(\n props.outlined ? 'text-foreground-disabled' : 'text-foreground-disabled'\n )\n } else {\n switch (props.color) {\n case 'invert':\n classParts.push(\n props.outlined ? 'text-foundation dark:text-foreground' : 'text-primary'\n )\n break\n case 'card':\n classParts.push(props.outlined ? 'text-foreground' : 'text-foreground')\n break\n case 'danger':\n classParts.push(\n props.outlined ? 'text-danger' : 'text-foundation dark:text-foreground'\n )\n break\n case 'warning':\n classParts.push(\n props.outlined ? 'text-warning' : 'text-foundation dark:text-foreground'\n )\n break\n case 'info':\n classParts.push(\n props.outlined ? 'text-info' : 'text-foundation dark:text-foreground'\n )\n break\n case 'success':\n classParts.push(\n props.outlined ? 'text-success' : 'text-foundation dark:text-foreground'\n )\n break\n case 'secondary':\n classParts.push(\n props.outlined\n ? 'text-foreground hover:text-primary'\n : 'text-foreground hover:text-primary'\n )\n break\n case 'default':\n default:\n classParts.push(\n props.outlined\n ? 'text-primary hover:text-primary-focus'\n : 'text-foundation dark:text-foreground'\n )\n break\n }\n }\n } else {\n if (isDisabled.value) {\n classParts.push('text-foreground-disabled')\n } else {\n if (props.color === 'invert') {\n classParts.push(\n 'text-foundation hover:text-foundation-2 dark:text-foreground dark:hover:text-foreground'\n )\n } else if (props.color === 'secondary') {\n classParts.push('text-foreground-2 hover:text-primary-focus')\n } else if (props.color === 'success') {\n classParts.push('text-success')\n } else if (props.color === 'warning') {\n classParts.push('text-warning')\n } else if (props.color === 'info') {\n classParts.push('text-info')\n } else if (props.color === 'danger') {\n classParts.push('text-danger')\n } else {\n classParts.push('text-primary hover:text-primary-focus')\n }\n }\n }\n return classParts.join(' ')\n})\n\nconst roundedClasses = computed(() => {\n const classParts: string[] = []\n classParts.push(props.rounded ? 'rounded-full' : 'rounded-md')\n return classParts.join(' ')\n})\n\nconst ringClasses = computed(() => {\n const classParts: string[] = []\n if (!isDisabled.value) {\n switch (props.color) {\n case 'invert':\n classParts.push('hover:ring-4 ring-white/50')\n break\n case 'danger':\n classParts.push('hover:ring-4 ring-danger-lighter dark:ring-danger-darker')\n break\n case 'warning':\n classParts.push('hover:ring-4 ring-warning-lighter dark:ring-warning-darker')\n break\n case 'info':\n classParts.push('hover:ring-4 ring-info-lighter dark:ring-info-darker')\n break\n case 'success':\n classParts.push('hover:ring-4 ring-success-lighter dark:ring-success-darker')\n break\n case 'default':\n default:\n classParts.push('hover:ring-2')\n break\n }\n }\n return classParts.join(' ')\n})\n\nconst sizeClasses = computed(() => {\n switch (props.size) {\n case 'xs':\n return 'h-5 text-xs font-medium xxx-tracking-wide'\n case 'sm':\n return 'h-6 text-sm font-medium xxx-tracking-wide'\n case 'lg':\n return 'h-10 text-lg font-semibold xxx-tracking-wide'\n case 'xl':\n return 'h-14 text-xl font-bold xxx-tracking-wide'\n default:\n case 'base':\n return 'h-8 text-base font-medium xxx-tracking-wide'\n }\n})\n\nconst paddingClasses = computed(() => {\n switch (props.size) {\n case 'xs':\n return 'px-1'\n case 'sm':\n return 'px-2'\n case 'lg':\n return 'px-4'\n case 'xl':\n return 'px-5'\n default:\n case 'base':\n return 'px-3'\n }\n})\n\nconst generalClasses = computed(() => {\n const classParts: string[] = []\n\n if (props.fullWidth) {\n classParts.push('w-full')\n }\n\n if (isDisabled.value) {\n classParts.push('cursor-not-allowed')\n }\n\n return classParts.join(' ')\n})\n\nconst decoratorClasses = computed(() => {\n const classParts: string[] = []\n if (!isDisabled.value && !props.link && !props.text) {\n classParts.push('active:scale-[0.97]')\n }\n\n if (!isDisabled.value && props.link) {\n classParts.push(\n 'underline decoration-transparent decoration-2 underline-offset-4\thover:decoration-inherit'\n )\n }\n\n return classParts.join(' ')\n})\n\nconst buttonClasses = computed(() => {\n const isLinkOrText = props.link || props.text\n return [\n 'transition inline-flex justify-center items-center space-x-2 outline-none select-none',\n generalClasses.value,\n sizeClasses.value,\n foregroundClasses.value,\n isLinkOrText ? '' : bgAndBorderClasses.value,\n isLinkOrText ? '' : roundedClasses.value,\n isLinkOrText ? '' : ringClasses.value,\n props.link ? '' : paddingClasses.value,\n decoratorClasses.value\n ].join(' ')\n})\n\nconst iconClasses = computed(() => {\n const classParts: string[] = ['']\n\n if (props.loading) {\n classParts.push('animate-spin')\n }\n\n switch (props.size) {\n case 'xs':\n classParts.push('h-3 w-3')\n break\n case 'sm':\n classParts.push('h-4 w-4')\n break\n case 'lg':\n classParts.push('h-6 w-6')\n break\n case 'xl':\n classParts.push('h-8 w-8')\n break\n case 'base':\n default:\n classParts.push('h-5 w-5')\n break\n }\n\n return classParts.join(' ')\n})\n\nconst onClick = (e: MouseEvent) => {\n if (isDisabled.value) {\n e.preventDefault()\n e.stopPropagation()\n e.stopImmediatePropagation()\n return\n }\n\n emit('click', e)\n}\n</script>\n<style scoped>\n.icon-slot:empty {\n display: none;\n}\n</style>\n","<template>\n <FormButton\n link\n :to=\"to\"\n :external=\"external\"\n :disabled=\"disabled\"\n :size=\"size\"\n :foreground-link=\"foregroundLink\"\n :icon-left=\"iconLeft\"\n :icon-right=\"iconRight\"\n :hide-text=\"hideText\"\n role=\"link\"\n @click.capture=\"onClick\"\n >\n <slot>Link</slot>\n </FormButton>\n</template>\n<script setup lang=\"ts\">\nimport FormButton from '~~/src/components/form/Button.vue'\nimport { PropType } from 'vue'\nimport { Nullable, Optional } from '@speckle/shared'\nimport { PropComponentType } from '~~/src/helpers/common/components'\n\ntype LinkSize = 'xs' | 'sm' | 'base' | 'lg' | 'xl'\nconst emit = defineEmits([\"click\"])\n\nconst props = defineProps({\n to: {\n type: String as PropType<Optional<string>>,\n required: false,\n default: undefined\n },\n external: {\n type: Boolean as PropType<Optional<boolean>>,\n required: false,\n default: undefined\n },\n disabled: {\n type: Boolean as PropType<Optional<boolean>>,\n required: false,\n default: undefined\n },\n size: {\n type: String as PropType<LinkSize>,\n default: 'base'\n },\n foregroundLink: {\n type: Boolean,\n default: false\n },\n /**\n * Add icon to the left from the text\n */\n iconLeft: {\n type: [Object, Function] as PropType<Nullable<PropComponentType>>,\n default: null\n },\n /**\n * Add icon to the right from the text\n */\n iconRight: {\n type: [Object, Function] as PropType<Nullable<PropComponentType>>,\n default: null\n },\n /**\n * Hide default slot (when you want to show icons only)\n */\n hideText: {\n type: Boolean,\n default: false\n }\n})\n\nconst onClick = (e: MouseEvent) => {\n if (props.disabled) {\n e.preventDefault()\n e.stopPropagation()\n e.stopImmediatePropagation()\n return\n }\n\n emit('click', e)\n}\n</script>\n","export enum ToastNotificationType {\n Success,\n Warning,\n Danger,\n Info\n}\n\nexport type ToastNotification = {\n title?: string\n /**\n * Optionally provide extra text\n */\n description?: string\n type: ToastNotificationType\n /**\n * Optionally specify a CTA link on the right\n */\n cta?: {\n title: string\n url?: string\n onClick?: (e: MouseEvent) => void\n }\n}\n","<template>\n <div\n aria-live=\"assertive\"\n class=\"pointer-events-none fixed inset-0 flex items-end px-4 py-6 mt-10 sm:items-start sm:p-6 z-50\"\n >\n <div class=\"flex w-full flex-col items-center space-y-4 sm:items-end\">\n <!-- Notification panel, dynamically insert this into the live region when it needs to be displayed -->\n <Transition\n enter-active-class=\"transform ease-out duration-300 transition\"\n enter-from-class=\"translate-y-2 opacity-0 sm:translate-y-0 sm:translate-x-2\"\n enter-to-class=\"translate-y-0 opacity-100 sm:translate-x-0\"\n leave-active-class=\"transition ease-in duration-100\"\n leave-from-class=\"opacity-100\"\n leave-to-class=\"opacity-0\"\n >\n <div\n v-if=\"notification\"\n class=\"pointer-events-auto w-full max-w-sm overflow-hidden rounded-lg bg-foundation text-foreground shadow-lg ring-1 ring-primary-muted ring-opacity-5\"\n >\n <div class=\"p-4\">\n <div class=\"flex items-start\">\n <div class=\"flex-shrink-0\">\n <CheckCircleIcon\n v-if=\"notification.type === ToastNotificationType.Success\"\n class=\"h-6 w-6 text-success\"\n aria-hidden=\"true\"\n />\n <XCircleIcon\n v-else-if=\"notification.type === ToastNotificationType.Danger\"\n class=\"h-6 w-6 text-danger\"\n aria-hidden=\"true\"\n />\n <ExclamationCircleIcon\n v-else-if=\"notification.type === ToastNotificationType.Warning\"\n class=\"h-6 w-6 text-warning\"\n aria-hidden=\"true\"\n />\n <InformationCircleIcon\n v-else-if=\"notification.type === ToastNotificationType.Info\"\n class=\"h-6 w-6 text-info\"\n aria-hidden=\"true\"\n />\n </div>\n <div class=\"ml-2 w-0 flex-1 flex flex-col\">\n <p v-if=\"notification.title\" class=\"text-foreground font-bold\">\n {{ notification.title }}\n </p>\n <p\n v-if=\"notification.description\"\n class=\"label label--light text-foreground-2\"\n >\n {{ notification.description }}\n </p>\n <div v-if=\"notification.cta\" class=\"flex justify-start mt-2\">\n <CommonTextLink\n :to=\"notification.cta.url\"\n class=\"label\"\n primary\n @click=\"onCtaClick\"\n >\n {{ notification.cta.title }}\n </CommonTextLink>\n </div>\n </div>\n <div\n class=\"ml-4 flex flex-shrink-0\"\n :class=\"{ 'self-center': shouldVerticallyCenterCloser }\"\n >\n <button\n type=\"button\"\n class=\"inline-flex rounded-md bg-foundation text-foreground-2 hover:text-foreground focus:outline-none focus:ring-2 focus:ring-primary focus:ring-offset-2\"\n @click=\"dismiss\"\n >\n <span class=\"sr-only\">Close</span>\n <XMarkIcon class=\"h-6 w-6\" aria-hidden=\"true\" />\n </button>\n </div>\n </div>\n </div>\n </div>\n </Transition>\n </div>\n </div>\n</template>\n<script setup lang=\"ts\">\nimport CommonTextLink from '~~/src/components/common/text/Link.vue'\nimport {\n CheckCircleIcon,\n XCircleIcon,\n ExclamationCircleIcon,\n InformationCircleIcon\n} from '@heroicons/vue/24/outline'\nimport { XMarkIcon } from '@heroicons/vue/20/solid'\nimport { computed } from 'vue'\nimport { Nullable } from '@speckle/shared'\nimport { ToastNotification, ToastNotificationType } from '~~/src/helpers/global/toast'\n\nconst emit = defineEmits([\"update:notification\"])\n\nconst props = defineProps({\n \"notification\": null\n})\n\nconst shouldVerticallyCenterCloser = computed(\n () => !props.notification?.description && !props.notification?.cta\n)\n\nconst dismiss = () => {\n emit('update:notification', null)\n}\n\nconst onCtaClick = (e: MouseEvent) => {\n props.notification?.cta?.onClick?.(e)\n dismiss()\n}\n</script>\n","<template>\n <span :class=\"badgeClasses\">\n <svg v-if=\"dot\" :class=\"dotClasses\" fill=\"currentColor\" viewBox=\"0 0 8 8\">\n <circle cx=\"4\" cy=\"4\" r=\"3\" />\n </svg>\n <slot>Badge</slot>\n <button v-if=\"iconLeft\" :class=\"iconClasses\" @click=\"onIconClick($event)\">\n <Component :is=\"iconLeft\" :class=\"['h-4 w-4', badgeDotIconColorClasses]\" />\n </button>\n </span>\n</template>\n<script setup lang=\"ts\">\nimport { ConcreteComponent, computed } from 'vue'\n\ntype BadgeSize = 'base' | 'lg'\n\nconst emit = defineEmits([\"click-icon\"])\n\nconst props = defineProps({\n \"size\": null,\n \"colorClasses\": null,\n \"dot\": { type: Boolean, },\n \"dotIconColorClasses\": null,\n \"iconLeft\": null,\n \"rounded\": { type: Boolean, },\n \"clickableIcon\": { type: Boolean, }\n})\n\nconst badgeColorClasses = computed(\n () => props.colorClasses || 'bg-blue-100 text-blue-800'\n)\n\nconst badgeDotIconColorClasses = computed(\n () => props.dotIconColorClasses || 'text-blue-400'\n)\n\nconst badgeClasses = computed(() => {\n const classParts: string[] = [\n 'inline-flex items-center',\n badgeColorClasses.value,\n props.size === 'lg' ? 'px-3 py-0.5 label' : 'px-2.5 py-0.5 caption font-medium'\n ]\n\n if (props.rounded) {\n classParts.push('rounded')\n classParts.push(\n props.size === 'lg' ? 'px-2 py-0.5 label' : 'px-2.5 py-0.5 caption font-medium'\n )\n } else {\n classParts.push('rounded-full')\n classParts.push(\n props.size === 'lg' ? 'px-2.5 py-0.5 label' : 'px-2.5 py-0.5 caption font-medium'\n )\n }\n\n return classParts.join(' ')\n})\n\nconst iconClasses = computed(() => {\n const classParts: string[] = [\n 'mt-0.5 ml-0.5 inline-flex h-4 w-4 flex-shrink-0 items-center justify-center rounded-full focus:outline-none'\n ]\n\n if (props.clickableIcon) {\n classParts.push('cursor-pointer')\n } else {\n classParts.push('cursor-default')\n }\n\n return classParts.join(' ')\n})\n\nconst dotClasses = computed(() => {\n const classParts: string[] = [\n '-ml-0.5 mr-1.5 h-2 w-2',\n badgeDotIconColorClasses.value\n ]\n\n return classParts.join(' ')\n})\n\nconst onIconClick = (e: MouseEvent) => {\n if (!props.clickableIcon) {\n e.stopPropagation()\n e.stopImmediatePropagation()\n e.preventDefault()\n return\n }\n\n emit('click-icon', e)\n}\n</script>\n","let junkVariable: string[] = []\n\n/**\n * If you use concatenation or variables to build tailwind classes, PurgeCSS won't pick up on them\n * during build and will not add them to the build. So you can use this function to just add string\n * literals of tailwind classes so PurgeCSS picks up on them.\n *\n * While you could just define an unused array of these classes, eslint/TS will bother you about the unused\n * variable so it's better to use this instead.\n */\nexport function markClassesUsed(classes: string[]) {\n // this doesn't do anything, except trick the compiler into thinking this isn't a pure\n // function so that the invocations aren't tree-shaken out\n junkVariable = junkVariable ? classes : classes.slice()\n}\n\n/**\n * Default tailwind breakpoint set. Each value is the minimum width (in pixels) expected for each breakpoint.\n */\nexport enum TailwindBreakpoints {\n sm = 640,\n md = 746,\n lg = 1024,\n xl = 1280,\n '2xl' = 1536\n}\n","import { ToRefs, computed } from 'vue'\nimport { HorizontalOrVertical, StepCoreType } from '~~/src/helpers/common/components'\nimport { clamp } from 'lodash'\nimport { TailwindBreakpoints, markClassesUsed } from '~~/src/helpers/tailwind'\n\nexport type StepsPadding = 'base' | 'xs' | 'sm'\n\nexport function useStepsInternals(params: {\n props: ToRefs<{\n orientation?: HorizontalOrVertical\n steps: StepCoreType[]\n modelValue?: number\n goVerticalBelow?: TailwindBreakpoints\n nonInteractive?: boolean\n stepsPadding?: StepsPadding\n }>\n emit: {\n (e: 'update:modelValue', val: number): void\n }\n}) {\n const {\n props: {\n modelValue,\n steps,\n orientation,\n goVerticalBelow,\n nonInteractive,\n stepsPadding\n },\n emit\n } = params\n\n const finalOrientation = computed(\n (): HorizontalOrVertical =>\n orientation?.value === 'vertical' ? 'vertical' : 'horizontal'\n )\n\n const value = computed({\n get: () => clamp(modelValue?.value || 0, -1, steps.value.length),\n set: (newVal) => emit('update:modelValue', clamp(newVal, 0, steps.value.length))\n })\n\n const getStepDisplayValue = (step: number) => `${step + 1}`\n const isCurrentStep = (step: number) => step === value.value\n const isFinishedStep = (step: number) => step < value.value\n\n const switchStep = (newStep: number, e?: MouseEvent) => {\n if (nonInteractive?.value) {\n e?.preventDefault()\n e?.stopPropagation()\n e?.stopImmediatePropagation()\n return\n }\n\n value.value = newStep\n\n const stepObj = steps.value[value.value]\n stepObj?.onClick?.()\n }\n\n const listClasses = computed(() => {\n const classParts: string[] = ['flex']\n\n let paddingHorizontal: string\n let paddingVertical: string\n if (stepsPadding?.value === 'xs') {\n paddingHorizontal = 'space-x-2'\n paddingVertical = 'space-y-1'\n } else if (stepsPadding?.value === 'sm') {\n paddingHorizontal = 'space-x-4'\n paddingVertical = 'space-y-1'\n } else {\n paddingHorizontal = 'space-x-8'\n paddingVertical = 'space-y-4'\n }\n\n classParts.push('flex')\n if (finalOrientation.value === 'vertical' || goVerticalBelow?.value) {\n classParts.push(`flex-col ${paddingVertical} justify-center`)\n\n if (goVerticalBelow?.value === TailwindBreakpoints.sm) {\n classParts.push(\n `sm:flex-row sm:space-y-0 sm:justify-start sm:${paddingHorizontal} sm:items-center`\n )\n } else if (goVerticalBelow?.value === TailwindBreakpoints.md) {\n classParts.push(\n `md:flex-row md:space-y-0 md:justify-start md:${paddingHorizontal} md:items-center`\n )\n } else if (goVerticalBelow?.value === TailwindBreakpoints.lg) {\n classParts.push(\n `lg:flex-row lg:space-y-0 lg:justify-start lg:${paddingHorizontal} lg:items-center`\n )\n } else if (goVerticalBelow?.value === TailwindBreakpoints.xl) {\n classParts.push(\n `xl:flex-row xl:space-y-0 xl:justify-start xl:${paddingHorizontal} xl:items-center`\n )\n }\n } else {\n classParts.push(`flex-row ${paddingHorizontal} items-center`)\n }\n\n return classParts.join(' ')\n })\n\n const linkClasses = computed(() => {\n const classParts: string[] = ['flex items-center']\n\n if (!nonInteractive?.value) {\n classParts.push('cursor-pointer')\n }\n\n return classParts.join(' ')\n })\n\n return {\n value,\n isCurrentStep,\n isFinishedStep,\n switchStep,\n getStepDisplayValue,\n listClasses,\n linkClasses,\n orientation: finalOrientation\n }\n}\n\n// to allow for dynamic class building above:\nmarkClassesUsed([\n 'sm:space-x-8',\n 'md:space-x-8',\n 'lg:space-x-8',\n 'xl:space-x-8',\n 'sm:space-x-2',\n 'md:space-x-2',\n 'lg:space-x-2',\n 'xl:space-x-2',\n 'sm:space-x-4',\n 'md:space-x-4',\n 'lg:space-x-4',\n 'xl:space-x-4'\n])\n","<template>\n <nav class=\"flex justify-center\" :aria-label=\"ariaLabel || 'Progress steps'\">\n <ol :class=\"listClasses\">\n <li v-for=\"(step, i) in steps\" :key=\"step.name\">\n <a\n v-if=\"isFinishedStep(i)\"\n :href=\"step.href\"\n :class=\"linkClasses\"\n @click=\"(e) => switchStep(i, e)\"\n >\n <div\n class=\"flex space-x-3 items-center text-primary-focus normal font-medium leading-5\"\n >\n <div\n class=\"shrink-0 h-8 w-8 rounded-full bg-primary-focus text-foreground-on-primary inline-flex items-center justify-center\"\n >\n <CheckIcon class=\"w-5 h-5\" />\n </div>\n <div class=\"flex flex-col\">\n <div>{{ step.name }}</div>\n <div v-if=\"step.description\" class=\"label label--light text-foreground\">\n {{ step.description }}\n </div>\n </div>\n </div>\n </a>\n <a\n v-else-if=\"isCurrentStep(i)\"\n :href=\"step.href\"\n :class=\"linkClasses\"\n aria-current=\"step\"\n @click=\"(e) => switchStep(i, e)\"\n >\n <div\n class=\"flex space-x-3 items-center text-primary-focus normal font-medium leading-5\"\n >\n <div\n class=\"shrink-0 h-8 w-8 rounded-full border-2 border-primary-focus inline-flex items-center justify-center\"\n >\n {{ getStepDisplayValue(i) }}\n </div>\n <div class=\"flex flex-col\">\n <div>{{ step.name }}</div>\n <div v-if=\"step.description\" class=\"label label--light text-foreground\">\n {{ step.description }}\n </div>\n </div>\n </div>\n </a>\n <a\n v-else\n :href=\"step.href\"\n :class=\"linkClasses\"\n @click=\"(e) => switchStep(i, e)\"\n >\n <div\n class=\"flex space-x-3 items-center text-foreground-disabled normal font-medium leading-5\"\n >\n <div\n class=\"shrink-0 h-8 w-8 rounded-full border-2 border-foreground-disabled inline-flex items-center justify-center\"\n >\n {{ getStepDisplayValue(i) }}\n </div>\n <div class=\"flex flex-col\">\n <div>{{ step.name }}</div>\n <div v-if=\"step.description\" class=\"label label--light\">\n {{ step.description }}\n </div>\n </div>\n </div>\n </a>\n </li>\n </ol>\n </nav>\n</template>\n<script setup lang=\"ts\">\nimport { CheckIcon } from '@heroicons/vue/20/solid'\nimport { toRefs } from 'vue'\nimport { StepsPadding, useStepsInternals } from '~~/src/composables/common/steps'\nimport { HorizontalOrVertical, NumberStepType } from '~~/src/helpers/common/components'\nimport { TailwindBreakpoints } from '~~/src/helpers/tailwind'\n\nconst emit = defineEmits([\"update:modelValue\"])\n\nconst props = defineProps({\n \"ariaLabel\": null,\n \"orientation\": null,\n \"steps\": null,\n \"modelValue\": null,\n \"goVerticalBelow\": null,\n \"nonInteractive\": { type: Boolean, },\n \"stepsPadding\": null\n})\n\nconst {\n isCurrentStep,\n isFinishedStep,\n switchStep,\n getStepDisplayValue,\n listClasses,\n linkClasses\n} = useStepsInternals({\n props: toRefs(props),\n emit\n})\n</script>\n","<template>\n <nav class=\"flex justify-center\" :aria-label=\"ariaLabel || 'Progress steps'\">\n <ol :class=\"[listClasses, extraListClasses]\">\n <li v-for=\"(step, i) in steps\" :key=\"step.name\">\n <a\n v-if=\"isFinishedStep(i)\"\n :href=\"step.href\"\n :class=\"linkClasses\"\n @click=\"(e) => switchStep(i, e)\"\n >\n <span class=\"relative flex h-5 w-5 flex-shrink-0 items-center justify-center\">\n <span v-if=\"basic\" class=\"h-3 w-3 rounded-full bg-foreground-2\" />\n <CheckCircleIcon\n v-else\n class=\"h-full w-full text-primary\"\n aria-hidden=\"true\"\n />\n </span>\n <span :class=\"['text-foreground', labelClasses]\">\n {{ step.name }}\n </span>\n </a>\n <a\n v-else-if=\"isCurrentStep(i)\"\n :href=\"step.href\"\n :class=\"linkClasses\"\n aria-current=\"step\"\n @click=\"(e) => switchStep(i, e)\"\n >\n <span\n class=\"relative flex h-5 w-5 flex-shrink-0 items-center justify-center\"\n aria-hidden=\"true\"\n >\n <template v-if=\"basic\">\n <span class=\"h-3 w-3 rounded-full bg-foreground\" />\n </template>\n <template v-else>\n <span class=\"absolute h-4 w-4 rounded-full bg-outline-2\" />\n <span class=\"relative block h-2 w-2 rounded-full bg-primary-focus\" />\n </template>\n </span>\n <span :class=\"['text-primary-focus', labelClasses]\">\n {{ step.name }}\n </span>\n </a>\n <a\n v-else\n :href=\"step.href\"\n :class=\"linkClasses\"\n @click=\"(e) => switchStep(i, e)\"\n >\n <div\n class=\"relative flex h-5 w-5 flex-shrink-0 items-center justify-center\"\n aria-hidden=\"true\"\n >\n <span v-if=\"basic\" class=\"h-3 w-3 rounded-full bg-foreground-2\" />\n <div v-else class=\"h-4 w-4 rounded-full bg-foreground-disabled\" />\n </div>\n <p :class=\"['text-foreground-disabled', labelClasses]\">\n {{ step.name }}\n </p>\n </a>\n </li>\n </ol>\n </nav>\n</template>\n<script setup lang=\"ts\">\nimport { CheckCircleIcon } from '@heroicons/vue/20/solid'\nimport { computed, toRefs } from 'vue'\nimport { StepsPadding, useStepsInternals } from '~~/src/composables/common/steps'\nimport { BulletStepType, HorizontalOrVertical } from '~~/src/helpers/common/components'\nimport { TailwindBreakpoints } from '~~/src/helpers/tailwind'\n\nconst emit = defineEmits([\"update:modelValue\"])\n\nconst props = defineProps({\n \"ariaLabel\": null,\n \"basic\": { type: Boolean, },\n \"orientation\": null,\n \"steps\": null,\n \"modelValue\": null,\n \"goVerticalBelow\": null,\n \"nonInteractive\": { type: Boolean, },\n \"stepsPadding\": null\n})\n\nconst { isCurrentStep, isFinishedStep, switchStep, listClasses, linkClasses } =\n useStepsInternals({\n props: toRefs(props),\n emit\n })\n\nconst labelClasses = computed(() => {\n const classParts: string[] = ['h6 font-medium leading-7']\n\n let leftMargin: string\n if (props.stepsPadding === 'xs') {\n leftMargin = 'ml-1'\n } else if (props.stepsPadding === 'sm') {\n leftMargin = 'ml-2'\n } else {\n leftMargin = 'ml-3'\n }\n\n classParts.push(leftMargin)\n\n if (props.basic) {\n classParts.push('sr-only')\n }\n\n return classParts.join(' ')\n})\n\nconst extraListClasses = computed(() => {\n const classParts: string[] = []\n\n if (props.basic) {\n classParts.push('basic')\n }\n\n return classParts.join(' ')\n})\n</script>\n","<template>\n <button :class=\"computedClasses\" :disabled=\"disabled\" @click=\"onClick\">\n <slot>Text</slot>\n </button>\n</template>\n<script setup lang=\"ts\">\nimport { computed } from 'vue'\n\nconst emit = defineEmits([\"update:modelValue\", \"click\"])\n\nconst props = defineProps({\n \"disabled\": { type: Boolean, },\n \"modelValue\": { type: Boolean, }\n})\n\nconst computedClasses = computed(() => {\n const classParts: string[] = [\n 'h-20 bg-foundation-2 inline-flex justify-center items-center outline-none',\n 'normal px-16 py-5 shadow rounded transition active:scale-95'\n ]\n\n if (props.disabled) {\n classParts.push('bg-foundation-disabled text-foreground-2 cursor-not-allowed')\n } else {\n classParts.push(\n props.modelValue\n ? 'bg-primary-focus text-foreground-on-primary'\n : 'bg-foundation text-foreground'\n )\n classParts.push('ring-outline-2 hover:ring-4')\n }\n\n return classParts.join(' ')\n})\n\nconst onClick = (e: MouseEvent) => {\n if (props.disabled) {\n e.preventDefault()\n e.stopPropagation()\n e.stopImmediatePropagation()\n return\n }\n\n emit('update:modelValue', !props.modelValue)\n emit('click', e)\n}\n</script>\n","<template>\n <div class=\"relative flex items-start\">\n <div class=\"flex h-6 items-center\">\n <!-- eslint-disable-next-line vuejs-accessibility/form-control-has-label -->\n <input\n :id=\"finalId\"\n :checked=\"coreChecked\"\n :aria-describedby=\"descriptionId\"\n :name=\"name\"\n :disabled=\"disabled\"\n :value=\"checkboxValue\"\n type=\"checkbox\"\n class=\"h-4 w-4 rounded text-primary focus:ring-primary bg-foundation disabled:cursor-not-allowed disabled:bg-disabled disabled:text-disabled-2\"\n :class=\"computedClasses\"\n v-bind=\"$attrs\"\n @change=\"onChange\"\n />\n </div>\n <div class=\"ml-2 text-sm\" style=\"padding-top: 2px\">\n <label\n :for=\"finalId\"\n class=\"font-medium text-foreground\"\n :class=\"{ 'sr-only': hideLabel }\"\n >\n <span>{{ title }}</span>\n <span v-if=\"showRequired\" class=\"text-danger ml-1\">*</span>\n </label>\n <p v-if=\"descriptionText\" :id=\"descriptionId\" :class=\"descriptionClasses\">\n {{ descriptionText }}\n </p>\n </div>\n </div>\n</template>\n<script setup lang=\"ts\">\n/* eslint-disable @typescript-eslint/no-explicit-any */\n/* eslint-disable @typescript-eslint/no-unsafe-argument */\nimport { RuleExpression, useField } from 'vee-validate'\nimport { PropType, computed, onMounted, ref } from 'vue'\nimport { Optional } from '@speckle/shared'\nimport { nanoid } from 'nanoid'\n\n/**\n * Troubleshooting:\n * - If clicking on the checkbox doesn't do anything, check if any of its ancestor elements\n * have a @click.prevent on them anywhere.\n * - If you're not using the checkbox in a group, it's suggested that you set :value=\"true\",\n * so that a v-model attached to the checkbox will be either 'true' or 'undefined' depending on the\n * checked state\n */\n\ntype ValueType = Optional<string | true> | string[]\n\ndefineOptions({\n inheritAttrs: false\n})\n\nconst props = defineProps({\n /**\n * Input name/id. In a checkbox group, all checkboxes must have the same name and different values.\n */\n name: {\n type: String,\n required: true\n },\n /**\n * Whether the input is disabled\n */\n disabled: {\n type: Boolean,\n default: false\n },\n /**\n * Set label text\n */\n label: {\n type: String as PropType<Optional<string>>,\n default: undefined\n },\n /**\n * Help text\n */\n description: {\n type: String as PropType<Optional<string>>,\n default: undefined\n },\n /**\n * Whether to inline the help description\n */\n inlineDescription: {\n type: Boolean,\n default: false\n },\n /**\n * vee-validate validation rules\n */\n rules: {\n type: [String, Object, Function, Array] as PropType<RuleExpression<ValueType>>,\n default: undefined\n },\n /**\n * vee-validate validation() on component mount\n */\n validateOnMount: {\n type: Boolean,\n default: false\n },\n /**\n * Whether to show the red \"required\" asterisk\n */\n showRequired: {\n type: Boolean,\n default: false\n },\n /**\n * Checkbox group's value\n */\n modelValue: {\n type: [String, Boolean] as PropType<ValueType | false>,\n default: undefined\n },\n /**\n * Checkbox's own value. If it is checked, modelValue will include this value (amongst any other checked values from the same group).\n * If not set will default to 'name' value.\n */\n value: {\n type: [String, Boolean] as PropType<Optional<string | true>>,\n default: true\n },\n /**\n * HTML ID to use, must be globally unique. If not specified, a random ID will be generated. One is necessary to properly associate the label and checkbox.\n */\n id: {\n type: String as PropType<Optional<string>>,\n default: undefined\n },\n hideLabel: {\n type: Boolean,\n default: false\n }\n})\n\nconst generateRandomId = (prefix: string) => `${prefix}-${nanoid()}`\n\ndefineEmits([\"update:modelValue\"])\n\nconst checkboxValue = computed(() => props.value || props.name)\n\nconst {\n checked: coreChecked,\n errorMessage,\n handleChange,\n value: coreValue\n} = useField<ValueType>(props.name, props.rules, {\n validateOnMount: props.validateOnMount,\n type: 'checkbox',\n checkedValue: checkboxValue,\n initialValue: props.modelValue || undefined\n})\n\nconst title = computed(() => props.label || props.name)\n\nconst computedClasses = computed((): string => {\n return errorMessage.value ? 'border-danger-lighter' : 'border-foreground-4 '\n})\n\nconst descriptionText = computed(() => props.description || errorMessage.value)\nconst descriptionId = computed(() => `${props.name}-description`)\nconst descriptionClasses = computed((): string => {\n const classParts: string[] = []\n\n if (props.inlineDescription) {\n classParts.push('inline ml-2')\n } else {\n classParts.push('block')\n }\n\n if (errorMessage.value) {\n classParts.push('text-danger')\n } else {\n classParts.push('text-foreground-2')\n }\n\n return classParts.join(' ')\n})\n\nconst implicitId = ref<Optional<string>>(generateRandomId('checkbox'))\nconst finalId = computed(() => props.id || implicitId.value)\n\nconst onChange = (e: unknown) => {\n if (props.disabled) return\n handleChange(e)\n}\n\n/**\n * Bugfix for strange issue where checkbox appears checked even tho it shouldnt be.\n * It's not clear why this happens, but for some reason coreValue.value shows that the checkbox\n * is checked, even tho props.modelValue is undefined.\n */\nonMounted(() => {\n const newModelValue = props.modelValue\n const newCoreValue = coreValue.value\n\n const shouldBeChecked = Array.isArray(newModelValue)\n ? newModelValue.includes(props.value as any)\n : newModelValue === props.value\n\n const isCoreChecked = Array.isArray(newCoreValue)\n ? newCoreValue.includes(props.value as any)\n : newCoreValue === props.value\n\n if (shouldBeChecked !== isCoreChecked) {\n handleChange(newModelValue)\n }\n})\n</script>\n","import { RuleExpression, useField } from 'vee-validate'\nimport { Ref, ToRefs, computed, onMounted, ref, unref } from 'vue'\nimport { Nullable } from '@speckle/shared'\nimport { nanoid } from 'nanoid'\n\nexport type InputColor = 'page' | 'foundation'\n\n/**\n * Common setup for text input & textarea fields\n */\nexport function useTextInputCore(params: {\n props: ToRefs<{\n name: string\n help?: string\n label?: string\n showLabel?: boolean\n rules?: RuleExpression<string>\n validateOnMount?: boolean\n validateOnValueUpdate?: boolean\n modelValue?: string\n autoFocus?: boolean\n showClear?: boolean\n useLabelInErrors?: boolean\n hideErrorMessage?: boolean\n color?: InputColor\n }>\n emit: {\n (e: 'change', val: { event?: Event; value: string }): void\n (e: 'clear'): void\n }\n inputEl: Ref<Nullable<HTMLInputElement | HTMLTextAreaElement>>\n}) {\n const { props, inputEl, emit } = params\n\n const { value, errorMessage: error } = useField(props.name, props.rules, {\n validateOnMount: unref(props.validateOnMount),\n validateOnValueUpdate: unref(props.validateOnValueUpdate),\n initialValue: unref(props.modelValue) || undefined\n })\n\n const labelClasses = computed(() => {\n const classParts = ['block label text-foreground-2 mb-2']\n if (!unref(props.showLabel)) {\n classParts.push('sr-only')\n }\n\n return classParts.join(' ')\n })\n\n const coreClasses = computed(() => {\n const classParts = [\n 'block w-full rounded focus:outline-none text-foreground transition-all',\n 'disabled:cursor-not-allowed disabled:bg-foundation-disabled disabled:text-disabled-muted',\n 'placeholder:text-foreground-2'\n ]\n\n if (error.value) {\n classParts.push(\n 'border-2 border-danger text-danger-darker focus:border-danger focus:ring-danger'\n )\n } else {\n classParts.push('border-0 focus:ring-2 focus:ring-outline-2')\n }\n\n const color = unref(props.color)\n if (color === 'foundation') {\n classParts.push('bg-foundation shadow-sm hover:shadow')\n } else {\n classParts.push('bg-foundation-page')\n }\n\n return classParts.join(' ')\n })\n\n const internalHelpTipId = ref(nanoid())\n\n const title = computed(() => unref(props.label) || unref(props.name))\n const errorMessage = computed(() => {\n const base = error.value\n if (!base || !unref(props.useLabelInErrors)) return base\n return base.replace('Value', title.value)\n })\n\n const hideHelpTip = computed(\n () => errorMessage.value && unref(props.hideErrorMessage)\n )\n const helpTip = computed(() => errorMessage.value || unref(props.help))\n const hasHelpTip = computed(() => !!helpTip.value)\n const helpTipId = computed(() =>\n hasHelpTip.value ? `${unref(props.name)}-${internalHelpTipId.value}` : undefined\n )\n const helpTipClasses = computed((): string => {\n const classParts = ['mt-2 text-sm']\n classParts.push(error.value ? 'text-danger' : 'text-foreground-2')\n return classParts.join(' ')\n })\n\n const focus = () => {\n inputEl.value?.focus()\n }\n\n const clear = () => {\n value.value = ''\n emit('change', { value: '' })\n emit('clear')\n }\n\n onMounted(() => {\n if (unref(props.autoFocus)) {\n focus()\n }\n })\n\n return {\n coreClasses,\n title,\n value,\n helpTipId,\n helpTipClasses,\n helpTip,\n hideHelpTip,\n errorMessage,\n clear,\n focus,\n labelClasses\n }\n}\n","<template>\n <div :class=\"[fullWidth ? 'w-full' : '']\">\n <label :for=\"name\" :class=\"labelClasses\">\n <span>{{ title }}</span>\n </label>\n <div class=\"relative\">\n <textarea\n :id=\"name\"\n ref=\"inputElement\"\n v-model=\"value\"\n :name=\"name\"\n :class=\"[\n coreClasses,\n iconClasses,\n textareaClasses || '',\n 'min-h-[4rem] simple-scrollbar'\n ]\"\n :placeholder=\"placeholder\"\n :disabled=\"disabled\"\n :aria-invalid=\"errorMessage ? 'true' : 'false'\"\n :aria-describedby=\"helpTipId\"\n v-bind=\"$attrs\"\n @change=\"$emit('change', { event: $event, value })\"\n @input=\"$emit('input', { event: $event, value })\"\n />\n <a\n v-if=\"showClear\"\n title=\"Clear input\"\n class=\"absolute top-2 right-0 flex items-center pr-2 cursor-pointer\"\n @click=\"clear\"\n @keydown=\"clear\"\n >\n <span class=\"text-xs sr-only\">Clear input</span>\n <XMarkIcon class=\"h-5 w-5 text-foreground\" aria-hidden=\"true\" />\n </a>\n <div\n v-if=\"errorMessage\"\n :class=\"[\n 'pointer-events-none absolute inset-y-0 right-0 flex items-start mt-2',\n showClear ? 'pr-8' : 'pr-2'\n ]\"\n >\n <ExclamationCircleIcon class=\"h-4 w-4 text-danger\" aria-hidden=\"true\" />\n </div>\n <div\n v-if=\"showRequired && !errorMessage\"\n class=\"pointer-events-none absolute inset-y-0 mt-0.5 text-4xl right-0 flex items-start pr-2 text-danger opacity-50\"\n >\n *\n </div>\n </div>\n <p v-if=\"helpTipId\" :id=\"helpTipId\" :class=\"helpTipClasses\">\n {{ helpTip }}\n </p>\n </div>\n</template>\n<script setup lang=\"ts\">\nimport { ExclamationCircleIcon, XMarkIcon } from '@heroicons/vue/20/solid'\nimport { Nullable } from '@speckle/shared'\nimport { RuleExpression } from 'vee-validate'\nimport { computed, ref, toRefs } from 'vue'\nimport { InputColor, useTextInputCore } from '~~/src/composables/form/textInput'\n\nconst emit = defineEmits([\"update:modelValue\", \"change\", \"input\", \"clear\"])\n\nconst props = defineProps({\n \"name\": null,\n \"showLabel\": { type: Boolean, },\n \"help\": null,\n \"placeholder\": null,\n \"label\": null,\n \"disabled\": { type: Boolean, },\n \"rules\": null,\n \"validateOnMount\": { type: Boolean, },\n \"validateOnValueUpdate\": { type: Boolean, },\n \"useLabelInErrors\": { type: Boolean, default: true },\n \"autoFocus\": { type: Boolean, },\n \"modelValue\": { default: '' },\n \"showClear\": { type: Boolean, },\n \"fullWidth\": { type: Boolean, },\n \"showRequired\": { type: Boolean, },\n \"color\": { default: 'page' },\n \"textareaClasses\": null\n})\n\nconst inputElement = ref(null as Nullable<HTMLTextAreaElement>)\n\nconst {\n coreClasses,\n title,\n value,\n helpTipId,\n helpTipClasses,\n helpTip,\n errorMessage,\n labelClasses,\n clear,\n focus\n} = useTextInputCore({\n props: toRefs(props),\n emit,\n inputEl: inputElement\n})\n\nconst iconClasses = computed(() => {\n const classParts: string[] = ['pl-2']\n\n if (props.showClear && errorMessage.value) {\n classParts.push('pr-12')\n } else if (props.showClear || errorMessage.value) {\n classParts.push('pr-8')\n }\n\n return classParts.join(' ')\n})\n\ndefineExpose({ focus })\n</script>\n","<template>\n <div :class=\"[fullWidth ? 'w-full' : '', wrapperClasses]\">\n <label :for=\"name\" :class=\"labelClasses\">\n <span>{{ title }}</span>\n </label>\n <div class=\"relative\">\n <div\n v-if=\"hasLeadingIcon\"\n class=\"pointer-events-none absolute inset-y-0 left-0 flex items-center pl-2\"\n >\n <Component\n :is=\"customIcon\"\n v-if=\"customIcon\"\n :class=\"leadingIconClasses\"\n aria-hidden=\"true\"\n />\n <EnvelopeIcon\n v-else-if=\"type === 'email'\"\n :class=\"leadingIconClasses\"\n aria-hidden=\"true\"\n />\n <KeyIcon\n v-else-if=\"type === 'password'\"\n :class=\"leadingIconClasses\"\n aria-hidden=\"true\"\n />\n </div>\n <input\n :id=\"name\"\n ref=\"inputElement\"\n v-model=\"value\"\n :type=\"type\"\n :name=\"name\"\n :class=\"[coreClasses, iconClasses, sizeClasses, inputClasses || '']\"\n :placeholder=\"placeholder\"\n :disabled=\"disabled\"\n :aria-invalid=\"errorMessage ? 'true' : 'false'\"\n :aria-describedby=\"helpTipId\"\n role=\"textbox\"\n v-bind=\"$attrs\"\n @change=\"$emit('change', { event: $event, value })\"\n @input=\"$emit('input', { event: $event, value })\"\n />\n <slot name=\"input-right\">\n <a\n v-if=\"showClear\"\n title=\"Clear input\"\n class=\"absolute inset-y-0 right-0 flex items-center pr-2 cursor-pointer\"\n @click=\"clear\"\n @keydown=\"clear\"\n >\n <span class=\"text-xs sr-only\">Clear input</span>\n <XMarkIcon class=\"h-5 w-5 text-foreground\" aria-hidden=\"true\" />\n </a>\n <div\n v-if=\"errorMessage\"\n :class=\"[\n 'pointer-events-none absolute inset-y-0 right-0 flex items-center',\n showClear ? 'pr-8' : 'pr-2'\n ]\"\n >\n <ExclamationCircleIcon class=\"h-4 w-4 text-danger\" aria-hidden=\"true\" />\n </div>\n <div\n v-if=\"showRequired && !errorMessage\"\n class=\"pointer-events-none absolute inset-y-0 mt-3 text-4xl right-0 flex items-center pr-2 text-danger opacity-50\"\n >\n *\n </div>\n </slot>\n </div>\n <p v-if=\"helpTipId && !hideHelpTip\" :id=\"helpTipId\" :class=\"helpTipClasses\">\n {{ helpTip }}\n </p>\n </div>\n</template>\n<script setup lang=\"ts\">\nimport { RuleExpression } from 'vee-validate'\nimport {\n ExclamationCircleIcon,\n EnvelopeIcon,\n KeyIcon,\n XMarkIcon\n} from '@heroicons/vue/20/solid'\nimport { ConcreteComponent, PropType, computed, ref, toRefs, useSlots } from 'vue'\nimport { Nullable, Optional } from '@speckle/shared'\nimport { useTextInputCore } from '~~/src/composables/form/textInput'\n\ntype InputType = 'text' | 'email' | 'password' | 'url' | 'search' | 'number' | string\ntype InputSize = 'sm' | 'base' | 'lg' | 'xl'\ntype InputColor = 'page' | 'foundation'\n\ndefineOptions({\n inheritAttrs: false\n})\n\nconst props = defineProps({\n /**\n * Input \"type\" value (changes behaviour & look)\n */\n type: {\n type: String as PropType<InputType>,\n default: 'text'\n },\n /**\n * Unique ID for the input (must be unique page-wide)\n */\n name: {\n type: String,\n required: true\n },\n /**\n * Whether to show label (label will always be shown to screen readers)\n */\n showLabel: {\n type: Boolean,\n required: false\n },\n /**\n * Optional help text\n */\n help: {\n type: String as PropType<Optional<string>>,\n default: undefined\n },\n /**\n * Placeholder text\n */\n placeholder: {\n type: String as PropType<Optional<string>>,\n default: undefined\n },\n /**\n * Set label text explicitly\n */\n label: {\n type: String as PropType<Optional<string>>,\n default: undefined\n },\n /**\n * Whether to show the red \"required\" asterisk\n */\n showRequired: {\n type: Boolean,\n default: false\n },\n /**\n * Whether to disable the component, blocking it from user input\n */\n disabled: {\n type: Boolean,\n default: false\n },\n /**\n * vee-validate validation rules\n */\n rules: {\n type: [String, Object, Function, Array] as PropType<RuleExpression<string>>,\n default: undefined\n },\n /**\n * vee-validate validation() on component mount\n */\n validateOnMount: {\n type: Boolean,\n default: false\n },\n /**\n * Whether to trigger validation whenever the value changes\n */\n validateOnValueUpdate: {\n type: Boolean,\n default: false\n },\n /**\n * Will replace the generic \"Value\" text with the name of the input in error messages\n */\n useLabelInErrors: {\n type: Boolean,\n default: true\n },\n /**\n * Set a custom icon to use inside the input\n */\n customIcon: {\n type: [Object, Function] as PropType<Optional<ConcreteComponent>>,\n default: undefined\n },\n /**\n * Whether to focus on the input when component is mounted\n */\n autoFocus: {\n type: Boolean,\n default: false\n },\n modelValue: {\n type: String,\n default: ''\n },\n size: {\n type: String as PropType<InputSize>,\n default: 'base'\n },\n showClear: {\n type: Boolean,\n default: false\n },\n fullWidth: {\n type: Boolean,\n default: false\n },\n inputClasses: {\n type: String,\n default: null\n },\n hideErrorMessage: {\n type: Boolean,\n default: false\n },\n wrapperClasses: {\n type: String,\n default: () => ''\n },\n color: {\n type: String as PropType<InputColor>,\n default: 'page'\n }\n})\n\nconst emit = defineEmits([\"update:modelValue\", \"change\", \"input\", \"clear\", \"focusin\", \"focusout\"])\n\nconst slots = useSlots()\n\nconst inputElement = ref(null as Nullable<HTMLInputElement>)\n\nconst {\n coreClasses,\n title,\n value,\n helpTipId,\n helpTipClasses,\n helpTip,\n hideHelpTip,\n errorMessage,\n clear,\n focus,\n labelClasses\n} = useTextInputCore({\n props: toRefs(props),\n emit,\n inputEl: inputElement\n})\n\nconst leadingIconClasses = computed(() => {\n const classParts: string[] = ['h-5 w-5']\n\n if (errorMessage.value) {\n classParts.push('text-danger')\n } else {\n classParts.push('text-foreground-2')\n }\n\n return classParts.join(' ')\n})\n\nconst hasLeadingIcon = computed(\n () => ['email', 'password'].includes(props.type) || props.customIcon\n)\n\nconst iconClasses = computed((): string => {\n const classParts: string[] = []\n\n if (hasLeadingIcon.value) {\n classParts.push('pl-8')\n } else {\n classParts.push('pl-2')\n }\n\n if (!slots['input-right']) {\n if (errorMessage.value || props.showClear) {\n if (errorMessage.value && props.showClear) {\n classParts.push('pr-12')\n } else {\n classParts.push('pr-8')\n }\n }\n }\n\n return classParts.join(' ')\n})\n\nconst sizeClasses = computed((): string => {\n switch (props.size) {\n case 'sm':\n return 'h-6'\n case 'lg':\n return 'h-10'\n case 'xl':\n return 'h-14'\n case 'base':\n default:\n return 'h-8'\n }\n})\n\ndefineExpose({ focus })\n</script>\n","import { isString, isUndefined } from 'lodash'\nimport { GenericValidateFunction } from 'vee-validate'\nimport { isNullOrUndefined } from '@speckle/shared'\n\nexport const VALID_HTTP_URL = /^https?:\\/\\//\nexport const VALID_EMAIL = /^[\\w-_.+]+@[\\w-_.+]+$/\n\n/**\n * Note about new validators:\n * Make sure you use the word \"Value\" to refer to the value being validated in all error messages, cause the dynamic string replace\n * that replaces that part with the actual field name works based on that\n */\n\n/**\n * E-mail validation rule (not perfect, but e-mails should be validated by sending out confirmation e-mails anyway)\n */\nexport const isEmail: GenericValidateFunction<string> = (val) =>\n (val || '').match(VALID_EMAIL) ? true : 'Value should be a valid e-mail address'\n\nexport const isOneOrMultipleEmails: GenericValidateFunction<string> = (val) => {\n const emails = (val || '').split(',').map((i) => i.trim())\n const valid = emails.every((e) => e.match(VALID_EMAIL))\n return valid || 'Value should be one or multiple comma-delimited e-mail addresses'\n}\n\nexport const isRequired: GenericValidateFunction<unknown> = (val) => {\n if (isString(val)) {\n val = val.trim()\n }\n\n return val ? true : 'Value is required'\n}\n\nexport const isSameAs: (\n otherFieldName: string,\n otherFieldDisplayName?: string\n) => GenericValidateFunction<unknown> =\n (otherFieldName, otherFieldDisplayName) => (val, meta) => {\n return val === meta.form[otherFieldName]\n ? true\n : `Value must be the same as in field '${\n otherFieldDisplayName || otherFieldName\n }'`\n }\n\nexport const isStringOfLength =\n (params: {\n minLength?: number\n maxLength?: number\n }): GenericValidateFunction<string> =>\n (val) => {\n const { minLength, maxLength } = params\n val = isNullOrUndefined(val) ? '' : val\n\n if (!isString(val)) return 'Value should be a text string'\n if (!isUndefined(minLength) && val.length < minLength)\n return `Value needs to be at least ${minLength} characters long`\n if (!isUndefined(maxLength) && val.length > maxLength)\n return `Value needs to be no more than ${maxLength} characters long`\n return true\n }\n\nexport const stringContains =\n (params: {\n match: string | RegExp\n message: string\n }): GenericValidateFunction<string> =>\n (val) => {\n const { match, message } = params\n\n if (!isString(val)) return 'Value should be a text string'\n if (!match) return true\n\n if (isString(match)) {\n return val.includes(match) ? true : message\n } else {\n return match.test(val) ? true : message\n }\n }\n\nexport const isUrl: GenericValidateFunction<string> = (value) => {\n if (VALID_HTTP_URL.test(value)) {\n return true\n }\n return 'Value is not a valid URL'\n}\n\nexport const isItemSelected: GenericValidateFunction<unknown[]> = (val) => {\n if (Array.isArray(val) && val.length > 0) {\n return true\n }\n return 'Value should have at least a single item selected'\n}\n","import { Nullable, Optional } from '@speckle/shared'\nimport { useMutationObserver, useResizeObserver } from '@vueuse/core'\nimport { isUndefined } from 'lodash'\nimport { Ref, ComputedRef, ref } from 'vue'\n\n/**\n * Use this to calculate the number of hidden elements (e.g. user avatars) in a wrapping flex row that\n * is styled to only show the first row. For example, there are 12 users total, there's only space for 5,\n * and this composable will calculate the number of hidden ones to use for the \"+X\" label (+7 in the example)\n *\n * Note: The \"hidden\" items must wrap into another line, because we use their offset from the top of the parent\n * to check if they're hidden (compared to items in the 1st row)\n */\nexport function useWrappingContainerHiddenCount(params: {\n /**\n * Element to watch for any changes\n */\n elementToWatchForChanges: Ref<Nullable<HTMLElement>>\n /**\n * The element that actually contains the potentially visible/hidden items as direct children\n */\n itemContainer: Ref<Nullable<HTMLElement>>\n\n /**\n * Allows you to pause calculations conditionally\n */\n skipCalculation?: ComputedRef<boolean>\n\n /**\n * If true, will track resizing of 'elementToWatchForChanges'.\n * Default: false\n */\n trackResize?: boolean\n\n /**\n * If true, will track descendants being added/removed to 'elementToWatchForChanges'.\n * Default: true\n */\n trackMutations?: boolean\n}) {\n const {\n skipCalculation,\n elementToWatchForChanges,\n itemContainer,\n trackResize = false,\n trackMutations = true\n } = params || {}\n\n /**\n * Dynamically updated to show the number of items currently not visible in the container\n */\n const hiddenItemCount = ref(0)\n\n const recalculate = () => {\n const target = itemContainer.value\n if (skipCalculation?.value || !target) return\n\n const avatarElements = target.children\n\n /**\n * Comparing offset from parent to between all avatars to see when they break off into another line\n * and become invisible\n */\n let visibleCount = 0\n let totalCount = 0\n let firstElOffsetTop = undefined as Optional<number>\n for (const avatarEl of avatarElements) {\n const offsetTop = (avatarEl as HTMLElement).offsetTop\n if (isUndefined(firstElOffsetTop)) {\n firstElOffsetTop = offsetTop\n visibleCount += 1\n } else {\n if (offsetTop === firstElOffsetTop) {\n visibleCount += 1\n }\n }\n\n totalCount += 1\n }\n\n hiddenItemCount.value = totalCount - visibleCount\n }\n\n if (trackResize) {\n useResizeObserver(elementToWatchForChanges, recalculate)\n }\n\n if (trackMutations) {\n useMutationObserver(elementToWatchForChanges, recalculate, {\n childList: true,\n subtree: true\n })\n }\n\n return {\n hiddenItemCount\n }\n}\n","/* eslint-disable @typescript-eslint/no-unsafe-assignment */\n/* eslint-disable @typescript-eslint/no-unsafe-return */\nimport { isArray } from 'lodash'\nimport { Ref, ToRefs, computed, ref } from 'vue'\nimport { Nullable } from '@speckle/shared'\nimport { useWrappingContainerHiddenCount } from '~~/src/composables/layout/resize'\n\ntype GenericSelectValueType<T> = T | T[] | undefined\n\n/**\n * Common setup for FormSelectBase wrapping selector components\n */\nexport function useFormSelectChildInternals<T>(params: {\n props: ToRefs<{\n modelValue?: GenericSelectValueType<T>\n multiple?: boolean\n }>\n emit: {\n (e: 'update:modelValue', val: GenericSelectValueType<T>): void\n }\n /**\n * @see {useWrappingContainerHiddenCount()}\n */\n dynamicVisibility?: {\n elementToWatchForChanges: Ref<Nullable<HTMLElement>>\n itemContainer: Ref<Nullable<HTMLElement>>\n }\n}) {\n const { props, emit, dynamicVisibility } = params\n\n let hiddenItemCount: Ref<number>\n if (dynamicVisibility) {\n const { elementToWatchForChanges, itemContainer } = dynamicVisibility\n const hiddenCountData = useWrappingContainerHiddenCount({\n skipCalculation: computed(() => !props.multiple?.value),\n elementToWatchForChanges,\n itemContainer\n })\n hiddenItemCount = hiddenCountData.hiddenItemCount\n } else {\n hiddenItemCount = ref(0)\n }\n\n /**\n * Use this to get or set the v-model value of the select input in a proper way\n */\n const selectedValue = computed({\n get: (): GenericSelectValueType<T> => {\n const currentValue = props.modelValue?.value\n if (props.multiple?.value) {\n return isArray(currentValue) ? currentValue : []\n } else {\n return isArray(currentValue) ? undefined : currentValue\n }\n },\n set: (newVal: GenericSelectValueType<T>) => {\n if (props.multiple?.value && !isArray(newVal)) {\n console.warn('Attempting to set non-array value in selector w/ multiple=true')\n return\n } else if (!props.multiple?.value && isArray(newVal)) {\n console.warn('Attempting to set array value in selector w/ multiple=false')\n return\n }\n\n emit('update:modelValue', props.multiple?.value ? newVal || [] : newVal)\n }\n })\n\n const isArrayValue = (v: GenericSelectValueType<T>): v is T[] => isArray(v)\n const isMultiItemArrayValue = (v: GenericSelectValueType<T>): v is T[] =>\n isArray(v) && v.length > 1\n const firstItem = (v: NonNullable<GenericSelectValueType<T>>): T =>\n isArrayValue(v) ? v[0] : v\n\n return {\n selectedValue,\n hiddenSelectedItemCount: hiddenItemCount,\n isArrayValue,\n isMultiItemArrayValue,\n firstItem\n }\n}\n","<template>\n <div>\n <Listbox\n :key=\"forceUpdateKey\"\n v-model=\"wrappedValue\"\n :name=\"name\"\n :multiple=\"multiple\"\n :by=\"by\"\n :disabled=\"isDisabled\"\n as=\"div\"\n >\n <ListboxLabel\n class=\"block label text-foreground-2 mb-2\"\n :class=\"{ 'sr-only': !showLabel }\"\n >\n {{ label }}\n </ListboxLabel>\n <div :class=\"buttonsWrapperClasses\">\n <!-- <div class=\"relative flex\"> -->\n <ListboxButton v-slot=\"{ open }\" :class=\"buttonClasses\">\n <div class=\"flex items-center justify-between w-full\">\n <div class=\"block truncate grow text-left\">\n <template\n v-if=\"!wrappedValue || (isArray(wrappedValue) && !wrappedValue.length)\"\n >\n <slot name=\"nothing-selected\">\n {{ placeholder ? placeholder : label }}\n </slot>\n </template>\n <template v-else>\n <slot name=\"something-selected\" :value=\"wrappedValue\">\n {{ simpleDisplayText(wrappedValue) }}\n </slot>\n </template>\n </div>\n <div class=\"pointer-events-none shrink-0 ml-1 flex items-center space-x-2\">\n <ExclamationCircleIcon\n v-if=\"errorMessage\"\n class=\"h-4 w-4 text-danger\"\n aria-hidden=\"true\"\n />\n <div\n v-else-if=\"showRequired\"\n class=\"text-4xl text-danger opacity-50 h-4 w-4 leading-6\"\n >\n *\n </div>\n <ChevronUpIcon\n v-if=\"open\"\n class=\"h-4 w-4 text-foreground\"\n aria-hidden=\"true\"\n />\n <ChevronDownIcon\n v-else\n class=\"h-4 w-4 text-foreground\"\n aria-hidden=\"true\"\n />\n </div>\n </div>\n </ListboxButton>\n <!-- </div> -->\n <!-- Clear Button -->\n <button\n v-if=\"renderClearButton\"\n v-tippy=\"'Clear'\"\n :class=\"clearButtonClasses\"\n :disabled=\"disabled\"\n @click=\"clearValue()\"\n >\n <XMarkIcon class=\"w-3 h-3\" />\n </button>\n <Transition\n leave-active-class=\"transition ease-in duration-100\"\n leave-from-class=\"opacity-100\"\n leave-to-class=\"opacity-0\"\n >\n <ListboxOptions\n class=\"absolute top-[100%] z-10 mt-1 w-full rounded-md bg-foundation-2 py-1 label label--light outline outline-2 outline-primary-muted focus:outline-none shadow\"\n @focus=\"searchInput?.focus()\"\n >\n <label v-if=\"hasSearch\" class=\"flex flex-col mx-1 mb-1\">\n <span class=\"sr-only label text-foreground\">Search</span>\n <div class=\"relative\">\n <div\n class=\"pointer-events-none absolute inset-y-0 left-0 flex items-center pl-2\"\n >\n <MagnifyingGlassIcon class=\"h-5 w-5 text-foreground\" />\n </div>\n <input\n ref=\"searchInput\"\n v-model=\"searchValue\"\n type=\"text\"\n class=\"pl-9 w-full border-0 bg-foundation-page rounded placeholder:font-normal normal placeholder:text-foreground-2 focus:outline-none focus:ring-1 focus:border-outline-1 focus:ring-outline-1\"\n :placeholder=\"searchPlaceholder\"\n @keydown.stop\n />\n </div>\n </label>\n <div\n class=\"overflow-auto simple-scrollbar\"\n :class=\"[hasSearch ? 'max-h-52' : 'max-h-60']\"\n >\n <div v-if=\"isAsyncSearchMode && isAsyncLoading\" class=\"px-1\">\n <CommonLoadingBar :loading=\"true\" />\n </div>\n <div v-else-if=\"isAsyncSearchMode && !currentItems.length\">\n <slot name=\"nothing-found\">\n <div class=\"text-foreground-2 text-center\">Nothing found 🤷‍♂️</div>\n </slot>\n </div>\n <template v-if=\"!isAsyncSearchMode || !isAsyncLoading\">\n <ListboxOption\n v-for=\"item in finalItems\"\n :key=\"itemKey(item)\"\n v-slot=\"{ active, selected }: { active: boolean, selected: boolean }\"\n :value=\"item\"\n :disabled=\"disabledItemPredicate?.(item) || false\"\n >\n <li\n :class=\"\n listboxOptionClasses({\n active,\n disabled: disabledItemPredicate?.(item) || false\n })\n \"\n >\n <span :class=\"['block truncate']\">\n <slot\n name=\"option\"\n :item=\"item\"\n :active=\"active\"\n :selected=\"selected\"\n :disabled=\"disabledItemPredicate?.(item) || false\"\n >\n {{ simpleDisplayText(item) }}\n </slot>\n </span>\n\n <span\n v-if=\"!hideCheckmarks && selected\"\n :class=\"[\n active ? 'text-primary' : 'text-foreground',\n 'absolute inset-y-0 right-0 flex items-center pr-4'\n ]\"\n >\n <CheckIcon class=\"h-5 w-5\" aria-hidden=\"true\" />\n </span>\n </li>\n </ListboxOption>\n </template>\n </div>\n </ListboxOptions>\n </Transition>\n </div>\n </Listbox>\n <p v-if=\"helpTipId\" :id=\"helpTipId\" class=\"mt-2 text-sm\" :class=\"helpTipClasses\">\n {{ helpTip }}\n </p>\n </div>\n</template>\n<script setup lang=\"ts\">\n// Vue components don't support generic props, so having to rely on any\n/* eslint-disable @typescript-eslint/no-explicit-any */\n/* eslint-disable @typescript-eslint/no-unsafe-return */\n/* eslint-disable @typescript-eslint/no-unsafe-assignment */\n/* eslint-disable @typescript-eslint/no-unsafe-member-access */\n\nimport {\n Listbox,\n ListboxButton,\n ListboxOption,\n ListboxOptions,\n ListboxLabel\n} from '@headlessui/vue'\nimport {\n ChevronDownIcon,\n CheckIcon,\n ChevronUpIcon,\n MagnifyingGlassIcon,\n XMarkIcon,\n ExclamationCircleIcon\n} from '@heroicons/vue/24/solid'\nimport { debounce, isArray } from 'lodash'\nimport { PropType, computed, onMounted, ref, unref, watch } from 'vue'\nimport { MaybeAsync, Nullable, Optional } from '@speckle/shared'\nimport { RuleExpression, useField } from 'vee-validate'\nimport { nanoid } from 'nanoid'\nimport CommonLoadingBar from '~~/src/components/common/loading/Bar.vue'\nimport { directive as vTippy } from 'vue-tippy'\n\ntype ButtonStyle = 'base' | 'simple' | 'tinted'\ntype SingleItem = any\ntype ValueType = SingleItem | SingleItem[] | undefined\n\nconst emit = defineEmits([\"update:modelValue\"])\n\nconst props = defineProps({\n multiple: {\n type: Boolean,\n default: false\n },\n items: {\n type: Array as PropType<SingleItem[]>,\n default: () => []\n },\n modelValue: {\n type: [Object, Array, String] as PropType<ValueType>,\n default: undefined\n },\n /**\n * Whether to enable the search bar. You must also set one of the following:\n * * filterPredicate - to allow filtering passed in `items` based on search bar\n * * getSearchResults - to allow asynchronously loading items from server (props.items no longer required in this case,\n * but can be used to prefill initial values)\n */\n search: {\n type: Boolean,\n default: false\n },\n /**\n * If search=true and this is set, you can use this to filter passed in items based on whatever\n * the user enters in the search bar\n */\n filterPredicate: {\n type: Function as PropType<\n Optional<(item: SingleItem, searchString: string) => boolean>\n >,\n default: undefined\n },\n /**\n * Set this to disable certain items in the list\n */\n disabledItemPredicate: {\n type: Function as PropType<Optional<(item: SingleItem) => boolean>>,\n default: undefined\n },\n /**\n * If search=true and this is set, you can use this to load data asynchronously depending\n * on the search query\n */\n getSearchResults: {\n type: Function as PropType<\n Optional<(searchString: string) => MaybeAsync<SingleItem[]>>\n >,\n default: undefined\n },\n searchPlaceholder: {\n type: String,\n default: 'Search'\n },\n /**\n * Label is required at the very least for screen-readers\n */\n label: {\n type: String,\n required: true\n },\n /**\n * Optional text that replaces the label as the placeholder when set.\n */\n placeholder: {\n type: String\n },\n /**\n * Whether to show the label visually\n */\n showLabel: {\n type: Boolean,\n default: false\n },\n name: {\n type: String,\n required: true\n },\n /**\n * Objects will be compared by the values in the specified prop\n */\n by: {\n type: String,\n required: false\n },\n disabled: {\n type: Boolean as PropType<Optional<boolean>>,\n default: false\n },\n buttonStyle: {\n type: String as PropType<Optional<ButtonStyle>>,\n default: 'base'\n },\n hideCheckmarks: {\n type: Boolean as PropType<Optional<boolean>>,\n default: false\n },\n allowUnset: {\n type: Boolean as PropType<Optional<boolean>>,\n default: true\n },\n clearable: {\n type: Boolean,\n default: false\n },\n /**\n * Validation stuff\n */\n rules: {\n type: [String, Object, Function, Array] as PropType<RuleExpression<ValueType>>,\n default: undefined\n },\n /**\n * vee-validate validation() on component mount\n */\n validateOnMount: {\n type: Boolean,\n default: false\n },\n /**\n * Whether to trigger validation whenever the value changes\n */\n validateOnValueUpdate: {\n type: Boolean,\n default: false\n },\n /**\n * Will replace the generic \"Value\" text with the name of the input in error messages\n */\n useLabelInErrors: {\n type: Boolean,\n default: true\n },\n /**\n * Optional help text\n */\n help: {\n type: String as PropType<Optional<string>>,\n default: undefined\n },\n fixedHeight: {\n type: Boolean,\n default: false\n },\n /**\n * By default component holds its own internal value state so that even if you don't have it tied up to a real `modelValue` ref somewhere\n * it knows its internal state and can report it on form submits.\n *\n * If you set this to true, its only going to rely on `modelValue` as its primary source of truth so that you can reject updates etc.\n */\n fullyControlValue: {\n type: Boolean,\n default: false\n },\n /**\n * Whether to show the red \"required\" asterisk\n */\n showRequired: {\n type: Boolean,\n default: false\n }\n})\n\nconst { value, errorMessage: error } = useField<ValueType>(props.name, props.rules, {\n validateOnMount: props.validateOnMount,\n validateOnValueUpdate: props.validateOnValueUpdate,\n initialValue: props.modelValue\n})\n\nconst searchInput = ref(null as Nullable<HTMLInputElement>)\nconst searchValue = ref('')\nconst currentItems = ref([] as SingleItem[])\nconst isAsyncLoading = ref(false)\nconst forceUpdateKey = ref(1)\n\nconst internalHelpTipId = ref(nanoid())\n\nconst title = computed(() => unref(props.label) || unref(props.name))\nconst errorMessage = computed(() => {\n const base = error.value\n if (!base || !unref(props.useLabelInErrors)) return base\n return base.replace('Value', title.value)\n})\nconst helpTip = computed(() => errorMessage.value || unref(props.help))\nconst hasHelpTip = computed(() => !!helpTip.value)\nconst helpTipId = computed(() =>\n hasHelpTip.value ? `${unref(props.name)}-${internalHelpTipId.value}` : undefined\n)\nconst helpTipClasses = computed((): string =>\n error.value ? 'text-danger' : 'text-foreground-2'\n)\n\nconst renderClearButton = computed(\n () => props.buttonStyle !== 'simple' && props.clearable && !props.disabled\n)\n\nconst buttonsWrapperClasses = computed(() => {\n const classParts: string[] = ['relative flex group']\n\n if (error.value) {\n classParts.push('hover:shadow rounded-md')\n classParts.push('text-danger-darker focus:border-danger focus:ring-danger')\n\n if (props.buttonStyle !== 'simple') {\n classParts.push('outline outline-2 outline-danger')\n }\n } else if (props.buttonStyle !== 'simple') {\n classParts.push('hover:shadow rounded-md')\n classParts.push('outline outline-2 outline-primary-muted')\n }\n\n if (props.fixedHeight) {\n classParts.push('h-8')\n }\n\n return classParts.join(' ')\n})\n\nconst commonButtonClasses = computed(() => {\n const classParts: string[] = []\n\n if (props.buttonStyle !== 'simple') {\n // classParts.push('group-hover:shadow')\n // classParts.push('outline outline-2 outline-primary-muted ')\n classParts.push(\n isDisabled.value ? 'bg-foundation-disabled text-foreground-disabled' : ''\n )\n }\n\n if (isDisabled.value) classParts.push('cursor-not-allowed')\n\n return classParts.join(' ')\n})\n\nconst clearButtonClasses = computed(() => {\n const classParts = [\n 'relative z-[1]',\n 'flex items-center justify-center text-center shrink-0',\n 'rounded-r-md overflow-hidden transition-all',\n 'text-foreground',\n hasValueSelected.value ? `w-6 ${commonButtonClasses.value}` : 'w-0'\n ]\n\n if (!isDisabled.value) {\n classParts.push(\n 'hover:bg-primary hover:text-foreground-on-primary dark:text-foreground-on-primary'\n )\n if (props.buttonStyle === 'tinted') {\n classParts.push('bg-outline-3')\n } else {\n classParts.push('bg-primary-muted')\n }\n }\n\n return classParts.join(' ')\n})\n\nconst buttonClasses = computed(() => {\n const classParts = [\n 'relative z-[2]',\n 'normal rounded-md cursor-pointer transition truncate flex-1',\n 'flex items-center',\n commonButtonClasses.value\n ]\n\n if (props.buttonStyle !== 'simple') {\n classParts.push('py-2 px-3')\n\n if (!isDisabled.value) {\n if (props.buttonStyle === 'tinted') {\n classParts.push('bg-foundation-page text-foreground')\n } else {\n classParts.push('bg-foundation text-foreground')\n }\n }\n }\n\n if (renderClearButton.value && hasValueSelected.value) {\n classParts.push('rounded-r-none')\n }\n\n return classParts.join(' ')\n})\n\nconst hasSearch = computed(\n () => !!(props.search && (props.filterPredicate || props.getSearchResults))\n)\nconst isAsyncSearchMode = computed(() => hasSearch.value && props.getSearchResults)\nconst isDisabled = computed(\n () => props.disabled || (!props.items.length && !isAsyncSearchMode.value)\n)\n\nconst wrappedValue = computed({\n get: () => {\n const currentValue = value.value\n if (props.multiple) {\n return isArray(currentValue) ? currentValue : []\n } else {\n return isArray(currentValue) ? undefined : currentValue\n }\n },\n set: (newVal) => {\n if (props.multiple && !isArray(newVal)) {\n console.warn('Attempting to set non-array value in selector w/ multiple=true')\n return\n } else if (!props.multiple && isArray(newVal)) {\n console.warn('Attempting to set array value in selector w/ multiple=false')\n return\n }\n\n let finalValue: typeof value.value\n if (props.multiple) {\n finalValue = newVal || []\n } else {\n const currentVal = value.value\n const isUnset =\n props.allowUnset &&\n currentVal &&\n newVal &&\n itemKey(currentVal as SingleItem) === itemKey(newVal as SingleItem)\n finalValue = isUnset ? undefined : newVal\n }\n\n if (props.fullyControlValue) {\n // Not setting value.value, cause then we don't give a chance for the parent\n // component to reject the update\n emit('update:modelValue', finalValue)\n } else {\n value.value = finalValue\n }\n\n // hacky, but there's no other way to force ListBox to re-read the modelValue prop which\n // we need in case the update was rejected and ListBox still thinks the value is the one\n // that was clicked on\n forceUpdateKey.value += 1\n }\n})\n\nconst hasValueSelected = computed(() => {\n if (props.multiple) return wrappedValue.value.length !== 0\n else return !!wrappedValue.value\n})\n\nconst clearValue = () => {\n if (props.multiple) wrappedValue.value = []\n else wrappedValue.value = undefined\n}\n\nconst finalItems = computed(() => {\n const searchVal = searchValue.value\n if (!hasSearch.value || !searchVal?.length) return currentItems.value\n\n if (props.filterPredicate) {\n return currentItems.value.filter(\n (i) => props.filterPredicate?.(i, searchVal) || false\n )\n }\n\n return currentItems.value\n})\n\nconst simpleDisplayText = (v: ValueType) => JSON.stringify(v)\nconst itemKey = (v: SingleItem): string | number =>\n props.by ? (v[props.by] as string) : v\n\nconst triggerSearch = async () => {\n if (!isAsyncSearchMode.value || !props.getSearchResults) return\n\n isAsyncLoading.value = true\n try {\n currentItems.value = await props.getSearchResults(searchValue.value)\n } finally {\n isAsyncLoading.value = false\n }\n}\nconst debouncedSearch = debounce(triggerSearch, 1000)\n\nconst listboxOptionClasses = (params: { active: boolean; disabled: boolean }) => {\n const { active, disabled } = params || {}\n const { hideCheckmarks } = props\n\n const classParts = [\n 'relative transition cursor-pointer select-none py-1.5 pl-3',\n !hideCheckmarks ? 'pr-9' : ''\n ]\n\n if (disabled) {\n classParts.push('opacity-50 cursor-not-allowed')\n } else {\n classParts.push(active ? 'text-primary' : 'text-foreground')\n }\n\n return classParts.join(' ')\n}\n\nwatch(\n () => props.items,\n (newItems) => {\n currentItems.value = newItems.slice()\n },\n { immediate: true }\n)\n\nwatch(searchValue, () => {\n if (!isAsyncSearchMode.value) return\n debouncedSearch()\n})\n\nonMounted(() => {\n if (isAsyncSearchMode.value && !props.items.length) {\n triggerSearch()\n }\n})\n\ndefineExpose({ triggerSearch })\n</script>\n","<template>\n <FormSelectBase\n v-model=\"selectedValue\"\n :multiple=\"multiple\"\n :items=\"items ?? SourceApps\"\n :search=\"search\"\n :search-placeholder=\"searchPlaceholder\"\n :label=\"label\"\n :show-label=\"showLabel\"\n :name=\"name || 'sourceApps'\"\n :filter-predicate=\"searchFilterPredicate\"\n by=\"name\"\n >\n <template #nothing-selected>\n <template v-if=\"selectorPlaceholder\">\n {{ selectorPlaceholder }}\n </template>\n <template v-else>\n {{ multiple ? 'Select apps' : 'Select an app' }}\n </template>\n </template>\n <template #something-selected=\"{ value }\">\n <template v-if=\"isMultiItemArrayValue(value)\">\n <div ref=\"elementToWatchForChanges\" class=\"flex items-center space-x-0.5 h-5\">\n <div\n ref=\"itemContainer\"\n class=\"flex flex-wrap overflow-hidden space-x-0.5 h-5\"\n >\n <SourceAppBadge v-for=\"item in value\" :key=\"item.name\" :source-app=\"item\" />\n </div>\n <div v-if=\"hiddenSelectedItemCount > 0\" class=\"text-foreground-2 normal\">\n +{{ hiddenSelectedItemCount }}\n </div>\n </div>\n </template>\n <template v-else>\n <div class=\"flex items-center\">\n <div\n class=\"h-2 w-2 rounded-full mr-2\"\n :style=\"{ backgroundColor: firstItem(value).bgColor }\"\n />\n <span class=\"truncate\">{{ firstItem(value).name }}</span>\n </div>\n </template>\n </template>\n <template #option=\"{ item }\">\n <div class=\"flex items-center\">\n <div\n class=\"h-2 w-2 rounded-full mr-2\"\n :style=\"{ backgroundColor: item.bgColor }\"\n />\n <span class=\"truncate\">{{ item.name }}</span>\n </div>\n </template>\n </FormSelectBase>\n</template>\n<script setup lang=\"ts\">\nimport { Nullable, Optional, SourceAppDefinition, SourceApps } from '@speckle/shared'\nimport { PropType, ref, toRefs } from 'vue'\nimport { useFormSelectChildInternals } from '~~/src/composables/form/select'\nimport FormSelectBase from '~~/src/components/form/select/Base.vue'\nimport SourceAppBadge from '~~/src/components/SourceAppBadge.vue'\n\ntype ValueType = SourceAppDefinition | SourceAppDefinition[] | undefined\n\nconst emit = defineEmits([\"update:modelValue\"])\n\nconst props = defineProps({\n /**\n * Whether to allow selecting multiple source apps\n */\n multiple: {\n type: Boolean,\n default: false\n },\n modelValue: {\n type: [Object, Array] as PropType<ValueType>,\n default: undefined\n },\n /**\n * Whether to allow filtering source apps through a search box\n */\n search: {\n type: Boolean,\n default: false\n },\n /**\n * Search placeholder text\n */\n searchPlaceholder: {\n type: String,\n default: 'Search apps'\n },\n selectorPlaceholder: {\n type: String as PropType<Optional<string>>,\n default: undefined\n },\n /**\n * Label is required at the very least for screen-readers\n */\n label: {\n type: String,\n required: true\n },\n /**\n * Whether to show the label visually\n */\n showLabel: {\n type: Boolean,\n default: false\n },\n name: {\n type: String as PropType<Optional<string>>,\n default: undefined\n },\n /**\n * Control source apps to show. If left undefined, will show all available options.\n */\n items: {\n type: Array as PropType<Optional<SourceAppDefinition[]>>,\n default: undefined\n }\n})\n\nconst elementToWatchForChanges = ref(null as Nullable<HTMLElement>)\nconst itemContainer = ref(null as Nullable<HTMLElement>)\n\nconst { selectedValue, hiddenSelectedItemCount, isMultiItemArrayValue, firstItem } =\n useFormSelectChildInternals<SourceAppDefinition>({\n props: toRefs(props),\n emit,\n dynamicVisibility: { elementToWatchForChanges, itemContainer }\n })\n\nconst searchFilterPredicate = (i: SourceAppDefinition, search: string) =>\n i.name.toLocaleLowerCase().includes(search.toLocaleLowerCase())\n</script>\n","<template>\n <FormSelectBase\n v-model=\"selectedValue\"\n :multiple=\"multiple\"\n :items=\"items\"\n :label=\"label\"\n :name=\"name\"\n :help=\"help\"\n :rules=\"rules\"\n :by=\"by\"\n >\n <template #something-selected=\"{ value }\">\n <ul class=\"flex flex-wrap gap-1.5 text-xs\">\n <li v-for=\"item in isArrayValue(value) ? value : [value]\" :key=\"item[by]\">\n <CommonBadge\n size=\"lg\"\n :clickable-icon=\"true\"\n :icon-left=\"XMarkIcon\"\n @click-icon.stop=\"deselectItem(item)\"\n >\n {{ item.text }}\n </CommonBadge>\n </li>\n </ul>\n </template>\n <template #option=\"{ item }\">\n {{ item.text }}\n </template>\n </FormSelectBase>\n</template>\n\n<script setup lang=\"ts\">\n// Vue components don't support generic props, so having to rely on any\n/* eslint-disable @typescript-eslint/no-explicit-any */\n/* eslint-disable @typescript-eslint/no-unsafe-return */\n/* eslint-disable @typescript-eslint/no-unsafe-assignment */\n/* eslint-disable @typescript-eslint/no-unsafe-argument */\n/* eslint-disable @typescript-eslint/no-unsafe-member-access */\n\nimport { toRefs } from 'vue'\nimport FormSelectBase from '~~/src/components/form/select/Base.vue'\nimport CommonBadge from '~~/src/components/common/Badge.vue'\nimport { useFormSelectChildInternals } from '~~/src/composables/form/select'\nimport { XMarkIcon } from '@heroicons/vue/24/solid'\n\ntype SingleItem = any\n\nconst emit = defineEmits([\"update:modelValue\"])\n\nconst props = defineProps({\n \"items\": null,\n \"label\": null,\n \"name\": null,\n \"help\": null,\n \"modelValue\": null,\n \"multiple\": { type: Boolean, },\n \"rules\": null,\n \"by\": null\n})\n\nconst { selectedValue, isArrayValue } = useFormSelectChildInternals<SingleItem>({\n props: toRefs(props),\n emit\n})\n\nconst deselectItem = (item: SingleItem) => {\n if (isArrayValue(selectedValue.value)) {\n selectedValue.value = selectedValue.value.filter((i) => i.id !== item.id)\n } else {\n selectedValue.value = undefined\n }\n}\n</script>\n","<template>\n <div class=\"flex items-center\">\n <HeadlessSwitch\n v-model=\"enabled\"\n class=\"relative inline-flex flex-shrink-0 h-6 w-11 border-2 border-transparent rounded-full cursor-pointer transition-colors ease-in-out duration-200 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-primary\"\n :class=\"{ 'bg-primary': enabled, 'bg-primary-muted': !enabled }\"\n >\n <div class=\"absolute inset-0 flex items-center gap-2 px-1 text-white\">\n <CheckIcon class=\"h-5 w-5 drop-shadow-md\" />\n <XMarkIcon class=\"h-5 w-5 drop-shadow-md\" />\n </div>\n <span\n class=\"scale-95 pointer-events-none inline-block h-5 w-5 rounded-full bg-white shadow transform ring-0 transition ease-in-out duration-200\"\n :class=\"{ 'translate-x-5': enabled, 'translate-x-0': !enabled }\"\n ></span>\n </HeadlessSwitch>\n </div>\n</template>\n\n<script setup lang=\"ts\">\nimport { Switch as HeadlessSwitch } from '@headlessui/vue'\nimport { CheckIcon, XMarkIcon } from '@heroicons/vue/24/solid'\n\nconst enabled = defineModel<boolean>()\n</script>\n","import { getClientOperatingSystem, OperatingSystem } from '@speckle/shared'\n\nexport enum ModifierKeys {\n CtrlOrCmd = 'cmd-or-ctrl',\n AltOrOpt = 'alt-or-opt',\n Shift = 'shift'\n}\n\nexport const clientOs = getClientOperatingSystem()\n\nexport const ModifierKeyTitles: Record<ModifierKeys, string> = {\n [ModifierKeys.CtrlOrCmd]: clientOs === OperatingSystem.Mac ? 'Cmd' : 'Ctrl',\n [ModifierKeys.AltOrOpt]: clientOs === OperatingSystem.Mac ? 'Opt' : 'Alt',\n [ModifierKeys.Shift]: 'Shift'\n}\n\nexport function getKeyboardShortcutTitle(keys: Array<string | ModifierKeys>) {\n const isModifierKey = (k: string): k is ModifierKeys =>\n (Object.values(ModifierKeys) as string[]).includes(k)\n\n return keys.map((v) => (isModifierKey(v) ? ModifierKeyTitles[v] : v)).join('+')\n}\n","import { onKeyDown } from '@vueuse/core'\nimport { OperatingSystem } from '@speckle/shared'\nimport { clientOs, ModifierKeys } from '~~/src/helpers/form/input'\nimport { computed, Ref, ref } from 'vue'\n\n/**\n * onKeyDown wrapper that also checks for modifier keys being pressed\n */\nexport function onKeyboardShortcut(\n modifiers: ModifierKeys[],\n ...args: Parameters<typeof onKeyDown>\n) {\n onKeyDown(\n args[0],\n (e) => {\n const isAltOrOpt = e.getModifierState('Alt')\n const isCtrlOrCmd =\n clientOs === OperatingSystem.Mac\n ? e.getModifierState('Meta')\n : e.getModifierState('Control')\n const isShift = e.getModifierState('Shift')\n\n for (const modifier of modifiers) {\n switch (modifier) {\n case ModifierKeys.CtrlOrCmd:\n if (!isCtrlOrCmd) return\n break\n case ModifierKeys.AltOrOpt:\n if (!isAltOrOpt) return\n break\n case ModifierKeys.Shift:\n if (!isShift) return\n break\n }\n }\n\n args[1](e)\n },\n args[2]\n )\n}\n\n/**\n * To support group checkboxes, the checkbox v-model API is a bit confusing: The value is `true` or `undefined`\n * not `true` or `false`.\n *\n * To simplify working with single checkboxes, you can use the model returned from this composable\n * as the model and `isChecked` as a helpful wrapper that allows you to deal with boolean values only\n */\nexport function useFormCheckboxModel(\n options?: Partial<{\n model: Ref<true | undefined>\n }>\n) {\n const model = options?.model || ref<true | undefined>()\n const isChecked = computed({\n get: () => !!model.value,\n set: (newVal) => (model.value = newVal ? true : undefined)\n })\n\n return { model, isChecked }\n}\n","<template>\n <TransitionRoot as=\"template\" :show=\"open\">\n <Dialog as=\"div\" class=\"relative z-40\" @close=\"onClose\">\n <TransitionChild\n as=\"template\"\n enter=\"ease-out duration-300\"\n enter-from=\"opacity-0\"\n enter-to=\"opacity-100\"\n leave=\"ease-in duration-200\"\n leave-from=\"opacity-100\"\n leave-to=\"opacity-0\"\n >\n <div\n class=\"fixed inset-0 bg-neutral-100/70 dark:bg-neutral-900/70 transition-opacity\"\n />\n </TransitionChild>\n\n <div class=\"fixed inset-0 z-10 overflow-y-auto\">\n <div class=\"flex min-h-full justify-center p-4 text-center items-center sm:p-0\">\n <TransitionChild\n as=\"template\"\n enter=\"ease-out duration-300\"\n enter-from=\"opacity-0 translate-y-4 sm:translate-y-0 sm:scale-95\"\n enter-to=\"opacity-100 translate-y-0 sm:scale-100\"\n leave=\"ease-in duration-200\"\n leave-from=\"opacity-100 translate-y-0 sm:scale-100\"\n leave-to=\"opacity-0 translate-y-4 sm:translate-y-0 sm:scale-95\"\n @after-leave=\"$emit('fully-closed')\"\n >\n <DialogPanel\n :class=\"[\n 'transform rounded-lg bg-foundation text-left shadow-xl transition-all',\n widthClasses\n ]\"\n :as=\"isForm ? 'form' : 'div'\"\n @submit.prevent=\"onSubmit\"\n >\n <div\n v-if=\"title\"\n class=\"flex items-center justify-center shadow p-4 relative z-10 bg-foundation rounded-t-lg\"\n >\n <h4 class=\"text-2xl font-bold\">{{ title }}</h4>\n </div>\n <button\n v-if=\"!hideCloser\"\n class=\"absolute z-20 top-5 right-4 text-foreground\"\n @click=\"open = false\"\n >\n <XMarkIcon class=\"h-6 w-6\" />\n </button>\n <div class=\"p-4 sm:p-6\">\n <slot>Put your content here!</slot>\n </div>\n <div\n v-if=\"hasButtons\"\n class=\"flex p-4 sm:px-6 sm:py-5 border-t gap-2 border-outline-3\"\n >\n <template v-if=\"buttons\">\n <FormButton\n v-for=\"(button, index) in buttons\"\n :key=\"index\"\n v-bind=\"button.props\"\n @click=\"button.onClick\"\n >\n {{ button.text }}\n </FormButton>\n </template>\n <template v-else>\n <slot name=\"buttons\" />\n </template>\n </div>\n </DialogPanel>\n </TransitionChild>\n </div>\n </div>\n </Dialog>\n </TransitionRoot>\n</template>\n<script setup lang=\"ts\">\nimport { Dialog, DialogPanel, TransitionChild, TransitionRoot } from '@headlessui/vue'\nimport { FormButton } from '~~/src/lib'\nimport { XMarkIcon } from '@heroicons/vue/24/outline'\nimport { computed, useSlots } from 'vue'\n\ntype MaxWidthValue = 'sm' | 'md' | 'lg' | 'xl'\n\nconst emit = defineEmits([\"update:open\", \"fully-closed\"])\n\nconst props = defineProps({\n \"open\": { type: Boolean, },\n \"maxWidth\": null,\n \"hideCloser\": { type: Boolean, },\n \"preventCloseOnClickOutside\": { type: Boolean, },\n \"title\": null,\n \"buttons\": null,\n \"onSubmit\": { type: Function, }\n})\n\nconst slots = useSlots()\n\nconst isForm = computed(() => !!props.onSubmit)\nconst hasButtons = computed(() => props.buttons || slots.buttons)\n\nconst open = computed({\n get: () => props.open,\n set: (newVal) => emit('update:open', newVal)\n})\n\nconst maxWidthWeight = computed(() => {\n switch (props.maxWidth) {\n case 'sm':\n return 0\n case 'md':\n return 1\n case 'lg':\n return 2\n case 'xl':\n return 3\n default:\n return 10000\n }\n})\n\nconst widthClasses = computed(() => {\n const classParts: string[] = ['w-full', 'sm:my-8 sm:w-full sm:max-w-xl']\n\n if (!props.title && !hasButtons.value) {\n classParts.push('px-4 pt-4 pb-4', 'sm:p-6')\n }\n\n if (maxWidthWeight.value >= 1) {\n classParts.push('md:max-w-2xl')\n }\n\n if (maxWidthWeight.value >= 2) {\n classParts.push('lg:max-w-4xl')\n }\n\n if (maxWidthWeight.value >= 3) {\n classParts.push('xl:max-w-6xl')\n }\n\n if (maxWidthWeight.value >= 4) {\n classParts.push('2xl:max-w-7xl')\n }\n\n return classParts.join(' ')\n})\n\nconst onClose = () => {\n if (props.preventCloseOnClickOutside) return\n open.value = false\n}\n</script>\n","<template>\n <div>\n <Disclosure v-slot=\"{ open }\">\n <DisclosureButton :class=\"buttonClasses\">\n <div class=\"inline-flex items-center space-x-2\">\n <Component :is=\"icon\" v-if=\"icon\" class=\"h-4 w-4\" />\n <span>{{ title }}</span>\n </div>\n <ChevronUpIcon :class=\"!open ? 'rotate-180 transform' : ''\" class=\"h-5 w-5\" />\n </DisclosureButton>\n <DisclosurePanel :class=\"panelClasses\">\n <div class=\"label-light\">\n <slot>Panel contents</slot>\n </div>\n </DisclosurePanel>\n </Disclosure>\n </div>\n</template>\n<script setup lang=\"ts\">\nimport { DisclosureButton, Disclosure, DisclosurePanel } from '@headlessui/vue'\nimport { ChevronUpIcon } from '@heroicons/vue/24/solid'\nimport { ConcreteComponent, computed } from 'vue'\n\ntype DisclosureColor = 'default' | 'danger' | 'success' | 'warning'\n\nconst props = defineProps({\n \"title\": null,\n \"icon\": null,\n \"color\": { default: 'default' }\n})\n\nconst buttonClasses = computed(() => {\n const classParts = [\n 'pr-3 h-10 w-full flex items-center justify-between border-l-2 px-2 rounded transition',\n 'ring-1 font-medium'\n ]\n\n switch (props.color) {\n case 'warning':\n classParts.push(\n 'border-warning text-warning ring-warning-lighter hover:ring-warning'\n )\n break\n case 'success':\n classParts.push(\n 'border-success text-success ring-success-lighter hover:ring-success'\n )\n break\n case 'danger':\n classParts.push('border-danger text-danger ring-danger-lighter hover:ring-danger')\n break\n case 'default':\n default:\n classParts.push(\n 'border-primary text-primary ring-primary-muted hover:ring-primary'\n )\n break\n }\n\n return classParts.join(' ')\n})\n\nconst panelClasses = computed(() => {\n const classParts = ['mt-4 px-3 py-1 border-x ']\n\n switch (props.color) {\n case 'warning':\n classParts.push('border-warning-lighter')\n break\n case 'success':\n classParts.push('border-success-lighter')\n break\n case 'danger':\n classParts.push('border-danger-lighter')\n break\n case 'default':\n default:\n classParts.push('border-primary-muted')\n break\n }\n\n return classParts.join(' ')\n})\n</script>\n","export enum GridListToggleValue {\n Grid = 'grid',\n List = 'list'\n}\n\nexport type LayoutTabItem<I extends string = string> = {\n title: string\n id: I\n}\n\nexport type LayoutMenuItem<I extends string = string> = {\n title: string\n id: I\n disabled?: boolean\n disabledTooltip?: string\n}\n","<template>\n <button\n class=\"flex items-center justify-center rounded bg-foundation h-8 w-8 shadow cursor-pointer text-foreground\"\n @click=\"onClick\"\n >\n <Component :is=\"currentIcon\" class=\"h-6 w-6\" />\n </button>\n</template>\n<script setup lang=\"ts\">\nimport { Bars3Icon, Squares2X2Icon } from '@heroicons/vue/24/solid'\nimport { computed } from 'vue'\nimport { GridListToggleValue } from '~~/src/helpers/layout/components'\n\nconst emit = defineEmits([\"click\", \"update:modelValue\"])\n\nconst props = defineProps({\n \"modelValue\": null\n})\n\nconst value = computed({\n get: () => props.modelValue || GridListToggleValue.Grid,\n set: (newVal) => emit('update:modelValue', newVal)\n})\n\nconst currentIcon = computed(() =>\n value.value === GridListToggleValue.Grid ? Bars3Icon : Squares2X2Icon\n)\n\nconst onClick = (e: MouseEvent) => {\n emit('click', e)\n\n const newVal =\n value.value === GridListToggleValue.Grid\n ? GridListToggleValue.List\n : GridListToggleValue.Grid\n value.value = newVal\n}\n</script>\n","import { Nullable } from '@speckle/shared'\nimport { MaybeRef, isClient } from '@vueuse/core'\nimport { debounce, isUndefined, throttle } from 'lodash'\nimport { computed, onBeforeUnmount, onMounted, ref, unref, watch } from 'vue'\n\nexport enum ThrottleOrDebounce {\n Throttle,\n Debounce\n}\n\nexport enum HorizontalDirection {\n Left,\n Right\n}\n\nexport function useWindowResizeHandler(\n handler: (e: UIEvent) => void,\n options?: Partial<{\n wait: number\n throttleOrDebounce: ThrottleOrDebounce\n }>\n) {\n if (!isClient) return\n\n const { wait = 100, throttleOrDebounce = ThrottleOrDebounce.Throttle } = options || {}\n const finalHandler = wait\n ? throttleOrDebounce === ThrottleOrDebounce.Throttle\n ? throttle(handler, wait)\n : debounce(handler, wait)\n : handler\n\n onMounted(() => window.addEventListener('resize', finalHandler))\n onBeforeUnmount(() => window.removeEventListener('resize', finalHandler))\n}\n\nexport function useOnBeforeWindowUnload(handler: (e: BeforeUnloadEvent) => void) {\n onMounted(() => {\n window.addEventListener('beforeunload', handler)\n })\n\n onBeforeUnmount(() => {\n window.removeEventListener('beforeunload', handler)\n })\n}\n\nexport function useResponsiveHorizontalDirectionCalculation(params: {\n el: MaybeRef<Nullable<HTMLElement>>\n defaultDirection?: HorizontalDirection\n /**\n * Stop recalculation below this screen size. Defaults to el.width * 2\n */\n stopUpdatesBelowWidth?: MaybeRef<number>\n}) {\n const { el, defaultDirection } = params\n\n const direction = ref<HorizontalDirection>(\n !isUndefined(defaultDirection) ? defaultDirection : HorizontalDirection.Right\n )\n const stopUpdatesBelowWidth = computed(() => {\n const stopUpdatesBelowWidth = unref(params.stopUpdatesBelowWidth)\n if (!isUndefined(stopUpdatesBelowWidth)) return stopUpdatesBelowWidth\n\n const element = unref(el)\n return element?.offsetWidth ? element.offsetWidth * 2 : undefined\n })\n\n const recalculateDirection = () => {\n if (!isClient) return\n\n const element = unref(el)\n if (!element) return\n\n const rect = element.getBoundingClientRect()\n const showOnLeftSide = rect.x + rect.width > window.innerWidth\n const showOnRightSide = rect.x < 0\n\n // Screen too small - do nothing\n if (\n (showOnLeftSide && showOnRightSide) ||\n (!isUndefined(stopUpdatesBelowWidth.value) &&\n window.innerWidth < stopUpdatesBelowWidth.value)\n )\n return\n\n if (showOnLeftSide) {\n direction.value = HorizontalDirection.Left\n } else if (showOnRightSide) {\n direction.value = HorizontalDirection.Right\n }\n }\n\n useWindowResizeHandler(() => recalculateDirection())\n\n watch(\n () => unref(el),\n (element) => {\n if (element) {\n recalculateDirection()\n }\n }\n )\n\n return {\n direction: computed(() => direction.value),\n recalculateDirection\n }\n}\n","<template>\n <Menu v-slot=\"{ open: isMenuOpen }\" as=\"div\" class=\"relative inline-block\">\n <div>\n <MenuButton ref=\"menuButton\" class=\"hidden\" @click.stop.prevent />\n <!-- conditional pointer-events-none is necessary to avoid double events when clicking on the button when the menu is already open -->\n <div :class=\"isMenuOpen ? 'pointer-events-none' : ''\">\n <slot :toggle=\"toggle\" :open=\"processOpen(isMenuOpen)\" />\n </div>\n </div>\n <Transition\n enter-active-class=\"transition duration-100 ease-out\"\n enter-from-class=\"transform scale-95 opacity-0\"\n enter-to-class=\"transform scale-100 opacity-100\"\n leave-active-class=\"transition duration-75 ease-in\"\n leave-from-class=\"transform scale-100 opacity-100\"\n leave-to-class=\"transform scale-95 opacity-0\"\n >\n <MenuItems\n ref=\"menuItems\"\n :class=\"[\n 'absolute mt-2 w-56 origin-top-right divide-y divide-outline-3 rounded-md bg-foundation shadow-lg ring-1 ring-black ring-opacity-5 focus:outline-none z-40',\n menuDirection === HorizontalDirection.Left ? 'right-0' : ''\n ]\"\n >\n <div v-for=\"(group, i) in items\" :key=\"i\" class=\"px-1 py-1\">\n <MenuItem\n v-for=\"item in group\"\n v-slot=\"{ active, disabled }\"\n :key=\"item.id\"\n :disabled=\"item.disabled\"\n >\n <span v-tippy=\"item.disabled && item.disabledTooltip\">\n <button\n :class=\"buildButtonClassses({ active, disabled })\"\n :disabled=\"disabled\"\n @click=\"chooseItem(item, $event)\"\n >\n <slot name=\"item\" :item=\"item\">{{ item.title }}</slot>\n </button>\n </span>\n </MenuItem>\n </div>\n </MenuItems>\n </Transition>\n </Menu>\n</template>\n<script setup lang=\"ts\">\nimport { directive as vTippy } from 'vue-tippy'\nimport { Menu, MenuButton, MenuItems, MenuItem } from '@headlessui/vue'\nimport { Nullable } from '@speckle/shared'\nimport { computed, ref, watch } from 'vue'\nimport {\n HorizontalDirection,\n useResponsiveHorizontalDirectionCalculation\n} from '~~/src/composables/common/window'\nimport { LayoutMenuItem } from '~~/src/helpers/layout/components'\n\nconst emit = defineEmits([\"update:open\", \"chosen\"])\n\nconst props = defineProps({\n \"open\": { type: Boolean, },\n \"items\": null\n})\n\nconst menuItems = ref(null as Nullable<{ el: HTMLDivElement }>)\nconst { direction: menuDirection } = useResponsiveHorizontalDirectionCalculation({\n el: computed(() => menuItems.value?.el || null),\n defaultDirection: HorizontalDirection.Left,\n stopUpdatesBelowWidth: 300\n})\n\nconst menuButton = ref(null as Nullable<{ el: HTMLButtonElement }>)\nconst isOpenInternally = ref(false)\n\nconst finalOpen = computed({\n get: () => props.open || false,\n set: (newVal) => emit('update:open', newVal)\n})\n\nconst buildButtonClassses = (params: { active?: boolean; disabled?: boolean }) => {\n const { active, disabled } = params\n const classParts = ['group flex w-full items-center rounded-md px-2 py-2 text-sm']\n\n if (active) {\n classParts.push('bg-primary text-foreground-on-primary')\n } else if (disabled) {\n classParts.push('text-foreground-disabled')\n } else {\n classParts.push('text-foreground')\n }\n\n return classParts.join(' ')\n}\n\nconst chooseItem = (item: LayoutMenuItem, event: MouseEvent) => {\n emit('chosen', { item, event })\n}\n\nconst toggle = () => menuButton.value?.el.click()\n\n// ok this is a bit hacky, but it's done because of headlessui's limited API\n// the point of this is 1) cast any to bool 2) store 'open' state locally\n// so that we can access it outside of the template\nconst processOpen = (val: unknown): val is boolean => {\n const isOpen = !!val\n isOpenInternally.value = isOpen\n return isOpen\n}\n\nwatch(isOpenInternally, (newVal, oldVal) => {\n if (newVal === oldVal) return\n finalOpen.value = newVal\n})\n\nwatch(finalOpen, (shouldBeOpen) => {\n if (shouldBeOpen && !isOpenInternally.value) {\n toggle()\n } else if (!shouldBeOpen && isOpenInternally.value) {\n toggle()\n }\n})\n</script>\n","<template>\n <div class=\"flex flex-col space-y-4\">\n <div class=\"flex space-x-6\">\n <FormButton\n v-for=\"item in items\"\n :key=\"item.id\"\n link\n :color=\"activeItem.id === item.id ? 'default' : 'secondary'\"\n @click=\"onTabClick(item)\"\n >\n {{ item.title }}\n </FormButton>\n </div>\n <slot :active-item=\"activeItem\" />\n </div>\n</template>\n<script setup lang=\"ts\">\n/* eslint-disable @typescript-eslint/no-explicit-any */\nimport { Nullable } from '@speckle/shared'\nimport { computed, ref } from 'vue'\nimport { LayoutTabItem } from '~~/src/helpers/layout/components'\nimport FormButton from '~~/src/components/form/Button.vue'\n\nconst props = defineProps({\n \"items\": null\n})\n\nconst activeItemId = ref(null as Nullable<string>)\nconst activeItem = computed(() => {\n if (!activeItemId.value) return props.items[0]\n return props.items.find((i) => i.id === activeItemId.value) || props.items[0]\n})\n\nconst onTabClick = (item: LayoutTabItem) => {\n activeItemId.value = item.id\n}\n</script>\n","<template>\n <div class=\"text-foreground\">\n <div class=\"w-full text-sm overflow-x-auto overflow-y-visible simple-scrollbar\">\n <div\n v-if=\"items.length > 0\"\n class=\"grid z-10 grid-cols-12 items-center gap-6 font-semibold bg-foundation rounded-t-lg w-full border-b border-outline-3 pb-2 pt-4 px-4 min-w-[900px]\"\n :style=\"{ paddingRight: paddingRightStyle }\"\n >\n <div\n v-for=\"column in columns\"\n :key=\"column.id\"\n :class=\"getHeaderClasses(column.id)\"\n class=\"capitalize\"\n >\n {{ column.header }}\n </div>\n </div>\n <div\n class=\"divide-y divide-outline-3 h-full overflow-visible\"\n :class=\"{ 'pb-32': overflowCells }\"\n >\n <div\n v-for=\"item in items\"\n :key=\"item.id\"\n class=\"relative grid grid-cols-12 items-center gap-6 px-4 py-1 min-w-[900px] bg-foundation\"\n :style=\"{ paddingRight: paddingRightStyle }\"\n :class=\"{ 'cursor-pointer hover:bg-primary-muted': !!onRowClick }\"\n tabindex=\"0\"\n @click=\"handleRowClick(item)\"\n @keypress=\"handleRowClick(item)\"\n >\n <template v-for=\"(column, colIndex) in columns\" :key=\"column.id\">\n <div :class=\"getClasses(column.id, colIndex)\" tabindex=\"0\">\n <slot :name=\"column.id\" :item=\"item\">\n <div class=\"text-gray-900 font-medium order-1\">Placeholder</div>\n </slot>\n </div>\n </template>\n <div class=\"absolute right-1.5 gap-1 flex items-center p-0\">\n <div v-for=\"button in buttons\" :key=\"button.label\">\n <FormButton\n :icon-left=\"button.icon\"\n size=\"sm\"\n color=\"secondary\"\n hide-text\n :class=\"button.class\"\n @click.stop=\"button.action(item)\"\n />\n </div>\n </div>\n </div>\n </div>\n </div>\n </div>\n</template>\n\n<script setup lang=\"ts\" generic=\"T extends {id: string}, C extends string\">\nimport { ConcreteComponent, computed } from 'vue'\nimport { FormButton } from '~~/src/lib'\n\nexport type TableColumn<I> = {\n id: I\n header: string\n classes: string\n}\n\nexport interface RowButton<T = unknown> {\n icon: ConcreteComponent\n label: string\n action: (item: T) => void\n class: string\n}\n\nconst props = defineProps({\n \"items\": null,\n \"buttons\": null,\n \"columns\": null,\n \"overflowCells\": { type: Boolean, },\n \"onRowClick\": { type: Function, }\n})\n\nconst paddingRightStyle = computed(() => {\n const buttonCount = (props.buttons || []).length\n let padding = 16\n if (buttonCount > 0) {\n padding = 48 + (buttonCount - 1) * 42\n }\n return `${padding}px`\n})\n\nconst getHeaderClasses = (column: C): string => {\n return props.columns.find((c) => c.id === column)?.classes || ''\n}\n\nconst getClasses = (column: C, colIndex: number): string => {\n const columnClass = getHeaderClasses(column)\n\n if (colIndex === 0) {\n return `bg-transparent py-3 pr-5 px-1 ${columnClass}`\n }\n return `lg:p-0 px-1 ${columnClass}`\n}\n\nconst handleRowClick = (item: T) => {\n props.onRowClick?.(item)\n}\n</script>\n","<template>\n <div ref=\"wrapper\">\n <InternalInfiniteLoading\n v-if=\"initializeLoader\"\n v-bind=\"$props.settings || {}\"\n @infinite=\"$emit('infinite', $event)\"\n >\n <template #spinner>\n <CommonLoadingBar :loading=\"true\" class=\"my-2\" />\n </template>\n <template #complete>\n <div class=\"w-full flex flex-col items-center my-2 space-y-2 mt-4\">\n <div class=\"inline-flex items-center space-x-1\">\n <CheckIcon class=\"w-5 h-5 text-success\" />\n <span class=\"text-foreground-2\">That's it, you've loaded everything!</span>\n </div>\n </div>\n </template>\n <template #error=\"{ retry }\">\n <div class=\"w-full flex flex-col items-center my-2 space-y-2 mt-4\">\n <div class=\"inline-flex items-center space-x-1\">\n <ExclamationTriangleIcon class=\"w-5 h-5 text-danger\" />\n <span class=\"text-foreground-2\">An error occurred while loading</span>\n </div>\n <FormButton v-if=\"allowRetry\" @click=\"retry\">Retry</FormButton>\n </div>\n </template>\n </InternalInfiniteLoading>\n </div>\n</template>\n<script setup lang=\"ts\">\nimport InternalInfiniteLoading from 'v3-infinite-loading'\nimport { ExclamationTriangleIcon, CheckIcon } from '@heroicons/vue/24/outline'\nimport { InfiniteLoaderState } from '~~/src/helpers/global/components'\nimport { Nullable } from '@speckle/shared'\nimport CommonLoadingBar from '~~/src/components/common/loading/Bar.vue'\nimport { onMounted, ref } from 'vue'\nimport { isClient } from '@vueuse/core'\nimport FormButton from '~~/src/components/form/Button.vue'\n\ndefineEmits([\"infinite\"])\n\ndefineProps({\n \"settings\": null,\n \"allowRetry\": { type: Boolean, }\n})\n\nconst wrapper = ref(null as Nullable<HTMLElement>)\nconst initializeLoader = ref(false)\n\n// This hack is necessary cause sometimes v3-infinite-loading initializes too early and doesnt trigger\nif (isClient) {\n onMounted(() => {\n const int = setInterval(() => {\n if (wrapper.value?.isConnected) {\n initializeLoader.value = true\n clearInterval(int)\n }\n }, 200)\n })\n}\n</script>\n","<template>\n <div class=\"relative group\">\n <div\n v-if=\"fancyGlow\"\n class=\"absolute -inset-1 bg-blue-300 dark:bg-blue-500 opacity-5 dark:opacity-0 rounded-md blur-sm group-hover:opacity-60 dark:group-hover:opacity-30 transition duration-500\"\n ></div>\n <Component\n :is=\"form ? 'form' : 'div'\"\n :class=\"[\n 'relative divide-outline-3 bg-foundation text-foreground flex flex-col divide-y overflow-hidden',\n computedClasses\n ]\"\n @submit=\"emit('submit', $event)\"\n >\n <div v-if=\"$slots.header\" :class=\"secondarySlotPaddingClasses\">\n <slot name=\"header\" />\n </div>\n <div :class=\"['grow', defaultSlotPaddingClasses]\">\n <slot />\n </div>\n <div v-if=\"$slots.footer\" :class=\"secondarySlotPaddingClasses\">\n <slot name=\"footer\" />\n </div>\n </Component>\n </div>\n</template>\n<script setup lang=\"ts\">\nimport { computed } from 'vue'\n\nconst emit = defineEmits([\"submit\"])\n\nconst props = defineProps({\n /**\n * Use a `<form/>` element as a wrapper that will emit 'submit' events out from the component when they occur\n */\n form: {\n type: Boolean,\n default: false\n },\n /**\n * Add a ring outline on hover\n */\n ring: {\n type: Boolean,\n default: false\n },\n /**\n * Add a primary-colored glow on hover\n */\n fancyGlow: {\n type: Boolean,\n default: false\n },\n customPadding: {\n type: Boolean,\n default: false\n },\n noShadow: {\n type: Boolean,\n default: false\n },\n panelClasses: {\n type: String\n }\n})\n\nconst secondarySlotPaddingClasses = computed(() =>\n props.customPadding ? '' : 'px-4 py-4 sm:px-6'\n)\nconst defaultSlotPaddingClasses = computed(() =>\n props.customPadding ? '' : 'px-4 py-4 sm:p-6'\n)\n\nconst computedClasses = computed(() => {\n const classParts: string[] = ['rounded-lg']\n\n if (!props.noShadow) classParts.push('shadow')\n if (props.ring) {\n classParts.push('ring-outline-2 hover:ring-2')\n }\n if (props.panelClasses) {\n classParts.push(props.panelClasses)\n }\n\n return classParts.join(' ')\n})\n</script>\n","<template>\n <div class=\"rounded-md\" :class=\"[containerClasses, textClasses]\">\n <div class=\"flex\" :class=\"subcontainerClasses\">\n <div class=\"flex-shrink-0\">\n <Component :is=\"icon\" :class=\"iconClasses\" aria-hidden=\"true\" />\n </div>\n <div :class=\"mainContentContainerClasses\">\n <h3 class=\"text-sm\" :class=\"[hasDescription ? 'font-medium' : '']\">\n <slot name=\"title\">Title</slot>\n </h3>\n <div v-if=\"hasDescription\" :class=\"descriptionWrapperClasses\">\n <slot name=\"description\">\n Lorem ipsum dolor sit amet consectetur adipisicing elit. Aliquid pariatur,\n ipsum similique veniam.\n </slot>\n </div>\n <div :class=\"actionsContainerClasses\">\n <FormButton\n v-for=\"(action, i) in actions || []\"\n :key=\"i\"\n :color=\"color\"\n :size=\"actionSize\"\n :to=\"action.url\"\n :external=\"action.externalUrl || false\"\n @click=\"action.onClick || noop\"\n >\n {{ action.title }}\n </FormButton>\n </div>\n </div>\n <div\n v-if=\"withDismiss\"\n class=\"flex\"\n :class=\"[hasDescription ? 'items-start' : 'items-center']\"\n >\n <button\n type=\"button\"\n class=\"inline-flex rounded-md focus:outline-none focus:ring-2\"\n :class=\"buttonClasses\"\n @click=\"$emit('dismiss')\"\n >\n <span class=\"sr-only\">Dismiss</span>\n <XMarkIcon class=\"h-5 w-5\" aria-hidden=\"true\" />\n </button>\n </div>\n </div>\n </div>\n</template>\n<script setup lang=\"ts\">\nimport {\n CheckCircleIcon,\n XMarkIcon,\n XCircleIcon,\n InformationCircleIcon,\n ExclamationCircleIcon\n} from '@heroicons/vue/20/solid'\nimport { noop } from 'lodash'\nimport { ConcreteComponent, computed, useSlots } from 'vue'\nimport FormButton from '~~/src/components/form/Button.vue'\n\ntype AlertColor = 'success' | 'danger' | 'warning' | 'info'\ntype Size = 'default' | 'xs'\n\ndefineEmits([\"dismiss\"])\n\nconst props = defineProps({\n \"color\": { default: 'success' },\n \"withDismiss\": { type: Boolean, },\n \"actions\": null,\n \"customIcon\": null,\n \"size\": { default: 'default' }\n})\n\nconst slots = useSlots()\nconst hasDescription = computed(() => !!slots['description'])\n\nconst icon = computed(() => {\n if (props.customIcon) return props.customIcon\n\n switch (props.color) {\n case 'info':\n return InformationCircleIcon\n case 'warning':\n return ExclamationCircleIcon\n case 'danger':\n return XCircleIcon\n case 'success':\n default:\n return CheckCircleIcon\n }\n})\n\nconst containerClasses = computed(() => {\n const classParts: string[] = []\n\n switch (props.size) {\n case 'xs':\n classParts.push('p-1')\n break\n case 'default':\n default:\n classParts.push(hasDescription.value ? 'p-4' : 'p-2')\n break\n }\n\n switch (props.color) {\n case 'success':\n classParts.push('bg-success-lighter border-l-4 border-success')\n break\n case 'info':\n classParts.push('bg-info-lighter border-l-4 border-info')\n break\n case 'danger':\n classParts.push('bg-danger-lighter border-l-4 border-danger')\n break\n case 'warning':\n classParts.push('bg-warning-lighter border-l-4 border-warning')\n break\n }\n\n return classParts.join(' ')\n})\n\nconst subcontainerClasses = computed(() => {\n const classParts: string[] = []\n\n if (hasDescription.value) {\n classParts.push('')\n } else {\n classParts.push('items-center')\n\n switch (props.size) {\n case 'xs':\n classParts.push('space-x-1')\n break\n case 'default':\n default:\n classParts.push('space-x-2')\n break\n }\n }\n\n return classParts.join(' ')\n})\n\nconst mainContentContainerClasses = computed(() => {\n const classParts: string[] = ['grow']\n\n if (!hasDescription.value) {\n classParts.push('flex items-center space-x-2')\n }\n\n switch (props.size) {\n case 'xs':\n classParts.push('ml-1')\n break\n case 'default':\n default:\n classParts.push('ml-3')\n\n break\n }\n\n return classParts.join(' ')\n})\n\nconst descriptionWrapperClasses = computed(() => {\n const classParts: string[] = []\n\n switch (props.size) {\n case 'xs':\n classParts.push('text-xs')\n break\n case 'default':\n default:\n classParts.push('mt-2 text-sm')\n break\n }\n\n return classParts.join(' ')\n})\n\nconst actionsContainerClasses = computed(() => {\n const classParts: string[] = ['flex']\n\n if (!hasDescription.value) {\n classParts.push('grow justify-end')\n }\n\n const hasDescriptionAndActions = hasDescription.value && props.actions?.length\n\n switch (props.size) {\n case 'xs':\n classParts.push('space-x-1')\n if (hasDescriptionAndActions) {\n classParts.push('mt-1')\n }\n break\n case 'default':\n default:\n classParts.push('space-x-2')\n if (hasDescriptionAndActions) {\n classParts.push('mt-4')\n }\n break\n }\n\n return classParts.join(' ')\n})\n\nconst textClasses = computed(() => {\n const classParts: string[] = []\n\n switch (props.color) {\n case 'success':\n classParts.push('text-success-darker')\n break\n case 'info':\n classParts.push('text-info-darker')\n break\n case 'danger':\n classParts.push('text-danger-darker')\n break\n case 'warning':\n classParts.push('text-warning-darker')\n break\n }\n\n return classParts.join(' ')\n})\n\nconst iconClasses = computed(() => {\n const classParts: string[] = []\n\n switch (props.size) {\n case 'xs':\n classParts.push('h-4 w-4')\n classParts.push(hasDescription.value ? 'mt-0.5' : '')\n break\n case 'default':\n default:\n classParts.push('h-5 w-5')\n break\n }\n\n switch (props.color) {\n case 'success':\n classParts.push('text-success')\n break\n case 'info':\n classParts.push('text-info')\n break\n case 'danger':\n classParts.push('text-danger')\n break\n case 'warning':\n classParts.push('text-warning')\n break\n }\n\n return classParts.join(' ')\n})\n\nconst buttonClasses = computed(() => {\n const classParts: string[] = []\n\n switch (props.color) {\n case 'success':\n classParts.push('bg-success-lighter ring-success')\n break\n case 'info':\n classParts.push('bg-info-lighter ring-info')\n break\n case 'danger':\n classParts.push('bg-danger-lighter ring-danger')\n break\n case 'warning':\n classParts.push('bg-warning-lighter ring-warning')\n break\n }\n\n return classParts.join(' ')\n})\n\nconst actionSize = computed(() => {\n switch (props.size) {\n case 'xs':\n return 'xs'\n case 'default':\n default:\n return 'sm'\n }\n})\n</script>\n","/* eslint-disable @typescript-eslint/no-explicit-any */\nimport { MaybeAsync } from '@speckle/shared'\nimport { AsyncComputedOptions, computedAsync } from '@vueuse/core'\nimport { ComputedRef, computed } from 'vue'\n\nexport interface AsyncWritableComputedOptions<T> {\n get: (...args: any[]) => MaybeAsync<T>\n set: (value: T) => MaybeAsync<void>\n initialState: T\n readOptions?: AsyncComputedOptions\n asyncRead?: boolean\n debugging?: Partial<{\n log: {\n name: string\n writesOnly?: boolean\n readsOnly?: boolean\n logger?: (msg: string, ...args: any[]) => void\n }\n }>\n}\n\nexport type AsyncWritableComputedRef<T> = ComputedRef<T> & {\n update: AsyncWritableComputedOptions<T>['set']\n}\n\n/**\n * Allows async read/write from/to computed. Use `res.value` to read and `res.update` to write. If you only need\n * the computed to be read-only then use vueuse's `computedAsync`. If you only need async writes you can\n * disable async reads through the `asyncRead` param.\n * @param params\n */\nexport function writableAsyncComputed<T>(\n params: AsyncWritableComputedOptions<T>\n): AsyncWritableComputedRef<T> {\n const { get, initialState, readOptions, set, asyncRead = true, debugging } = params\n const logSettings = debugging?.log\n const getTrace = () => (new Error('Trace:').stack || '').substring(7)\n const logger = params.debugging?.log?.logger || console.debug\n\n const finalGet: typeof get =\n logSettings && !logSettings.writesOnly\n ? () => {\n const res = get()\n logger(`debugging: '${logSettings.name}' read`, res, getTrace())\n return res\n }\n : get\n\n const finalSet: typeof set =\n logSettings && !logSettings.readsOnly\n ? (newVal) => {\n logger(`debugging: '${logSettings.name}' written to`, newVal, getTrace())\n return set(newVal)\n }\n : set\n\n const readValue = asyncRead\n ? computedAsync(finalGet, initialState, readOptions)\n : computed(finalGet)\n\n const getter = computed(() => readValue.value) as AsyncWritableComputedRef<T>\n getter.update = finalSet\n\n return getter\n}\n"],"names":["NuxtLink","resolveDynamicComponent","RouterLink","linkComponent","computed","props","isObjectLike","buttonType","isDisabled","finalLeftIcon","ArrowPathIcon","bgAndBorderClasses","classParts","foregroundClasses","roundedClasses","ringClasses","sizeClasses","paddingClasses","generalClasses","decoratorClasses","buttonClasses","isLinkOrText","iconClasses","onClick","e","emit","ToastNotificationType","ToastNotificationType2","shouldVerticallyCenterCloser","_a","_b","dismiss","onCtaClick","_c","badgeColorClasses","badgeDotIconColorClasses","badgeClasses","dotClasses","onIconClick","junkVariable","markClassesUsed","classes","TailwindBreakpoints","useStepsInternals","params","modelValue","steps","orientation","goVerticalBelow","nonInteractive","stepsPadding","finalOrientation","value","clamp","newVal","getStepDisplayValue","step","isCurrentStep","isFinishedStep","switchStep","newStep","stepObj","listClasses","paddingHorizontal","paddingVertical","linkClasses","toRefs","labelClasses","leftMargin","extraListClasses","computedClasses","generateRandomId","prefix","nanoid","checkboxValue","coreChecked","errorMessage","handleChange","coreValue","useField","title","descriptionText","descriptionId","descriptionClasses","implicitId","ref","finalId","onChange","onMounted","newModelValue","newCoreValue","shouldBeChecked","isCoreChecked","useTextInputCore","inputEl","error","unref","coreClasses","internalHelpTipId","base","hideHelpTip","helpTip","hasHelpTip","helpTipId","helpTipClasses","focus","clear","inputElement","__expose","slots","useSlots","leadingIconClasses","hasLeadingIcon","VALID_HTTP_URL","VALID_EMAIL","isEmail","val","isOneOrMultipleEmails","i","isRequired","isString","isSameAs","otherFieldName","otherFieldDisplayName","meta","isStringOfLength","minLength","maxLength","isNullOrUndefined","isUndefined","stringContains","match","message","isUrl","isItemSelected","useWrappingContainerHiddenCount","skipCalculation","elementToWatchForChanges","itemContainer","trackResize","trackMutations","hiddenItemCount","recalculate","target","avatarElements","visibleCount","totalCount","firstElOffsetTop","avatarEl","offsetTop","useResizeObserver","useMutationObserver","useFormSelectChildInternals","dynamicVisibility","selectedValue","currentValue","isArray","isArrayValue","v","searchInput","searchValue","currentItems","isAsyncLoading","forceUpdateKey","renderClearButton","buttonsWrapperClasses","commonButtonClasses","clearButtonClasses","hasValueSelected","hasSearch","isAsyncSearchMode","wrappedValue","finalValue","currentVal","itemKey","clearValue","finalItems","searchVal","simpleDisplayText","triggerSearch","debouncedSearch","debounce","listboxOptionClasses","active","disabled","hideCheckmarks","watch","newItems","hiddenSelectedItemCount","isMultiItemArrayValue","firstItem","searchFilterPredicate","search","deselectItem","item","enabled","_useModel","__props","ModifierKeys","clientOs","getClientOperatingSystem","ModifierKeyTitles","OperatingSystem","getKeyboardShortcutTitle","keys","isModifierKey","k","onKeyboardShortcut","modifiers","args","onKeyDown","isAltOrOpt","isCtrlOrCmd","isShift","modifier","useFormCheckboxModel","options","model","isChecked","isForm","hasButtons","open","maxWidthWeight","widthClasses","onClose","panelClasses","GridListToggleValue","currentIcon","Bars3Icon","Squares2X2Icon","ThrottleOrDebounce","ThrottleOrDebounce2","HorizontalDirection","HorizontalDirection2","useWindowResizeHandler","handler","isClient","wait","throttleOrDebounce","finalHandler","throttle","onBeforeUnmount","useOnBeforeWindowUnload","useResponsiveHorizontalDirectionCalculation","el","defaultDirection","direction","stopUpdatesBelowWidth","element","recalculateDirection","rect","showOnLeftSide","showOnRightSide","menuItems","menuDirection","menuButton","isOpenInternally","finalOpen","buildButtonClassses","chooseItem","event","toggle","processOpen","isOpen","oldVal","shouldBeOpen","activeItemId","activeItem","onTabClick","paddingRightStyle","buttonCount","padding","getHeaderClasses","column","c","getClasses","colIndex","columnClass","handleRowClick","wrapper","initializeLoader","int","secondarySlotPaddingClasses","defaultSlotPaddingClasses","hasDescription","icon","InformationCircleIcon","ExclamationCircleIcon","XCircleIcon","CheckCircleIcon","containerClasses","subcontainerClasses","mainContentContainerClasses","descriptionWrapperClasses","actionsContainerClasses","hasDescriptionAndActions","textClasses","actionSize","writableAsyncComputed","get","initialState","readOptions","set","asyncRead","debugging","logSettings","getTrace","logger","finalGet","res","finalSet","readValue","computedAsync","getter"],"mappings":"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"}
package/dist/lib.d.ts CHANGED
@@ -16,6 +16,8 @@ import { useWrappingContainerHiddenCount } from './composables/layout/resize';
16
16
  import { useFormSelectChildInternals } from './composables/form/select';
17
17
  import FormSelectSourceApps from './components/form/select/SourceApps.vue';
18
18
  import FormSelectBase from './components/form/select/Base.vue';
19
+ import FormSelectBadges from './components/form/select/Badges.vue';
20
+ import FormSwitch from './components/form/Switch.vue';
19
21
  import CommonLoadingBar from './components/common/loading/Bar.vue';
20
22
  import SourceAppBadge from './components/SourceAppBadge.vue';
21
23
  import { onKeyboardShortcut, useFormCheckboxModel } from './composables/form/input';
@@ -28,10 +30,11 @@ import { ThrottleOrDebounce, HorizontalDirection, useWindowResizeHandler, useOnB
28
30
  import LayoutMenu from './components/layout/Menu.vue';
29
31
  import { LayoutMenuItem, LayoutTabItem } from './helpers/layout/components';
30
32
  import LayoutTabs from './components/layout/Tabs.vue';
33
+ import LayoutTable from './components/layout/Table.vue';
31
34
  import InfiniteLoading from './components/InfiniteLoading.vue';
32
35
  import { InfiniteLoaderState } from './helpers/global/components';
33
36
  import LayoutPanel from './components/layout/Panel.vue';
34
37
  import CommonAlert from './components/common/Alert.vue';
35
38
  import { writableAsyncComputed, AsyncWritableComputedOptions, AsyncWritableComputedRef } from './composables/common/async';
36
- export { GlobalToastRenderer, ToastNotificationType, FormButton, CommonTextLink, CommonBadge, TailwindBreakpoints, CommonStepsBullet, CommonStepsNumber, FormCardButton, FormCheckbox, FormTextArea, FormTextInput, ValidationHelpers, useWrappingContainerHiddenCount, useFormSelectChildInternals, FormSelectBase, FormSelectSourceApps, CommonLoadingBar, SourceAppBadge, onKeyboardShortcut, ModifierKeys, getKeyboardShortcutTitle, clientOs, LayoutDialog, LayoutDisclosure, LayoutGridListToggle, GridListToggleValue, ThrottleOrDebounce, HorizontalDirection, useWindowResizeHandler, useOnBeforeWindowUnload, useResponsiveHorizontalDirectionCalculation, LayoutMenu, LayoutTabs, InfiniteLoading, LayoutPanel, CommonAlert, writableAsyncComputed, useFormCheckboxModel };
39
+ export { GlobalToastRenderer, ToastNotificationType, FormButton, CommonTextLink, CommonBadge, TailwindBreakpoints, CommonStepsBullet, CommonStepsNumber, FormCardButton, FormCheckbox, FormTextArea, FormTextInput, FormSwitch, ValidationHelpers, useWrappingContainerHiddenCount, useFormSelectChildInternals, FormSelectBase, FormSelectBadges, FormSelectSourceApps, CommonLoadingBar, SourceAppBadge, onKeyboardShortcut, ModifierKeys, getKeyboardShortcutTitle, clientOs, LayoutDialog, LayoutDisclosure, LayoutGridListToggle, GridListToggleValue, ThrottleOrDebounce, HorizontalDirection, useWindowResizeHandler, useOnBeforeWindowUnload, useResponsiveHorizontalDirectionCalculation, LayoutMenu, LayoutTabs, LayoutTable, InfiniteLoading, LayoutPanel, CommonAlert, writableAsyncComputed, useFormCheckboxModel };
37
40
  export type { ToastNotification, BulletStepType, NumberStepType, HorizontalOrVertical, LayoutMenuItem, LayoutTabItem, InfiniteLoaderState, AsyncWritableComputedOptions, AsyncWritableComputedRef };