@leaflink/stash 51.11.1 → 51.12.0

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.
Files changed (190) hide show
  1. package/README.md +41 -12
  2. package/dist/Accordion.js.map +1 -1
  3. package/dist/ActionsDropdown.js.map +1 -1
  4. package/dist/AddressSelect.js.map +1 -1
  5. package/dist/Alert.js.map +1 -1
  6. package/dist/AppNavigationItem.js.map +1 -1
  7. package/dist/AppSidebar.js.map +1 -1
  8. package/dist/Avatar.js.map +1 -1
  9. package/dist/Backdrop.js.map +1 -1
  10. package/dist/Badge.js.map +1 -1
  11. package/dist/Button.js.map +1 -1
  12. package/dist/ButtonGroup.js.map +1 -1
  13. package/dist/Card.js.map +1 -1
  14. package/dist/CardContent.js.map +1 -1
  15. package/dist/CardFooter.js.map +1 -1
  16. package/dist/CardMedia.js.map +1 -1
  17. package/dist/Carousel.js.map +1 -1
  18. package/dist/Checkbox.js.map +1 -1
  19. package/dist/Chip.js.map +1 -1
  20. package/dist/ConfirmationCodeInput.js.map +1 -1
  21. package/dist/ContextSwitcher.js.map +1 -1
  22. package/dist/Copy.js.map +1 -1
  23. package/dist/CurrencyInput.js.map +1 -1
  24. package/dist/CustomRender.js.map +1 -1
  25. package/dist/DataView.js.map +1 -1
  26. package/dist/DataView.keys-aSOnA4AD.js.map +1 -1
  27. package/dist/DataViewFilters.js.map +1 -1
  28. package/dist/DataViewFilters.keys-BLu07FiP.js.map +1 -1
  29. package/dist/DataViewSortButton.js.map +1 -1
  30. package/dist/DataViewToolbar.js +83 -151
  31. package/dist/DataViewToolbar.js.map +1 -1
  32. package/dist/DatePicker.js +10 -10
  33. package/dist/DatePicker.js.map +1 -1
  34. package/dist/DescriptionList.js.map +1 -1
  35. package/dist/DescriptionListDetail.js.map +1 -1
  36. package/dist/DescriptionListGroup.js.map +1 -1
  37. package/dist/DescriptionListTerm.js.map +1 -1
  38. package/dist/Dialog.js.map +1 -1
  39. package/dist/Divider.js.map +1 -1
  40. package/dist/Dropdown.js.map +1 -1
  41. package/dist/EmptyState.js.map +1 -1
  42. package/dist/Expand.vue_vue_type_script_setup_true_lang-CiONJfAp.js.map +1 -1
  43. package/dist/Field.vue_vue_type_script_setup_true_lang-DI6z3AE9.js.map +1 -1
  44. package/dist/FileUpload.js.map +1 -1
  45. package/dist/FilterChip.js.map +1 -1
  46. package/dist/FilterDrawerItem.js.map +1 -1
  47. package/dist/FilterDropdown.js.map +1 -1
  48. package/dist/FilterSelect.js.map +1 -1
  49. package/dist/Filters.js.map +1 -1
  50. package/dist/Filters.vue.d.ts +1 -1
  51. package/dist/HttpError.js.map +1 -1
  52. package/dist/Icon.js.map +1 -1
  53. package/dist/IconLabel.js.map +1 -1
  54. package/dist/Illustration.vue_vue_type_script_setup_true_lang-BrqEF8xe.js.map +1 -1
  55. package/dist/Image.vue_vue_type_script_setup_true_lang-D5u4av0_.js.map +1 -1
  56. package/dist/InlineEdit.js.map +1 -1
  57. package/dist/Input.js.map +1 -1
  58. package/dist/InputOptions.js.map +1 -1
  59. package/dist/IntegrationIcon.js.map +1 -1
  60. package/dist/LicenseChip.js.map +1 -1
  61. package/dist/ListItem.js.map +1 -1
  62. package/dist/ListItemCell.js.map +1 -1
  63. package/dist/ListView.js.map +1 -1
  64. package/dist/ListView.vue.d.ts +1 -1
  65. package/dist/Loading.js.map +1 -1
  66. package/dist/Logo.vue_vue_type_script_setup_true_lang-Dz8c98sc.js.map +1 -1
  67. package/dist/Menu.js.map +1 -1
  68. package/dist/MenuItem.js.map +1 -1
  69. package/dist/MenusPlugin-Bk6UW6o9.js.map +1 -1
  70. package/dist/Metric.js.map +1 -1
  71. package/dist/Modal.js.map +1 -1
  72. package/dist/Modals.js.map +1 -1
  73. package/dist/ModalsPlugin.js.map +1 -1
  74. package/dist/Module.js.map +1 -1
  75. package/dist/Module.keys-CEsrW2f0.js.map +1 -1
  76. package/dist/Module.types-B1FfGGac.js.map +1 -1
  77. package/dist/ModuleContent.js.map +1 -1
  78. package/dist/ModuleFooter.js.map +1 -1
  79. package/dist/ModuleHeader.js.map +1 -1
  80. package/dist/MoreActions.js +1 -1
  81. package/dist/MoreActions.js.map +1 -1
  82. package/dist/ObfuscateText.js.map +1 -1
  83. package/dist/PageContent.js.map +1 -1
  84. package/dist/PageHeader.js.map +1 -1
  85. package/dist/PageNavigation.js.map +1 -1
  86. package/dist/Paginate.js.map +1 -1
  87. package/dist/PlaidLink.js.map +1 -1
  88. package/dist/QuickAction.js.map +1 -1
  89. package/dist/Radio.js.map +1 -1
  90. package/dist/RadioGroup.js.map +1 -1
  91. package/dist/RadioNew.js.map +1 -1
  92. package/dist/RangeInput.js.map +1 -1
  93. package/dist/SearchBar.js.map +1 -1
  94. package/dist/SectionHeader.js.map +1 -1
  95. package/dist/Select.js +1 -1
  96. package/dist/Select.js.map +1 -1
  97. package/dist/SelectStatus.js.map +1 -1
  98. package/dist/Skeleton.js.map +1 -1
  99. package/dist/Step.js.map +1 -1
  100. package/dist/Stepper.js.map +1 -1
  101. package/dist/Switch.js.map +1 -1
  102. package/dist/Tab.js +9 -9
  103. package/dist/Tab.js.map +1 -1
  104. package/dist/Table.js.map +1 -1
  105. package/dist/Table.keys-LHQf6FEH.js.map +1 -1
  106. package/dist/TableCell.js.map +1 -1
  107. package/dist/TableHeaderCell.js.map +1 -1
  108. package/dist/TableHeaderRow.js.map +1 -1
  109. package/dist/TableRow.js.map +1 -1
  110. package/dist/Tabs.js +2 -2
  111. package/dist/Tabs.vue_vue_type_script_setup_true_lang-CmnBP4i1.js +159 -0
  112. package/dist/Tabs.vue_vue_type_script_setup_true_lang-CmnBP4i1.js.map +1 -0
  113. package/dist/TextEditor.js +20 -20
  114. package/dist/TextEditor.js.map +1 -1
  115. package/dist/Textarea.js.map +1 -1
  116. package/dist/Thumbnail.js.map +1 -1
  117. package/dist/ThumbnailEmpty.js.map +1 -1
  118. package/dist/ThumbnailGroup.js.map +1 -1
  119. package/dist/ThumbnailGroup.keys-EJ4qFNhx.js.map +1 -1
  120. package/dist/TimelineItem.js.map +1 -1
  121. package/dist/Toast.js.map +1 -1
  122. package/dist/Toasts.js.map +1 -1
  123. package/dist/ToastsPlugin.js.map +1 -1
  124. package/dist/Tooltip.js +2 -2
  125. package/dist/Tooltip.js.map +1 -1
  126. package/dist/colors-DDDVvqfQ.js.map +1 -1
  127. package/dist/components.css +1 -1
  128. package/dist/constants.js.map +1 -1
  129. package/dist/directives/autofocus.js.map +1 -1
  130. package/dist/directives/clickoutside.js.map +1 -1
  131. package/dist/directives/observe.js +8 -8
  132. package/dist/directives/observe.js.map +1 -1
  133. package/dist/directives/sticky.js.map +1 -1
  134. package/dist/directives/tooltip.js.map +1 -1
  135. package/dist/directives/viewable.js.map +1 -1
  136. package/dist/floating-ui.vue-DLFiymOf.js +1093 -0
  137. package/dist/floating-ui.vue-DLFiymOf.js.map +1 -0
  138. package/dist/formatDateTime-Dz8bXV0R.js.map +1 -1
  139. package/dist/index-D6bxWkZ1.js.map +1 -1
  140. package/dist/{index-C14LhAwV.js → index-DA_ft08e.js} +6 -6
  141. package/dist/index-DA_ft08e.js.map +1 -0
  142. package/dist/index.js +2 -2
  143. package/dist/index.js.map +1 -1
  144. package/dist/isDefined-DzVx0B6k.js.map +1 -1
  145. package/dist/isValid-DN-HkCoi.js.map +1 -1
  146. package/dist/keys-BEdEsanp.js.map +1 -1
  147. package/dist/keys-C8Zfr_By.js.map +1 -1
  148. package/dist/locale.js.map +1 -1
  149. package/dist/misc-CHQs-G03.js.map +1 -1
  150. package/dist/parseISO-wlfIB_QJ.js.map +1 -1
  151. package/dist/{searchFuzzy-DRasJ33G.js → searchFuzzy-B3TsUO-V.js} +8 -8
  152. package/dist/searchFuzzy-B3TsUO-V.js.map +1 -0
  153. package/dist/statusLevels-D8EgtE_L.js.map +1 -1
  154. package/dist/storage.js.map +1 -1
  155. package/dist/tailwind-base.js.map +1 -1
  156. package/dist/toTimeZone-Coq1oPTt.js.map +1 -1
  157. package/dist/useConfirmBeforeClosing.js.map +1 -1
  158. package/dist/useDialog.js.map +1 -1
  159. package/dist/useGoogleMaps.js.map +1 -1
  160. package/dist/useMediaQuery.js.map +1 -1
  161. package/dist/useModals.js.map +1 -1
  162. package/dist/usePaginationStats-d_q39naC.js.map +1 -1
  163. package/dist/usePlaidLink.js.map +1 -1
  164. package/dist/useScriptTag.js.map +1 -1
  165. package/dist/useSearch.js +1 -1
  166. package/dist/useSearch.js.map +1 -1
  167. package/dist/useSelection.js.map +1 -1
  168. package/dist/useSortable.js +1 -1
  169. package/dist/useSortable.js.map +1 -1
  170. package/dist/useStepper.js.map +1 -1
  171. package/dist/useToasts.js.map +1 -1
  172. package/dist/useValidation.js.map +1 -1
  173. package/dist/utils/calculateElementOverflow.js.map +1 -1
  174. package/dist/utils/colorScheme.js.map +1 -1
  175. package/dist/utils/createQueryString.js.map +1 -1
  176. package/dist/utils/createValidDate.js.map +1 -1
  177. package/dist/utils/getContrastingTextColor.js.map +1 -1
  178. package/dist/utils/helpers.js.map +1 -1
  179. package/dist/utils/i18n.js.map +1 -1
  180. package/dist/utils/normalizeDate.js.map +1 -1
  181. package/dist/utils/obfuscateText.js.map +1 -1
  182. package/dist/utils/searchFuzzy.js +1 -1
  183. package/dist/utils/storage.js.map +1 -1
  184. package/package.json +23 -10
  185. package/dist/Tabs.vue_vue_type_script_setup_true_lang-BlJVDr7o.js +0 -78
  186. package/dist/Tabs.vue_vue_type_script_setup_true_lang-BlJVDr7o.js.map +0 -1
  187. package/dist/floating-ui.vue-pzUuloyX.js +0 -1075
  188. package/dist/floating-ui.vue-pzUuloyX.js.map +0 -1
  189. package/dist/index-C14LhAwV.js.map +0 -1
  190. package/dist/searchFuzzy-DRasJ33G.js.map +0 -1
@@ -1 +1 @@
1
- {"version":3,"file":"Filters.js","sources":["../src/components/Filters/Filters.vue"],"sourcesContent":["<script>\n import cloneDeep from 'lodash-es/cloneDeep';\n import merge from 'lodash-es/merge';\n import { nextTick, ref, toRefs } from 'vue';\n\n import useValidation from '../../composables/useValidation/useValidation';\n import { LLLV_CHANGE_TRIGGERS } from '../../constants';\n import { t } from '../../locale';\n import { persistentStorage } from '../../storage';\n import Button from '../Button/Button.vue';\n import Checkbox from '../Checkbox/Checkbox.vue';\n import DatePicker from '../DatePicker/DatePicker.vue';\n import Input from '../Input/Input.vue';\n import InputOptions from '../InputOptions/InputOptions.vue';\n import Radio from '../Radio/Radio.vue';\n import Select from '../Select/Select.vue';\n\n export default {\n name: 'll-filters',\n\n components: {\n 'll-button': Button,\n 'll-checkbox': Checkbox,\n 'll-input': Input,\n 'll-input-options': InputOptions,\n 'll-radio': Radio,\n 'll-select': Select,\n DatePicker,\n },\n\n props: {\n /**\n * Whether to disable the Apply button\n */\n disableApply: Boolean,\n /**\n * Whether to disable the Clear button\n */\n disableClear: Boolean,\n /**\n * Whether to disable the sticky filters\n * If disabled, a default pre-selected value(s) can be added to\n * the filter component's attributes\n */\n disablePersistency: Boolean,\n /**\n * Filters schema\n */\n schema: {\n type: Array,\n default: () => [],\n },\n /**\n * Validation schema function that returns an object\n */\n validationSchema: {\n type: Function,\n default: () => () => undefined,\n },\n },\n\n emits: ['change', 'submit', 'reset'],\n\n setup(props) {\n const { validationSchema: getValidationSchema } = toRefs(props);\n const validationSchema = getValidationSchema.value();\n const validationValues = ref({});\n\n // Without ref, `this.validation` will always evaluate to its initial value of `undefined` due to lack of reactivity.\n const validation = ref();\n\n function initValidation() {\n if (validationSchema?.toString() !== '[object Object]') {\n return;\n }\n\n validationValues.value = Object.keys(validationSchema).reduce((values, fieldName) => {\n values[fieldName] = undefined;\n\n return values;\n }, {});\n\n const validationRules = Object.entries(validationSchema).reduce((rules, [fieldName, fieldRules]) => {\n rules[fieldName] = fieldRules.map((fieldRule) => {\n return fieldRule(validationValues);\n });\n\n return rules;\n }, {});\n\n validation.value = useValidation({ rules: validationRules, values: validationValues });\n validation.value.validate();\n }\n\n return {\n validation,\n validationValues,\n initValidation,\n };\n },\n\n data() {\n return {\n applyText: t('ll.apply'),\n clearText: t('ll.clear'),\n filters: {},\n filterValues: {},\n forceRenderCount: 0,\n };\n },\n\n watch: {\n filterValues: {\n /**\n * Maps filters to a partcular object structure:\n * @param {IFilterSchemaItem} newFilterValues all selected filters\n * @returns {IFilter}\n */\n handler: function (newFilterValues) {\n const filters = Object.keys(newFilterValues).reduce((acc, i) => {\n const schema = this.schema[i];\n\n if (!schema || !schema.fieldToFilter) {\n return acc;\n }\n\n const item = newFilterValues[i];\n\n // Ignore empty string or undefined/null filter values\n if (item === '' || item == null) {\n return acc;\n }\n\n const trackBy = schema.attributes.trackBy || 'id';\n const isObject = typeof item === 'object';\n const isCustomFilterComponent = typeof schema.type === 'object';\n // TODO: remove handling of schema.attributes.multiple when we remove the vue-multiselect version of Select\n const isMultiple =\n (isCustomFilterComponent && schema.attributes.multiple) ||\n (!isCustomFilterComponent &&\n schema.type.includes('ll-select') &&\n (schema.attributes.multiple || !schema.attributes.single));\n const filterBy = isMultiple\n ? // local storage might have item stored as an object from the old Select\n (Array.isArray(item) ? item : [item]).map((v) => v[trackBy])\n : isObject\n ? [item[trackBy]]\n : [item];\n\n const groupedWith = schema.groupedWith;\n\n if (groupedWith) {\n filterBy[0] = {\n index: groupedWith,\n value: newFilterValues[groupedWith],\n };\n filterBy.push({\n index: Number(i),\n value: newFilterValues[i],\n });\n }\n\n if (filterBy.length) {\n acc[schema.fieldToFilter] = {\n // don't add to `filters` if no filterBy\n filterBy,\n filterType: schema.type, // Informs the applied filter count\n isMultiple,\n ...('fn' in schema && { customFilter: schema.fn }),\n };\n }\n\n return acc;\n }, {});\n\n this.filters = filters;\n this.$emit('change', filters);\n },\n\n deep: true,\n immediate: true,\n },\n\n filters() {\n if (this.validation) {\n this.updateValidationValues();\n }\n },\n },\n\n async created() {\n // initFilterValues updates the filterValues so using await nextTick() forces the code\n // after it to wait until nextTick is done, at which point the filterValues will\n // be done initializing. Otherwise, applyFilters sometimes applies the wrong\n // filters because filterValues is not done updating.\n this.initFilterValues();\n await nextTick();\n this.initValidation();\n this.applyFilters({ trigger: LLLV_CHANGE_TRIGGERS.LOAD });\n },\n\n methods: {\n initFilterValues() {\n if (this.disablePersistency) {\n this.filterValues = this.getDefaultFilterValues();\n\n return;\n }\n\n this.filterValues = this.getPersistentFilterValues() || this.getDefaultFilterValues();\n },\n\n /**\n * Apply the selected filters and save them to localStorage.\n * ListView calls this method using a ref to Filters.\n * The trigger option is used in ListView.\n * @param {object} [options] - optional parameters\n * @param {string} [options.trigger] - the action that triggered this function call\n */\n async applyFilters({ trigger = LLLV_CHANGE_TRIGGERS.APPLY } = {}) {\n if (this.validation) {\n await this.validation.validate();\n\n if (this.validation.hasErrors) {\n return;\n }\n }\n\n if (!this.disablePersistency) {\n this.persistFilterValues(this.filterValues);\n }\n\n this.$emit('submit', { trigger });\n },\n\n resetFilters() {\n this.filterValues = this.getDefaultFilterValues();\n\n this.forceRenderCount++;\n\n if (!this.disablePersistency) {\n this.persistFilterValues(this.filterValues);\n }\n\n // Emit after filters are updated\n this.$nextTick(() => {\n this.$emit('reset');\n });\n },\n\n /**\n * Returns pre-defined filter values to become the default values\n */\n getDefaultFilterValues() {\n return this.schema.reduce((acc, item, filterIndex) => {\n if (item.type === 'll-checkbox') {\n acc[filterIndex] = item.attributes.checked || false;\n } else if (Object.prototype.hasOwnProperty.call(item.attributes, 'modelValue')) {\n acc[filterIndex] = item.attributes.modelValue;\n }\n\n return acc;\n }, {});\n },\n\n /**\n * Intended for external use, when filter values need to be set for the user\n */\n setFilterValues(newValues) {\n this.filterValues = merge({}, this.filterValues, newValues);\n this.forceRenderCount++;\n },\n\n updateValidationValues() {\n const validatable = Object.keys(this.validationSchema());\n\n this.schema.forEach((fieldSchema, filterIndex) => {\n const fieldToFilter = fieldSchema.fieldToFilter;\n const validate = validatable.includes(fieldToFilter);\n\n if (validate) {\n const filter = this.filters[fieldToFilter];\n\n /**\n * Get all validatable fields.\n * Use parsed value of filters that are set,\n * otherwise fall back to `filterValue` value if not set.\n */\n const filterValue = filter\n ? filter.isMultiple\n ? filter.filterBy\n : filter.filterBy[0]\n : this.filterValues[filterIndex];\n\n this.validationValues[fieldToFilter] = filterValue;\n }\n });\n },\n\n /**\n * Change handler for filter fields\n */\n onChange(filter, filterValues, filterIndex) {\n if (filter.on?.change) {\n // Maps to `on.change` handlers in the filter schema.\n filter.on.change(filterValues, filterIndex);\n }\n },\n\n /**\n * Select input event handler for filter fields\n */\n onSelectInput(newValue, filter, filterIndex) {\n if (newValue === undefined) {\n delete this.filterValues[filterIndex]; // prevent undefined filterValues which cause an empty result list\n } else {\n this.filterValues[filterIndex] = newValue;\n }\n\n this.onChange(filter, this.filterValues, filterIndex);\n },\n\n /**\n * Get filter values from local storage.\n * @returns {any}\n */\n getPersistentFilterValues() {\n return persistentStorage.get('filter-values');\n },\n\n /**\n * Clone new filterValues to remove reactivity, and save them to localStorage.\n * @param {object} newValues - the filterValues to be persisted in localStorage\n */\n persistFilterValues(newValues) {\n persistentStorage.set('filter-values', cloneDeep(newValues));\n },\n },\n };\n</script>\n\n<template>\n <div class=\"tw-ll-grid tw-grid-cols-4 md:tw-grid-cols-12\">\n <template v-for=\"(filter, filterIndex) in schema\">\n <div\n v-if=\"!filter.hidden\"\n :key=\"`${filterIndex} ${forceRenderCount}`\"\n class=\"field-wrapper tw-col-span-4 md:tw-col-span-3\"\n :class=\"{ 'max-md:tw-hidden': !filter.type, 'tw-flex tw-items-end': filter.type === 'll-checkbox' }\"\n :data-test=\"`filter|${filter.fieldToFilter}`\"\n >\n <!-- Filter component -->\n <ll-select\n v-if=\"filter.type === 'll-select'\"\n v-bind=\"filter.attributes\"\n :error=\"validation?.fields[filter.fieldToFilter] && validation?.getError(filter.fieldToFilter)\"\n :label=\"filter.label\"\n :model-value=\"filterValues[filterIndex]\"\n @update:model-value=\"(newValue) => onSelectInput(newValue, filter, filterIndex)\"\n />\n <ll-checkbox\n v-else-if=\"filter.type === 'll-checkbox'\"\n v-model:checked=\"filterValues[filterIndex]\"\n v-bind=\"filter.attributes\"\n :error-text=\"validation?.fields[filter.fieldToFilter] && validation?.getError(filter.fieldToFilter)\"\n :label=\"filter.label\"\n @update:checked=\"onChange(filter, filterValues, filterIndex)\"\n />\n <ll-radio\n v-else-if=\"filter.type === 'll-radio'\"\n v-model:checked=\"filterValues[filterIndex]\"\n v-bind=\"filter.attributes\"\n :error-text=\"validation?.fields[filter.fieldToFilter] && validation?.getError(filter.fieldToFilter)\"\n :label=\"filter.label\"\n @update:checked=\"onChange(filter, filterValues, filterIndex)\"\n />\n <component\n v-bind=\"filter.attributes\"\n :is=\"filter.type\"\n v-else-if=\"filter.type\"\n v-model=\"filterValues[filterIndex]\"\n :error-text=\"validation?.fields[filter.fieldToFilter] && validation?.getError(filter.fieldToFilter)\"\n :label=\"filter.label\"\n @update:model-value=\"onChange(filter, filterValues, filterIndex)\"\n >\n <template v-if=\"filter.slots && filter.slots.selected\" #selected=\"{ option }\">\n <component :is=\"filter.slots.selected\" v-bind=\"option.props\" />\n </template>\n <template v-if=\"filter.slots && filter.slots.option\" #option=\"{ option }\">\n <component :is=\"filter.slots.option\" v-bind=\"option.props\" />\n </template>\n <template v-if=\"filter.slots && filter.slots.prepend\" #prepend>\n <!-- eslint-disable-next-line vue/no-v-html -->\n <span v-html=\"filter.slots.prepend\"></span>\n </template>\n <template v-if=\"filter.slots && filter.slots.append\" #append>\n <!-- eslint-disable-next-line vue/no-v-html -->\n <span v-html=\"filter.slots.append\"></span>\n </template>\n </component>\n </div>\n </template>\n <div\n class=\"button-grid tw-col-span-4 tw-flex tw-items-end tw-justify-end md:tw-col-span-12\"\n :class=\"$style['filter-button-group']\"\n >\n <ll-button secondary data-test=\"button|reset-filters\" :disabled=\"disableClear\" @click=\"resetFilters\">\n {{ clearText }}\n </ll-button>\n <ll-button\n primary\n data-test=\"button|apply-filters\"\n :disabled=\"disableApply || validation?.hasErrors\"\n @click=\"applyFilters\"\n >\n {{ applyText }}\n </ll-button>\n </div>\n </div>\n</template>\n\n<style module>\n .filter-button-group {\n @media screen('max-md') {\n display: flex;\n flex-direction: column-reverse;\n }\n\n button {\n @media screen('max-md') {\n width: 100% !important;\n }\n\n &:nth-child(2) {\n @media screen('max-md') {\n margin-bottom: theme('spacing.3');\n }\n }\n }\n }\n</style>\n"],"names":["_sfc_main","Button","Checkbox","Input","InputOptions","Radio","Select","DatePicker","props","getValidationSchema","toRefs","validationSchema","validationValues","ref","validation","initValidation","values","fieldName","validationRules","rules","fieldRules","fieldRule","useValidation","t","newFilterValues","filters","acc","i","schema","item","trackBy","isObject","isCustomFilterComponent","isMultiple","filterBy","v","groupedWith","nextTick","LLLV_CHANGE_TRIGGERS","trigger","filterIndex","newValues","merge","validatable","fieldSchema","fieldToFilter","filter","filterValue","filterValues","_a","newValue","persistentStorage","cloneDeep","_hoisted_1","_hoisted_2","_hoisted_3","_hoisted_4","_openBlock","_createElementBlock","_Fragment","_renderList","$props","_createCommentVNode","$data","_normalizeClass","_createBlock","_component_ll_select","_mergeProps","$setup","_b","$options","_component_ll_checkbox","$event","_c","_d","_component_ll_radio","_e","_f","_resolveDynamicComponent","_g","_h","_createSlots","_withCtx","option","_createElementVNode","_ctx","_createVNode","_component_ll_button","_createTextVNode","_toDisplayString"],"mappings":"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"}
1
+ {"version":3,"file":"Filters.js","sources":["../src/components/Filters/Filters.vue"],"sourcesContent":["<script>\n import cloneDeep from 'lodash-es/cloneDeep';\n import merge from 'lodash-es/merge';\n import { nextTick, ref, toRefs } from 'vue';\n\n import useValidation from '../../composables/useValidation/useValidation';\n import { LLLV_CHANGE_TRIGGERS } from '../../constants';\n import { t } from '../../locale';\n import { persistentStorage } from '../../storage';\n import Button from '../Button/Button.vue';\n import Checkbox from '../Checkbox/Checkbox.vue';\n import DatePicker from '../DatePicker/DatePicker.vue';\n import Input from '../Input/Input.vue';\n import InputOptions from '../InputOptions/InputOptions.vue';\n import Radio from '../Radio/Radio.vue';\n import Select from '../Select/Select.vue';\n\n export default {\n name: 'll-filters',\n\n components: {\n 'll-button': Button,\n 'll-checkbox': Checkbox,\n 'll-input': Input,\n 'll-input-options': InputOptions,\n 'll-radio': Radio,\n 'll-select': Select,\n DatePicker,\n },\n\n props: {\n /**\n * Whether to disable the Apply button\n */\n disableApply: Boolean,\n /**\n * Whether to disable the Clear button\n */\n disableClear: Boolean,\n /**\n * Whether to disable the sticky filters\n * If disabled, a default pre-selected value(s) can be added to\n * the filter component's attributes\n */\n disablePersistency: Boolean,\n /**\n * Filters schema\n */\n schema: {\n type: Array,\n default: () => [],\n },\n /**\n * Validation schema function that returns an object\n */\n validationSchema: {\n type: Function,\n default: () => () => undefined,\n },\n },\n\n emits: ['change', 'submit', 'reset'],\n\n setup(props) {\n const { validationSchema: getValidationSchema } = toRefs(props);\n const validationSchema = getValidationSchema.value();\n const validationValues = ref({});\n\n // Without ref, `this.validation` will always evaluate to its initial value of `undefined` due to lack of reactivity.\n const validation = ref();\n\n function initValidation() {\n if (validationSchema?.toString() !== '[object Object]') {\n return;\n }\n\n validationValues.value = Object.keys(validationSchema).reduce((values, fieldName) => {\n values[fieldName] = undefined;\n\n return values;\n }, {});\n\n const validationRules = Object.entries(validationSchema).reduce((rules, [fieldName, fieldRules]) => {\n rules[fieldName] = fieldRules.map((fieldRule) => {\n return fieldRule(validationValues);\n });\n\n return rules;\n }, {});\n\n validation.value = useValidation({ rules: validationRules, values: validationValues });\n validation.value.validate();\n }\n\n return {\n validation,\n validationValues,\n initValidation,\n };\n },\n\n data() {\n return {\n applyText: t('ll.apply'),\n clearText: t('ll.clear'),\n filters: {},\n filterValues: {},\n forceRenderCount: 0,\n };\n },\n\n watch: {\n filterValues: {\n /**\n * Maps filters to a partcular object structure:\n * @param {IFilterSchemaItem} newFilterValues all selected filters\n * @returns {IFilter}\n */\n handler: function (newFilterValues) {\n const filters = Object.keys(newFilterValues).reduce((acc, i) => {\n const schema = this.schema[i];\n\n if (!schema || !schema.fieldToFilter) {\n return acc;\n }\n\n const item = newFilterValues[i];\n\n // Ignore empty string or undefined/null filter values\n if (item === '' || item == null) {\n return acc;\n }\n\n const trackBy = schema.attributes.trackBy || 'id';\n const isObject = typeof item === 'object';\n const isCustomFilterComponent = typeof schema.type === 'object';\n // TODO: remove handling of schema.attributes.multiple when we remove the vue-multiselect version of Select\n const isMultiple =\n (isCustomFilterComponent && schema.attributes.multiple) ||\n (!isCustomFilterComponent &&\n schema.type.includes('ll-select') &&\n (schema.attributes.multiple || !schema.attributes.single));\n const filterBy = isMultiple\n ? // local storage might have item stored as an object from the old Select\n (Array.isArray(item) ? item : [item]).map((v) => v[trackBy])\n : isObject\n ? [item[trackBy]]\n : [item];\n\n const groupedWith = schema.groupedWith;\n\n if (groupedWith) {\n filterBy[0] = {\n index: groupedWith,\n value: newFilterValues[groupedWith],\n };\n filterBy.push({\n index: Number(i),\n value: newFilterValues[i],\n });\n }\n\n if (filterBy.length) {\n acc[schema.fieldToFilter] = {\n // don't add to `filters` if no filterBy\n filterBy,\n filterType: schema.type, // Informs the applied filter count\n isMultiple,\n ...('fn' in schema && { customFilter: schema.fn }),\n };\n }\n\n return acc;\n }, {});\n\n this.filters = filters;\n this.$emit('change', filters);\n },\n\n deep: true,\n immediate: true,\n },\n\n filters() {\n if (this.validation) {\n this.updateValidationValues();\n }\n },\n },\n\n async created() {\n // initFilterValues updates the filterValues so using await nextTick() forces the code\n // after it to wait until nextTick is done, at which point the filterValues will\n // be done initializing. Otherwise, applyFilters sometimes applies the wrong\n // filters because filterValues is not done updating.\n this.initFilterValues();\n await nextTick();\n this.initValidation();\n this.applyFilters({ trigger: LLLV_CHANGE_TRIGGERS.LOAD });\n },\n\n methods: {\n initFilterValues() {\n if (this.disablePersistency) {\n this.filterValues = this.getDefaultFilterValues();\n\n return;\n }\n\n this.filterValues = this.getPersistentFilterValues() || this.getDefaultFilterValues();\n },\n\n /**\n * Apply the selected filters and save them to localStorage.\n * ListView calls this method using a ref to Filters.\n * The trigger option is used in ListView.\n * @param {object} [options] - optional parameters\n * @param {string} [options.trigger] - the action that triggered this function call\n */\n async applyFilters({ trigger = LLLV_CHANGE_TRIGGERS.APPLY } = {}) {\n if (this.validation) {\n await this.validation.validate();\n\n if (this.validation.hasErrors) {\n return;\n }\n }\n\n if (!this.disablePersistency) {\n this.persistFilterValues(this.filterValues);\n }\n\n this.$emit('submit', { trigger });\n },\n\n resetFilters() {\n this.filterValues = this.getDefaultFilterValues();\n\n this.forceRenderCount++;\n\n if (!this.disablePersistency) {\n this.persistFilterValues(this.filterValues);\n }\n\n // Emit after filters are updated\n this.$nextTick(() => {\n this.$emit('reset');\n });\n },\n\n /**\n * Returns pre-defined filter values to become the default values\n */\n getDefaultFilterValues() {\n return this.schema.reduce((acc, item, filterIndex) => {\n if (item.type === 'll-checkbox') {\n acc[filterIndex] = item.attributes.checked || false;\n } else if (Object.prototype.hasOwnProperty.call(item.attributes, 'modelValue')) {\n acc[filterIndex] = item.attributes.modelValue;\n }\n\n return acc;\n }, {});\n },\n\n /**\n * Intended for external use, when filter values need to be set for the user\n */\n setFilterValues(newValues) {\n this.filterValues = merge({}, this.filterValues, newValues);\n this.forceRenderCount++;\n },\n\n updateValidationValues() {\n const validatable = Object.keys(this.validationSchema());\n\n this.schema.forEach((fieldSchema, filterIndex) => {\n const fieldToFilter = fieldSchema.fieldToFilter;\n const validate = validatable.includes(fieldToFilter);\n\n if (validate) {\n const filter = this.filters[fieldToFilter];\n\n /**\n * Get all validatable fields.\n * Use parsed value of filters that are set,\n * otherwise fall back to `filterValue` value if not set.\n */\n const filterValue = filter\n ? filter.isMultiple\n ? filter.filterBy\n : filter.filterBy[0]\n : this.filterValues[filterIndex];\n\n this.validationValues[fieldToFilter] = filterValue;\n }\n });\n },\n\n /**\n * Change handler for filter fields\n */\n onChange(filter, filterValues, filterIndex) {\n if (filter.on?.change) {\n // Maps to `on.change` handlers in the filter schema.\n filter.on.change(filterValues, filterIndex);\n }\n },\n\n /**\n * Select input event handler for filter fields\n */\n onSelectInput(newValue, filter, filterIndex) {\n if (newValue === undefined) {\n delete this.filterValues[filterIndex]; // prevent undefined filterValues which cause an empty result list\n } else {\n this.filterValues[filterIndex] = newValue;\n }\n\n this.onChange(filter, this.filterValues, filterIndex);\n },\n\n /**\n * Get filter values from local storage.\n * @returns {any}\n */\n getPersistentFilterValues() {\n return persistentStorage.get('filter-values');\n },\n\n /**\n * Clone new filterValues to remove reactivity, and save them to localStorage.\n * @param {object} newValues - the filterValues to be persisted in localStorage\n */\n persistFilterValues(newValues) {\n persistentStorage.set('filter-values', cloneDeep(newValues));\n },\n },\n };\n</script>\n\n<template>\n <div class=\"tw-ll-grid tw-grid-cols-4 md:tw-grid-cols-12\">\n <template v-for=\"(filter, filterIndex) in schema\">\n <div\n v-if=\"!filter.hidden\"\n :key=\"`${filterIndex} ${forceRenderCount}`\"\n class=\"field-wrapper tw-col-span-4 md:tw-col-span-3\"\n :class=\"{ 'max-md:tw-hidden': !filter.type, 'tw-flex tw-items-end': filter.type === 'll-checkbox' }\"\n :data-test=\"`filter|${filter.fieldToFilter}`\"\n >\n <!-- Filter component -->\n <ll-select\n v-if=\"filter.type === 'll-select'\"\n v-bind=\"filter.attributes\"\n :error=\"validation?.fields[filter.fieldToFilter] && validation?.getError(filter.fieldToFilter)\"\n :label=\"filter.label\"\n :model-value=\"filterValues[filterIndex]\"\n @update:model-value=\"(newValue) => onSelectInput(newValue, filter, filterIndex)\"\n />\n <ll-checkbox\n v-else-if=\"filter.type === 'll-checkbox'\"\n v-model:checked=\"filterValues[filterIndex]\"\n v-bind=\"filter.attributes\"\n :error-text=\"validation?.fields[filter.fieldToFilter] && validation?.getError(filter.fieldToFilter)\"\n :label=\"filter.label\"\n @update:checked=\"onChange(filter, filterValues, filterIndex)\"\n />\n <ll-radio\n v-else-if=\"filter.type === 'll-radio'\"\n v-model:checked=\"filterValues[filterIndex]\"\n v-bind=\"filter.attributes\"\n :error-text=\"validation?.fields[filter.fieldToFilter] && validation?.getError(filter.fieldToFilter)\"\n :label=\"filter.label\"\n @update:checked=\"onChange(filter, filterValues, filterIndex)\"\n />\n <component\n v-bind=\"filter.attributes\"\n :is=\"filter.type\"\n v-else-if=\"filter.type\"\n v-model=\"filterValues[filterIndex]\"\n :error-text=\"validation?.fields[filter.fieldToFilter] && validation?.getError(filter.fieldToFilter)\"\n :label=\"filter.label\"\n @update:model-value=\"onChange(filter, filterValues, filterIndex)\"\n >\n <template v-if=\"filter.slots && filter.slots.selected\" #selected=\"{ option }\">\n <component :is=\"filter.slots.selected\" v-bind=\"option.props\" />\n </template>\n <template v-if=\"filter.slots && filter.slots.option\" #option=\"{ option }\">\n <component :is=\"filter.slots.option\" v-bind=\"option.props\" />\n </template>\n <template v-if=\"filter.slots && filter.slots.prepend\" #prepend>\n <!-- eslint-disable-next-line vue/no-v-html -->\n <span v-html=\"filter.slots.prepend\"></span>\n </template>\n <template v-if=\"filter.slots && filter.slots.append\" #append>\n <!-- eslint-disable-next-line vue/no-v-html -->\n <span v-html=\"filter.slots.append\"></span>\n </template>\n </component>\n </div>\n </template>\n <div\n class=\"button-grid tw-col-span-4 tw-flex tw-items-end tw-justify-end md:tw-col-span-12\"\n :class=\"$style['filter-button-group']\"\n >\n <ll-button secondary data-test=\"button|reset-filters\" :disabled=\"disableClear\" @click=\"resetFilters\">\n {{ clearText }}\n </ll-button>\n <ll-button\n primary\n data-test=\"button|apply-filters\"\n :disabled=\"disableApply || validation?.hasErrors\"\n @click=\"applyFilters\"\n >\n {{ applyText }}\n </ll-button>\n </div>\n </div>\n</template>\n\n<style module>\n .filter-button-group {\n @media screen('max-md') {\n display: flex;\n flex-direction: column-reverse;\n }\n\n button {\n @media screen('max-md') {\n width: 100% !important;\n }\n\n &:nth-child(2) {\n @media screen('max-md') {\n margin-bottom: theme('spacing.3');\n }\n }\n }\n }\n</style>\n"],"names":["_sfc_main","Button","Checkbox","Input","InputOptions","Radio","Select","DatePicker","props","getValidationSchema","toRefs","validationSchema","validationValues","ref","validation","initValidation","values","fieldName","validationRules","rules","fieldRules","fieldRule","useValidation","t","newFilterValues","filters","acc","i","schema","item","trackBy","isObject","isCustomFilterComponent","isMultiple","filterBy","v","groupedWith","nextTick","LLLV_CHANGE_TRIGGERS","trigger","filterIndex","newValues","merge","validatable","fieldSchema","fieldToFilter","filter","filterValue","filterValues","_a","newValue","persistentStorage","cloneDeep","_hoisted_1","_hoisted_2","_hoisted_3","_hoisted_4","_openBlock","_createElementBlock","_Fragment","_renderList","$props","_createCommentVNode","$data","_normalizeClass","_createBlock","_component_ll_select","_mergeProps","$setup","_b","$options","_component_ll_checkbox","$event","_c","_d","_component_ll_radio","_e","_f","_resolveDynamicComponent","_g","_h","_createSlots","_withCtx","option","_createElementVNode","_ctx","_createVNode","_component_ll_button","_createTextVNode","_toDisplayString"],"mappings":"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"}
@@ -9,7 +9,7 @@ import { DefineComponent } from 'vue';
9
9
  import { ExtractPropTypes } from 'vue';
10
10
  import { GlobalComponents } from 'vue';
11
11
  import { GlobalDirectives } from 'vue';
12
- import { Placement } from '@floating-ui/utils';
12
+ import { Placement } from '@floating-ui/vue';
13
13
  import { PopoverOptions } from 'v-calendar/dist/types/src/utils/popovers.d.ts';
14
14
  import { PropType } from 'vue';
15
15
  import { PublicProps } from 'vue';
@@ -1 +1 @@
1
- {"version":3,"file":"HttpError.js","sources":["../src/components/HttpError/HttpError.vue"],"sourcesContent":["<script setup lang=\"ts\">\n import { computed, useCssModule, useSlots } from 'vue';\n\n import { t } from '../../locale';\n import Button from '../Button/Button.vue';\n import { IllustrationType, VignetteName } from '../Illustration/Illustration.models';\n import Illustration from '../Illustration/Illustration.vue';\n import Logo from '../Logo/Logo.vue';\n\n type ErrorCodes = 401 | 403 | 404 | 405 | 500 | 502 | 503 | 504;\n const errors: Record<ErrorCodes, { title: string; description: string }> = {\n 401: {\n title: t('ll.httpError.401.title'),\n description: t('ll.httpError.401.description'),\n },\n 403: {\n title: t('ll.httpError.403.title'),\n description: t('ll.httpError.403.description'),\n },\n 404: {\n title: t('ll.httpError.404.title'),\n description: t('ll.httpError.404.description'),\n },\n 405: {\n title: t('ll.httpError.405.title'),\n description: t('ll.httpError.405.description'),\n },\n 500: {\n title: t('ll.httpError.50X.title'),\n description: t('ll.httpError.50X.description'),\n },\n 502: {\n title: t('ll.httpError.50X.title'),\n description: t('ll.httpError.50X.description'),\n },\n 503: {\n title: t('ll.httpError.50X.title'),\n description: t('ll.httpError.50X.description'),\n },\n 504: {\n title: t('ll.httpError.504.title'),\n description: t('ll.httpError.504.description'),\n },\n };\n\n export interface HttpErrorProps {\n /**\n * A description of what possibly happened.\n */\n description?: string;\n\n /**\n * The error code.\n */\n errorCode: keyof typeof errors | `${keyof typeof errors}`;\n\n /**\n * By default, the logout button is visible unless content is provided to the `actions` slot or\n * this prop is `true`.\n */\n hideLogoutButton?: boolean;\n\n /**\n * A callback that will be called when the user clicks the logout button. If not provided,\n * a `logout` event will be emitted.\n */\n onLogout?: () => void;\n\n /**\n * A link to redirect the user to see if a hard refresh fixes the issue.\n */\n retryLink?: string;\n\n /**\n * The error title.\n */\n title?: string;\n }\n\n const props = withDefaults(defineProps<HttpErrorProps>(), {\n description: '',\n errorCode: '404',\n onLogout: undefined,\n hideLogoutButton: false,\n retryLink: undefined,\n title: '',\n });\n\n const classes = useCssModule();\n const slots = useSlots();\n\n const errorCodeStr = computed(() => props.errorCode.toString());\n const errorCodeInt = computed(() => parseInt(errorCodeStr.value, 10));\n const defaultInfoByErrorCode = computed(() => errors[errorCodeInt.value] || errors['500']);\n const errorTitle = computed(() => props.title || defaultInfoByErrorCode.value.title);\n const errorDescription = computed(() => props.description || defaultInfoByErrorCode.value.description);\n\n const showLogoutButton = computed(() => !props.hideLogoutButton && props.onLogout);\n const computedRetryLink = computed(() => props.retryLink || window.location.href);\n</script>\n\n<template>\n <div class=\"stash-http-error tw-px-6 tw-py-12\" :class=\"classes.root\" data-test=\"stash-http-error\">\n <div :class=\"classes.wrapper\">\n <router-link to=\"/\" class=\"tw-mb-8 tw-block\">\n <Logo color=\"white\" width=\"192\" />\n </router-link>\n\n <div class=\"tw-mb-8 tw-gap-6\" :class=\"classes.content\">\n <div class=\"tw-order-2 lg:tw-order-1\" :class=\"classes.content__text\">\n <h1 class=\"heading-jumbo tw-m-0 tw-mb-3 !tw-text-white\">\n {{ errorTitle }}\n </h1>\n <h2 class=\"tw-mb-8 tw-text-white\">Error Code: {{ props.errorCode }}</h2>\n <p class=\"tw-mb-4 tw-text-white\">\n {{ errorDescription }} You can <a :href=\"computedRetryLink\" class=\"link\">try again</a> or reach out to\n <a href=\"mailto:support@leaflink.com\" class=\"link\">support@leaflink.com</a> for assistance.\n </p>\n </div>\n <div class=\"tw-order-1 lg:tw-order-2\" :class=\"classes.illustration\">\n <Illustration :size=\"300\" :type=\"IllustrationType.Vignette\" :name=\"VignetteName.SearchStorefront\" />\n </div>\n </div>\n\n <div v-if=\"slots.actions || showLogoutButton\" class=\"tw-flex tw-items-start tw-gap-6\">\n <slot name=\"actions\">\n <Button tertiary @click=\"props.onLogout\">Logout</Button>\n </slot>\n </div>\n </div>\n </div>\n</template>\n\n<style module>\n .root {\n background-color: var(--color-purple-500);\n display: flex;\n height: 100%;\n justify-content: center;\n align-items: center;\n max-width: 100vw;\n }\n\n .wrapper {\n max-width: 100%;\n width: 56rem;\n }\n\n .content {\n display: flex;\n justify-content: space-between;\n align-items: center;\n }\n\n .illustration {\n /* width and height similar to figma. */\n width: 300px;\n height: 193px;\n }\n\n @media screen and (width < 1024px) {\n .content {\n flex-wrap: wrap;\n gap: 0;\n }\n\n .illustration {\n margin-bottom: 30px;\n }\n }\n\n @media screen and (width >= 1024px) {\n .content__text {\n max-width: 50vw;\n }\n }\n\n .illustration svg {\n /*\n * We cannot use the same sizes from figma because the illustration would be smaller\n * and it would break alignment. The specified height in figma is 193px but the\n * illustration is 300px, so, (300 - 193) / 2 ~= 53, which keeps it aligned.\n */\n margin-top: -53px;\n }\n</style>\n"],"names":["errors","props","__props","classes","useCssModule","slots","useSlots","errorCodeStr","computed","errorCodeInt","defaultInfoByErrorCode","errorTitle","errorDescription","showLogoutButton","computedRetryLink"],"mappings":";;;;;;;;;;;;;;;;;;;;AAUE,UAAMA,IAAqE;AAAA,MACzE,KAAK;AAAA,QACH,OAAO,EAAE,wBAAwB;AAAA,QACjC,aAAa,EAAE,8BAA8B;AAAA,MAC/C;AAAA,MACA,KAAK;AAAA,QACH,OAAO,EAAE,wBAAwB;AAAA,QACjC,aAAa,EAAE,8BAA8B;AAAA,MAC/C;AAAA,MACA,KAAK;AAAA,QACH,OAAO,EAAE,wBAAwB;AAAA,QACjC,aAAa,EAAE,8BAA8B;AAAA,MAC/C;AAAA,MACA,KAAK;AAAA,QACH,OAAO,EAAE,wBAAwB;AAAA,QACjC,aAAa,EAAE,8BAA8B;AAAA,MAC/C;AAAA,MACA,KAAK;AAAA,QACH,OAAO,EAAE,wBAAwB;AAAA,QACjC,aAAa,EAAE,8BAA8B;AAAA,MAC/C;AAAA,MACA,KAAK;AAAA,QACH,OAAO,EAAE,wBAAwB;AAAA,QACjC,aAAa,EAAE,8BAA8B;AAAA,MAC/C;AAAA,MACA,KAAK;AAAA,QACH,OAAO,EAAE,wBAAwB;AAAA,QACjC,aAAa,EAAE,8BAA8B;AAAA,MAC/C;AAAA,MACA,KAAK;AAAA,QACH,OAAO,EAAE,wBAAwB;AAAA,QACjC,aAAa,EAAE,8BAA8B;AAAA,MAAA;AAAA,IAEjD,GAoCMC,IAAQC,GASRC,IAAUC,EAAa,GACvBC,IAAQC,EAAS,GAEjBC,IAAeC,EAAS,MAAMP,EAAM,UAAU,UAAU,GACxDQ,IAAeD,EAAS,MAAM,SAASD,EAAa,OAAO,EAAE,CAAC,GAC9DG,IAAyBF,EAAS,MAAMR,EAAOS,EAAa,KAAK,KAAKT,EAAO,GAAK,CAAC,GACnFW,IAAaH,EAAS,MAAMP,EAAM,SAASS,EAAuB,MAAM,KAAK,GAC7EE,IAAmBJ,EAAS,MAAMP,EAAM,eAAeS,EAAuB,MAAM,WAAW,GAE/FG,IAAmBL,EAAS,MAAM,CAACP,EAAM,oBAAoBA,EAAM,QAAQ,GAC3Ea,IAAoBN,EAAS,MAAMP,EAAM,aAAa,OAAO,SAAS,IAAI;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
1
+ {"version":3,"file":"HttpError.js","sources":["../src/components/HttpError/HttpError.vue"],"sourcesContent":["<script setup lang=\"ts\">\n import { computed, useCssModule, useSlots } from 'vue';\n\n import { t } from '../../locale';\n import Button from '../Button/Button.vue';\n import { IllustrationType, VignetteName } from '../Illustration/Illustration.models';\n import Illustration from '../Illustration/Illustration.vue';\n import Logo from '../Logo/Logo.vue';\n\n type ErrorCodes = 401 | 403 | 404 | 405 | 500 | 502 | 503 | 504;\n const errors: Record<ErrorCodes, { title: string; description: string }> = {\n 401: {\n title: t('ll.httpError.401.title'),\n description: t('ll.httpError.401.description'),\n },\n 403: {\n title: t('ll.httpError.403.title'),\n description: t('ll.httpError.403.description'),\n },\n 404: {\n title: t('ll.httpError.404.title'),\n description: t('ll.httpError.404.description'),\n },\n 405: {\n title: t('ll.httpError.405.title'),\n description: t('ll.httpError.405.description'),\n },\n 500: {\n title: t('ll.httpError.50X.title'),\n description: t('ll.httpError.50X.description'),\n },\n 502: {\n title: t('ll.httpError.50X.title'),\n description: t('ll.httpError.50X.description'),\n },\n 503: {\n title: t('ll.httpError.50X.title'),\n description: t('ll.httpError.50X.description'),\n },\n 504: {\n title: t('ll.httpError.504.title'),\n description: t('ll.httpError.504.description'),\n },\n };\n\n export interface HttpErrorProps {\n /**\n * A description of what possibly happened.\n */\n description?: string;\n\n /**\n * The error code.\n */\n errorCode: keyof typeof errors | `${keyof typeof errors}`;\n\n /**\n * By default, the logout button is visible unless content is provided to the `actions` slot or\n * this prop is `true`.\n */\n hideLogoutButton?: boolean;\n\n /**\n * A callback that will be called when the user clicks the logout button. If not provided,\n * a `logout` event will be emitted.\n */\n onLogout?: () => void;\n\n /**\n * A link to redirect the user to see if a hard refresh fixes the issue.\n */\n retryLink?: string;\n\n /**\n * The error title.\n */\n title?: string;\n }\n\n const props = withDefaults(defineProps<HttpErrorProps>(), {\n description: '',\n errorCode: '404',\n onLogout: undefined,\n hideLogoutButton: false,\n retryLink: undefined,\n title: '',\n });\n\n const classes = useCssModule();\n const slots = useSlots();\n\n const errorCodeStr = computed(() => props.errorCode.toString());\n const errorCodeInt = computed(() => parseInt(errorCodeStr.value, 10));\n const defaultInfoByErrorCode = computed(() => errors[errorCodeInt.value] || errors['500']);\n const errorTitle = computed(() => props.title || defaultInfoByErrorCode.value.title);\n const errorDescription = computed(() => props.description || defaultInfoByErrorCode.value.description);\n\n const showLogoutButton = computed(() => !props.hideLogoutButton && props.onLogout);\n const computedRetryLink = computed(() => props.retryLink || window.location.href);\n</script>\n\n<template>\n <div class=\"stash-http-error tw-px-6 tw-py-12\" :class=\"classes.root\" data-test=\"stash-http-error\">\n <div :class=\"classes.wrapper\">\n <router-link to=\"/\" class=\"tw-mb-8 tw-block\">\n <Logo color=\"white\" width=\"192\" />\n </router-link>\n\n <div class=\"tw-mb-8 tw-gap-6\" :class=\"classes.content\">\n <div class=\"tw-order-2 lg:tw-order-1\" :class=\"classes.content__text\">\n <h1 class=\"heading-jumbo tw-m-0 tw-mb-3 !tw-text-white\">\n {{ errorTitle }}\n </h1>\n <h2 class=\"tw-mb-8 tw-text-white\">Error Code: {{ props.errorCode }}</h2>\n <p class=\"tw-mb-4 tw-text-white\">\n {{ errorDescription }} You can <a :href=\"computedRetryLink\" class=\"link\">try again</a> or reach out to\n <a href=\"mailto:support@leaflink.com\" class=\"link\">support@leaflink.com</a> for assistance.\n </p>\n </div>\n <div class=\"tw-order-1 lg:tw-order-2\" :class=\"classes.illustration\">\n <Illustration :size=\"300\" :type=\"IllustrationType.Vignette\" :name=\"VignetteName.SearchStorefront\" />\n </div>\n </div>\n\n <div v-if=\"slots.actions || showLogoutButton\" class=\"tw-flex tw-items-start tw-gap-6\">\n <slot name=\"actions\">\n <Button tertiary @click=\"props.onLogout\">Logout</Button>\n </slot>\n </div>\n </div>\n </div>\n</template>\n\n<style module>\n .root {\n background-color: var(--color-purple-500);\n display: flex;\n height: 100%;\n justify-content: center;\n align-items: center;\n max-width: 100vw;\n }\n\n .wrapper {\n max-width: 100%;\n width: 56rem;\n }\n\n .content {\n display: flex;\n justify-content: space-between;\n align-items: center;\n }\n\n .illustration {\n /* width and height similar to figma. */\n width: 300px;\n height: 193px;\n }\n\n @media screen and (width < 1024px) {\n .content {\n flex-wrap: wrap;\n gap: 0;\n }\n\n .illustration {\n margin-bottom: 30px;\n }\n }\n\n @media screen and (width >= 1024px) {\n .content__text {\n max-width: 50vw;\n }\n }\n\n .illustration svg {\n /*\n * We cannot use the same sizes from figma because the illustration would be smaller\n * and it would break alignment. The specified height in figma is 193px but the\n * illustration is 300px, so, (300 - 193) / 2 ~= 53, which keeps it aligned.\n */\n margin-top: -53px;\n }\n</style>\n"],"names":["errors","props","__props","classes","useCssModule","slots","useSlots","errorCodeStr","computed","errorCodeInt","defaultInfoByErrorCode","errorTitle","errorDescription","showLogoutButton","computedRetryLink"],"mappings":";;;;;;;;;;;;;;;;;;;;AAUE,UAAMA,IAAqE;AAAA,MACzE,KAAK;AAAA,QACH,OAAO,EAAE,wBAAwB;AAAA,QACjC,aAAa,EAAE,8BAA8B;AAAA,MAAA;AAAA,MAE/C,KAAK;AAAA,QACH,OAAO,EAAE,wBAAwB;AAAA,QACjC,aAAa,EAAE,8BAA8B;AAAA,MAAA;AAAA,MAE/C,KAAK;AAAA,QACH,OAAO,EAAE,wBAAwB;AAAA,QACjC,aAAa,EAAE,8BAA8B;AAAA,MAAA;AAAA,MAE/C,KAAK;AAAA,QACH,OAAO,EAAE,wBAAwB;AAAA,QACjC,aAAa,EAAE,8BAA8B;AAAA,MAAA;AAAA,MAE/C,KAAK;AAAA,QACH,OAAO,EAAE,wBAAwB;AAAA,QACjC,aAAa,EAAE,8BAA8B;AAAA,MAAA;AAAA,MAE/C,KAAK;AAAA,QACH,OAAO,EAAE,wBAAwB;AAAA,QACjC,aAAa,EAAE,8BAA8B;AAAA,MAAA;AAAA,MAE/C,KAAK;AAAA,QACH,OAAO,EAAE,wBAAwB;AAAA,QACjC,aAAa,EAAE,8BAA8B;AAAA,MAAA;AAAA,MAE/C,KAAK;AAAA,QACH,OAAO,EAAE,wBAAwB;AAAA,QACjC,aAAa,EAAE,8BAA8B;AAAA,MAAA;AAAA,IAC/C,GAqCIC,IAAQC,GASRC,IAAUC,EAAA,GACVC,IAAQC,EAAA,GAERC,IAAeC,EAAS,MAAMP,EAAM,UAAU,UAAU,GACxDQ,IAAeD,EAAS,MAAM,SAASD,EAAa,OAAO,EAAE,CAAC,GAC9DG,IAAyBF,EAAS,MAAMR,EAAOS,EAAa,KAAK,KAAKT,EAAO,GAAK,CAAC,GACnFW,IAAaH,EAAS,MAAMP,EAAM,SAASS,EAAuB,MAAM,KAAK,GAC7EE,IAAmBJ,EAAS,MAAMP,EAAM,eAAeS,EAAuB,MAAM,WAAW,GAE/FG,IAAmBL,EAAS,MAAM,CAACP,EAAM,oBAAoBA,EAAM,QAAQ,GAC3Ea,IAAoBN,EAAS,MAAMP,EAAM,aAAa,OAAO,SAAS,IAAI;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
package/dist/Icon.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"Icon.js","sources":["../src/components/Icon/Icon.types.ts","../src/components/Icon/Icon.vue"],"sourcesContent":["/**\n * To add a new icon, follow these steps:\n *\n * https://github.com/LeafLink/stash/blob/main/CONTRIBUTING.md#adding-a-new-icon\n */\nexport const iconNames = [\n 'action-dots',\n 'activity',\n 'alert-bell',\n 'archive',\n 'arrow-down',\n 'arrow-left',\n 'arrow-right',\n 'arrow-up',\n 'badge-discount',\n 'badge-seller-elite',\n 'badge-seller-power',\n 'badge-seller-verified',\n 'bank',\n 'book-customer',\n 'building-office',\n 'bulk-add',\n 'calendar-reschedule',\n 'calendar',\n 'camera',\n 'caret-down',\n 'caret-up',\n 'change-log',\n 'check',\n 'chevron-down',\n 'chevron-left',\n 'chevron-right',\n 'chevron-up',\n 'circle-check',\n 'circle-close',\n 'circle-dollar',\n 'circle-empty',\n 'circle-info',\n 'circle-partial',\n 'circle-percent',\n 'circle-question-mark',\n 'circle-slash',\n 'circle-status',\n 'circle-warning',\n 'clipboard-checkmark',\n 'clipboard-inventory',\n 'close',\n 'cloud-share',\n 'combine',\n 'compass',\n 'contact',\n 'contract',\n 'copy',\n 'credit-card',\n 'credit-profile',\n 'dashboard',\n 'document-accept',\n 'document-invoice',\n 'document-recieved',\n 'document-sent',\n 'document-view',\n 'document',\n 'dolly',\n 'download',\n 'edit',\n 'ellipsis',\n 'envelope-open',\n 'envelope',\n 'equals',\n 'export',\n 'face-id',\n 'face',\n 'figma',\n 'file-csv',\n 'file',\n 'filter-funnel',\n 'filter-line',\n 'fingerprint',\n 'flag',\n 'folder',\n 'folder-bar-graph',\n 'folder-orders',\n 'font-bold',\n 'font-clear-format',\n 'font-italic',\n 'font-underline',\n 'gear',\n 'github',\n 'globe',\n 'graph-bar-chart',\n 'graph-line-chart',\n 'graph-pie-chart',\n 'hazard',\n 'hazard-outline',\n 'headset-agent',\n 'headset-mic',\n 'heart-filled',\n 'heart-outline',\n 'help-question-mark',\n 'hide',\n 'history',\n 'home',\n 'image',\n 'import',\n 'keyboard-return',\n 'tier-1',\n 'tier-2',\n 'tier-3',\n 'license-approved',\n 'license-certificate',\n 'lightbulb',\n 'link-add',\n 'link-unlink',\n 'link',\n 'list-bulleted',\n 'list-items',\n 'list-numbered',\n 'loading-big',\n 'loading-empty',\n 'loading-small',\n 'location',\n 'lock-unlock',\n 'lock',\n 'logo-facebook',\n 'logo-instagram',\n 'logo-linkedin',\n 'logo-ll',\n 'logo-metrc',\n 'logo-plaid',\n 'logo-x',\n 'logo-youtube',\n 'logout',\n 'medical',\n 'megaphone-sound',\n 'megaphone',\n 'menu',\n 'message-dispute',\n 'message-reply',\n 'message',\n 'minus',\n 'mj-leaf',\n 'money',\n 'note-add',\n 'note',\n 'open-in-new',\n 'paperclip',\n 'paper-plane',\n 'performance',\n 'phone',\n 'plus',\n 'preview',\n 'print',\n 'product-menu-manage',\n 'product-menu-search',\n 'product-menu',\n 'queue-add',\n 'queue',\n 'recent',\n 'refresh',\n 'register',\n 'reorder',\n 'reply',\n 'report-download',\n 'sample',\n 'save',\n 'scale-law',\n 'scale-weight',\n 'search',\n 'seed-cycle',\n 'share',\n 'shop-bag-browse',\n 'shop-bag-reorder',\n 'shop-bag',\n 'shop-basket',\n 'shop-cart-add',\n 'shop-cart',\n 'show',\n 'sign-dollar',\n 'sign-percent',\n 'sort',\n 'split',\n 'star-filled',\n 'star-outline',\n 'start',\n 'storefront',\n 'submit',\n 'swap-horizontal',\n 'swap-vertical',\n 'tag-star',\n 'tag',\n 'tag-leaf',\n 'test-results',\n 'ticket-star',\n 'ticket',\n 'tool-dropper',\n 'tool-wrench',\n 'transfer',\n 'trashcan',\n 'truck',\n 'upload',\n 'user-add',\n 'user-admin',\n 'user-check',\n 'user-group',\n 'user',\n 'view-card',\n 'view-detailed',\n 'view-list',\n 'warehouse',\n 'working',\n] as const;\n\nexport type IconName = (typeof iconNames)[number];\n\nexport enum IconSizes {\n Standard = 'standard',\n Dense = 'dense',\n Small = 'small',\n Large = 'large',\n}\n\nexport type IconSize = `${IconSizes}`;\n","<script lang=\"ts\">\n export * from './Icon.types';\n</script>\n\n<script lang=\"ts\" setup>\n import uniqueId from 'lodash-es/uniqueId';\n import { computed, inject, useCssModule } from 'vue';\n import InlineSvg from 'vue-inline-svg';\n\n import { StashProvideState } from '../../../types/misc';\n import { IconName, iconNames, IconSize } from './Icon.types';\n\n export interface IconProps {\n id?: string;\n\n /**\n * The filename of the icon that should be displayed\n */\n name: IconName;\n\n /**\n * Accessible, short-text description for the icon. Not rendered as part of the graphic, but\n * browsers usually display it as a tooltip and screen readers use this.\n */\n title?: string;\n\n /**\n * The size of the icon\n * Options: large (32x32px), default (24x24px), dense (20x20px), small (14x14px).\n */\n size?: IconSize;\n\n /**\n * @deprecated Use the `size` prop with value \"dense\" instead\n */\n dense?: boolean;\n\n /**\n` * @deprecated Use the `size` prop with value \"small\" instead\n */\n small?: boolean;\n\n /**\n * Icon's custom static path. It'll default to either the staticPath defined on the library installation or '/static' if none are provided.\n */\n staticPath?: string;\n }\n\n defineOptions({\n name: 'll-icon',\n });\n\n const props = withDefaults(defineProps<IconProps>(), {\n id: () => uniqueId('ll-icon-'),\n size: 'standard',\n title: '',\n staticPath: '',\n });\n const classes = useCssModule();\n const stashOptions = inject<Partial<StashProvideState>>('stashOptions', {\n staticPath: '/static',\n });\n\n const computedName = computed<IconName>(() => {\n if (iconNames.includes(props.name)) {\n return props.name;\n }\n\n return 'mj-leaf';\n });\n\n const computedStaticPath = computed(() => {\n return props.staticPath || stashOptions?.staticPath;\n });\n\n /**\n * Event handler to add the use tag for the specific icon we need to the svg\n */\n const transformSvgSource = (svgElem: SVGElement) => {\n if (!svgElem) {\n return svgElem;\n }\n\n const useNode = document.createElement('use');\n useNode.setAttribute('href', `#${computedName.value}`);\n\n // Grab icon from sprite\n const symbolNode = svgElem.querySelector(`#${computedName.value}`);\n\n // This really shouldn't happen but if the spritesheet gets out of sync with the `IconName` type it could\n if (!symbolNode) {\n // still insert <use> element but it will not be found (this is more for tests than anything else)\n svgElem.insertBefore(useNode, svgElem.firstChild);\n return svgElem;\n }\n\n /**\n * Repeatedly inlining the entire spritesheet was causing failures in mobile Safari, and also\n * performance issues on long list pages where the svg was being inlined over and over.\n * Since the SVG is cached after the first request, this callback is just removing the unnecessary\n * <symbol> nodes to slim down the DOM manipulation and insertion.\n */\n // Replace all children with just the one <symbol> element and <use> element\n svgElem.replaceChildren(symbolNode, useNode);\n\n return svgElem;\n };\n</script>\n\n<!-- Use inline svg so that requests to pull the spritesheet are done via JS and avoid\n browser restrictions for different domains for svgs. inline svg also caches the requests\n so we don't load the spritesheet multiple times\n Reference: https://oreillymedia.github.io/Using_SVG/extras/ch10-cors.html -->\n<template>\n <InlineSvg\n :id=\"props.id\"\n role=\"presentation\"\n :aria-labelledby=\"props.id\"\n class=\"stash-icon\"\n :class=\"[\n classes.icon,\n `icon--${props.name}`,\n {\n [classes.standard]: props.size === 'standard',\n [classes.dense]: props.size === 'dense' || props.dense,\n [classes.small]: props.size === 'small' || props.small,\n [classes.large]: props.size === 'large',\n },\n ]\"\n data-test=\"stash-icon\"\n :src=\"`${computedStaticPath}/spritesheet.svg`\"\n :title=\"props.title\"\n :transform-source=\"transformSvgSource\"\n />\n</template>\n\n<style module>\n .icon {\n display: inline-block;\n fill: currentcolor;\n vertical-align: middle;\n }\n\n .standard {\n height: 24px;\n min-height: 24px;\n min-width: 24px;\n width: 24px;\n }\n\n .dense {\n height: 20px;\n min-height: 20px;\n min-width: 20px;\n width: 20px;\n }\n\n .small {\n height: 14px;\n min-height: 14px;\n min-width: 14px;\n width: 14px;\n }\n\n .large {\n height: 32px;\n min-height: 32px;\n min-width: 32px;\n width: 32px;\n }\n</style>\n"],"names":["iconNames","IconSizes","props","__props","classes","useCssModule","stashOptions","inject","computedName","computed","computedStaticPath","transformSvgSource","svgElem","useNode","symbolNode"],"mappings":";;;;AAKO,MAAMA,IAAY;AAAA,EACvB;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF;AAIY,IAAAC,sBAAAA,OACVA,EAAA,WAAW,YACXA,EAAA,QAAQ,SACRA,EAAA,QAAQ,SACRA,EAAA,QAAQ,SAJEA,IAAAA,KAAA,CAAA,CAAA;;;;;;;;;;;;;;AClKV,UAAMC,IAAQC,GAMRC,IAAUC,EAAa,GACvBC,IAAeC,EAAmC,gBAAgB;AAAA,MACtE,YAAY;AAAA,IAAA,CACb,GAEKC,IAAeC,EAAmB,MAClCT,EAAU,SAASE,EAAM,IAAI,IACxBA,EAAM,OAGR,SACR,GAEKQ,IAAqBD,EAAS,MAC3BP,EAAM,eAAcI,KAAA,gBAAAA,EAAc,WAC1C,GAKKK,IAAqB,CAACC,MAAwB;AAClD,UAAI,CAACA;AACI,eAAAA;AAGH,YAAAC,IAAU,SAAS,cAAc,KAAK;AAC5C,MAAAA,EAAQ,aAAa,QAAQ,IAAIL,EAAa,KAAK,EAAE;AAGrD,YAAMM,IAAaF,EAAQ,cAAc,IAAIJ,EAAa,KAAK,EAAE;AAGjE,aAAKM,KAaGF,EAAA,gBAAgBE,GAAYD,CAAO,GAEpCD,MAbGA,EAAA,aAAaC,GAASD,EAAQ,UAAU,GACzCA;AAAA,IAaX;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
1
+ {"version":3,"file":"Icon.js","sources":["../src/components/Icon/Icon.types.ts","../src/components/Icon/Icon.vue"],"sourcesContent":["/**\n * To add a new icon, follow these steps:\n *\n * https://github.com/LeafLink/stash/blob/main/CONTRIBUTING.md#adding-a-new-icon\n */\nexport const iconNames = [\n 'action-dots',\n 'activity',\n 'alert-bell',\n 'archive',\n 'arrow-down',\n 'arrow-left',\n 'arrow-right',\n 'arrow-up',\n 'badge-discount',\n 'badge-seller-elite',\n 'badge-seller-power',\n 'badge-seller-verified',\n 'bank',\n 'book-customer',\n 'building-office',\n 'bulk-add',\n 'calendar-reschedule',\n 'calendar',\n 'camera',\n 'caret-down',\n 'caret-up',\n 'change-log',\n 'check',\n 'chevron-down',\n 'chevron-left',\n 'chevron-right',\n 'chevron-up',\n 'circle-check',\n 'circle-close',\n 'circle-dollar',\n 'circle-empty',\n 'circle-info',\n 'circle-partial',\n 'circle-percent',\n 'circle-question-mark',\n 'circle-slash',\n 'circle-status',\n 'circle-warning',\n 'clipboard-checkmark',\n 'clipboard-inventory',\n 'close',\n 'cloud-share',\n 'combine',\n 'compass',\n 'contact',\n 'contract',\n 'copy',\n 'credit-card',\n 'credit-profile',\n 'dashboard',\n 'document-accept',\n 'document-invoice',\n 'document-recieved',\n 'document-sent',\n 'document-view',\n 'document',\n 'dolly',\n 'download',\n 'edit',\n 'ellipsis',\n 'envelope-open',\n 'envelope',\n 'equals',\n 'export',\n 'face-id',\n 'face',\n 'figma',\n 'file-csv',\n 'file',\n 'filter-funnel',\n 'filter-line',\n 'fingerprint',\n 'flag',\n 'folder',\n 'folder-bar-graph',\n 'folder-orders',\n 'font-bold',\n 'font-clear-format',\n 'font-italic',\n 'font-underline',\n 'gear',\n 'github',\n 'globe',\n 'graph-bar-chart',\n 'graph-line-chart',\n 'graph-pie-chart',\n 'hazard',\n 'hazard-outline',\n 'headset-agent',\n 'headset-mic',\n 'heart-filled',\n 'heart-outline',\n 'help-question-mark',\n 'hide',\n 'history',\n 'home',\n 'image',\n 'import',\n 'keyboard-return',\n 'tier-1',\n 'tier-2',\n 'tier-3',\n 'license-approved',\n 'license-certificate',\n 'lightbulb',\n 'link-add',\n 'link-unlink',\n 'link',\n 'list-bulleted',\n 'list-items',\n 'list-numbered',\n 'loading-big',\n 'loading-empty',\n 'loading-small',\n 'location',\n 'lock-unlock',\n 'lock',\n 'logo-facebook',\n 'logo-instagram',\n 'logo-linkedin',\n 'logo-ll',\n 'logo-metrc',\n 'logo-plaid',\n 'logo-x',\n 'logo-youtube',\n 'logout',\n 'medical',\n 'megaphone-sound',\n 'megaphone',\n 'menu',\n 'message-dispute',\n 'message-reply',\n 'message',\n 'minus',\n 'mj-leaf',\n 'money',\n 'note-add',\n 'note',\n 'open-in-new',\n 'paperclip',\n 'paper-plane',\n 'performance',\n 'phone',\n 'plus',\n 'preview',\n 'print',\n 'product-menu-manage',\n 'product-menu-search',\n 'product-menu',\n 'queue-add',\n 'queue',\n 'recent',\n 'refresh',\n 'register',\n 'reorder',\n 'reply',\n 'report-download',\n 'sample',\n 'save',\n 'scale-law',\n 'scale-weight',\n 'search',\n 'seed-cycle',\n 'share',\n 'shop-bag-browse',\n 'shop-bag-reorder',\n 'shop-bag',\n 'shop-basket',\n 'shop-cart-add',\n 'shop-cart',\n 'show',\n 'sign-dollar',\n 'sign-percent',\n 'sort',\n 'split',\n 'star-filled',\n 'star-outline',\n 'start',\n 'storefront',\n 'submit',\n 'swap-horizontal',\n 'swap-vertical',\n 'tag-star',\n 'tag',\n 'tag-leaf',\n 'test-results',\n 'ticket-star',\n 'ticket',\n 'tool-dropper',\n 'tool-wrench',\n 'transfer',\n 'trashcan',\n 'truck',\n 'upload',\n 'user-add',\n 'user-admin',\n 'user-check',\n 'user-group',\n 'user',\n 'view-card',\n 'view-detailed',\n 'view-list',\n 'warehouse',\n 'working',\n] as const;\n\nexport type IconName = (typeof iconNames)[number];\n\nexport enum IconSizes {\n Standard = 'standard',\n Dense = 'dense',\n Small = 'small',\n Large = 'large',\n}\n\nexport type IconSize = `${IconSizes}`;\n","<script lang=\"ts\">\n export * from './Icon.types';\n</script>\n\n<script lang=\"ts\" setup>\n import uniqueId from 'lodash-es/uniqueId';\n import { computed, inject, useCssModule } from 'vue';\n import InlineSvg from 'vue-inline-svg';\n\n import { StashProvideState } from '../../../types/misc';\n import { IconName, iconNames, IconSize } from './Icon.types';\n\n export interface IconProps {\n id?: string;\n\n /**\n * The filename of the icon that should be displayed\n */\n name: IconName;\n\n /**\n * Accessible, short-text description for the icon. Not rendered as part of the graphic, but\n * browsers usually display it as a tooltip and screen readers use this.\n */\n title?: string;\n\n /**\n * The size of the icon\n * Options: large (32x32px), default (24x24px), dense (20x20px), small (14x14px).\n */\n size?: IconSize;\n\n /**\n * @deprecated Use the `size` prop with value \"dense\" instead\n */\n dense?: boolean;\n\n /**\n` * @deprecated Use the `size` prop with value \"small\" instead\n */\n small?: boolean;\n\n /**\n * Icon's custom static path. It'll default to either the staticPath defined on the library installation or '/static' if none are provided.\n */\n staticPath?: string;\n }\n\n defineOptions({\n name: 'll-icon',\n });\n\n const props = withDefaults(defineProps<IconProps>(), {\n id: () => uniqueId('ll-icon-'),\n size: 'standard',\n title: '',\n staticPath: '',\n });\n const classes = useCssModule();\n const stashOptions = inject<Partial<StashProvideState>>('stashOptions', {\n staticPath: '/static',\n });\n\n const computedName = computed<IconName>(() => {\n if (iconNames.includes(props.name)) {\n return props.name;\n }\n\n return 'mj-leaf';\n });\n\n const computedStaticPath = computed(() => {\n return props.staticPath || stashOptions?.staticPath;\n });\n\n /**\n * Event handler to add the use tag for the specific icon we need to the svg\n */\n const transformSvgSource = (svgElem: SVGElement) => {\n if (!svgElem) {\n return svgElem;\n }\n\n const useNode = document.createElement('use');\n useNode.setAttribute('href', `#${computedName.value}`);\n\n // Grab icon from sprite\n const symbolNode = svgElem.querySelector(`#${computedName.value}`);\n\n // This really shouldn't happen but if the spritesheet gets out of sync with the `IconName` type it could\n if (!symbolNode) {\n // still insert <use> element but it will not be found (this is more for tests than anything else)\n svgElem.insertBefore(useNode, svgElem.firstChild);\n return svgElem;\n }\n\n /**\n * Repeatedly inlining the entire spritesheet was causing failures in mobile Safari, and also\n * performance issues on long list pages where the svg was being inlined over and over.\n * Since the SVG is cached after the first request, this callback is just removing the unnecessary\n * <symbol> nodes to slim down the DOM manipulation and insertion.\n */\n // Replace all children with just the one <symbol> element and <use> element\n svgElem.replaceChildren(symbolNode, useNode);\n\n return svgElem;\n };\n</script>\n\n<!-- Use inline svg so that requests to pull the spritesheet are done via JS and avoid\n browser restrictions for different domains for svgs. inline svg also caches the requests\n so we don't load the spritesheet multiple times\n Reference: https://oreillymedia.github.io/Using_SVG/extras/ch10-cors.html -->\n<template>\n <InlineSvg\n :id=\"props.id\"\n role=\"presentation\"\n :aria-labelledby=\"props.id\"\n class=\"stash-icon\"\n :class=\"[\n classes.icon,\n `icon--${props.name}`,\n {\n [classes.standard]: props.size === 'standard',\n [classes.dense]: props.size === 'dense' || props.dense,\n [classes.small]: props.size === 'small' || props.small,\n [classes.large]: props.size === 'large',\n },\n ]\"\n data-test=\"stash-icon\"\n :src=\"`${computedStaticPath}/spritesheet.svg`\"\n :title=\"props.title\"\n :transform-source=\"transformSvgSource\"\n />\n</template>\n\n<style module>\n .icon {\n display: inline-block;\n fill: currentcolor;\n vertical-align: middle;\n }\n\n .standard {\n height: 24px;\n min-height: 24px;\n min-width: 24px;\n width: 24px;\n }\n\n .dense {\n height: 20px;\n min-height: 20px;\n min-width: 20px;\n width: 20px;\n }\n\n .small {\n height: 14px;\n min-height: 14px;\n min-width: 14px;\n width: 14px;\n }\n\n .large {\n height: 32px;\n min-height: 32px;\n min-width: 32px;\n width: 32px;\n }\n</style>\n"],"names":["iconNames","IconSizes","props","__props","classes","useCssModule","stashOptions","inject","computedName","computed","computedStaticPath","transformSvgSource","svgElem","useNode","symbolNode"],"mappings":";;;;AAKO,MAAMA,IAAY;AAAA,EACvB;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF;AAIO,IAAKC,sBAAAA,OACVA,EAAA,WAAW,YACXA,EAAA,QAAQ,SACRA,EAAA,QAAQ,SACRA,EAAA,QAAQ,SAJEA,IAAAA,KAAA,CAAA,CAAA;;;;;;;;;;;;;;AClKV,UAAMC,IAAQC,GAMRC,IAAUC,EAAA,GACVC,IAAeC,EAAmC,gBAAgB;AAAA,MACtE,YAAY;AAAA,IAAA,CACb,GAEKC,IAAeC,EAAmB,MAClCT,EAAU,SAASE,EAAM,IAAI,IACxBA,EAAM,OAGR,SACR,GAEKQ,IAAqBD,EAAS,MAC3BP,EAAM,eAAcI,KAAA,gBAAAA,EAAc,WAC1C,GAKKK,IAAqB,CAACC,MAAwB;AAClD,UAAI,CAACA;AACH,eAAOA;AAGT,YAAMC,IAAU,SAAS,cAAc,KAAK;AAC5C,MAAAA,EAAQ,aAAa,QAAQ,IAAIL,EAAa,KAAK,EAAE;AAGrD,YAAMM,IAAaF,EAAQ,cAAc,IAAIJ,EAAa,KAAK,EAAE;AAGjE,aAAKM,KAaLF,EAAQ,gBAAgBE,GAAYD,CAAO,GAEpCD,MAbLA,EAAQ,aAAaC,GAASD,EAAQ,UAAU,GACzCA;AAAA,IAaX;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
@@ -1 +1 @@
1
- {"version":3,"file":"IconLabel.js","sources":["../src/components/IconLabel/IconLabel.vue"],"sourcesContent":["<script setup lang=\"ts\">\n import { computed } from 'vue';\n\n import { StashCommonColor } from '../../../types/colors';\n import { IconName } from '../Icon/Icon.types';\n import Icon from '../Icon/Icon.vue';\n\n export interface IconLabelProps {\n /**\n * Name of the icon to use. All design system icons are supported.\n */\n icon: IconName;\n\n /**\n * Color to apply to the icon. Common Stash colors are supported (100, 500, & 700 shades).\n */\n color?: StashCommonColor;\n\n /**\n * Valid hyperlink.\n */\n href?: string;\n\n /**\n * Valid vue-router route.\n */\n to?: string | object;\n\n /**\n * If true, renders the label below the icon instead of to the right\n */\n stacked?: boolean;\n\n /**\n * If true, truncates overflowing text with an ellipsis when it's unable to wrap\n */\n truncate?: boolean;\n }\n\n const props = withDefaults(defineProps<IconLabelProps>(), {\n color: undefined,\n href: undefined,\n to: undefined,\n stacked: false,\n truncate: false,\n });\n\n defineOptions({\n name: 'll-icon-label',\n });\n\n const is = computed(() => {\n if (props.to) {\n return 'router-link';\n }\n\n if (props.href) {\n return 'a';\n }\n\n return 'div';\n });\n\n const attributes = computed(() => {\n if (props.to) {\n return {\n to: props.to,\n };\n }\n\n if (props.href) {\n return {\n href: props.href,\n };\n }\n\n return {};\n });\n</script>\n\n<template>\n <component :is=\"is\" v-bind=\"attributes\" class=\"tw-flex\" :class=\"{ 'tw-flex-col tw-items-center': props.stacked }\">\n <Icon :name=\"props.icon\" size=\"dense\" :class=\"[$style.icon, { [`tw-text-${color}`]: !!color }]\" />\n\n <div\n :class=\"{\n 'tw-ml-1.5 tw-flex-1': !props.stacked,\n 'tw-mt-1.5 tw-text-xs tw-leading-3': props.stacked,\n 'tw-truncate': truncate,\n }\"\n >\n <!-- @slot Label text -->\n <slot></slot>\n </div>\n </component>\n</template>\n\n<style module>\n .icon {\n margin-top: -1px;\n }\n</style>\n"],"names":["props","__props","is","computed","attributes"],"mappings":";;;;;;;;;;;;;;;AAuCE,UAAMA,IAAQC,GAYRC,IAAKC,EAAS,MACdH,EAAM,KACD,gBAGLA,EAAM,OACD,MAGF,KACR,GAEKI,IAAaD,EAAS,MACtBH,EAAM,KACD;AAAA,MACL,IAAIA,EAAM;AAAA,IACZ,IAGEA,EAAM,OACD;AAAA,MACL,MAAMA,EAAM;AAAA,IACd,IAGK,CAAC,CACT;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
1
+ {"version":3,"file":"IconLabel.js","sources":["../src/components/IconLabel/IconLabel.vue"],"sourcesContent":["<script setup lang=\"ts\">\n import { computed } from 'vue';\n\n import { StashCommonColor } from '../../../types/colors';\n import { IconName } from '../Icon/Icon.types';\n import Icon from '../Icon/Icon.vue';\n\n export interface IconLabelProps {\n /**\n * Name of the icon to use. All design system icons are supported.\n */\n icon: IconName;\n\n /**\n * Color to apply to the icon. Common Stash colors are supported (100, 500, & 700 shades).\n */\n color?: StashCommonColor;\n\n /**\n * Valid hyperlink.\n */\n href?: string;\n\n /**\n * Valid vue-router route.\n */\n to?: string | object;\n\n /**\n * If true, renders the label below the icon instead of to the right\n */\n stacked?: boolean;\n\n /**\n * If true, truncates overflowing text with an ellipsis when it's unable to wrap\n */\n truncate?: boolean;\n }\n\n const props = withDefaults(defineProps<IconLabelProps>(), {\n color: undefined,\n href: undefined,\n to: undefined,\n stacked: false,\n truncate: false,\n });\n\n defineOptions({\n name: 'll-icon-label',\n });\n\n const is = computed(() => {\n if (props.to) {\n return 'router-link';\n }\n\n if (props.href) {\n return 'a';\n }\n\n return 'div';\n });\n\n const attributes = computed(() => {\n if (props.to) {\n return {\n to: props.to,\n };\n }\n\n if (props.href) {\n return {\n href: props.href,\n };\n }\n\n return {};\n });\n</script>\n\n<template>\n <component :is=\"is\" v-bind=\"attributes\" class=\"tw-flex\" :class=\"{ 'tw-flex-col tw-items-center': props.stacked }\">\n <Icon :name=\"props.icon\" size=\"dense\" :class=\"[$style.icon, { [`tw-text-${color}`]: !!color }]\" />\n\n <div\n :class=\"{\n 'tw-ml-1.5 tw-flex-1': !props.stacked,\n 'tw-mt-1.5 tw-text-xs tw-leading-3': props.stacked,\n 'tw-truncate': truncate,\n }\"\n >\n <!-- @slot Label text -->\n <slot></slot>\n </div>\n </component>\n</template>\n\n<style module>\n .icon {\n margin-top: -1px;\n }\n</style>\n"],"names":["props","__props","is","computed","attributes"],"mappings":";;;;;;;;;;;;;;;AAuCE,UAAMA,IAAQC,GAYRC,IAAKC,EAAS,MACdH,EAAM,KACD,gBAGLA,EAAM,OACD,MAGF,KACR,GAEKI,IAAaD,EAAS,MACtBH,EAAM,KACD;AAAA,MACL,IAAIA,EAAM;AAAA,IAAA,IAIVA,EAAM,OACD;AAAA,MACL,MAAMA,EAAM;AAAA,IAAA,IAIT,CAAA,CACR;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
@@ -1 +1 @@
1
- {"version":3,"file":"Illustration.vue_vue_type_script_setup_true_lang-BrqEF8xe.js","sources":["../src/components/Illustration/Illustration.models.ts","../src/components/Illustration/Illustration.vue"],"sourcesContent":["/**\n * Enum to strongly map between a friendly name and file name of the illustration\n */\nexport enum SpotName {\n Approved = 'approved',\n Avatar = 'avatar',\n Barcode = 'barcode',\n Calendar = 'calendar',\n Cartridge = 'cartridge',\n Celebrate = 'celebrate',\n ChatBubble = 'chat-bubble',\n CheckBox = 'check-box',\n CheckCircle = 'check-circle',\n Click = 'click',\n Cocktail = 'cocktail',\n Confirmation = 'confirmation',\n Connnect = 'connnect',\n Cookie = 'cookie',\n CreditCard = 'credit-card',\n Crm = 'crm',\n Cultivation = 'cultivation',\n Data = 'data',\n DeliveryCompleted = 'delivery-completed',\n Delivery = 'delivery',\n DigitalPayments = 'digital-payments',\n Discover = 'discover',\n Diversity = 'diversity',\n Drink = 'drink',\n Dolly = 'dolly',\n EasyReconciliations = 'easy-reconciliations',\n Efficiency = 'efficiency',\n Error = 'error',\n ExtendDate = 'extend-date',\n FinancialGrowth = 'financial-growth',\n FinancialInstitution = 'financial-institution',\n Focus = 'focus',\n FulfillmentIssues = 'fulfillment-issues',\n Growth = 'growth',\n Handshake = 'handshake',\n Hierarchy = 'hierarchy',\n Home = 'home',\n Laptop = 'laptop',\n Licenses = 'licenses',\n LightBulb = 'light-bulb',\n LightbulbError = 'lightbulb-error',\n LineChart = 'line-chart',\n Link = 'link',\n LocationPin = 'location-pin',\n Lock = 'lock',\n Messaging = 'messaging',\n Messages = 'messages',\n Microchip = 'microchip',\n MissingData = 'missing-data',\n MoneyTransfer = 'money-transfer',\n Money = 'money',\n NoInventoryAccess = 'no-inventory-access',\n NoInventory = 'no-inventory',\n NoPromote = 'no-promote',\n PackageReceived = 'package-received',\n Package = 'package',\n PaymentProcessing = 'payment-processing',\n Phone = 'phone',\n PieChart = 'pie-chart',\n ProductCycle = 'product-cycle',\n Puzzle = 'puzzle',\n Receipt = 'receipt',\n Retail = 'retail',\n SearchingDocument = 'searching-document',\n ShoppingBasket = 'shopping-basket',\n Shopping = 'shopping',\n Sign = 'sign',\n Smile = 'smile',\n Speed = 'speed',\n Time = 'time',\n Tools = 'tools',\n Truck = 'truck',\n User = 'user',\n Warehouse = 'warehouse',\n Warning = 'warning',\n XCircle = 'x-circle',\n}\n\nexport type SpotNames = `${SpotName}`;\n\n/**\n * String array of all illustration names\n */\nexport const spotNames = Object.values(SpotName);\n\nexport enum VignetteName {\n Api = 'api',\n Bank = 'bank',\n Basket = 'basket',\n BrandMenu = 'brand-menu',\n Calendar = 'calendar',\n Dashboard = 'dashboard',\n Deals = 'deals',\n DocumentSearch = 'document-search',\n Edit = 'edit',\n EmptyTray = 'empty-tray',\n Graph = 'graph',\n Integrations = 'integrations',\n LightBulb = 'light-bulb',\n Map = 'map',\n Megaphone = 'megaphone',\n Messages = 'messages',\n MoneyBank = 'money-bank',\n NoFiltersResult = 'no-filters-result',\n Notifications = 'notifications',\n OrdersEmpty = 'orders-empty',\n Payments = 'payments',\n PieChart = 'pie-chart',\n ProductCards = 'product-cards',\n ProductDetails = 'product-details',\n ProductDisplay = 'product-display',\n Search = 'search',\n SearchStorefront = 'search-storefront',\n Store = 'store',\n Todo = 'todo',\n Truck = 'truck',\n Users = 'users',\n Warehouse = 'warehouse',\n WarehouseDelivery = 'warehouse-delivery',\n}\n\nexport type VignetteNames = `${VignetteName}`;\n\n/**\n * String array of all vignette names\n */\nexport const vignetteNames = Object.values(VignetteName);\n\n/**\n * Types of illustrations that map to the subfolder under ./assets/illustrations/<type>\n */\nexport enum IllustrationType {\n Spot = 'spot',\n Vignette = 'vignette',\n // Scene is not implemented, but adding it for future work mentioned in STASH-61.\n Scene = 'scene',\n}\n\nexport type IllustrationTypes = `${IllustrationType}`;\n","<script lang=\"ts\">\n export * from './Illustration.models';\n</script>\n\n<script lang=\"ts\" setup>\n import uniqueId from 'lodash-es/uniqueId';\n import { computed, inject } from 'vue';\n import InlineSvg from 'vue-inline-svg';\n\n import { StashPrimaryColor, StashPrimaryColorGroup } from '../../../types/colors';\n import { StashProvideState } from '../../../types/misc';\n import {\n IllustrationType,\n IllustrationTypes,\n SpotName,\n SpotNames,\n spotNames,\n VignetteName,\n VignetteNames,\n vignetteNames,\n } from './Illustration.models';\n\n export interface IllustrationProps {\n id?: string;\n\n /**\n * The filename of the icon that should be displayed\n */\n name: SpotNames | VignetteNames;\n\n /**\n * Accessible, short-text description for the icon. Not rendered as part of the graphic, but\n * browsers usually display it as a tooltip and screen readers use this.\n */\n title?: string;\n\n /**\n * The size in pixels of the illustration. This number will be used for width and height\n */\n size?: number;\n\n /**\n * Type of the illustration\n */\n type?: IllustrationTypes;\n\n /**\n * The fill color for the illustration. This component will use the 400 shade of the color\n * per design's request. Defaults to teal.\n */\n fillColor?: StashPrimaryColorGroup;\n\n /**\n * The color theme for the illustration. This component will use the standard 500 shade of the color.\n * Defaults to purple\n */\n strokeColor?: StashPrimaryColor;\n\n /**\n * Illustration's custom static path. It'll default to either the staticPath defined on the library installation or '/static' if none are provided.\n */\n staticPath?: string;\n }\n\n const props = withDefaults(defineProps<IllustrationProps>(), {\n id: uniqueId('ll-illustration-'),\n title: '',\n size: 48,\n type: IllustrationType.Spot,\n fillColor: 'blue',\n strokeColor: 'purple-500',\n staticPath: '',\n });\n\n if (props.type === IllustrationType.Scene) {\n throw new Error(\n 'Scene illustration types are not supported. Illustrations will need to be uploaded under ./assets/illustrations/scene. Illustrations to be provided by design.',\n );\n }\n\n if (\n (props.type === IllustrationType.Spot && !spotNames.includes(props.name as SpotName)) ||\n (props.type === IllustrationType.Vignette && !vignetteNames.includes(props.name as VignetteName))\n ) {\n throw new Error(\n `${props.type} illustration name ${props.name} not found. Did you check that you are using the correct type for your illustration?`,\n );\n }\n\n const stashOptions = inject<Partial<StashProvideState>>('stashOptions', {\n staticPath: '/static',\n });\n\n const isSpotIllustration = computed(() => props.type === IllustrationType.Spot);\n\n /**\n * Browsers won't add the `stroke-width` attribute if it is set to false.\n * However, setting it to specific number value affects vignettes\n */\n const strokeWidth = computed<boolean | string>(() => {\n return isSpotIllustration.value ? '0' : false;\n });\n\n const computedStaticPath = computed(() => {\n return props.staticPath || stashOptions?.staticPath;\n });\n</script>\n\n<template>\n <!-- InlineSvg package (https://github.com/shrpne/vue-inline-svg) swaps external svgs and puts\n them inline so we can style them with CSS -->\n <!-- Having to override fill to be none and stroke to be zero so the exported svgs from Figma\n that do not have those attributes specified do not get a default one applied -->\n <InlineSvg\n :id=\"props.id\"\n class=\"tw-inline-block tw-align-middle\"\n :class=\"{\n [`tw-text-${props.fillColor}-400 tw-stroke-${props.strokeColor}`]: isSpotIllustration,\n }\"\n :title=\"props.title\"\n :height=\"props.size\"\n :width=\"props.size\"\n :stroke-width=\"strokeWidth\"\n fill=\"none\"\n :src=\"`${computedStaticPath}/illustrations/${props.type}/${props.name}.svg`\"\n />\n</template>\n"],"names":["SpotName","spotNames","VignetteName","vignetteNames","IllustrationType","props","__props","stashOptions","inject","isSpotIllustration","computed","strokeWidth","computedStaticPath"],"mappings":";;;AAGY,IAAAA,sBAAAA,OACVA,EAAA,WAAW,YACXA,EAAA,SAAS,UACTA,EAAA,UAAU,WACVA,EAAA,WAAW,YACXA,EAAA,YAAY,aACZA,EAAA,YAAY,aACZA,EAAA,aAAa,eACbA,EAAA,WAAW,aACXA,EAAA,cAAc,gBACdA,EAAA,QAAQ,SACRA,EAAA,WAAW,YACXA,EAAA,eAAe,gBACfA,EAAA,WAAW,YACXA,EAAA,SAAS,UACTA,EAAA,aAAa,eACbA,EAAA,MAAM,OACNA,EAAA,cAAc,eACdA,EAAA,OAAO,QACPA,EAAA,oBAAoB,sBACpBA,EAAA,WAAW,YACXA,EAAA,kBAAkB,oBAClBA,EAAA,WAAW,YACXA,EAAA,YAAY,aACZA,EAAA,QAAQ,SACRA,EAAA,QAAQ,SACRA,EAAA,sBAAsB,wBACtBA,EAAA,aAAa,cACbA,EAAA,QAAQ,SACRA,EAAA,aAAa,eACbA,EAAA,kBAAkB,oBAClBA,EAAA,uBAAuB,yBACvBA,EAAA,QAAQ,SACRA,EAAA,oBAAoB,sBACpBA,EAAA,SAAS,UACTA,EAAA,YAAY,aACZA,EAAA,YAAY,aACZA,EAAA,OAAO,QACPA,EAAA,SAAS,UACTA,EAAA,WAAW,YACXA,EAAA,YAAY,cACZA,EAAA,iBAAiB,mBACjBA,EAAA,YAAY,cACZA,EAAA,OAAO,QACPA,EAAA,cAAc,gBACdA,EAAA,OAAO,QACPA,EAAA,YAAY,aACZA,EAAA,WAAW,YACXA,EAAA,YAAY,aACZA,EAAA,cAAc,gBACdA,EAAA,gBAAgB,kBAChBA,EAAA,QAAQ,SACRA,EAAA,oBAAoB,uBACpBA,EAAA,cAAc,gBACdA,EAAA,YAAY,cACZA,EAAA,kBAAkB,oBAClBA,EAAA,UAAU,WACVA,EAAA,oBAAoB,sBACpBA,EAAA,QAAQ,SACRA,EAAA,WAAW,aACXA,EAAA,eAAe,iBACfA,EAAA,SAAS,UACTA,EAAA,UAAU,WACVA,EAAA,SAAS,UACTA,EAAA,oBAAoB,sBACpBA,EAAA,iBAAiB,mBACjBA,EAAA,WAAW,YACXA,EAAA,OAAO,QACPA,EAAA,QAAQ,SACRA,EAAA,QAAQ,SACRA,EAAA,OAAO,QACPA,EAAA,QAAQ,SACRA,EAAA,QAAQ,SACRA,EAAA,OAAO,QACPA,EAAA,YAAY,aACZA,EAAA,UAAU,WACVA,EAAA,UAAU,YA5EAA,IAAAA,KAAA,CAAA,CAAA;AAoFC,MAAAC,IAAY,OAAO,OAAOD,CAAQ;AAEnC,IAAAE,sBAAAA,OACVA,EAAA,MAAM,OACNA,EAAA,OAAO,QACPA,EAAA,SAAS,UACTA,EAAA,YAAY,cACZA,EAAA,WAAW,YACXA,EAAA,YAAY,aACZA,EAAA,QAAQ,SACRA,EAAA,iBAAiB,mBACjBA,EAAA,OAAO,QACPA,EAAA,YAAY,cACZA,EAAA,QAAQ,SACRA,EAAA,eAAe,gBACfA,EAAA,YAAY,cACZA,EAAA,MAAM,OACNA,EAAA,YAAY,aACZA,EAAA,WAAW,YACXA,EAAA,YAAY,cACZA,EAAA,kBAAkB,qBAClBA,EAAA,gBAAgB,iBAChBA,EAAA,cAAc,gBACdA,EAAA,WAAW,YACXA,EAAA,WAAW,aACXA,EAAA,eAAe,iBACfA,EAAA,iBAAiB,mBACjBA,EAAA,iBAAiB,mBACjBA,EAAA,SAAS,UACTA,EAAA,mBAAmB,qBACnBA,EAAA,QAAQ,SACRA,EAAA,OAAO,QACPA,EAAA,QAAQ,SACRA,EAAA,QAAQ,SACRA,EAAA,YAAY,aACZA,EAAA,oBAAoB,sBAjCVA,IAAAA,KAAA,CAAA,CAAA;AAyCC,MAAAC,IAAgB,OAAO,OAAOD,CAAY;AAK3C,IAAAE,sBAAAA,OACVA,EAAA,OAAO,QACPA,EAAA,WAAW,YAEXA,EAAA,QAAQ,SAJEA,IAAAA,KAAA,CAAA,CAAA;;;;;;;;;;;;;;ACvEV,UAAMC,IAAQC;AAUV,QAAAD,EAAM,SAASD,EAAiB;AAClC,YAAM,IAAI;AAAA,QACR;AAAA,MACF;AAGF,QACGC,EAAM,SAASD,EAAiB,QAAQ,CAACH,EAAU,SAASI,EAAM,IAAgB,KAClFA,EAAM,SAASD,EAAiB,YAAY,CAACD,EAAc,SAASE,EAAM,IAAoB;AAE/F,YAAM,IAAI;AAAA,QACR,GAAGA,EAAM,IAAI,sBAAsBA,EAAM,IAAI;AAAA,MAC/C;AAGI,UAAAE,IAAeC,EAAmC,gBAAgB;AAAA,MACtE,YAAY;AAAA,IAAA,CACb,GAEKC,IAAqBC,EAAS,MAAML,EAAM,SAASD,EAAiB,IAAI,GAMxEO,IAAcD,EAA2B,MACtCD,EAAmB,QAAQ,MAAM,EACzC,GAEKG,IAAqBF,EAAS,MAC3BL,EAAM,eAAcE,KAAA,gBAAAA,EAAc,WAC1C;;;;;;;;;;;;;;;"}
1
+ {"version":3,"file":"Illustration.vue_vue_type_script_setup_true_lang-BrqEF8xe.js","sources":["../src/components/Illustration/Illustration.models.ts","../src/components/Illustration/Illustration.vue"],"sourcesContent":["/**\n * Enum to strongly map between a friendly name and file name of the illustration\n */\nexport enum SpotName {\n Approved = 'approved',\n Avatar = 'avatar',\n Barcode = 'barcode',\n Calendar = 'calendar',\n Cartridge = 'cartridge',\n Celebrate = 'celebrate',\n ChatBubble = 'chat-bubble',\n CheckBox = 'check-box',\n CheckCircle = 'check-circle',\n Click = 'click',\n Cocktail = 'cocktail',\n Confirmation = 'confirmation',\n Connnect = 'connnect',\n Cookie = 'cookie',\n CreditCard = 'credit-card',\n Crm = 'crm',\n Cultivation = 'cultivation',\n Data = 'data',\n DeliveryCompleted = 'delivery-completed',\n Delivery = 'delivery',\n DigitalPayments = 'digital-payments',\n Discover = 'discover',\n Diversity = 'diversity',\n Drink = 'drink',\n Dolly = 'dolly',\n EasyReconciliations = 'easy-reconciliations',\n Efficiency = 'efficiency',\n Error = 'error',\n ExtendDate = 'extend-date',\n FinancialGrowth = 'financial-growth',\n FinancialInstitution = 'financial-institution',\n Focus = 'focus',\n FulfillmentIssues = 'fulfillment-issues',\n Growth = 'growth',\n Handshake = 'handshake',\n Hierarchy = 'hierarchy',\n Home = 'home',\n Laptop = 'laptop',\n Licenses = 'licenses',\n LightBulb = 'light-bulb',\n LightbulbError = 'lightbulb-error',\n LineChart = 'line-chart',\n Link = 'link',\n LocationPin = 'location-pin',\n Lock = 'lock',\n Messaging = 'messaging',\n Messages = 'messages',\n Microchip = 'microchip',\n MissingData = 'missing-data',\n MoneyTransfer = 'money-transfer',\n Money = 'money',\n NoInventoryAccess = 'no-inventory-access',\n NoInventory = 'no-inventory',\n NoPromote = 'no-promote',\n PackageReceived = 'package-received',\n Package = 'package',\n PaymentProcessing = 'payment-processing',\n Phone = 'phone',\n PieChart = 'pie-chart',\n ProductCycle = 'product-cycle',\n Puzzle = 'puzzle',\n Receipt = 'receipt',\n Retail = 'retail',\n SearchingDocument = 'searching-document',\n ShoppingBasket = 'shopping-basket',\n Shopping = 'shopping',\n Sign = 'sign',\n Smile = 'smile',\n Speed = 'speed',\n Time = 'time',\n Tools = 'tools',\n Truck = 'truck',\n User = 'user',\n Warehouse = 'warehouse',\n Warning = 'warning',\n XCircle = 'x-circle',\n}\n\nexport type SpotNames = `${SpotName}`;\n\n/**\n * String array of all illustration names\n */\nexport const spotNames = Object.values(SpotName);\n\nexport enum VignetteName {\n Api = 'api',\n Bank = 'bank',\n Basket = 'basket',\n BrandMenu = 'brand-menu',\n Calendar = 'calendar',\n Dashboard = 'dashboard',\n Deals = 'deals',\n DocumentSearch = 'document-search',\n Edit = 'edit',\n EmptyTray = 'empty-tray',\n Graph = 'graph',\n Integrations = 'integrations',\n LightBulb = 'light-bulb',\n Map = 'map',\n Megaphone = 'megaphone',\n Messages = 'messages',\n MoneyBank = 'money-bank',\n NoFiltersResult = 'no-filters-result',\n Notifications = 'notifications',\n OrdersEmpty = 'orders-empty',\n Payments = 'payments',\n PieChart = 'pie-chart',\n ProductCards = 'product-cards',\n ProductDetails = 'product-details',\n ProductDisplay = 'product-display',\n Search = 'search',\n SearchStorefront = 'search-storefront',\n Store = 'store',\n Todo = 'todo',\n Truck = 'truck',\n Users = 'users',\n Warehouse = 'warehouse',\n WarehouseDelivery = 'warehouse-delivery',\n}\n\nexport type VignetteNames = `${VignetteName}`;\n\n/**\n * String array of all vignette names\n */\nexport const vignetteNames = Object.values(VignetteName);\n\n/**\n * Types of illustrations that map to the subfolder under ./assets/illustrations/<type>\n */\nexport enum IllustrationType {\n Spot = 'spot',\n Vignette = 'vignette',\n // Scene is not implemented, but adding it for future work mentioned in STASH-61.\n Scene = 'scene',\n}\n\nexport type IllustrationTypes = `${IllustrationType}`;\n","<script lang=\"ts\">\n export * from './Illustration.models';\n</script>\n\n<script lang=\"ts\" setup>\n import uniqueId from 'lodash-es/uniqueId';\n import { computed, inject } from 'vue';\n import InlineSvg from 'vue-inline-svg';\n\n import { StashPrimaryColor, StashPrimaryColorGroup } from '../../../types/colors';\n import { StashProvideState } from '../../../types/misc';\n import {\n IllustrationType,\n IllustrationTypes,\n SpotName,\n SpotNames,\n spotNames,\n VignetteName,\n VignetteNames,\n vignetteNames,\n } from './Illustration.models';\n\n export interface IllustrationProps {\n id?: string;\n\n /**\n * The filename of the icon that should be displayed\n */\n name: SpotNames | VignetteNames;\n\n /**\n * Accessible, short-text description for the icon. Not rendered as part of the graphic, but\n * browsers usually display it as a tooltip and screen readers use this.\n */\n title?: string;\n\n /**\n * The size in pixels of the illustration. This number will be used for width and height\n */\n size?: number;\n\n /**\n * Type of the illustration\n */\n type?: IllustrationTypes;\n\n /**\n * The fill color for the illustration. This component will use the 400 shade of the color\n * per design's request. Defaults to teal.\n */\n fillColor?: StashPrimaryColorGroup;\n\n /**\n * The color theme for the illustration. This component will use the standard 500 shade of the color.\n * Defaults to purple\n */\n strokeColor?: StashPrimaryColor;\n\n /**\n * Illustration's custom static path. It'll default to either the staticPath defined on the library installation or '/static' if none are provided.\n */\n staticPath?: string;\n }\n\n const props = withDefaults(defineProps<IllustrationProps>(), {\n id: uniqueId('ll-illustration-'),\n title: '',\n size: 48,\n type: IllustrationType.Spot,\n fillColor: 'blue',\n strokeColor: 'purple-500',\n staticPath: '',\n });\n\n if (props.type === IllustrationType.Scene) {\n throw new Error(\n 'Scene illustration types are not supported. Illustrations will need to be uploaded under ./assets/illustrations/scene. Illustrations to be provided by design.',\n );\n }\n\n if (\n (props.type === IllustrationType.Spot && !spotNames.includes(props.name as SpotName)) ||\n (props.type === IllustrationType.Vignette && !vignetteNames.includes(props.name as VignetteName))\n ) {\n throw new Error(\n `${props.type} illustration name ${props.name} not found. Did you check that you are using the correct type for your illustration?`,\n );\n }\n\n const stashOptions = inject<Partial<StashProvideState>>('stashOptions', {\n staticPath: '/static',\n });\n\n const isSpotIllustration = computed(() => props.type === IllustrationType.Spot);\n\n /**\n * Browsers won't add the `stroke-width` attribute if it is set to false.\n * However, setting it to specific number value affects vignettes\n */\n const strokeWidth = computed<boolean | string>(() => {\n return isSpotIllustration.value ? '0' : false;\n });\n\n const computedStaticPath = computed(() => {\n return props.staticPath || stashOptions?.staticPath;\n });\n</script>\n\n<template>\n <!-- InlineSvg package (https://github.com/shrpne/vue-inline-svg) swaps external svgs and puts\n them inline so we can style them with CSS -->\n <!-- Having to override fill to be none and stroke to be zero so the exported svgs from Figma\n that do not have those attributes specified do not get a default one applied -->\n <InlineSvg\n :id=\"props.id\"\n class=\"tw-inline-block tw-align-middle\"\n :class=\"{\n [`tw-text-${props.fillColor}-400 tw-stroke-${props.strokeColor}`]: isSpotIllustration,\n }\"\n :title=\"props.title\"\n :height=\"props.size\"\n :width=\"props.size\"\n :stroke-width=\"strokeWidth\"\n fill=\"none\"\n :src=\"`${computedStaticPath}/illustrations/${props.type}/${props.name}.svg`\"\n />\n</template>\n"],"names":["SpotName","spotNames","VignetteName","vignetteNames","IllustrationType","props","__props","stashOptions","inject","isSpotIllustration","computed","strokeWidth","computedStaticPath"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"Image.vue_vue_type_script_setup_true_lang-D5u4av0_.js","sources":["../src/components/Image/Image.types.ts","../src/components/Image/providers/utils.ts","../src/components/Image/providers/cloudinary.ts","../src/components/Image/providers/static.ts","../src/components/Image/providers/index.ts","../src/components/Image/Image.vue"],"sourcesContent":["// Sizes used to generate resized and optimized versions of an image.\n// Generated in `srcset`, and informed by `sizes`.\nexport const Screens = {\n xs: 160,\n sm: 338,\n md: 676,\n lg: 1352,\n xl: 2704,\n} as const;\n\nexport interface ImageSizeCondition {\n mediaQuery: string;\n screenMinWidth: number;\n size: string;\n}\n\nexport enum ImageRadius {\n None = 'none',\n Rounded = 'rounded',\n Circle = 'circle',\n}\n\nexport type ImageRadii = `${ImageRadius}`;\n\nexport enum ImageProviders {\n Cloudinary = 'cloudinary',\n Static = 'static',\n}\n","export interface ImageModifiers {\n format?: string;\n height?: number;\n width?: number;\n [key: string]: any /* eslint-disable-line @typescript-eslint/no-explicit-any */;\n}\n\nexport type ParamFormatter = (key: string, value: string) => string;\n\nexport type ParamMapper = { [key: string]: string } | ((key: string) => string);\n\nexport interface ProviderUrlBuilder {\n keyMap?: ParamMapper;\n formatter?: ParamFormatter;\n joinWith?: string;\n valueMap?: {\n [key: string]: ParamMapper;\n };\n}\n\nfunction createMapper(map: ParamMapper) {\n return (key: string) => {\n return map[key] || key;\n };\n}\n\n/**\n * Builds the parameterized Cloudinary url\n */\nexport function buildProviderUrl({\n formatter = (key, value) => `${key}=${value}`,\n keyMap,\n joinWith = '/',\n valueMap = {},\n}: ProviderUrlBuilder = {}) {\n const keyMapper = typeof keyMap === 'function' ? keyMap : createMapper(keyMap || {});\n\n Object.keys(valueMap).forEach((valueKey) => {\n if (typeof valueMap[valueKey] !== 'function') {\n valueMap[valueKey] = createMapper(valueMap[valueKey]);\n }\n });\n\n return (modifiers: { [key: string]: string } = {}) => {\n const operations = Object.entries(modifiers).map(([key, value]) => {\n const mapper = valueMap[key];\n const newKey = keyMapper(key);\n let newVal = value;\n\n if (typeof mapper === 'function') {\n newVal = mapper(modifiers[key]);\n }\n\n return formatter(newKey, newVal);\n });\n\n return operations.join(joinWith);\n };\n}\n\n/**\n * Checks if a (sub)domain is included in a list of acceptable domains\n * @param str the (sub)domain to check\n * @param domains an array of valid domains\n */\nexport function isDomainValid(str = '', domains: string[] = []): boolean {\n const url = new URL(str);\n const host = url.host;\n\n return domains.some((domain) => {\n if (domain === host) {\n return true;\n }\n\n return domain.endsWith(`.${host}`);\n });\n}\n","import merge from 'lodash-es/merge';\n\nimport { IMAGE_PROVIDER_URLS } from '../../../constants';\nimport { buildProviderUrl, ImageModifiers } from './utils';\n\nconst BASE_URL = IMAGE_PROVIDER_URLS.CLOUDINARY;\n\nconst convertHextoRGBFormat = (value: string) => (value.startsWith('#') ? value.replace('#', 'rgb_') : value);\n\n/**\n * Parameters (option and value pairs) that can be used in the <transformations> segment of the Cloudinary transformation URL.\n * Options and their respective values are connected by an underscore (eg `w_250` for width of 250px.).\n * Multiple parameters are comma separated (eg. `w_250,h_250`).\n *\n * `keyMap` maps the option to its option prefix.\n * `valueMap` is used for grouping options using the same `keyMap` value under a 'category', allowing for easier usage and custom labelling in the component context.\n *\n * Transformation URL structure:\n * https://cloudinary.com/documentation/transformation_reference\n *\n * Transformation URL parameters (options and values):\n * https://cloudinary.com/documentation/image_transformations#transformation_url_syntax\n *\n */\nexport const operationsGenerator = buildProviderUrl({\n keyMap: {\n fit: 'c',\n width: 'w',\n height: 'h',\n format: 'f',\n quality: 'q',\n background: 'b',\n dpr: 'dpr',\n },\n valueMap: {\n fit: {\n fill: 'fill',\n inside: 'pad',\n outside: 'lpad',\n cover: 'fit',\n contain: 'scale',\n },\n format: {\n jpeg: 'jpg',\n },\n background(value: string) {\n return convertHextoRGBFormat(value);\n },\n },\n joinWith: ',',\n formatter: (key, value) => `${key}_${value}`,\n});\n\n// Note: Not configurable via Image props (for now).\nconst defaultModifiers = {\n format: 'auto',\n quality: 'auto:best',\n};\n\nexport function getImageUrl(src: string, modifiers: Partial<ImageModifiers> = {}): string {\n const mergeModifiers = merge(defaultModifiers, modifiers);\n const operations = operationsGenerator(mergeModifiers);\n\n return `${BASE_URL}/${operations}/${src}`;\n}\n","export function getImageUrl(src = ''): string {\n return src;\n}\n","import * as cloudinary from './cloudinary';\nimport * as staticProvider from './static';\n\nexport default {\n cloudinary,\n static: staticProvider,\n};\n","<script lang=\"ts\">\n export * from './Image.types';\n</script>\n\n<script setup lang=\"ts\">\n import { computed, inject, useAttrs } from 'vue';\n\n import { StashImageProviders, StashProvideState } from '../../../types/misc';\n import { SCREEN_SIZES } from '../../constants';\n import { ImageProviders, ImageRadii, ImageRadius, ImageSizeCondition, Screens } from './Image.types';\n import providers from './providers';\n import { ImageModifiers } from './providers/utils';\n\n export interface ImageProps {\n /**\n * The path to the image you want to embed.\n */\n src: string;\n\n /**\n * Native srcset attribute.\n * One or more strings separated by commas, indicating possible image sources\n * Can only be used with provider=static, otherwise it's ignored and auto-generated with `sizes` usage\n */\n srcset?: string;\n\n /**\n * For specifying responsive sizes\n */\n sizes?: string;\n\n /**\n * Where the image is served from.\n * If not provided, the provider will inherit from the Stash config `stashOptions.images.provider` (default: `static`).\n * - `static` for relative or absolute paths\n * - `cloudinary` for images served via Cloudinary\n */\n provider?: StashImageProviders;\n\n /**\n * For applying border radius\n */\n radius?: ImageRadii;\n\n /**\n * A custom static path the image src will be appended onto when provider=static.\n * Can be used to override the library-level default.\n */\n staticPath?: string;\n\n /**\n * TODO - https://leaflink.atlassian.net/browse/GRO-204\n * A custom function used to resolve a URL string for the image\n */\n // loader?: () => string;\n }\n\n defineOptions({\n inheritAttrs: false,\n });\n\n const BREAKPOINTS = {\n md: SCREEN_SIZES.md,\n lg: SCREEN_SIZES.lg,\n };\n const stashOptions = inject<StashProvideState>('stashOptions');\n const props = withDefaults(defineProps<ImageProps>(), {\n src: '',\n srcset: undefined,\n sizes: undefined,\n staticPath: undefined,\n provider: undefined,\n radius: 'none',\n // loader: undefined, // TODO - https://leaflink.atlassian.net/browse/GRO-204\n });\n\n const attrs = computed(() => {\n const { src, ...attrs } = useAttrs();\n\n attrs.sizes = imgSizes.value;\n attrs.srcset = imgSrcset.value;\n\n return attrs;\n });\n\n const isAbsoluteUrl = computed(() => {\n // return true if not an absolute url\n try {\n new URL(props.src);\n return true;\n } catch (e) {\n return false;\n }\n });\n\n const computedProvider = computed(() => props.provider || stashOptions?.images?.provider || ImageProviders.Static);\n\n const computedStaticPath = computed(() => props.staticPath ?? stashOptions?.staticPath);\n\n const isStatic = computed(() => computedProvider.value === ImageProviders.Static);\n\n const imgProvider = computed(() => providers[computedProvider.value]);\n\n const imgSrc = computed(() => (isStatic.value ? getProviderImage() : getProviderImage({ width: Screens.md })));\n\n const imgSizes = computed(() => (props.sizes ? getSizes() : props.sizes));\n\n const imgSrcset = computed(() => (props.sizes && !props.srcset && !isStatic.value ? getSources() : props.srcset));\n\n const parsedSizes = computed(() => {\n return props.sizes ? parseSizes(props.sizes) : [];\n });\n\n function getProviderImage(modifiers: ImageModifiers = {}) {\n if (isStatic.value && isAbsoluteUrl.value) {\n return props.src;\n }\n\n const src = isStatic.value && computedStaticPath.value ? `${computedStaticPath.value}/${props.src}` : props.src;\n\n return imgProvider.value.getImageUrl(src, modifiers);\n }\n\n function getSources() {\n return Object.values(Screens)\n .map((width) => {\n const src = getProviderImage({ width });\n\n return `${src} ${width}w`;\n })\n .join(', ');\n }\n\n function getSizes() {\n // return if using native media conditions\n if (props.sizes?.includes('(')) {\n return props.sizes;\n }\n\n return parsedSizes.value.map((v) => `${v.mediaQuery ? v.mediaQuery + ' ' : ''}${v.size}`).join(', ');\n }\n\n function parseSizes(providedSizes = '') {\n const conditions: ImageSizeCondition[] = [];\n const sizes = {\n default: '100vw',\n };\n\n // parse sizes and convert to object\n if (typeof providedSizes === 'string') {\n const definitions = providedSizes.split(/[\\s]+/).filter((size) => size);\n\n for (const entry of definitions) {\n const size = entry.split(':');\n\n if (size.length !== 2) {\n sizes['default'] = size[0].trim();\n continue;\n }\n\n sizes[size[0].trim()] = size[1].trim();\n }\n } else {\n throw new Error('`sizes` needs to be a string');\n }\n\n for (const key in sizes) {\n const screenMinWidth = parseInt(BREAKPOINTS[key] || 0);\n let size = String(sizes[key]);\n const isFluidSize = size.endsWith('vw');\n\n // convert integer to pixels\n if (!isFluidSize && /^\\d+$/.test(size)) {\n size = `${size}px`;\n }\n\n if (!isFluidSize && size.endsWith('%')) {\n throw new Error('Image: `sizes` does not support percentage values');\n }\n\n const condition = {\n mediaQuery: screenMinWidth ? `(min-width: ${screenMinWidth}px)` : '',\n screenMinWidth,\n size,\n };\n\n conditions.push(condition);\n }\n\n conditions.sort((v1, v2) => (v1.screenMinWidth > v2.screenMinWidth ? -1 : 1));\n\n return conditions;\n }\n</script>\n\n<template>\n <img\n ref=\"img\"\n :key=\"imgSrc\"\n data-test=\"stash-image\"\n class=\"stash-image\"\n :class=\"{\n 'tw-rounded': props.radius === ImageRadius.Rounded,\n 'tw-rounded-full': props.radius === ImageRadius.Circle,\n }\"\n :src=\"imgSrc\"\n v-bind=\"attrs\"\n />\n</template>\n"],"names":["Screens","ImageRadius","ImageProviders","createMapper","map","key","buildProviderUrl","formatter","value","keyMap","joinWith","valueMap","keyMapper","valueKey","modifiers","mapper","newKey","newVal","BASE_URL","IMAGE_PROVIDER_URLS","convertHextoRGBFormat","operationsGenerator","defaultModifiers","getImageUrl","src","mergeModifiers","merge","operations","providers","cloudinary","staticProvider","BREAKPOINTS","SCREEN_SIZES","stashOptions","inject","props","__props","attrs","computed","useAttrs","imgSizes","imgSrcset","isAbsoluteUrl","computedProvider","_a","computedStaticPath","isStatic","imgProvider","imgSrc","getProviderImage","getSizes","getSources","parsedSizes","parseSizes","width","v","providedSizes","conditions","sizes","definitions","size","entry","screenMinWidth","isFluidSize","condition","v1","v2"],"mappings":";;;AAEO,MAAMA,IAAU;AAAA,EACrB,IAAI;AAAA,EACJ,IAAI;AAAA,EACJ,IAAI;AAAA,EACJ,IAAI;AAAA,EACJ,IAAI;AACN;AAQY,IAAAC,sBAAAA,OACVA,EAAA,OAAO,QACPA,EAAA,UAAU,WACVA,EAAA,SAAS,UAHCA,IAAAA,KAAA,CAAA,CAAA,GAQAC,sBAAAA,OACVA,EAAA,aAAa,cACbA,EAAA,SAAS,UAFCA,IAAAA,KAAA,CAAA,CAAA;ACJZ,SAASC,EAAaC,GAAkB;AACtC,SAAO,CAACC,MACCD,EAAIC,CAAG,KAAKA;AAEvB;AAKO,SAASC,EAAiB;AAAA,EAC/B,WAAAC,IAAY,CAACF,GAAKG,MAAU,GAAGH,CAAG,IAAIG,CAAK;AAAA,EAC3C,QAAAC;AAAA,EACA,UAAAC,IAAW;AAAA,EACX,UAAAC,IAAW,CAAA;AACb,IAAwB,IAAI;AACpB,QAAAC,IAAY,OAAOH,KAAW,aAAaA,IAASN,EAAaM,KAAU,EAAE;AAEnF,gBAAO,KAAKE,CAAQ,EAAE,QAAQ,CAACE,MAAa;AAC1C,IAAI,OAAOF,EAASE,CAAQ,KAAM,eAChCF,EAASE,CAAQ,IAAIV,EAAaQ,EAASE,CAAQ,CAAC;AAAA,EACtD,CACD,GAEM,CAACC,IAAuC,OAC1B,OAAO,QAAQA,CAAS,EAAE,IAAI,CAAC,CAACT,GAAKG,CAAK,MAAM;AAC3D,UAAAO,IAASJ,EAASN,CAAG,GACrBW,IAASJ,EAAUP,CAAG;AAC5B,QAAIY,IAAST;AAET,WAAA,OAAOO,KAAW,eACXE,IAAAF,EAAOD,EAAUT,CAAG,CAAC,IAGzBE,EAAUS,GAAQC,CAAM;AAAA,EAAA,CAChC,EAEiB,KAAKP,CAAQ;AAEnC;ACrDA,MAAMQ,IAAWC,EAAoB,YAE/BC,IAAwB,CAACZ,MAAmBA,EAAM,WAAW,GAAG,IAAIA,EAAM,QAAQ,KAAK,MAAM,IAAIA,GAiB1Fa,IAAsBf,EAAiB;AAAA,EAClD,QAAQ;AAAA,IACN,KAAK;AAAA,IACL,OAAO;AAAA,IACP,QAAQ;AAAA,IACR,QAAQ;AAAA,IACR,SAAS;AAAA,IACT,YAAY;AAAA,IACZ,KAAK;AAAA,EACP;AAAA,EACA,UAAU;AAAA,IACR,KAAK;AAAA,MACH,MAAM;AAAA,MACN,QAAQ;AAAA,MACR,SAAS;AAAA,MACT,OAAO;AAAA,MACP,SAAS;AAAA,IACX;AAAA,IACA,QAAQ;AAAA,MACN,MAAM;AAAA,IACR;AAAA,IACA,WAAWE,GAAe;AACxB,aAAOY,EAAsBZ,CAAK;AAAA,IAAA;AAAA,EAEtC;AAAA,EACA,UAAU;AAAA,EACV,WAAW,CAACH,GAAKG,MAAU,GAAGH,CAAG,IAAIG,CAAK;AAC5C,CAAC,GAGKc,IAAmB;AAAA,EACvB,QAAQ;AAAA,EACR,SAAS;AACX;AAEO,SAASC,EAAYC,GAAaV,IAAqC,IAAY;AAClF,QAAAW,IAAiBC,EAAMJ,GAAkBR,CAAS,GAClDa,IAAaN,EAAoBI,CAAc;AAErD,SAAO,GAAGP,CAAQ,IAAIS,CAAU,IAAIH,CAAG;AACzC;;;;;;AChEgB,SAAAD,EAAYC,IAAM,IAAY;AACrC,SAAAA;AACT;;;;8CCCeI,IAAA;AAAA,EACb,YAAAC;AAAA,EACA,QAAQC;AACV;;;;;;;;;;;;ACuDE,UAAMC,IAAc;AAAA,MAClB,IAAIC,EAAa;AAAA,MACjB,IAAIA,EAAa;AAAA,IACnB,GACMC,IAAeC,EAA0B,cAAc,GACvDC,IAAQC,GAURC,IAAQC,EAAS,MAAM;AAC3B,YAAM,EAAE,KAAAd,GAAK,GAAGa,EAAAA,IAAUE,EAAS;AAEnCF,aAAAA,EAAM,QAAQG,EAAS,OACvBH,EAAM,SAASI,EAAU,OAElBJ;AAAAA,IAAA,CACR,GAEKK,IAAgBJ,EAAS,MAAM;AAE/B,UAAA;AACE,mBAAA,IAAIH,EAAM,GAAG,GACV;AAAA,cACG;AACH,eAAA;AAAA,MAAA;AAAA,IACT,CACD,GAEKQ,IAAmBL,EAAS,MAAA;;AAAM,aAAAH,EAAM,cAAYS,IAAAX,KAAA,gBAAAA,EAAc,WAAd,gBAAAW,EAAsB,aAAY1C,EAAe;AAAA,KAAM,GAE3G2C,IAAqBP,EAAS,MAAMH,EAAM,eAAcF,KAAA,gBAAAA,EAAc,WAAU,GAEhFa,IAAWR,EAAS,MAAMK,EAAiB,UAAUzC,EAAe,MAAM,GAE1E6C,IAAcT,EAAS,MAAMV,EAAUe,EAAiB,KAAK,CAAC,GAE9DK,IAASV,EAAS,MAAOQ,EAAS,QAAQG,MAAqBA,EAAiB,EAAE,OAAOjD,EAAQ,GAAI,CAAA,CAAE,GAEvGwC,IAAWF,EAAS,MAAOH,EAAM,QAAQe,EAAS,IAAIf,EAAM,KAAM,GAElEM,IAAYH,EAAS,MAAOH,EAAM,SAAS,CAACA,EAAM,UAAU,CAACW,EAAS,QAAQK,EAAW,IAAIhB,EAAM,MAAO,GAE1GiB,IAAcd,EAAS,MACpBH,EAAM,QAAQkB,EAAWlB,EAAM,KAAK,IAAI,CAAC,CACjD;AAEQ,aAAAc,EAAiBnC,IAA4B,IAAI;AACpD,UAAAgC,EAAS,SAASJ,EAAc;AAClC,eAAOP,EAAM;AAGf,YAAMX,IAAMsB,EAAS,SAASD,EAAmB,QAAQ,GAAGA,EAAmB,KAAK,IAAIV,EAAM,GAAG,KAAKA,EAAM;AAE5G,aAAOY,EAAY,MAAM,YAAYvB,GAAKV,CAAS;AAAA,IAAA;AAGrD,aAASqC,IAAa;AACpB,aAAO,OAAO,OAAOnD,CAAO,EACzB,IAAI,CAACsD,MAGG,GAFKL,EAAiB,EAAE,OAAAK,GAAO,CAEzB,IAAIA,CAAK,GACvB,EACA,KAAK,IAAI;AAAA,IAAA;AAGd,aAASJ,IAAW;;AAElB,cAAIN,IAAAT,EAAM,UAAN,QAAAS,EAAa,SAAS,OACjBT,EAAM,QAGRiB,EAAY,MAAM,IAAI,CAACG,MAAM,GAAGA,EAAE,aAAaA,EAAE,aAAa,MAAM,EAAE,GAAGA,EAAE,IAAI,EAAE,EAAE,KAAK,IAAI;AAAA,IAAA;AAG5F,aAAAF,EAAWG,IAAgB,IAAI;AACtC,YAAMC,IAAmC,CAAC,GACpCC,IAAQ;AAAA,QACZ,SAAS;AAAA,MACX;AAGI,UAAA,OAAOF,KAAkB,UAAU;AAC/B,cAAAG,IAAcH,EAAc,MAAM,OAAO,EAAE,OAAO,CAACI,MAASA,CAAI;AAEtE,mBAAWC,KAASF,GAAa;AACzB,gBAAAC,IAAOC,EAAM,MAAM,GAAG;AAExB,cAAAD,EAAK,WAAW,GAAG;AACrB,YAAAF,EAAM,UAAaE,EAAK,CAAC,EAAE,KAAK;AAChC;AAAA,UAAA;AAGI,UAAAF,EAAAE,EAAK,CAAC,EAAE,KAAM,CAAA,IAAIA,EAAK,CAAC,EAAE,KAAK;AAAA,QAAA;AAAA,MACvC;AAEM,cAAA,IAAI,MAAM,8BAA8B;AAGhD,iBAAWvD,KAAOqD,GAAO;AACvB,cAAMI,IAAiB,SAAS/B,EAAY1B,CAAG,KAAK,CAAC;AACrD,YAAIuD,IAAO,OAAOF,EAAMrD,CAAG,CAAC;AACtB,cAAA0D,IAAcH,EAAK,SAAS,IAAI;AAOtC,YAJI,CAACG,KAAe,QAAQ,KAAKH,CAAI,MACnCA,IAAO,GAAGA,CAAI,OAGZ,CAACG,KAAeH,EAAK,SAAS,GAAG;AAC7B,gBAAA,IAAI,MAAM,mDAAmD;AAGrE,cAAMI,IAAY;AAAA,UAChB,YAAYF,IAAiB,eAAeA,CAAc,QAAQ;AAAA,UAClE,gBAAAA;AAAA,UACA,MAAAF;AAAA,QACF;AAEA,QAAAH,EAAW,KAAKO,CAAS;AAAA,MAAA;AAGhB,aAAAP,EAAA,KAAK,CAACQ,GAAIC,MAAQD,EAAG,iBAAiBC,EAAG,iBAAiB,KAAK,CAAE,GAErET;AAAA,IAAA;;;;;;;;;;;;;"}
1
+ {"version":3,"file":"Image.vue_vue_type_script_setup_true_lang-D5u4av0_.js","sources":["../src/components/Image/Image.types.ts","../src/components/Image/providers/utils.ts","../src/components/Image/providers/cloudinary.ts","../src/components/Image/providers/static.ts","../src/components/Image/providers/index.ts","../src/components/Image/Image.vue"],"sourcesContent":["// Sizes used to generate resized and optimized versions of an image.\n// Generated in `srcset`, and informed by `sizes`.\nexport const Screens = {\n xs: 160,\n sm: 338,\n md: 676,\n lg: 1352,\n xl: 2704,\n} as const;\n\nexport interface ImageSizeCondition {\n mediaQuery: string;\n screenMinWidth: number;\n size: string;\n}\n\nexport enum ImageRadius {\n None = 'none',\n Rounded = 'rounded',\n Circle = 'circle',\n}\n\nexport type ImageRadii = `${ImageRadius}`;\n\nexport enum ImageProviders {\n Cloudinary = 'cloudinary',\n Static = 'static',\n}\n","export interface ImageModifiers {\n format?: string;\n height?: number;\n width?: number;\n [key: string]: any /* eslint-disable-line @typescript-eslint/no-explicit-any */;\n}\n\nexport type ParamFormatter = (key: string, value: string) => string;\n\nexport type ParamMapper = { [key: string]: string } | ((key: string) => string);\n\nexport interface ProviderUrlBuilder {\n keyMap?: ParamMapper;\n formatter?: ParamFormatter;\n joinWith?: string;\n valueMap?: {\n [key: string]: ParamMapper;\n };\n}\n\nfunction createMapper(map: ParamMapper) {\n return (key: string) => {\n return map[key] || key;\n };\n}\n\n/**\n * Builds the parameterized Cloudinary url\n */\nexport function buildProviderUrl({\n formatter = (key, value) => `${key}=${value}`,\n keyMap,\n joinWith = '/',\n valueMap = {},\n}: ProviderUrlBuilder = {}) {\n const keyMapper = typeof keyMap === 'function' ? keyMap : createMapper(keyMap || {});\n\n Object.keys(valueMap).forEach((valueKey) => {\n if (typeof valueMap[valueKey] !== 'function') {\n valueMap[valueKey] = createMapper(valueMap[valueKey]);\n }\n });\n\n return (modifiers: { [key: string]: string } = {}) => {\n const operations = Object.entries(modifiers).map(([key, value]) => {\n const mapper = valueMap[key];\n const newKey = keyMapper(key);\n let newVal = value;\n\n if (typeof mapper === 'function') {\n newVal = mapper(modifiers[key]);\n }\n\n return formatter(newKey, newVal);\n });\n\n return operations.join(joinWith);\n };\n}\n\n/**\n * Checks if a (sub)domain is included in a list of acceptable domains\n * @param str the (sub)domain to check\n * @param domains an array of valid domains\n */\nexport function isDomainValid(str = '', domains: string[] = []): boolean {\n const url = new URL(str);\n const host = url.host;\n\n return domains.some((domain) => {\n if (domain === host) {\n return true;\n }\n\n return domain.endsWith(`.${host}`);\n });\n}\n","import merge from 'lodash-es/merge';\n\nimport { IMAGE_PROVIDER_URLS } from '../../../constants';\nimport { buildProviderUrl, ImageModifiers } from './utils';\n\nconst BASE_URL = IMAGE_PROVIDER_URLS.CLOUDINARY;\n\nconst convertHextoRGBFormat = (value: string) => (value.startsWith('#') ? value.replace('#', 'rgb_') : value);\n\n/**\n * Parameters (option and value pairs) that can be used in the <transformations> segment of the Cloudinary transformation URL.\n * Options and their respective values are connected by an underscore (eg `w_250` for width of 250px.).\n * Multiple parameters are comma separated (eg. `w_250,h_250`).\n *\n * `keyMap` maps the option to its option prefix.\n * `valueMap` is used for grouping options using the same `keyMap` value under a 'category', allowing for easier usage and custom labelling in the component context.\n *\n * Transformation URL structure:\n * https://cloudinary.com/documentation/transformation_reference\n *\n * Transformation URL parameters (options and values):\n * https://cloudinary.com/documentation/image_transformations#transformation_url_syntax\n *\n */\nexport const operationsGenerator = buildProviderUrl({\n keyMap: {\n fit: 'c',\n width: 'w',\n height: 'h',\n format: 'f',\n quality: 'q',\n background: 'b',\n dpr: 'dpr',\n },\n valueMap: {\n fit: {\n fill: 'fill',\n inside: 'pad',\n outside: 'lpad',\n cover: 'fit',\n contain: 'scale',\n },\n format: {\n jpeg: 'jpg',\n },\n background(value: string) {\n return convertHextoRGBFormat(value);\n },\n },\n joinWith: ',',\n formatter: (key, value) => `${key}_${value}`,\n});\n\n// Note: Not configurable via Image props (for now).\nconst defaultModifiers = {\n format: 'auto',\n quality: 'auto:best',\n};\n\nexport function getImageUrl(src: string, modifiers: Partial<ImageModifiers> = {}): string {\n const mergeModifiers = merge(defaultModifiers, modifiers);\n const operations = operationsGenerator(mergeModifiers);\n\n return `${BASE_URL}/${operations}/${src}`;\n}\n","export function getImageUrl(src = ''): string {\n return src;\n}\n","import * as cloudinary from './cloudinary';\nimport * as staticProvider from './static';\n\nexport default {\n cloudinary,\n static: staticProvider,\n};\n","<script lang=\"ts\">\n export * from './Image.types';\n</script>\n\n<script setup lang=\"ts\">\n import { computed, inject, useAttrs } from 'vue';\n\n import { StashImageProviders, StashProvideState } from '../../../types/misc';\n import { SCREEN_SIZES } from '../../constants';\n import { ImageProviders, ImageRadii, ImageRadius, ImageSizeCondition, Screens } from './Image.types';\n import providers from './providers';\n import { ImageModifiers } from './providers/utils';\n\n export interface ImageProps {\n /**\n * The path to the image you want to embed.\n */\n src: string;\n\n /**\n * Native srcset attribute.\n * One or more strings separated by commas, indicating possible image sources\n * Can only be used with provider=static, otherwise it's ignored and auto-generated with `sizes` usage\n */\n srcset?: string;\n\n /**\n * For specifying responsive sizes\n */\n sizes?: string;\n\n /**\n * Where the image is served from.\n * If not provided, the provider will inherit from the Stash config `stashOptions.images.provider` (default: `static`).\n * - `static` for relative or absolute paths\n * - `cloudinary` for images served via Cloudinary\n */\n provider?: StashImageProviders;\n\n /**\n * For applying border radius\n */\n radius?: ImageRadii;\n\n /**\n * A custom static path the image src will be appended onto when provider=static.\n * Can be used to override the library-level default.\n */\n staticPath?: string;\n\n /**\n * TODO - https://leaflink.atlassian.net/browse/GRO-204\n * A custom function used to resolve a URL string for the image\n */\n // loader?: () => string;\n }\n\n defineOptions({\n inheritAttrs: false,\n });\n\n const BREAKPOINTS = {\n md: SCREEN_SIZES.md,\n lg: SCREEN_SIZES.lg,\n };\n const stashOptions = inject<StashProvideState>('stashOptions');\n const props = withDefaults(defineProps<ImageProps>(), {\n src: '',\n srcset: undefined,\n sizes: undefined,\n staticPath: undefined,\n provider: undefined,\n radius: 'none',\n // loader: undefined, // TODO - https://leaflink.atlassian.net/browse/GRO-204\n });\n\n const attrs = computed(() => {\n const { src, ...attrs } = useAttrs();\n\n attrs.sizes = imgSizes.value;\n attrs.srcset = imgSrcset.value;\n\n return attrs;\n });\n\n const isAbsoluteUrl = computed(() => {\n // return true if not an absolute url\n try {\n new URL(props.src);\n return true;\n } catch (e) {\n return false;\n }\n });\n\n const computedProvider = computed(() => props.provider || stashOptions?.images?.provider || ImageProviders.Static);\n\n const computedStaticPath = computed(() => props.staticPath ?? stashOptions?.staticPath);\n\n const isStatic = computed(() => computedProvider.value === ImageProviders.Static);\n\n const imgProvider = computed(() => providers[computedProvider.value]);\n\n const imgSrc = computed(() => (isStatic.value ? getProviderImage() : getProviderImage({ width: Screens.md })));\n\n const imgSizes = computed(() => (props.sizes ? getSizes() : props.sizes));\n\n const imgSrcset = computed(() => (props.sizes && !props.srcset && !isStatic.value ? getSources() : props.srcset));\n\n const parsedSizes = computed(() => {\n return props.sizes ? parseSizes(props.sizes) : [];\n });\n\n function getProviderImage(modifiers: ImageModifiers = {}) {\n if (isStatic.value && isAbsoluteUrl.value) {\n return props.src;\n }\n\n const src = isStatic.value && computedStaticPath.value ? `${computedStaticPath.value}/${props.src}` : props.src;\n\n return imgProvider.value.getImageUrl(src, modifiers);\n }\n\n function getSources() {\n return Object.values(Screens)\n .map((width) => {\n const src = getProviderImage({ width });\n\n return `${src} ${width}w`;\n })\n .join(', ');\n }\n\n function getSizes() {\n // return if using native media conditions\n if (props.sizes?.includes('(')) {\n return props.sizes;\n }\n\n return parsedSizes.value.map((v) => `${v.mediaQuery ? v.mediaQuery + ' ' : ''}${v.size}`).join(', ');\n }\n\n function parseSizes(providedSizes = '') {\n const conditions: ImageSizeCondition[] = [];\n const sizes = {\n default: '100vw',\n };\n\n // parse sizes and convert to object\n if (typeof providedSizes === 'string') {\n const definitions = providedSizes.split(/[\\s]+/).filter((size) => size);\n\n for (const entry of definitions) {\n const size = entry.split(':');\n\n if (size.length !== 2) {\n sizes['default'] = size[0].trim();\n continue;\n }\n\n sizes[size[0].trim()] = size[1].trim();\n }\n } else {\n throw new Error('`sizes` needs to be a string');\n }\n\n for (const key in sizes) {\n const screenMinWidth = parseInt(BREAKPOINTS[key] || 0);\n let size = String(sizes[key]);\n const isFluidSize = size.endsWith('vw');\n\n // convert integer to pixels\n if (!isFluidSize && /^\\d+$/.test(size)) {\n size = `${size}px`;\n }\n\n if (!isFluidSize && size.endsWith('%')) {\n throw new Error('Image: `sizes` does not support percentage values');\n }\n\n const condition = {\n mediaQuery: screenMinWidth ? `(min-width: ${screenMinWidth}px)` : '',\n screenMinWidth,\n size,\n };\n\n conditions.push(condition);\n }\n\n conditions.sort((v1, v2) => (v1.screenMinWidth > v2.screenMinWidth ? -1 : 1));\n\n return conditions;\n }\n</script>\n\n<template>\n <img\n ref=\"img\"\n :key=\"imgSrc\"\n data-test=\"stash-image\"\n class=\"stash-image\"\n :class=\"{\n 'tw-rounded': props.radius === ImageRadius.Rounded,\n 'tw-rounded-full': props.radius === ImageRadius.Circle,\n }\"\n :src=\"imgSrc\"\n v-bind=\"attrs\"\n />\n</template>\n"],"names":["Screens","ImageRadius","ImageProviders","createMapper","map","key","buildProviderUrl","formatter","value","keyMap","joinWith","valueMap","keyMapper","valueKey","modifiers","mapper","newKey","newVal","BASE_URL","IMAGE_PROVIDER_URLS","convertHextoRGBFormat","operationsGenerator","defaultModifiers","getImageUrl","src","mergeModifiers","merge","operations","providers","cloudinary","staticProvider","BREAKPOINTS","SCREEN_SIZES","stashOptions","inject","props","__props","attrs","computed","useAttrs","imgSizes","imgSrcset","isAbsoluteUrl","computedProvider","_a","computedStaticPath","isStatic","imgProvider","imgSrc","getProviderImage","getSizes","getSources","parsedSizes","parseSizes","width","v","providedSizes","conditions","sizes","definitions","size","entry","screenMinWidth","isFluidSize","condition","v1","v2"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"InlineEdit.js","sources":["../src/components/InlineEdit/InlineEdit.vue"],"sourcesContent":["<script setup lang=\"ts\">\n import { computed, ref, useAttrs, useSlots, watch } from 'vue';\n\n import { money, percent } from '../../utils/i18n';\n import Input from '../Input/Input.vue';\n\n defineOptions({\n name: 'll-inline-edit',\n inheritAttrs: false,\n });\n\n export interface InlineEditProps {\n /**\n * Formats the value displayed.\n * Options: currency, percent\n */\n format?: 'currency' | 'percent' | '';\n\n /**\n * DOM `type` property to be passed to `ll-input`.\n * Use type=\"number\" for localized numbers\n */\n type?: string;\n\n /**\n * The current value for the component.\n */\n modelValue?: string | number;\n\n /**\n * Used to display a crossed out value below the component\n * if the current `modelValue` does not match `oldValue`.\n */\n oldValue?: string | number;\n\n /**\n * Label to render for the input\n */\n label?: string;\n\n /**\n * Placeholder for the input\n */\n placeholder?: string;\n\n /**\n * Error text to display. Replaces `hintText` (if provided) & adds error styling.\n */\n errorText?: string;\n\n /**\n * Hint text to display below the input\n */\n hintText?: string;\n }\n\n const slots = useSlots();\n const attrs = useAttrs();\n\n const props = withDefaults(defineProps<InlineEditProps>(), {\n format: '',\n type: 'text',\n modelValue: undefined,\n oldValue: undefined,\n label: ' ',\n placeholder: '',\n errorText: '',\n hintText: '',\n });\n\n const emit = defineEmits<{\n /**\n * Emitted when the value is updated\n */\n (e: 'update:model-value', value: string | number | undefined): void;\n }>();\n\n const editing = ref(false);\n\n // this value gets set once and never changes\n const originalValue = ref<InlineEditProps['oldValue']>(props.oldValue || props.modelValue);\n\n // the _current_ value. This is a temporary value, used while editing\n const internalValue = ref<InlineEditProps['modelValue']>(props.modelValue);\n\n const inputAttrs = computed(() => {\n const tempAttrs = { ...attrs };\n\n delete tempAttrs.class;\n return tempAttrs;\n });\n\n const formattedOriginalValue = computed(() => formatValue(originalValue.value || ''));\n\n const showOldValue = computed(() => {\n return (props.oldValue || props.oldValue === 0) && props.oldValue !== internalValue.value;\n });\n\n const isAppended = computed(() => {\n return !!slots.append;\n });\n\n const isPrepended = computed(() => {\n return !!slots.prepend;\n });\n\n watch(\n () => props.modelValue,\n (newVal?: string | number, oldVal?: string | number) => {\n if (newVal !== oldVal) {\n internalValue.value = newVal;\n }\n },\n );\n\n function dismiss() {\n internalValue.value = props.modelValue || props.oldValue;\n editing.value = false;\n blurInput();\n }\n\n /**\n * Toggles edit state on\n */\n function edit() {\n editing.value = true;\n focusInput();\n }\n\n /**\n * Formats the value based on `format`\n */\n function formatValue(value: string | number) {\n switch (props.format) {\n case 'currency':\n return money({\n amount: value as number,\n });\n case 'percent':\n return percent((value as number) / 100);\n default:\n return value;\n }\n }\n\n /**\n * This method saves the current value of the input field by `$emit`ing.\n * If the new value is empty, it reverts `internalValue` to the original value.\n */\n function save() {\n internalValue.value = !(internalValue.value === '') ? internalValue.value : originalValue.value;\n\n emit('update:model-value', internalValue.value);\n editing.value = false;\n blurInput();\n }\n\n const llInput = ref();\n\n function focusInput() {\n if (llInput.value) {\n llInput.value.inputEl.focus();\n }\n }\n\n function blurInput() {\n if (llInput.value) {\n llInput.value.inputEl.blur();\n }\n }\n</script>\n\n<template>\n <div class=\"stash-inline-edit\" :class=\"attrs.class\" data-test=\"stash-inline-edit\">\n <div class=\"stash-inline-edit__input-wrapper\">\n <Input\n ref=\"llInput\"\n v-model=\"internalValue\"\n :error-text=\"props.errorText\"\n :hint-text=\"props.hintText\"\n :label=\"props.label\"\n :placeholder=\"`${props.placeholder || originalValue}`\"\n :type=\"props.type\"\n v-bind=\"inputAttrs\"\n @blur=\"save\"\n @focus=\"edit\"\n @keydown.esc=\"dismiss\"\n @keyup.enter=\"blurInput\"\n >\n <template v-if=\"isPrepended\" #prepend>\n <!-- @slot renders content on the left side of the input -->\n <slot name=\"prepend\"> </slot>\n </template>\n\n <template v-if=\"isAppended\" #append>\n <!-- @slot renders content on the right side of the input -->\n <slot name=\"append\"> </slot>\n </template>\n </Input>\n </div>\n\n <span v-if=\"showOldValue\" class=\"tw-mt-1 tw-inline-block tw-pl-3 tw-text-ice-700 tw-line-through\">\n {{ formattedOriginalValue }}\n </span>\n </div>\n</template>\n"],"names":["slots","useSlots","attrs","useAttrs","props","__props","emit","__emit","editing","ref","originalValue","internalValue","inputAttrs","computed","tempAttrs","formattedOriginalValue","formatValue","showOldValue","isAppended","isPrepended","watch","newVal","oldVal","dismiss","blurInput","edit","focusInput","value","money","percent","save","llInput"],"mappings":";;;;;;;;;;;;;;;;;;;;;;AAwDE,UAAMA,IAAQC,EAAS,GACjBC,IAAQC,EAAS,GAEjBC,IAAQC,GAWRC,IAAOC,GAOPC,IAAUC,EAAI,EAAK,GAGnBC,IAAgBD,EAAiCL,EAAM,YAAYA,EAAM,UAAU,GAGnFO,IAAgBF,EAAmCL,EAAM,UAAU,GAEnEQ,IAAaC,EAAS,MAAM;AAC1B,YAAAC,IAAY,EAAE,GAAGZ,EAAM;AAE7B,oBAAOY,EAAU,OACVA;AAAA,IAAA,CACR,GAEKC,IAAyBF,EAAS,MAAMG,EAAYN,EAAc,SAAS,EAAE,CAAC,GAE9EO,IAAeJ,EAAS,OACpBT,EAAM,YAAYA,EAAM,aAAa,MAAMA,EAAM,aAAaO,EAAc,KACrF,GAEKO,IAAaL,EAAS,MACnB,CAAC,CAACb,EAAM,MAChB,GAEKmB,IAAcN,EAAS,MACpB,CAAC,CAACb,EAAM,OAChB;AAED,IAAAoB;AAAA,MACE,MAAMhB,EAAM;AAAA,MACZ,CAACiB,GAA0BC,MAA6B;AACtD,QAAID,MAAWC,MACbX,EAAc,QAAQU;AAAA,MACxB;AAAA,IAEJ;AAEA,aAASE,IAAU;AACH,MAAAZ,EAAA,QAAQP,EAAM,cAAcA,EAAM,UAChDI,EAAQ,QAAQ,IACNgB,EAAA;AAAA,IAAA;AAMZ,aAASC,IAAO;AACd,MAAAjB,EAAQ,QAAQ,IACLkB,EAAA;AAAA,IAAA;AAMb,aAASV,EAAYW,GAAwB;AAC3C,cAAQvB,EAAM,QAAQ;AAAA,QACpB,KAAK;AACH,iBAAOwB,EAAM;AAAA,YACX,QAAQD;AAAA,UAAA,CACT;AAAA,QACH,KAAK;AACI,iBAAAE,EAASF,IAAmB,GAAG;AAAA,QACxC;AACS,iBAAAA;AAAA,MAAA;AAAA,IACX;AAOF,aAASG,IAAO;AACd,MAAAnB,EAAc,QAAUA,EAAc,UAAU,KAAMA,EAAc,QAAQD,EAAc,OAErFJ,EAAA,sBAAsBK,EAAc,KAAK,GAC9CH,EAAQ,QAAQ,IACNgB,EAAA;AAAA,IAAA;AAGZ,UAAMO,IAAUtB,EAAI;AAEpB,aAASiB,IAAa;AACpB,MAAIK,EAAQ,SACFA,EAAA,MAAM,QAAQ,MAAM;AAAA,IAC9B;AAGF,aAASP,IAAY;AACnB,MAAIO,EAAQ,SACFA,EAAA,MAAM,QAAQ,KAAK;AAAA,IAC7B;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
1
+ {"version":3,"file":"InlineEdit.js","sources":["../src/components/InlineEdit/InlineEdit.vue"],"sourcesContent":["<script setup lang=\"ts\">\n import { computed, ref, useAttrs, useSlots, watch } from 'vue';\n\n import { money, percent } from '../../utils/i18n';\n import Input from '../Input/Input.vue';\n\n defineOptions({\n name: 'll-inline-edit',\n inheritAttrs: false,\n });\n\n export interface InlineEditProps {\n /**\n * Formats the value displayed.\n * Options: currency, percent\n */\n format?: 'currency' | 'percent' | '';\n\n /**\n * DOM `type` property to be passed to `ll-input`.\n * Use type=\"number\" for localized numbers\n */\n type?: string;\n\n /**\n * The current value for the component.\n */\n modelValue?: string | number;\n\n /**\n * Used to display a crossed out value below the component\n * if the current `modelValue` does not match `oldValue`.\n */\n oldValue?: string | number;\n\n /**\n * Label to render for the input\n */\n label?: string;\n\n /**\n * Placeholder for the input\n */\n placeholder?: string;\n\n /**\n * Error text to display. Replaces `hintText` (if provided) & adds error styling.\n */\n errorText?: string;\n\n /**\n * Hint text to display below the input\n */\n hintText?: string;\n }\n\n const slots = useSlots();\n const attrs = useAttrs();\n\n const props = withDefaults(defineProps<InlineEditProps>(), {\n format: '',\n type: 'text',\n modelValue: undefined,\n oldValue: undefined,\n label: ' ',\n placeholder: '',\n errorText: '',\n hintText: '',\n });\n\n const emit = defineEmits<{\n /**\n * Emitted when the value is updated\n */\n (e: 'update:model-value', value: string | number | undefined): void;\n }>();\n\n const editing = ref(false);\n\n // this value gets set once and never changes\n const originalValue = ref<InlineEditProps['oldValue']>(props.oldValue || props.modelValue);\n\n // the _current_ value. This is a temporary value, used while editing\n const internalValue = ref<InlineEditProps['modelValue']>(props.modelValue);\n\n const inputAttrs = computed(() => {\n const tempAttrs = { ...attrs };\n\n delete tempAttrs.class;\n return tempAttrs;\n });\n\n const formattedOriginalValue = computed(() => formatValue(originalValue.value || ''));\n\n const showOldValue = computed(() => {\n return (props.oldValue || props.oldValue === 0) && props.oldValue !== internalValue.value;\n });\n\n const isAppended = computed(() => {\n return !!slots.append;\n });\n\n const isPrepended = computed(() => {\n return !!slots.prepend;\n });\n\n watch(\n () => props.modelValue,\n (newVal?: string | number, oldVal?: string | number) => {\n if (newVal !== oldVal) {\n internalValue.value = newVal;\n }\n },\n );\n\n function dismiss() {\n internalValue.value = props.modelValue || props.oldValue;\n editing.value = false;\n blurInput();\n }\n\n /**\n * Toggles edit state on\n */\n function edit() {\n editing.value = true;\n focusInput();\n }\n\n /**\n * Formats the value based on `format`\n */\n function formatValue(value: string | number) {\n switch (props.format) {\n case 'currency':\n return money({\n amount: value as number,\n });\n case 'percent':\n return percent((value as number) / 100);\n default:\n return value;\n }\n }\n\n /**\n * This method saves the current value of the input field by `$emit`ing.\n * If the new value is empty, it reverts `internalValue` to the original value.\n */\n function save() {\n internalValue.value = !(internalValue.value === '') ? internalValue.value : originalValue.value;\n\n emit('update:model-value', internalValue.value);\n editing.value = false;\n blurInput();\n }\n\n const llInput = ref();\n\n function focusInput() {\n if (llInput.value) {\n llInput.value.inputEl.focus();\n }\n }\n\n function blurInput() {\n if (llInput.value) {\n llInput.value.inputEl.blur();\n }\n }\n</script>\n\n<template>\n <div class=\"stash-inline-edit\" :class=\"attrs.class\" data-test=\"stash-inline-edit\">\n <div class=\"stash-inline-edit__input-wrapper\">\n <Input\n ref=\"llInput\"\n v-model=\"internalValue\"\n :error-text=\"props.errorText\"\n :hint-text=\"props.hintText\"\n :label=\"props.label\"\n :placeholder=\"`${props.placeholder || originalValue}`\"\n :type=\"props.type\"\n v-bind=\"inputAttrs\"\n @blur=\"save\"\n @focus=\"edit\"\n @keydown.esc=\"dismiss\"\n @keyup.enter=\"blurInput\"\n >\n <template v-if=\"isPrepended\" #prepend>\n <!-- @slot renders content on the left side of the input -->\n <slot name=\"prepend\"> </slot>\n </template>\n\n <template v-if=\"isAppended\" #append>\n <!-- @slot renders content on the right side of the input -->\n <slot name=\"append\"> </slot>\n </template>\n </Input>\n </div>\n\n <span v-if=\"showOldValue\" class=\"tw-mt-1 tw-inline-block tw-pl-3 tw-text-ice-700 tw-line-through\">\n {{ formattedOriginalValue }}\n </span>\n </div>\n</template>\n"],"names":["slots","useSlots","attrs","useAttrs","props","__props","emit","__emit","editing","ref","originalValue","internalValue","inputAttrs","computed","tempAttrs","formattedOriginalValue","formatValue","showOldValue","isAppended","isPrepended","watch","newVal","oldVal","dismiss","blurInput","edit","focusInput","value","money","percent","save","llInput"],"mappings":";;;;;;;;;;;;;;;;;;;;;;AAwDE,UAAMA,IAAQC,EAAA,GACRC,IAAQC,EAAA,GAERC,IAAQC,GAWRC,IAAOC,GAOPC,IAAUC,EAAI,EAAK,GAGnBC,IAAgBD,EAAiCL,EAAM,YAAYA,EAAM,UAAU,GAGnFO,IAAgBF,EAAmCL,EAAM,UAAU,GAEnEQ,IAAaC,EAAS,MAAM;AAChC,YAAMC,IAAY,EAAE,GAAGZ,EAAA;AAEvB,oBAAOY,EAAU,OACVA;AAAA,IACT,CAAC,GAEKC,IAAyBF,EAAS,MAAMG,EAAYN,EAAc,SAAS,EAAE,CAAC,GAE9EO,IAAeJ,EAAS,OACpBT,EAAM,YAAYA,EAAM,aAAa,MAAMA,EAAM,aAAaO,EAAc,KACrF,GAEKO,IAAaL,EAAS,MACnB,CAAC,CAACb,EAAM,MAChB,GAEKmB,IAAcN,EAAS,MACpB,CAAC,CAACb,EAAM,OAChB;AAED,IAAAoB;AAAA,MACE,MAAMhB,EAAM;AAAA,MACZ,CAACiB,GAA0BC,MAA6B;AACtD,QAAID,MAAWC,MACbX,EAAc,QAAQU;AAAA,MAE1B;AAAA,IAAA;AAGF,aAASE,IAAU;AACjB,MAAAZ,EAAc,QAAQP,EAAM,cAAcA,EAAM,UAChDI,EAAQ,QAAQ,IAChBgB,EAAA;AAAA,IACF;AAKA,aAASC,IAAO;AACd,MAAAjB,EAAQ,QAAQ,IAChBkB,EAAA;AAAA,IACF;AAKA,aAASV,EAAYW,GAAwB;AAC3C,cAAQvB,EAAM,QAAA;AAAA,QACZ,KAAK;AACH,iBAAOwB,EAAM;AAAA,YACX,QAAQD;AAAA,UAAA,CACT;AAAA,QACH,KAAK;AACH,iBAAOE,EAASF,IAAmB,GAAG;AAAA,QACxC;AACE,iBAAOA;AAAA,MAAA;AAAA,IAEb;AAMA,aAASG,IAAO;AACd,MAAAnB,EAAc,QAAUA,EAAc,UAAU,KAAMA,EAAc,QAAQD,EAAc,OAE1FJ,EAAK,sBAAsBK,EAAc,KAAK,GAC9CH,EAAQ,QAAQ,IAChBgB,EAAA;AAAA,IACF;AAEA,UAAMO,IAAUtB,EAAA;AAEhB,aAASiB,IAAa;AACpB,MAAIK,EAAQ,SACVA,EAAQ,MAAM,QAAQ,MAAA;AAAA,IAE1B;AAEA,aAASP,IAAY;AACnB,MAAIO,EAAQ,SACVA,EAAQ,MAAM,QAAQ,KAAA;AAAA,IAE1B;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
package/dist/Input.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"Input.js","sources":["../src/components/Input/Input.vue"],"sourcesContent":["<script lang=\"ts\" setup>\n import isNil from 'lodash-es/isNil';\n import { computed, onMounted, ref, useAttrs, useCssModule, useSlots, watchEffect } from 'vue';\n\n import { convertDecimal, decimalSeparator, sanitizeDecimal } from '../../utils/i18n';\n import { FieldProps } from '../Field/Field.types';\n import Field from '../Field/Field.vue';\n import Icon from '../Icon/Icon.vue';\n\n export interface InputProps extends FieldProps {\n /**\n * Autocomplete takes in a string of off or on\n */\n autocomplete?: string;\n\n /**\n * Value for the input element.\n */\n modelValue?: string | number;\n\n /**\n * @deprecated Use :model-value or v-model instead of :value.\n */\n value?: string | number | null;\n\n /**\n * Input type. Excludes certain types that have a dedicated component.\n *\n * Note: For distinguishing between text & number internally, passing `number`\n * will still render an input with a type of `text` (for localization).\n */\n type?: string extends 'button' | 'checkbox' | 'radio' | 'submit' ? never : string;\n\n /**\n * Placeholder text for the input.\n * **Note:** placeholders should be used to display examples; they should not be used as labels because they are not accessible as labels. If a real label cannot be used, use the `aria-label` attribute.\n */\n placeholder?: string;\n }\n\n defineOptions({\n name: 'll-input',\n inheritAttrs: false,\n });\n\n const props = withDefaults(defineProps<InputProps>(), {\n autocomplete: 'off',\n type: 'text',\n modelValue: '',\n value: null,\n placeholder: undefined,\n });\n\n const emit = defineEmits<{\n /**\n * Emitted when the input value changes.\n */\n (e: 'update:model-value', v: string | number): void;\n /**\n * Emitted when the input value changes.\n */\n (e: 'change', v: string | number): void;\n /**\n * Emitted when the input is focused\n */\n (e: 'focus', evt: Event): void;\n /**\n * Emitted when the input is blurred\n */\n (e: 'blur', evt: Event): void;\n }>();\n\n const slots = useSlots();\n const classes = useCssModule();\n const attrs = useAttrs();\n\n // declare a ref to hold the element reference\n // the name must match template ref value\n const inputEl = ref<HTMLInputElement>();\n\n // this exposes the input ref to any parent that renders the `Input` component\n // and gives it a template ref, giving parent components access to the DOM element.\n defineExpose({ inputEl });\n\n const internalValue = ref<string | number>(props.modelValue);\n\n if (props.type === 'number' && (props.modelValue || props.modelValue === 0)) {\n internalValue.value = convertDecimal(props.modelValue, decimalSeparator);\n }\n\n const showPassword = ref(false);\n\n const isReadOnly = computed(() => props.isReadOnly || ('readonly' in attrs && attrs.readonly !== false));\n const isNumber = computed(() => props.type === 'number');\n\n const inputAttrs = computed(() => {\n const tempAttrs = { ...attrs };\n\n delete tempAttrs.class;\n\n return tempAttrs;\n });\n\n const inputType = computed(() => {\n // type 'number' is a special use case and requires\n // that the type be 'text' to support internationalization\n if (isNumber.value) {\n return 'text';\n }\n\n if (props.type === 'password' && showPassword.value) {\n return 'text';\n }\n\n return props.type;\n });\n\n watchEffect(() => {\n internalValue.value = format(props.modelValue);\n });\n\n /**\n * Converts the localized number to a valid number (to emit). i.e. 12,50 > 12.50\n *\n * @param {string|number} value - Number you want to parse.\n * @returns {number|string} number or empty string (for empty input)\n */\n function parseNumber(value: string | number = '', isUserTyping = false): string | number {\n // If this isn't a number input, we shouldn't be calling this function\n if (!isNumber.value) {\n return value;\n }\n\n let tempValue = value;\n\n // If blank, just stop\n if (isNil(tempValue) || `${tempValue}`.length === 0) return '';\n\n // clean out different locale decimals\n if (decimalSeparator !== '.') {\n tempValue = convertDecimal(tempValue, '.');\n }\n\n // If the user is in the middle of an input, let them finish the number\n if (isUserTyping) {\n // Prefix values with a 0 if the user starts with a decimal point\n if (tempValue === '.') tempValue = '0.';\n\n // This is to prevent the parsing from correcting 0. to 0 and causing the value to be reset\n if (tempValue.toString().startsWith('0.')) return tempValue;\n }\n\n // Empty or null values convert to 0 with NumberFormat, so return '';\n if (!isNil(tempValue) && `${tempValue}`.length) {\n tempValue = Intl.NumberFormat('en-US', {\n style: 'decimal',\n maximumFractionDigits: 7,\n useGrouping: false,\n }).format(Number(tempValue));\n } else {\n return '';\n }\n\n // Ensure valid number, otherwise clear value\n return isNaN(Number(tempValue)) ? '' : parseFloat(tempValue);\n }\n\n /**\n * Formats the input based on conditions\n *\n * @param {number|string} value - The value to format.\n */\n function format(value: string | number) {\n if (isNumber.value) {\n return sanitizeDecimal(value, decimalSeparator);\n }\n\n return value;\n }\n\n /**\n * Fire after focusing out of input, if value has changed.\n */\n function handleChange() {\n // Parse the final value on blur\n const parsedValue = isNumber.value ? parseNumber(internalValue.value) : internalValue.value;\n emit('change', parsedValue);\n }\n\n /**\n * Fired when typing on input.\n */\n function handleInput(e: Event) {\n const value = (e.target as HTMLInputElement).value;\n\n // Update the internal value with a sanitized version\n internalValue.value = format(value);\n\n const parsedValue = isNumber.value ? parseNumber(internalValue.value, true) : value;\n\n emit('update:model-value', parsedValue);\n }\n\n onMounted(() => {\n if (props.value !== null) {\n throw new Error('ll-input: use :model-value or v-model instead of :value.');\n }\n\n if (attrs.onInput) {\n throw new Error('ll-input: use the @update:model-value event instead of @input');\n }\n });\n</script>\n\n<template>\n <Field v-bind=\"props\" class=\"stash-input\" :class=\"[classes.root, attrs.class]\" data-test=\"ll-input\">\n <template #default=\"{ fieldId, fieldErrorId, hasError }\">\n <div class=\"tw-relative\">\n <input\n v-bind=\"inputAttrs\"\n :id=\"fieldId\"\n ref=\"inputEl\"\n v-model=\"internalValue\"\n :aria-errormessage=\"fieldErrorId\"\n :aria-invalid=\"hasError\"\n :autocomplete=\"autocomplete\"\n :placeholder=\"props.placeholder\"\n :class=\"[\n { [classes['input-prepended']]: !!slots.prepend },\n { [classes['input-appended']]: !!slots.append || props.type === 'password' },\n { [classes['has-error']]: !!props.errorText },\n ]\"\n :type=\"inputType\"\n :disabled=\"props.isDisabled || props.disabled\"\n :readonly=\"isReadOnly\"\n @change=\"handleChange\"\n @input=\"handleInput\"\n @blur=\"(evt) => emit('blur', evt)\"\n @focus=\"(evt) => emit('focus', evt)\"\n />\n\n <div\n v-if=\"slots.prepend\"\n class=\"stash-input-prepend font-semibold\"\n :class=\"[classes.symbol, classes['symbol--prepend']]\"\n >\n <!-- @slot renders content on the left side of the input -->\n <slot name=\"prepend\"> </slot>\n </div>\n\n <div\n v-if=\"slots.append || props.type === 'password'\"\n class=\"stash-input-append font-semibold\"\n :class=\"[classes.symbol, classes['symbol--append']]\"\n >\n <!-- @slot renders content on the right side of the input -->\n <slot v-if=\"slots.append\" name=\"append\"></slot>\n <Icon\n v-else\n :name=\"showPassword ? 'hide' : 'show'\"\n class=\"tw-cursor-pointer\"\n :class=\"{ 'tw-text-ice-500': props.isDisabled || props.disabled }\"\n :data-test=\"showPassword ? 'hide-password-icon' : 'show-password-icon'\"\n @click=\"showPassword = !showPassword\"\n />\n </div>\n </div>\n </template>\n <template v-if=\"slots.hint\" #hint>\n <slot name=\"hint\"></slot>\n </template>\n </Field>\n</template>\n\n<style module>\n .root {\n position: relative;\n }\n\n .root input {\n background: var(--color-white);\n border: 1px solid var(--color-ice-500);\n border-radius: theme('borderRadius.DEFAULT');\n color: var(--color-ice-700);\n display: block;\n height: theme('height.input');\n font-size: theme('fontSize.sm');\n font-weight: theme('fontWeight.normal');\n outline: none;\n padding: 0 theme('spacing.3');\n width: 100%;\n }\n\n .root input:hover {\n border-color: var(--color-ice-500);\n }\n\n .root input:active,\n .root input:focus {\n border-color: var(--color-blue-500);\n }\n\n .root input::placeholder {\n color: var(--color-ice-500);\n opacity: 1;\n }\n\n .root input.has-error:not(:focus) {\n border-color: var(--color-red-500);\n }\n\n .root input.input-prepended {\n padding-left: 36px;\n }\n\n .root input.input-appended {\n padding-right: 36px;\n }\n\n .symbol {\n align-items: center;\n display: flex;\n height: theme('height.input');\n justify-content: center;\n overflow: hidden;\n position: absolute;\n top: 0;\n width: theme('height.input');\n }\n\n .symbol--prepend {\n border-bottom-left-radius: theme('borderRadius.DEFAULT');\n border-top-left-radius: theme('borderRadius.DEFAULT');\n left: 0;\n }\n\n .symbol--append {\n border-bottom-right-radius: theme('borderRadius.DEFAULT');\n border-top-right-radius: theme('borderRadius.DEFAULT');\n right: 0;\n }\n\n .root input[disabled] {\n background-color: var(--color-ice-100) !important;\n border-color: var(--color-ice-500) !important;\n color: var(--color-ice-500) !important;\n pointer-events: none;\n outline-color: var(--color-ice-500) !important;\n\n & + .symbol--prepend,\n & + .symbol--append {\n color: var(--color-ice-500);\n }\n }\n\n .root input[readonly] {\n border-color: transparent;\n background-color: transparent;\n padding-left: 0;\n padding-right: 0;\n }\n\n .root input[disabled]:active,\n .root input[readonly]:active,\n .root input[disabled]:focus,\n .root input[readonly]:focus {\n box-shadow: none !important;\n }\n\n .root input[disabled]::placeholder {\n text-transform: none;\n }\n</style>\n"],"names":["props","__props","emit","__emit","slots","useSlots","classes","useCssModule","attrs","useAttrs","inputEl","ref","__expose","internalValue","convertDecimal","decimalSeparator","showPassword","isReadOnly","computed","isNumber","inputAttrs","tempAttrs","inputType","watchEffect","format","parseNumber","value","isUserTyping","tempValue","isNil","sanitizeDecimal","handleChange","parsedValue","handleInput","e","onMounted"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA6CE,UAAMA,IAAQC,GAQRC,IAAOC,GAmBPC,IAAQC,EAAS,GACjBC,IAAUC,EAAa,GACvBC,IAAQC,EAAS,GAIjBC,IAAUC,EAAsB;AAIzB,IAAAC,EAAA,EAAE,SAAAF,GAAS;AAElB,UAAAG,IAAgBF,EAAqBX,EAAM,UAAU;AAE3D,IAAIA,EAAM,SAAS,aAAaA,EAAM,cAAcA,EAAM,eAAe,OACvEa,EAAc,QAAQC,EAAed,EAAM,YAAYe,CAAgB;AAGnE,UAAAC,IAAeL,EAAI,EAAK,GAExBM,IAAaC,EAAS,MAAMlB,EAAM,cAAe,cAAcQ,KAASA,EAAM,aAAa,EAAM,GACjGW,IAAWD,EAAS,MAAMlB,EAAM,SAAS,QAAQ,GAEjDoB,IAAaF,EAAS,MAAM;AAC1B,YAAAG,IAAY,EAAE,GAAGb,EAAM;AAE7B,oBAAOa,EAAU,OAEVA;AAAA,IAAA,CACR,GAEKC,IAAYJ,EAAS,MAGrBC,EAAS,SAITnB,EAAM,SAAS,cAAcgB,EAAa,QACrC,SAGFhB,EAAM,IACd;AAED,IAAAuB,EAAY,MAAM;AACF,MAAAV,EAAA,QAAQW,EAAOxB,EAAM,UAAU;AAAA,IAAA,CAC9C;AAQD,aAASyB,EAAYC,IAAyB,IAAIC,IAAe,IAAwB;AAEnF,UAAA,CAACR,EAAS;AACL,eAAAO;AAGT,UAAIE,IAAYF;AAGZ,UAAAG,EAAMD,CAAS,KAAK,GAAGA,CAAS,GAAG,WAAW,EAAU,QAAA;AAQ5D,UALIb,MAAqB,QACXa,IAAAd,EAAec,GAAW,GAAG,IAIvCD,MAEEC,MAAc,QAAiBA,IAAA,OAG/BA,EAAU,SAAS,EAAE,WAAW,IAAI;AAAU,eAAAA;AAIpD,UAAI,CAACC,EAAMD,CAAS,KAAK,GAAGA,CAAS,GAAG;AAC1B,QAAAA,IAAA,KAAK,aAAa,SAAS;AAAA,UACrC,OAAO;AAAA,UACP,uBAAuB;AAAA,UACvB,aAAa;AAAA,QACd,CAAA,EAAE,OAAO,OAAOA,CAAS,CAAC;AAAA;AAEpB,eAAA;AAIT,aAAO,MAAM,OAAOA,CAAS,CAAC,IAAI,KAAK,WAAWA,CAAS;AAAA,IAAA;AAQ7D,aAASJ,EAAOE,GAAwB;AACtC,aAAIP,EAAS,QACJW,EAAgBJ,GAAOX,CAAgB,IAGzCW;AAAA,IAAA;AAMT,aAASK,IAAe;AAEtB,YAAMC,IAAcb,EAAS,QAAQM,EAAYZ,EAAc,KAAK,IAAIA,EAAc;AACtF,MAAAX,EAAK,UAAU8B,CAAW;AAAA,IAAA;AAM5B,aAASC,EAAYC,GAAU;AACvB,YAAAR,IAASQ,EAAE,OAA4B;AAG/B,MAAArB,EAAA,QAAQW,EAAOE,CAAK;AAElC,YAAMM,IAAcb,EAAS,QAAQM,EAAYZ,EAAc,OAAO,EAAI,IAAIa;AAE9E,MAAAxB,EAAK,sBAAsB8B,CAAW;AAAA,IAAA;AAGxC,WAAAG,EAAU,MAAM;AACV,UAAAnC,EAAM,UAAU;AACZ,cAAA,IAAI,MAAM,0DAA0D;AAG5E,UAAIQ,EAAM;AACF,cAAA,IAAI,MAAM,+DAA+D;AAAA,IACjF,CACD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
1
+ {"version":3,"file":"Input.js","sources":["../src/components/Input/Input.vue"],"sourcesContent":["<script lang=\"ts\" setup>\n import isNil from 'lodash-es/isNil';\n import { computed, onMounted, ref, useAttrs, useCssModule, useSlots, watchEffect } from 'vue';\n\n import { convertDecimal, decimalSeparator, sanitizeDecimal } from '../../utils/i18n';\n import { FieldProps } from '../Field/Field.types';\n import Field from '../Field/Field.vue';\n import Icon from '../Icon/Icon.vue';\n\n export interface InputProps extends FieldProps {\n /**\n * Autocomplete takes in a string of off or on\n */\n autocomplete?: string;\n\n /**\n * Value for the input element.\n */\n modelValue?: string | number;\n\n /**\n * @deprecated Use :model-value or v-model instead of :value.\n */\n value?: string | number | null;\n\n /**\n * Input type. Excludes certain types that have a dedicated component.\n *\n * Note: For distinguishing between text & number internally, passing `number`\n * will still render an input with a type of `text` (for localization).\n */\n type?: string extends 'button' | 'checkbox' | 'radio' | 'submit' ? never : string;\n\n /**\n * Placeholder text for the input.\n * **Note:** placeholders should be used to display examples; they should not be used as labels because they are not accessible as labels. If a real label cannot be used, use the `aria-label` attribute.\n */\n placeholder?: string;\n }\n\n defineOptions({\n name: 'll-input',\n inheritAttrs: false,\n });\n\n const props = withDefaults(defineProps<InputProps>(), {\n autocomplete: 'off',\n type: 'text',\n modelValue: '',\n value: null,\n placeholder: undefined,\n });\n\n const emit = defineEmits<{\n /**\n * Emitted when the input value changes.\n */\n (e: 'update:model-value', v: string | number): void;\n /**\n * Emitted when the input value changes.\n */\n (e: 'change', v: string | number): void;\n /**\n * Emitted when the input is focused\n */\n (e: 'focus', evt: Event): void;\n /**\n * Emitted when the input is blurred\n */\n (e: 'blur', evt: Event): void;\n }>();\n\n const slots = useSlots();\n const classes = useCssModule();\n const attrs = useAttrs();\n\n // declare a ref to hold the element reference\n // the name must match template ref value\n const inputEl = ref<HTMLInputElement>();\n\n // this exposes the input ref to any parent that renders the `Input` component\n // and gives it a template ref, giving parent components access to the DOM element.\n defineExpose({ inputEl });\n\n const internalValue = ref<string | number>(props.modelValue);\n\n if (props.type === 'number' && (props.modelValue || props.modelValue === 0)) {\n internalValue.value = convertDecimal(props.modelValue, decimalSeparator);\n }\n\n const showPassword = ref(false);\n\n const isReadOnly = computed(() => props.isReadOnly || ('readonly' in attrs && attrs.readonly !== false));\n const isNumber = computed(() => props.type === 'number');\n\n const inputAttrs = computed(() => {\n const tempAttrs = { ...attrs };\n\n delete tempAttrs.class;\n\n return tempAttrs;\n });\n\n const inputType = computed(() => {\n // type 'number' is a special use case and requires\n // that the type be 'text' to support internationalization\n if (isNumber.value) {\n return 'text';\n }\n\n if (props.type === 'password' && showPassword.value) {\n return 'text';\n }\n\n return props.type;\n });\n\n watchEffect(() => {\n internalValue.value = format(props.modelValue);\n });\n\n /**\n * Converts the localized number to a valid number (to emit). i.e. 12,50 > 12.50\n *\n * @param {string|number} value - Number you want to parse.\n * @returns {number|string} number or empty string (for empty input)\n */\n function parseNumber(value: string | number = '', isUserTyping = false): string | number {\n // If this isn't a number input, we shouldn't be calling this function\n if (!isNumber.value) {\n return value;\n }\n\n let tempValue = value;\n\n // If blank, just stop\n if (isNil(tempValue) || `${tempValue}`.length === 0) return '';\n\n // clean out different locale decimals\n if (decimalSeparator !== '.') {\n tempValue = convertDecimal(tempValue, '.');\n }\n\n // If the user is in the middle of an input, let them finish the number\n if (isUserTyping) {\n // Prefix values with a 0 if the user starts with a decimal point\n if (tempValue === '.') tempValue = '0.';\n\n // This is to prevent the parsing from correcting 0. to 0 and causing the value to be reset\n if (tempValue.toString().startsWith('0.')) return tempValue;\n }\n\n // Empty or null values convert to 0 with NumberFormat, so return '';\n if (!isNil(tempValue) && `${tempValue}`.length) {\n tempValue = Intl.NumberFormat('en-US', {\n style: 'decimal',\n maximumFractionDigits: 7,\n useGrouping: false,\n }).format(Number(tempValue));\n } else {\n return '';\n }\n\n // Ensure valid number, otherwise clear value\n return isNaN(Number(tempValue)) ? '' : parseFloat(tempValue);\n }\n\n /**\n * Formats the input based on conditions\n *\n * @param {number|string} value - The value to format.\n */\n function format(value: string | number) {\n if (isNumber.value) {\n return sanitizeDecimal(value, decimalSeparator);\n }\n\n return value;\n }\n\n /**\n * Fire after focusing out of input, if value has changed.\n */\n function handleChange() {\n // Parse the final value on blur\n const parsedValue = isNumber.value ? parseNumber(internalValue.value) : internalValue.value;\n emit('change', parsedValue);\n }\n\n /**\n * Fired when typing on input.\n */\n function handleInput(e: Event) {\n const value = (e.target as HTMLInputElement).value;\n\n // Update the internal value with a sanitized version\n internalValue.value = format(value);\n\n const parsedValue = isNumber.value ? parseNumber(internalValue.value, true) : value;\n\n emit('update:model-value', parsedValue);\n }\n\n onMounted(() => {\n if (props.value !== null) {\n throw new Error('ll-input: use :model-value or v-model instead of :value.');\n }\n\n if (attrs.onInput) {\n throw new Error('ll-input: use the @update:model-value event instead of @input');\n }\n });\n</script>\n\n<template>\n <Field v-bind=\"props\" class=\"stash-input\" :class=\"[classes.root, attrs.class]\" data-test=\"ll-input\">\n <template #default=\"{ fieldId, fieldErrorId, hasError }\">\n <div class=\"tw-relative\">\n <input\n v-bind=\"inputAttrs\"\n :id=\"fieldId\"\n ref=\"inputEl\"\n v-model=\"internalValue\"\n :aria-errormessage=\"fieldErrorId\"\n :aria-invalid=\"hasError\"\n :autocomplete=\"autocomplete\"\n :placeholder=\"props.placeholder\"\n :class=\"[\n { [classes['input-prepended']]: !!slots.prepend },\n { [classes['input-appended']]: !!slots.append || props.type === 'password' },\n { [classes['has-error']]: !!props.errorText },\n ]\"\n :type=\"inputType\"\n :disabled=\"props.isDisabled || props.disabled\"\n :readonly=\"isReadOnly\"\n @change=\"handleChange\"\n @input=\"handleInput\"\n @blur=\"(evt) => emit('blur', evt)\"\n @focus=\"(evt) => emit('focus', evt)\"\n />\n\n <div\n v-if=\"slots.prepend\"\n class=\"stash-input-prepend font-semibold\"\n :class=\"[classes.symbol, classes['symbol--prepend']]\"\n >\n <!-- @slot renders content on the left side of the input -->\n <slot name=\"prepend\"> </slot>\n </div>\n\n <div\n v-if=\"slots.append || props.type === 'password'\"\n class=\"stash-input-append font-semibold\"\n :class=\"[classes.symbol, classes['symbol--append']]\"\n >\n <!-- @slot renders content on the right side of the input -->\n <slot v-if=\"slots.append\" name=\"append\"></slot>\n <Icon\n v-else\n :name=\"showPassword ? 'hide' : 'show'\"\n class=\"tw-cursor-pointer\"\n :class=\"{ 'tw-text-ice-500': props.isDisabled || props.disabled }\"\n :data-test=\"showPassword ? 'hide-password-icon' : 'show-password-icon'\"\n @click=\"showPassword = !showPassword\"\n />\n </div>\n </div>\n </template>\n <template v-if=\"slots.hint\" #hint>\n <slot name=\"hint\"></slot>\n </template>\n </Field>\n</template>\n\n<style module>\n .root {\n position: relative;\n }\n\n .root input {\n background: var(--color-white);\n border: 1px solid var(--color-ice-500);\n border-radius: theme('borderRadius.DEFAULT');\n color: var(--color-ice-700);\n display: block;\n height: theme('height.input');\n font-size: theme('fontSize.sm');\n font-weight: theme('fontWeight.normal');\n outline: none;\n padding: 0 theme('spacing.3');\n width: 100%;\n }\n\n .root input:hover {\n border-color: var(--color-ice-500);\n }\n\n .root input:active,\n .root input:focus {\n border-color: var(--color-blue-500);\n }\n\n .root input::placeholder {\n color: var(--color-ice-500);\n opacity: 1;\n }\n\n .root input.has-error:not(:focus) {\n border-color: var(--color-red-500);\n }\n\n .root input.input-prepended {\n padding-left: 36px;\n }\n\n .root input.input-appended {\n padding-right: 36px;\n }\n\n .symbol {\n align-items: center;\n display: flex;\n height: theme('height.input');\n justify-content: center;\n overflow: hidden;\n position: absolute;\n top: 0;\n width: theme('height.input');\n }\n\n .symbol--prepend {\n border-bottom-left-radius: theme('borderRadius.DEFAULT');\n border-top-left-radius: theme('borderRadius.DEFAULT');\n left: 0;\n }\n\n .symbol--append {\n border-bottom-right-radius: theme('borderRadius.DEFAULT');\n border-top-right-radius: theme('borderRadius.DEFAULT');\n right: 0;\n }\n\n .root input[disabled] {\n background-color: var(--color-ice-100) !important;\n border-color: var(--color-ice-500) !important;\n color: var(--color-ice-500) !important;\n pointer-events: none;\n outline-color: var(--color-ice-500) !important;\n\n & + .symbol--prepend,\n & + .symbol--append {\n color: var(--color-ice-500);\n }\n }\n\n .root input[readonly] {\n border-color: transparent;\n background-color: transparent;\n padding-left: 0;\n padding-right: 0;\n }\n\n .root input[disabled]:active,\n .root input[readonly]:active,\n .root input[disabled]:focus,\n .root input[readonly]:focus {\n box-shadow: none !important;\n }\n\n .root input[disabled]::placeholder {\n text-transform: none;\n }\n</style>\n"],"names":["props","__props","emit","__emit","slots","useSlots","classes","useCssModule","attrs","useAttrs","inputEl","ref","__expose","internalValue","convertDecimal","decimalSeparator","showPassword","isReadOnly","computed","isNumber","inputAttrs","tempAttrs","inputType","watchEffect","format","parseNumber","value","isUserTyping","tempValue","isNil","sanitizeDecimal","handleChange","parsedValue","handleInput","e","onMounted"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA6CE,UAAMA,IAAQC,GAQRC,IAAOC,GAmBPC,IAAQC,EAAA,GACRC,IAAUC,EAAA,GACVC,IAAQC,EAAA,GAIRC,IAAUC,EAAA;AAIhB,IAAAC,EAAa,EAAE,SAAAF,GAAS;AAExB,UAAMG,IAAgBF,EAAqBX,EAAM,UAAU;AAE3D,IAAIA,EAAM,SAAS,aAAaA,EAAM,cAAcA,EAAM,eAAe,OACvEa,EAAc,QAAQC,EAAed,EAAM,YAAYe,CAAgB;AAGzE,UAAMC,IAAeL,EAAI,EAAK,GAExBM,IAAaC,EAAS,MAAMlB,EAAM,cAAe,cAAcQ,KAASA,EAAM,aAAa,EAAM,GACjGW,IAAWD,EAAS,MAAMlB,EAAM,SAAS,QAAQ,GAEjDoB,IAAaF,EAAS,MAAM;AAChC,YAAMG,IAAY,EAAE,GAAGb,EAAA;AAEvB,oBAAOa,EAAU,OAEVA;AAAA,IACT,CAAC,GAEKC,IAAYJ,EAAS,MAGrBC,EAAS,SAITnB,EAAM,SAAS,cAAcgB,EAAa,QACrC,SAGFhB,EAAM,IACd;AAED,IAAAuB,EAAY,MAAM;AAChB,MAAAV,EAAc,QAAQW,EAAOxB,EAAM,UAAU;AAAA,IAC/C,CAAC;AAQD,aAASyB,EAAYC,IAAyB,IAAIC,IAAe,IAAwB;AAEvF,UAAI,CAACR,EAAS;AACZ,eAAOO;AAGT,UAAIE,IAAYF;AAGhB,UAAIG,EAAMD,CAAS,KAAK,GAAGA,CAAS,GAAG,WAAW,EAAG,QAAO;AAQ5D,UALIb,MAAqB,QACvBa,IAAYd,EAAec,GAAW,GAAG,IAIvCD,MAEEC,MAAc,QAAKA,IAAY,OAG/BA,EAAU,SAAA,EAAW,WAAW,IAAI;AAAG,eAAOA;AAIpD,UAAI,CAACC,EAAMD,CAAS,KAAK,GAAGA,CAAS,GAAG;AACtC,QAAAA,IAAY,KAAK,aAAa,SAAS;AAAA,UACrC,OAAO;AAAA,UACP,uBAAuB;AAAA,UACvB,aAAa;AAAA,QAAA,CACd,EAAE,OAAO,OAAOA,CAAS,CAAC;AAAA;AAE3B,eAAO;AAIT,aAAO,MAAM,OAAOA,CAAS,CAAC,IAAI,KAAK,WAAWA,CAAS;AAAA,IAC7D;AAOA,aAASJ,EAAOE,GAAwB;AACtC,aAAIP,EAAS,QACJW,EAAgBJ,GAAOX,CAAgB,IAGzCW;AAAA,IACT;AAKA,aAASK,IAAe;AAEtB,YAAMC,IAAcb,EAAS,QAAQM,EAAYZ,EAAc,KAAK,IAAIA,EAAc;AACtF,MAAAX,EAAK,UAAU8B,CAAW;AAAA,IAC5B;AAKA,aAASC,EAAYC,GAAU;AAC7B,YAAMR,IAASQ,EAAE,OAA4B;AAG7C,MAAArB,EAAc,QAAQW,EAAOE,CAAK;AAElC,YAAMM,IAAcb,EAAS,QAAQM,EAAYZ,EAAc,OAAO,EAAI,IAAIa;AAE9E,MAAAxB,EAAK,sBAAsB8B,CAAW;AAAA,IACxC;AAEA,WAAAG,EAAU,MAAM;AACd,UAAInC,EAAM,UAAU;AAClB,cAAM,IAAI,MAAM,0DAA0D;AAG5E,UAAIQ,EAAM;AACR,cAAM,IAAI,MAAM,+DAA+D;AAAA,IAEnF,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}