@leaflink/stash 51.11.1 → 51.12.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +41 -12
- package/dist/Accordion.js.map +1 -1
- package/dist/ActionsDropdown.js.map +1 -1
- package/dist/AddressSelect.js.map +1 -1
- package/dist/Alert.js.map +1 -1
- package/dist/AppNavigationItem.js.map +1 -1
- package/dist/AppSidebar.js.map +1 -1
- package/dist/Avatar.js.map +1 -1
- package/dist/Backdrop.js.map +1 -1
- package/dist/Badge.js.map +1 -1
- package/dist/Button.js.map +1 -1
- package/dist/ButtonGroup.js.map +1 -1
- package/dist/Card.js.map +1 -1
- package/dist/CardContent.js.map +1 -1
- package/dist/CardFooter.js.map +1 -1
- package/dist/CardMedia.js.map +1 -1
- package/dist/Carousel.js.map +1 -1
- package/dist/Checkbox.js.map +1 -1
- package/dist/Chip.js.map +1 -1
- package/dist/ConfirmationCodeInput.js.map +1 -1
- package/dist/ContextSwitcher.js.map +1 -1
- package/dist/Copy.js.map +1 -1
- package/dist/CurrencyInput.js.map +1 -1
- package/dist/CustomRender.js.map +1 -1
- package/dist/DataView.js.map +1 -1
- package/dist/DataView.keys-aSOnA4AD.js.map +1 -1
- package/dist/DataViewFilters.js.map +1 -1
- package/dist/DataViewFilters.keys-BLu07FiP.js.map +1 -1
- package/dist/DataViewSortButton.js.map +1 -1
- package/dist/DataViewToolbar.js +83 -151
- package/dist/DataViewToolbar.js.map +1 -1
- package/dist/DatePicker.js +10 -10
- package/dist/DatePicker.js.map +1 -1
- package/dist/DescriptionList.js.map +1 -1
- package/dist/DescriptionListDetail.js.map +1 -1
- package/dist/DescriptionListGroup.js.map +1 -1
- package/dist/DescriptionListTerm.js.map +1 -1
- package/dist/Dialog.js.map +1 -1
- package/dist/Divider.js.map +1 -1
- package/dist/Dropdown.js.map +1 -1
- package/dist/EmptyState.js.map +1 -1
- package/dist/Expand.vue_vue_type_script_setup_true_lang-CiONJfAp.js.map +1 -1
- package/dist/Field.vue_vue_type_script_setup_true_lang-DI6z3AE9.js.map +1 -1
- package/dist/FileUpload.js.map +1 -1
- package/dist/FilterChip.js.map +1 -1
- package/dist/FilterDrawerItem.js.map +1 -1
- package/dist/FilterDropdown.js.map +1 -1
- package/dist/FilterSelect.js.map +1 -1
- package/dist/Filters.js.map +1 -1
- package/dist/Filters.vue.d.ts +1 -1
- package/dist/HttpError.js.map +1 -1
- package/dist/Icon.js.map +1 -1
- package/dist/IconLabel.js.map +1 -1
- package/dist/Illustration.vue_vue_type_script_setup_true_lang-BrqEF8xe.js.map +1 -1
- package/dist/Image.vue_vue_type_script_setup_true_lang-D5u4av0_.js.map +1 -1
- package/dist/InlineEdit.js.map +1 -1
- package/dist/Input.js.map +1 -1
- package/dist/InputOptions.js.map +1 -1
- package/dist/IntegrationIcon.js.map +1 -1
- package/dist/LicenseChip.js.map +1 -1
- package/dist/ListItem.js.map +1 -1
- package/dist/ListItemCell.js.map +1 -1
- package/dist/ListView.js.map +1 -1
- package/dist/ListView.vue.d.ts +1 -1
- package/dist/Loading.js.map +1 -1
- package/dist/Logo.vue_vue_type_script_setup_true_lang-Dz8c98sc.js.map +1 -1
- package/dist/Menu.js.map +1 -1
- package/dist/MenuItem.js.map +1 -1
- package/dist/MenusPlugin-Bk6UW6o9.js.map +1 -1
- package/dist/Metric.js.map +1 -1
- package/dist/Modal.js.map +1 -1
- package/dist/Modals.js.map +1 -1
- package/dist/ModalsPlugin.js.map +1 -1
- package/dist/Module.js.map +1 -1
- package/dist/Module.keys-CEsrW2f0.js.map +1 -1
- package/dist/Module.types-B1FfGGac.js.map +1 -1
- package/dist/ModuleContent.js.map +1 -1
- package/dist/ModuleFooter.js.map +1 -1
- package/dist/ModuleHeader.js.map +1 -1
- package/dist/MoreActions.js +1 -1
- package/dist/MoreActions.js.map +1 -1
- package/dist/ObfuscateText.js.map +1 -1
- package/dist/PageContent.js.map +1 -1
- package/dist/PageHeader.js.map +1 -1
- package/dist/PageNavigation.js.map +1 -1
- package/dist/Paginate.js.map +1 -1
- package/dist/PlaidLink.js.map +1 -1
- package/dist/QuickAction.js.map +1 -1
- package/dist/Radio.js.map +1 -1
- package/dist/RadioGroup.js.map +1 -1
- package/dist/RadioNew.js.map +1 -1
- package/dist/RangeInput.js.map +1 -1
- package/dist/SearchBar.js.map +1 -1
- package/dist/SectionHeader.js.map +1 -1
- package/dist/Select.js +1 -1
- package/dist/Select.js.map +1 -1
- package/dist/SelectStatus.js.map +1 -1
- package/dist/Skeleton.js.map +1 -1
- package/dist/Step.js.map +1 -1
- package/dist/Stepper.js.map +1 -1
- package/dist/Switch.js.map +1 -1
- package/dist/Tab.js +9 -9
- package/dist/Tab.js.map +1 -1
- package/dist/Table.js.map +1 -1
- package/dist/Table.keys-LHQf6FEH.js.map +1 -1
- package/dist/TableCell.js.map +1 -1
- package/dist/TableHeaderCell.js.map +1 -1
- package/dist/TableHeaderRow.js.map +1 -1
- package/dist/TableRow.js.map +1 -1
- package/dist/Tabs.js +2 -2
- package/dist/Tabs.vue_vue_type_script_setup_true_lang-CmnBP4i1.js +159 -0
- package/dist/Tabs.vue_vue_type_script_setup_true_lang-CmnBP4i1.js.map +1 -0
- package/dist/TextEditor.js +20 -20
- package/dist/TextEditor.js.map +1 -1
- package/dist/Textarea.js.map +1 -1
- package/dist/Thumbnail.js.map +1 -1
- package/dist/ThumbnailEmpty.js.map +1 -1
- package/dist/ThumbnailGroup.js.map +1 -1
- package/dist/ThumbnailGroup.keys-EJ4qFNhx.js.map +1 -1
- package/dist/TimelineItem.js.map +1 -1
- package/dist/Toast.js.map +1 -1
- package/dist/Toasts.js.map +1 -1
- package/dist/ToastsPlugin.js.map +1 -1
- package/dist/Tooltip.js +2 -2
- package/dist/Tooltip.js.map +1 -1
- package/dist/colors-DDDVvqfQ.js.map +1 -1
- package/dist/components.css +1 -1
- package/dist/constants.js.map +1 -1
- package/dist/directives/autofocus.js.map +1 -1
- package/dist/directives/clickoutside.js.map +1 -1
- package/dist/directives/observe.js +8 -8
- package/dist/directives/observe.js.map +1 -1
- package/dist/directives/sticky.js.map +1 -1
- package/dist/directives/tooltip.js.map +1 -1
- package/dist/directives/viewable.js.map +1 -1
- package/dist/floating-ui.vue-DLFiymOf.js +1093 -0
- package/dist/floating-ui.vue-DLFiymOf.js.map +1 -0
- package/dist/formatDateTime-Dz8bXV0R.js.map +1 -1
- package/dist/index-D6bxWkZ1.js.map +1 -1
- package/dist/{index-C14LhAwV.js → index-DA_ft08e.js} +6 -6
- package/dist/index-DA_ft08e.js.map +1 -0
- package/dist/index.js +2 -2
- package/dist/index.js.map +1 -1
- package/dist/isDefined-DzVx0B6k.js.map +1 -1
- package/dist/isValid-DN-HkCoi.js.map +1 -1
- package/dist/keys-BEdEsanp.js.map +1 -1
- package/dist/keys-C8Zfr_By.js.map +1 -1
- package/dist/locale.js.map +1 -1
- package/dist/misc-CHQs-G03.js.map +1 -1
- package/dist/parseISO-wlfIB_QJ.js.map +1 -1
- package/dist/{searchFuzzy-DRasJ33G.js → searchFuzzy-B3TsUO-V.js} +8 -8
- package/dist/searchFuzzy-B3TsUO-V.js.map +1 -0
- package/dist/statusLevels-D8EgtE_L.js.map +1 -1
- package/dist/storage.js.map +1 -1
- package/dist/tailwind-base.js.map +1 -1
- package/dist/toTimeZone-Coq1oPTt.js.map +1 -1
- package/dist/useConfirmBeforeClosing.js.map +1 -1
- package/dist/useDialog.js.map +1 -1
- package/dist/useGoogleMaps.js.map +1 -1
- package/dist/useMediaQuery.js.map +1 -1
- package/dist/useModals.js.map +1 -1
- package/dist/usePaginationStats-d_q39naC.js.map +1 -1
- package/dist/usePlaidLink.js.map +1 -1
- package/dist/useScriptTag.js.map +1 -1
- package/dist/useSearch.js +1 -1
- package/dist/useSearch.js.map +1 -1
- package/dist/useSelection.js.map +1 -1
- package/dist/useSortable.js +1 -1
- package/dist/useSortable.js.map +1 -1
- package/dist/useStepper.js.map +1 -1
- package/dist/useToasts.js.map +1 -1
- package/dist/useValidation.js.map +1 -1
- package/dist/utils/calculateElementOverflow.js.map +1 -1
- package/dist/utils/colorScheme.js.map +1 -1
- package/dist/utils/createQueryString.js.map +1 -1
- package/dist/utils/createValidDate.js.map +1 -1
- package/dist/utils/getContrastingTextColor.js.map +1 -1
- package/dist/utils/helpers.js.map +1 -1
- package/dist/utils/i18n.js.map +1 -1
- package/dist/utils/normalizeDate.js.map +1 -1
- package/dist/utils/obfuscateText.js.map +1 -1
- package/dist/utils/searchFuzzy.js +1 -1
- package/dist/utils/storage.js.map +1 -1
- package/package.json +23 -10
- package/dist/Tabs.vue_vue_type_script_setup_true_lang-BlJVDr7o.js +0 -78
- package/dist/Tabs.vue_vue_type_script_setup_true_lang-BlJVDr7o.js.map +0 -1
- package/dist/floating-ui.vue-pzUuloyX.js +0 -1075
- package/dist/floating-ui.vue-pzUuloyX.js.map +0 -1
- package/dist/index-C14LhAwV.js.map +0 -1
- package/dist/searchFuzzy-DRasJ33G.js.map +0 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"CurrencyInput.js","sources":["../node_modules/vue-currency-input/dist/index.mjs","../src/components/CurrencyInput/CurrencyInput.vue"],"sourcesContent":["/**\n * Vue Currency Input 3.1.0\n * (c) 2018-2024 Matthias Stiller\n * @license MIT\n */\nimport { ref, getCurrentInstance, version, computed, watch } from 'vue';\n\nvar CurrencyDisplay;\n(function (CurrencyDisplay) {\n CurrencyDisplay[\"symbol\"] = \"symbol\";\n CurrencyDisplay[\"narrowSymbol\"] = \"narrowSymbol\";\n CurrencyDisplay[\"code\"] = \"code\";\n CurrencyDisplay[\"name\"] = \"name\";\n CurrencyDisplay[\"hidden\"] = \"hidden\";\n})(CurrencyDisplay || (CurrencyDisplay = {}));\nvar ValueScaling;\n(function (ValueScaling) {\n ValueScaling[\"precision\"] = \"precision\";\n ValueScaling[\"thousands\"] = \"thousands\";\n ValueScaling[\"millions\"] = \"millions\";\n ValueScaling[\"billions\"] = \"billions\";\n})(ValueScaling || (ValueScaling = {}));\n\nconst escapeRegExp = (str) => {\n return str.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\$&');\n};\nconst removeLeadingZeros = (str) => {\n return str.replace(/^0+(0$|[^0])/, '$1');\n};\nconst count = (str, search) => {\n return (str.match(new RegExp(escapeRegExp(search), 'g')) || []).length;\n};\nconst substringBefore = (str, search) => {\n return str.substring(0, str.indexOf(search));\n};\n\nconst DECIMAL_SEPARATORS = [\n ',',\n '.',\n '٫',\n '。'\n];\nconst INTEGER_PATTERN = '(0|[1-9]\\\\d*)';\nclass CurrencyFormat {\n constructor(options) {\n var _a, _b, _c, _d, _e, _f;\n const { currency, currencyDisplay, locale, precision, accountingSign, useGrouping } = options;\n this.locale = locale;\n this.options = {\n currency,\n useGrouping,\n style: 'currency',\n currencySign: accountingSign ? 'accounting' : undefined,\n currencyDisplay: currencyDisplay !== CurrencyDisplay.hidden ? currencyDisplay : undefined\n };\n const numberFormat = new Intl.NumberFormat(locale, this.options);\n const formatParts = numberFormat.formatToParts(123456);\n this.currency = (_a = formatParts.find(({ type }) => type === 'currency')) === null || _a === void 0 ? void 0 : _a.value;\n this.digits = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9].map((i) => i.toLocaleString(locale));\n this.decimalSymbol = (_b = formatParts.find(({ type }) => type === 'decimal')) === null || _b === void 0 ? void 0 : _b.value;\n this.groupingSymbol = (_c = formatParts.find(({ type }) => type === 'group')) === null || _c === void 0 ? void 0 : _c.value;\n this.minusSign = (_d = numberFormat.formatToParts(-1).find(({ type }) => type === 'minusSign')) === null || _d === void 0 ? void 0 : _d.value;\n if (this.decimalSymbol === undefined) {\n this.minimumFractionDigits = this.maximumFractionDigits = 0;\n }\n else if (typeof precision === 'number') {\n this.minimumFractionDigits = this.maximumFractionDigits = precision;\n }\n else {\n this.minimumFractionDigits = (_e = precision === null || precision === void 0 ? void 0 : precision.min) !== null && _e !== void 0 ? _e : numberFormat.resolvedOptions().minimumFractionDigits;\n this.maximumFractionDigits = (_f = precision === null || precision === void 0 ? void 0 : precision.max) !== null && _f !== void 0 ? _f : numberFormat.resolvedOptions().maximumFractionDigits;\n }\n const getPrefix = (str) => {\n return substringBefore(str, this.digits[1]);\n };\n const getSuffix = (str) => {\n return str.substring(str.lastIndexOf(this.decimalSymbol ? this.digits[0] : this.digits[1]) + 1);\n };\n this.prefix = getPrefix(numberFormat.format(1));\n this.suffix = getSuffix(numberFormat.format(1));\n this.negativePrefix = getPrefix(numberFormat.format(-1));\n this.negativeSuffix = getSuffix(numberFormat.format(-1));\n }\n parse(str) {\n if (str) {\n const negative = this.isNegative(str);\n str = this.normalizeDigits(str);\n str = this.stripCurrency(str, negative);\n str = this.stripSignLiterals(str);\n const fraction = this.decimalSymbol ? `(?:${escapeRegExp(this.decimalSymbol)}(\\\\d*))?` : '';\n const match = this.stripGroupingSeparator(str).match(new RegExp(`^${INTEGER_PATTERN}${fraction}$`));\n if (match && this.isValidIntegerFormat(this.decimalSymbol ? str.split(this.decimalSymbol)[0] : str, Number(match[1]))) {\n return Number(`${negative ? '-' : ''}${this.onlyDigits(match[1])}.${this.onlyDigits(match[2] || '')}`);\n }\n }\n return null;\n }\n isValidIntegerFormat(formattedNumber, integerNumber) {\n const options = { ...this.options, minimumFractionDigits: 0 };\n return [\n this.stripCurrency(this.normalizeDigits(integerNumber.toLocaleString(this.locale, { ...options, useGrouping: true })), false),\n this.stripCurrency(this.normalizeDigits(integerNumber.toLocaleString(this.locale, { ...options, useGrouping: false })), false)\n ].includes(formattedNumber);\n }\n format(value, options = {\n minimumFractionDigits: this.minimumFractionDigits,\n maximumFractionDigits: this.maximumFractionDigits\n }) {\n return value != null ? value.toLocaleString(this.locale, { ...this.options, ...options }) : '';\n }\n toFraction(str) {\n return `${this.digits[0]}${this.decimalSymbol}${this.onlyLocaleDigits(str.substring(1)).substring(0, this.maximumFractionDigits)}`;\n }\n isFractionIncomplete(str) {\n return !!this.normalizeDigits(this.stripGroupingSeparator(str)).match(new RegExp(`^${INTEGER_PATTERN}${escapeRegExp(this.decimalSymbol)}$`));\n }\n isNegative(str) {\n return (str.startsWith(this.negativePrefix) ||\n (this.minusSign === undefined && (str.startsWith('(') || str.startsWith('-'))) ||\n (this.minusSign !== undefined && str.replace('-', this.minusSign).startsWith(this.minusSign)));\n }\n insertCurrency(str, negative) {\n return `${negative ? this.negativePrefix : this.prefix}${str}${negative ? this.negativeSuffix : this.suffix}`;\n }\n stripGroupingSeparator(str) {\n return this.groupingSymbol !== undefined ? str.replace(new RegExp(escapeRegExp(this.groupingSymbol), 'g'), '') : str;\n }\n stripSignLiterals(str) {\n if (this.minusSign !== undefined) {\n return str.replace('-', this.minusSign).replace(this.minusSign, '');\n }\n else {\n return str.replace(/[-()]/g, '');\n }\n }\n stripCurrency(str, negative) {\n return str.replace(negative ? this.negativePrefix : this.prefix, '').replace(negative ? this.negativeSuffix : this.suffix, '');\n }\n normalizeDecimalSeparator(str, from) {\n DECIMAL_SEPARATORS.forEach((s) => {\n str = str.substring(0, from) + str.substring(from).replace(s, this.decimalSymbol);\n });\n return str;\n }\n normalizeDigits(str) {\n if (this.digits[0] !== '0') {\n this.digits.forEach((digit, index) => {\n str = str.replace(new RegExp(digit, 'g'), String(index));\n });\n }\n return str;\n }\n onlyDigits(str) {\n return this.normalizeDigits(str).replace(/\\D+/g, '');\n }\n onlyLocaleDigits(str) {\n return str.replace(new RegExp(`[^${this.digits.join('')}]*`, 'g'), '');\n }\n}\n\nclass AbstractInputMask {\n constructor(currencyFormat) {\n this.currencyFormat = currencyFormat;\n }\n}\nclass DefaultInputMask extends AbstractInputMask {\n conformToMask(str, previousConformedValue = '') {\n const negative = this.currencyFormat.isNegative(str);\n const isEmptyNegativeValue = (str) => str === '' &&\n negative &&\n !(this.currencyFormat.minusSign === undefined\n ? previousConformedValue === this.currencyFormat.negativePrefix + this.currencyFormat.negativeSuffix\n : previousConformedValue === this.currencyFormat.negativePrefix);\n const checkIncompleteValue = (str) => {\n if (isEmptyNegativeValue(str)) {\n return '';\n }\n else if (this.currencyFormat.maximumFractionDigits > 0) {\n if (this.currencyFormat.isFractionIncomplete(str)) {\n return str;\n }\n else if (str.startsWith(this.currencyFormat.decimalSymbol)) {\n return this.currencyFormat.toFraction(str);\n }\n }\n return null;\n };\n let value = str;\n value = this.currencyFormat.stripCurrency(value, negative);\n value = this.currencyFormat.stripSignLiterals(value);\n const incompleteValue = checkIncompleteValue(value);\n if (incompleteValue != null) {\n return this.currencyFormat.insertCurrency(incompleteValue, negative);\n }\n const [integer, ...fraction] = value.split(this.currencyFormat.decimalSymbol);\n const integerDigits = removeLeadingZeros(this.currencyFormat.onlyDigits(integer));\n const fractionDigits = this.currencyFormat.onlyDigits(fraction.join('')).substring(0, this.currencyFormat.maximumFractionDigits);\n const invalidFraction = fraction.length > 0 && fractionDigits.length === 0;\n const invalidNegativeValue = integerDigits === '' &&\n negative &&\n (this.currencyFormat.minusSign === undefined\n ? previousConformedValue === str.slice(0, -2) + this.currencyFormat.negativeSuffix\n : previousConformedValue === str.slice(0, -1));\n if (invalidFraction || invalidNegativeValue || isEmptyNegativeValue(integerDigits)) {\n return previousConformedValue;\n }\n else if (integerDigits.match(/\\d+/)) {\n return {\n numberValue: Number(`${negative ? '-' : ''}${integerDigits}.${fractionDigits}`),\n fractionDigits\n };\n }\n else {\n return '';\n }\n }\n}\nclass AutoDecimalDigitsInputMask extends AbstractInputMask {\n conformToMask(str, previousConformedValue = '') {\n if (str === '' ||\n (this.currencyFormat.parse(previousConformedValue) === 0 &&\n this.currencyFormat.stripCurrency(previousConformedValue, true).slice(0, -1) === this.currencyFormat.stripCurrency(str, true))) {\n return '';\n }\n const negative = this.currencyFormat.isNegative(str);\n const numberValue = this.currencyFormat.stripSignLiterals(str) === ''\n ? -0\n : Number(`${negative ? '-' : ''}${removeLeadingZeros(this.currencyFormat.onlyDigits(str))}`) / Math.pow(10, this.currencyFormat.maximumFractionDigits);\n return {\n numberValue,\n fractionDigits: numberValue.toFixed(this.currencyFormat.maximumFractionDigits).slice(-this.currencyFormat.maximumFractionDigits)\n };\n }\n}\n\nconst DEFAULT_OPTIONS = {\n locale: undefined,\n currency: undefined,\n currencyDisplay: undefined,\n hideGroupingSeparatorOnFocus: true,\n hideCurrencySymbolOnFocus: true,\n hideNegligibleDecimalDigitsOnFocus: true,\n precision: undefined,\n autoDecimalDigits: false,\n valueRange: undefined,\n useGrouping: undefined,\n valueScaling: undefined\n};\nclass CurrencyInput {\n constructor(args) {\n this.el = args.el;\n this.onInput = args.onInput;\n this.onChange = args.onChange;\n this.addEventListener();\n this.init(args.options);\n }\n setOptions(options) {\n this.init(options);\n this.format(this.currencyFormat.format(this.validateValueRange(this.numberValue)));\n this.onChange(this.getValue());\n }\n getValue() {\n const numberValue = this.valueScaling && this.numberValue != null ? this.toInteger(this.numberValue, this.valueScaling) : this.numberValue;\n return { number: numberValue, formatted: this.formattedValue };\n }\n setValue(value) {\n const newValue = this.valueScaling !== undefined && value != null ? this.toFloat(value, this.valueScaling) : value;\n if (newValue !== this.numberValue) {\n this.format(this.currencyFormat.format(this.validateValueRange(newValue)));\n this.onChange(this.getValue());\n }\n }\n init(options) {\n this.options = {\n ...DEFAULT_OPTIONS,\n ...options\n };\n if (this.options.autoDecimalDigits) {\n this.options.hideNegligibleDecimalDigitsOnFocus = false;\n }\n if (!this.el.getAttribute('inputmode')) {\n this.el.setAttribute('inputmode', this.options.autoDecimalDigits ? 'numeric' : 'decimal');\n }\n this.currencyFormat = new CurrencyFormat(this.options);\n this.numberMask = this.options.autoDecimalDigits ? new AutoDecimalDigitsInputMask(this.currencyFormat) : new DefaultInputMask(this.currencyFormat);\n const valueScalingOptions = {\n [ValueScaling.precision]: this.currencyFormat.maximumFractionDigits,\n [ValueScaling.thousands]: 3,\n [ValueScaling.millions]: 6,\n [ValueScaling.billions]: 9\n };\n this.valueScaling = this.options.valueScaling ? valueScalingOptions[this.options.valueScaling] : undefined;\n this.valueScalingFractionDigits =\n this.valueScaling !== undefined && this.options.valueScaling !== ValueScaling.precision\n ? this.valueScaling + this.currencyFormat.maximumFractionDigits\n : this.currencyFormat.maximumFractionDigits;\n this.minValue = this.getMinValue();\n this.maxValue = this.getMaxValue();\n }\n getMinValue() {\n var _a, _b;\n let min = this.toFloat(-Number.MAX_SAFE_INTEGER);\n if (((_a = this.options.valueRange) === null || _a === void 0 ? void 0 : _a.min) !== undefined) {\n min = Math.max((_b = this.options.valueRange) === null || _b === void 0 ? void 0 : _b.min, this.toFloat(-Number.MAX_SAFE_INTEGER));\n }\n return min;\n }\n getMaxValue() {\n var _a, _b;\n let max = this.toFloat(Number.MAX_SAFE_INTEGER);\n if (((_a = this.options.valueRange) === null || _a === void 0 ? void 0 : _a.max) !== undefined) {\n max = Math.min((_b = this.options.valueRange) === null || _b === void 0 ? void 0 : _b.max, this.toFloat(Number.MAX_SAFE_INTEGER));\n }\n return max;\n }\n toFloat(value, maxFractionDigits) {\n return value / Math.pow(10, maxFractionDigits !== null && maxFractionDigits !== void 0 ? maxFractionDigits : this.valueScalingFractionDigits);\n }\n toInteger(value, maxFractionDigits) {\n return Number(value\n .toFixed(maxFractionDigits !== null && maxFractionDigits !== void 0 ? maxFractionDigits : this.valueScalingFractionDigits)\n .split('.')\n .join(''));\n }\n validateValueRange(value) {\n return value != null ? Math.min(Math.max(value, this.minValue), this.maxValue) : value;\n }\n format(value, hideNegligibleDecimalDigits = false) {\n if (value != null) {\n if (this.decimalSymbolInsertedAt !== undefined) {\n value = this.currencyFormat.normalizeDecimalSeparator(value, this.decimalSymbolInsertedAt);\n this.decimalSymbolInsertedAt = undefined;\n }\n const conformedValue = this.numberMask.conformToMask(value, this.formattedValue);\n let formattedValue;\n if (typeof conformedValue === 'object') {\n const { numberValue, fractionDigits } = conformedValue;\n let { maximumFractionDigits, minimumFractionDigits } = this.currencyFormat;\n if (this.focus) {\n minimumFractionDigits = hideNegligibleDecimalDigits\n ? fractionDigits.replace(/0+$/, '').length\n : Math.min(maximumFractionDigits, fractionDigits.length);\n }\n else if (Number.isInteger(numberValue) && !this.options.autoDecimalDigits && (this.options.precision === undefined || minimumFractionDigits === 0)) {\n minimumFractionDigits = maximumFractionDigits = 0;\n }\n formattedValue =\n this.toInteger(Math.abs(numberValue)) > Number.MAX_SAFE_INTEGER\n ? this.formattedValue\n : this.currencyFormat.format(numberValue, {\n useGrouping: this.options.useGrouping !== false && !(this.focus && this.options.hideGroupingSeparatorOnFocus),\n minimumFractionDigits,\n maximumFractionDigits\n });\n }\n else {\n formattedValue = conformedValue;\n }\n if (this.maxValue <= 0 && !this.currencyFormat.isNegative(formattedValue) && this.currencyFormat.parse(formattedValue) !== 0) {\n formattedValue = formattedValue.replace(this.currencyFormat.prefix, this.currencyFormat.negativePrefix);\n }\n if (this.minValue >= 0) {\n formattedValue = formattedValue.replace(this.currencyFormat.negativePrefix, this.currencyFormat.prefix);\n }\n if (this.options.currencyDisplay === CurrencyDisplay.hidden || (this.focus && this.options.hideCurrencySymbolOnFocus)) {\n formattedValue = formattedValue\n .replace(this.currencyFormat.negativePrefix, this.currencyFormat.minusSign !== undefined ? this.currencyFormat.minusSign : '(')\n .replace(this.currencyFormat.negativeSuffix, this.currencyFormat.minusSign !== undefined ? '' : ')')\n .replace(this.currencyFormat.prefix, '')\n .replace(this.currencyFormat.suffix, '');\n }\n this.el.value = formattedValue;\n this.numberValue = this.currencyFormat.parse(formattedValue);\n }\n else {\n this.el.value = '';\n this.numberValue = null;\n }\n this.formattedValue = this.el.value;\n this.onInput(this.getValue());\n }\n addEventListener() {\n this.el.addEventListener('input', (e) => {\n const { value, selectionStart } = this.el;\n const inputEvent = e;\n if (selectionStart && inputEvent.data && DECIMAL_SEPARATORS.includes(inputEvent.data)) {\n this.decimalSymbolInsertedAt = selectionStart - 1;\n }\n this.format(value);\n if (this.focus && selectionStart != null) {\n const getCaretPositionAfterFormat = () => {\n const { prefix, suffix, decimalSymbol, maximumFractionDigits, groupingSymbol } = this.currencyFormat;\n let caretPositionFromLeft = value.length - selectionStart;\n const newValueLength = this.formattedValue.length;\n if (this.currencyFormat.minusSign === undefined && (value.startsWith('(') || value.startsWith('-')) && !value.endsWith(')')) {\n return newValueLength - this.currencyFormat.negativeSuffix.length > 1 ? this.formattedValue.substring(selectionStart).length : 1;\n }\n if (this.formattedValue.substring(selectionStart, 1) === groupingSymbol &&\n count(this.formattedValue, groupingSymbol) === count(value, groupingSymbol) + 1) {\n return newValueLength - caretPositionFromLeft - 1;\n }\n if (newValueLength < caretPositionFromLeft) {\n return selectionStart;\n }\n if (decimalSymbol !== undefined && value.indexOf(decimalSymbol) !== -1) {\n const decimalSymbolPosition = value.indexOf(decimalSymbol) + 1;\n if (Math.abs(newValueLength - value.length) > 1 && selectionStart <= decimalSymbolPosition) {\n return this.formattedValue.indexOf(decimalSymbol) + 1;\n }\n else {\n if (!this.options.autoDecimalDigits && selectionStart > decimalSymbolPosition) {\n if (this.currencyFormat.onlyDigits(value.substring(decimalSymbolPosition)).length - 1 === maximumFractionDigits) {\n caretPositionFromLeft -= 1;\n }\n }\n }\n }\n return this.options.hideCurrencySymbolOnFocus || this.options.currencyDisplay === CurrencyDisplay.hidden\n ? newValueLength - caretPositionFromLeft\n : Math.max(newValueLength - Math.max(caretPositionFromLeft, suffix.length), prefix.length);\n };\n this.setCaretPosition(getCaretPositionAfterFormat());\n }\n });\n this.el.addEventListener('focus', () => {\n this.focus = true;\n this.numberValueOnFocus = this.numberValue;\n setTimeout(() => {\n const { value, selectionStart, selectionEnd } = this.el;\n this.format(value, this.options.hideNegligibleDecimalDigitsOnFocus);\n if (selectionStart != null && selectionEnd != null && Math.abs(selectionStart - selectionEnd) > 0) {\n this.setCaretPosition(0, this.el.value.length);\n }\n else if (selectionStart != null) {\n const caretPositionOnFocus = this.getCaretPositionOnFocus(value, selectionStart);\n this.setCaretPosition(caretPositionOnFocus);\n }\n });\n });\n this.el.addEventListener('blur', () => {\n this.focus = false;\n this.format(this.currencyFormat.format(this.validateValueRange(this.numberValue)));\n if (this.numberValueOnFocus !== this.numberValue) {\n this.onChange(this.getValue());\n }\n });\n }\n getCaretPositionOnFocus(value, selectionStart) {\n if (this.numberValue == null) {\n return selectionStart;\n }\n const { prefix, negativePrefix, suffix, negativeSuffix, groupingSymbol, currency } = this.currencyFormat;\n const isNegative = this.numberValue < 0;\n const currentPrefix = isNegative ? negativePrefix : prefix;\n const prefixLength = currentPrefix.length;\n if (this.options.hideCurrencySymbolOnFocus || this.options.currencyDisplay === CurrencyDisplay.hidden) {\n if (isNegative) {\n if (selectionStart <= 1) {\n return 1;\n }\n else if (value.endsWith(')') && selectionStart > value.indexOf(')')) {\n return this.formattedValue.length - 1;\n }\n }\n }\n else {\n const suffixLength = isNegative ? negativeSuffix.length : suffix.length;\n if (selectionStart >= value.length - suffixLength) {\n return this.formattedValue.length - suffixLength;\n }\n else if (selectionStart < prefixLength) {\n return prefixLength;\n }\n }\n let result = selectionStart;\n if (this.options.hideCurrencySymbolOnFocus &&\n this.options.currencyDisplay !== CurrencyDisplay.hidden &&\n selectionStart >= prefixLength &&\n currency !== undefined &&\n currentPrefix.includes(currency)) {\n result -= prefixLength;\n if (isNegative) {\n result += 1;\n }\n }\n if (this.options.hideGroupingSeparatorOnFocus && groupingSymbol !== undefined) {\n result -= count(value.substring(0, selectionStart), groupingSymbol);\n }\n return result;\n }\n setCaretPosition(start, end = start) {\n this.el.setSelectionRange(start, end);\n }\n}\n\nconst findInput = (el) => ((el === null || el === void 0 ? void 0 : el.matches('input')) ? el : el === null || el === void 0 ? void 0 : el.querySelector('input'));\nfunction useCurrencyInput(options, autoEmit) {\n var _a, _b, _c, _d;\n let currencyInput;\n const inputRef = ref(null);\n const formattedValue = ref(null);\n const numberValue = ref(null);\n const vm = getCurrentInstance();\n const emit = (vm === null || vm === void 0 ? void 0 : vm.emit) || ((_b = (_a = vm === null || vm === void 0 ? void 0 : vm.proxy) === null || _a === void 0 ? void 0 : _a.$emit) === null || _b === void 0 ? void 0 : _b.bind(vm === null || vm === void 0 ? void 0 : vm.proxy));\n const props = ((vm === null || vm === void 0 ? void 0 : vm.props) || ((_c = vm === null || vm === void 0 ? void 0 : vm.proxy) === null || _c === void 0 ? void 0 : _c.$props));\n const isVue3 = version.startsWith('3');\n const lazyModel = isVue3 && ((_d = vm === null || vm === void 0 ? void 0 : vm.attrs.modelModifiers) === null || _d === void 0 ? void 0 : _d.lazy);\n const modelValue = computed(() => props === null || props === void 0 ? void 0 : props[isVue3 ? 'modelValue' : 'value']);\n const inputEvent = isVue3 ? 'update:modelValue' : 'input';\n const changeEvent = lazyModel ? 'update:modelValue' : 'change';\n watch(inputRef, (value) => {\n var _a;\n if (value) {\n const el = findInput((_a = value === null || value === void 0 ? void 0 : value.$el) !== null && _a !== void 0 ? _a : value);\n if (el) {\n currencyInput = new CurrencyInput({\n el,\n options,\n onInput: (value) => {\n if (!lazyModel && autoEmit !== false && modelValue.value !== value.number) {\n emit === null || emit === void 0 ? void 0 : emit(inputEvent, value.number);\n }\n numberValue.value = value.number;\n formattedValue.value = value.formatted;\n },\n onChange: (value) => {\n if (autoEmit !== false) {\n emit === null || emit === void 0 ? void 0 : emit(changeEvent, value.number);\n }\n }\n });\n currencyInput.setValue(modelValue.value);\n }\n else {\n console.error('No input element found. Please make sure that the \"inputRef\" template ref is properly assigned.');\n }\n }\n else {\n currencyInput = null;\n }\n });\n return {\n inputRef,\n numberValue,\n formattedValue,\n setValue: (value) => currencyInput === null || currencyInput === void 0 ? void 0 : currencyInput.setValue(value),\n setOptions: (options) => currencyInput === null || currencyInput === void 0 ? void 0 : currencyInput.setOptions(options)\n };\n}\n\nexport { CurrencyDisplay, ValueScaling, useCurrencyInput };\n","<script lang=\"ts\" setup>\n import isEmpty from 'lodash-es/isEmpty';\n import { computed, useAttrs, watch } from 'vue';\n import { CurrencyDisplay, CurrencyInputOptions, useCurrencyInput } from 'vue-currency-input';\n\n import Icon from '../Icon/Icon.vue';\n import Input, { InputProps } from '../Input/Input.vue';\n\n const CURRENCY_INPUT_BASE_OPTIONS: CurrencyInputOptions = {\n currency: 'USD',\n currencyDisplay: CurrencyDisplay.hidden,\n precision: 2,\n hideCurrencySymbolOnFocus: true,\n hideGroupingSeparatorOnFocus: true,\n hideNegligibleDecimalDigitsOnFocus: false,\n autoDecimalDigits: true,\n useGrouping: true,\n accountingSign: false,\n };\n\n export interface CurrencyInputProps extends Omit<InputProps, 'modelValue' | 'type'> {\n inputOptions?: Partial<CurrencyInputOptions>;\n modelValue: string | null;\n hidePrepend?: boolean;\n }\n\n const props = withDefaults(defineProps<CurrencyInputProps>(), {\n // Todo: this default should be removed if its a required prop...\n modelValue: '',\n errorText: undefined,\n hintText: undefined,\n label: undefined,\n id: undefined,\n inputOptions: undefined,\n hidePrepend: false,\n });\n\n const emit = defineEmits<{\n /**\n * Emitted when the input value changes.\n */\n (e: 'update:model-value', v: CurrencyInputProps['modelValue']): void;\n }>();\n\n const attrs = useAttrs();\n\n const currencyInputOptions = computed(() => {\n return {\n ...CURRENCY_INPUT_BASE_OPTIONS,\n ...(!isEmpty(props.inputOptions) ? props.inputOptions : {}),\n };\n });\n\n const { inputRef: inputEl, setOptions, setValue, numberValue } = useCurrencyInput(currencyInputOptions.value, false);\n\n defineExpose({ inputEl });\n\n watch(\n () => numberValue.value,\n (newValue: number | null | string) => {\n let stringValue: string | null;\n\n if (Object.is(newValue, -0)) {\n if (typeof currencyInputOptions.value.precision === 'number') {\n stringValue = '-0.' + '0'.repeat(currencyInputOptions.value.precision);\n } else {\n stringValue = '-0.' + '0'.repeat(currencyInputOptions.value.precision?.min || 0);\n }\n } else {\n stringValue = typeof newValue === 'number' ? newValue.toFixed(2) : newValue;\n }\n\n emit('update:model-value', stringValue);\n },\n );\n\n watch(\n () => props.modelValue,\n (newValue: number | null | string) => {\n let numberValue: number | null;\n\n if (typeof newValue === 'string') {\n numberValue = parseFloat(newValue || '0');\n } else {\n numberValue = newValue;\n }\n\n setValue(numberValue);\n },\n );\n\n watch(\n () => props.inputOptions,\n () => {\n setOptions(currencyInputOptions.value);\n },\n );\n\n const inputAttrs = computed(() => {\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n const { inputOptions: _, ...propsWithoutCurrencyInputOptions } = props;\n\n return { ...propsWithoutCurrencyInputOptions, ...attrs } as typeof attrs & InputProps;\n });\n</script>\n\n<template>\n <Input\n v-bind=\"inputAttrs\"\n ref=\"inputEl\"\n class=\"stash-currency-input\"\n type=\"text\"\n data-test=\"stash-currency-input\"\n inputmode=\"decimal\"\n >\n <template v-if=\"!hidePrepend\" #prepend>\n <Icon name=\"sign-dollar\" />\n </template>\n </Input>\n</template>\n"],"names":["CurrencyDisplay","ValueScaling","escapeRegExp","str","removeLeadingZeros","count","search","substringBefore","DECIMAL_SEPARATORS","INTEGER_PATTERN","CurrencyFormat","options","_a","_b","_c","_d","_e","_f","currency","currencyDisplay","locale","precision","accountingSign","useGrouping","numberFormat","formatParts","type","i","getPrefix","getSuffix","negative","fraction","match","formattedNumber","integerNumber","value","from","s","digit","index","AbstractInputMask","currencyFormat","DefaultInputMask","previousConformedValue","isEmptyNegativeValue","checkIncompleteValue","incompleteValue","integer","integerDigits","fractionDigits","invalidFraction","invalidNegativeValue","AutoDecimalDigitsInputMask","numberValue","DEFAULT_OPTIONS","CurrencyInput","args","newValue","valueScalingOptions","min","max","maxFractionDigits","hideNegligibleDecimalDigits","conformedValue","formattedValue","maximumFractionDigits","minimumFractionDigits","e","selectionStart","inputEvent","getCaretPositionAfterFormat","prefix","suffix","decimalSymbol","groupingSymbol","caretPositionFromLeft","newValueLength","decimalSymbolPosition","selectionEnd","caretPositionOnFocus","negativePrefix","negativeSuffix","isNegative","currentPrefix","prefixLength","suffixLength","result","start","end","findInput","el","useCurrencyInput","autoEmit","currencyInput","inputRef","ref","vm","getCurrentInstance","props","isVue3","version","modelValue","computed","watch","CURRENCY_INPUT_BASE_OPTIONS","__props","emit","__emit","attrs","useAttrs","currencyInputOptions","isEmpty","inputEl","setOptions","setValue","__expose","stringValue","inputAttrs","_","propsWithoutCurrencyInputOptions"],"mappings":";;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAOA,IAAIA;AAAA,CACH,SAAUA,GAAiB;AACxB,EAAAA,EAAgB,SAAY,UAC5BA,EAAgB,eAAkB,gBAClCA,EAAgB,OAAU,QAC1BA,EAAgB,OAAU,QAC1BA,EAAgB,SAAY;AAChC,GAAGA,MAAoBA,IAAkB,CAAA,EAAG;AAC5C,IAAIC;AAAA,CACH,SAAUA,GAAc;AACrB,EAAAA,EAAa,YAAe,aAC5BA,EAAa,YAAe,aAC5BA,EAAa,WAAc,YAC3BA,EAAa,WAAc;AAC/B,GAAGA,MAAiBA,IAAe,CAAA,EAAG;AAEtC,MAAMC,IAAe,CAACC,MACXA,EAAI,QAAQ,uBAAuB,MAAM,GAE9CC,IAAqB,CAACD,MACjBA,EAAI,QAAQ,gBAAgB,IAAI,GAErCE,IAAQ,CAACF,GAAKG,OACRH,EAAI,MAAM,IAAI,OAAOD,EAAaI,CAAM,GAAG,GAAG,CAAC,KAAK,CAAA,GAAI,QAE9DC,IAAkB,CAACJ,GAAKG,MACnBH,EAAI,UAAU,GAAGA,EAAI,QAAQG,CAAM,CAAC,GAGzCE,IAAqB;AAAA,EACvB;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACJ,GACMC,IAAkB;AACxB,MAAMC,EAAe;AAAA,EACjB,YAAYC,GAAS;AACjB,QAAIC,GAAIC,GAAIC,GAAIC,GAAIC,GAAIC;AACxB,UAAM,EAAE,UAAAC,GAAU,iBAAAC,GAAiB,QAAAC,GAAQ,WAAAC,GAAW,gBAAAC,GAAgB,aAAAC,EAAW,IAAKZ;AACtF,SAAK,SAASS,GACd,KAAK,UAAU;AAAA,MACX,UAAAF;AAAA,MACA,aAAAK;AAAA,MACA,OAAO;AAAA,MACP,cAAcD,IAAiB,eAAe;AAAA,MAC9C,iBAAiBH,MAAoBnB,EAAgB,SAASmB,IAAkB;AAAA,IACnF;AACD,UAAMK,IAAe,IAAI,KAAK,aAAaJ,GAAQ,KAAK,OAAO,GACzDK,IAAcD,EAAa,cAAc,MAAM;AACrD,SAAK,YAAYZ,IAAKa,EAAY,KAAK,CAAC,EAAE,MAAAC,EAAI,MAAOA,MAAS,UAAU,OAAO,QAAQd,MAAO,SAAS,SAASA,EAAG,OACnH,KAAK,SAAS,CAAC,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,CAAC,EAAE,IAAI,CAACe,MAAMA,EAAE,eAAeP,CAAM,CAAC,GAChF,KAAK,iBAAiBP,IAAKY,EAAY,KAAK,CAAC,EAAE,MAAAC,EAAI,MAAOA,MAAS,SAAS,OAAO,QAAQb,MAAO,SAAS,SAASA,EAAG,OACvH,KAAK,kBAAkBC,IAAKW,EAAY,KAAK,CAAC,EAAE,MAAAC,EAAI,MAAOA,MAAS,OAAO,OAAO,QAAQZ,MAAO,SAAS,SAASA,EAAG,OACtH,KAAK,aAAaC,IAAKS,EAAa,cAAc,EAAE,EAAE,KAAK,CAAC,EAAE,MAAAE,EAAI,MAAOA,MAAS,WAAW,OAAO,QAAQX,MAAO,SAAS,SAASA,EAAG,OACpI,KAAK,kBAAkB,SACvB,KAAK,wBAAwB,KAAK,wBAAwB,IAErD,OAAOM,KAAc,WAC1B,KAAK,wBAAwB,KAAK,wBAAwBA,KAG1D,KAAK,yBAAyBL,IAAKK,KAAc,OAA+B,SAASA,EAAU,SAAS,QAAQL,MAAO,SAASA,IAAKQ,EAAa,gBAAe,EAAG,uBACxK,KAAK,yBAAyBP,IAAKI,KAAc,OAA+B,SAASA,EAAU,SAAS,QAAQJ,MAAO,SAASA,IAAKO,EAAa,gBAAe,EAAG;AAE5K,UAAMI,IAAY,CAACzB,MACRI,EAAgBJ,GAAK,KAAK,OAAO,CAAC,CAAC,GAExC0B,IAAY,CAAC1B,MACRA,EAAI,UAAUA,EAAI,YAAY,KAAK,gBAAgB,KAAK,OAAO,CAAC,IAAI,KAAK,OAAO,CAAC,CAAC,IAAI,CAAC;AAElG,SAAK,SAASyB,EAAUJ,EAAa,OAAO,CAAC,CAAC,GAC9C,KAAK,SAASK,EAAUL,EAAa,OAAO,CAAC,CAAC,GAC9C,KAAK,iBAAiBI,EAAUJ,EAAa,OAAO,EAAE,CAAC,GACvD,KAAK,iBAAiBK,EAAUL,EAAa,OAAO,EAAE,CAAC;AAAA,EAC/D;AAAA,EACI,MAAMrB,GAAK;AACP,QAAIA,GAAK;AACL,YAAM2B,IAAW,KAAK,WAAW3B,CAAG;AACpC,MAAAA,IAAM,KAAK,gBAAgBA,CAAG,GAC9BA,IAAM,KAAK,cAAcA,GAAK2B,CAAQ,GACtC3B,IAAM,KAAK,kBAAkBA,CAAG;AAChC,YAAM4B,IAAW,KAAK,gBAAgB,MAAM7B,EAAa,KAAK,aAAa,CAAC,aAAa,IACnF8B,IAAQ,KAAK,uBAAuB7B,CAAG,EAAE,MAAM,IAAI,OAAO,IAAIM,CAAe,GAAGsB,CAAQ,GAAG,CAAC;AAClG,UAAIC,KAAS,KAAK,qBAAqB,KAAK,gBAAgB7B,EAAI,MAAM,KAAK,aAAa,EAAE,CAAC,IAAIA,GAAK,OAAO6B,EAAM,CAAC,CAAC,CAAC;AAChH,eAAO,CAAO,GAAGF,IAAW,MAAM,EAAE,GAAG,KAAK,WAAWE,EAAM,CAAC,CAAC,CAAC,IAAI,KAAK,WAAWA,EAAM,CAAC,KAAK,EAAE,CAAC;AAAA,IAEnH;AACQ,WAAO;AAAA,EACf;AAAA,EACI,qBAAqBC,GAAiBC,GAAe;AACjD,UAAMvB,IAAU,EAAE,GAAG,KAAK,SAAS,uBAAuB,EAAG;AAC7D,WAAO;AAAA,MACH,KAAK,cAAc,KAAK,gBAAgBuB,EAAc,eAAe,KAAK,QAAQ,EAAE,GAAGvB,GAAS,aAAa,GAAI,CAAE,CAAC,GAAG,EAAK;AAAA,MAC5H,KAAK,cAAc,KAAK,gBAAgBuB,EAAc,eAAe,KAAK,QAAQ,EAAE,GAAGvB,GAAS,aAAa,GAAO,CAAA,CAAC,GAAG,EAAK;AAAA,IACzI,EAAU,SAASsB,CAAe;AAAA,EAClC;AAAA,EACI,OAAOE,GAAOxB,IAAU;AAAA,IACpB,uBAAuB,KAAK;AAAA,IAC5B,uBAAuB,KAAK;AAAA,EACpC,GAAO;AACC,WAAOwB,KAAS,OAAOA,EAAM,eAAe,KAAK,QAAQ,EAAE,GAAG,KAAK,SAAS,GAAGxB,EAAO,CAAE,IAAI;AAAA,EACpG;AAAA,EACI,WAAWR,GAAK;AACZ,WAAO,GAAG,KAAK,OAAO,CAAC,CAAC,GAAG,KAAK,aAAa,GAAG,KAAK,iBAAiBA,EAAI,UAAU,CAAC,CAAC,EAAE,UAAU,GAAG,KAAK,qBAAqB,CAAC;AAAA,EACxI;AAAA,EACI,qBAAqBA,GAAK;AACtB,WAAO,CAAC,CAAC,KAAK,gBAAgB,KAAK,uBAAuBA,CAAG,CAAC,EAAE,MAAM,IAAI,OAAO,IAAIM,CAAe,GAAGP,EAAa,KAAK,aAAa,CAAC,GAAG,CAAC;AAAA,EACnJ;AAAA,EACI,WAAWC,GAAK;AACZ,WAAQA,EAAI,WAAW,KAAK,cAAc,KACrC,KAAK,cAAc,WAAcA,EAAI,WAAW,GAAG,KAAKA,EAAI,WAAW,GAAG,MAC1E,KAAK,cAAc,UAAaA,EAAI,QAAQ,KAAK,KAAK,SAAS,EAAE,WAAW,KAAK,SAAS;AAAA,EACvG;AAAA,EACI,eAAeA,GAAK2B,GAAU;AAC1B,WAAO,GAAGA,IAAW,KAAK,iBAAiB,KAAK,MAAM,GAAG3B,CAAG,GAAG2B,IAAW,KAAK,iBAAiB,KAAK,MAAM;AAAA,EACnH;AAAA,EACI,uBAAuB3B,GAAK;AACxB,WAAO,KAAK,mBAAmB,SAAYA,EAAI,QAAQ,IAAI,OAAOD,EAAa,KAAK,cAAc,GAAG,GAAG,GAAG,EAAE,IAAIC;AAAA,EACzH;AAAA,EACI,kBAAkBA,GAAK;AACnB,WAAI,KAAK,cAAc,SACZA,EAAI,QAAQ,KAAK,KAAK,SAAS,EAAE,QAAQ,KAAK,WAAW,EAAE,IAG3DA,EAAI,QAAQ,UAAU,EAAE;AAAA,EAE3C;AAAA,EACI,cAAcA,GAAK2B,GAAU;AACzB,WAAO3B,EAAI,QAAQ2B,IAAW,KAAK,iBAAiB,KAAK,QAAQ,EAAE,EAAE,QAAQA,IAAW,KAAK,iBAAiB,KAAK,QAAQ,EAAE;AAAA,EACrI;AAAA,EACI,0BAA0B3B,GAAKiC,GAAM;AACjC,WAAA5B,EAAmB,QAAQ,CAAC6B,MAAM;AAC9B,MAAAlC,IAAMA,EAAI,UAAU,GAAGiC,CAAI,IAAIjC,EAAI,UAAUiC,CAAI,EAAE,QAAQC,GAAG,KAAK,aAAa;AAAA,IAC5F,CAAS,GACMlC;AAAA,EACf;AAAA,EACI,gBAAgBA,GAAK;AACjB,WAAI,KAAK,OAAO,CAAC,MAAM,OACnB,KAAK,OAAO,QAAQ,CAACmC,GAAOC,MAAU;AAClC,MAAApC,IAAMA,EAAI,QAAQ,IAAI,OAAOmC,GAAO,GAAG,GAAG,OAAOC,CAAK,CAAC;AAAA,IACvE,CAAa,GAEEpC;AAAA,EACf;AAAA,EACI,WAAWA,GAAK;AACZ,WAAO,KAAK,gBAAgBA,CAAG,EAAE,QAAQ,QAAQ,EAAE;AAAA,EAC3D;AAAA,EACI,iBAAiBA,GAAK;AAClB,WAAOA,EAAI,QAAQ,IAAI,OAAO,KAAK,KAAK,OAAO,KAAK,EAAE,CAAC,MAAM,GAAG,GAAG,EAAE;AAAA,EAC7E;AACA;AAEA,MAAMqC,EAAkB;AAAA,EACpB,YAAYC,GAAgB;AACxB,SAAK,iBAAiBA;AAAA,EAC9B;AACA;AACA,MAAMC,UAAyBF,EAAkB;AAAA,EAC7C,cAAcrC,GAAKwC,IAAyB,IAAI;AAC5C,UAAMb,IAAW,KAAK,eAAe,WAAW3B,CAAG,GAC7CyC,IAAuB,CAACzC,MAAQA,MAAQ,MAC1C2B,KACA,EAAE,KAAK,eAAe,cAAc,SAC9Ba,MAA2B,KAAK,eAAe,iBAAiB,KAAK,eAAe,iBACpFA,MAA2B,KAAK,eAAe,iBACnDE,IAAuB,CAAC1C,MAAQ;AAClC,UAAIyC,EAAqBzC,CAAG;AACxB,eAAO;AAEN,UAAI,KAAK,eAAe,wBAAwB,GAAG;AACpD,YAAI,KAAK,eAAe,qBAAqBA,CAAG;AAC5C,iBAAOA;AAEN,YAAIA,EAAI,WAAW,KAAK,eAAe,aAAa;AACrD,iBAAO,KAAK,eAAe,WAAWA,CAAG;AAAA,MAE7D;AACY,aAAO;AAAA,IACV;AACD,QAAIgC,IAAQhC;AACZ,IAAAgC,IAAQ,KAAK,eAAe,cAAcA,GAAOL,CAAQ,GACzDK,IAAQ,KAAK,eAAe,kBAAkBA,CAAK;AACnD,UAAMW,IAAkBD,EAAqBV,CAAK;AAClD,QAAIW,KAAmB;AACnB,aAAO,KAAK,eAAe,eAAeA,GAAiBhB,CAAQ;AAEvE,UAAM,CAACiB,GAAS,GAAGhB,CAAQ,IAAII,EAAM,MAAM,KAAK,eAAe,aAAa,GACtEa,IAAgB5C,EAAmB,KAAK,eAAe,WAAW2C,CAAO,CAAC,GAC1EE,IAAiB,KAAK,eAAe,WAAWlB,EAAS,KAAK,EAAE,CAAC,EAAE,UAAU,GAAG,KAAK,eAAe,qBAAqB,GACzHmB,IAAkBnB,EAAS,SAAS,KAAKkB,EAAe,WAAW,GACnEE,IAAuBH,MAAkB,MAC3ClB,MACC,KAAK,eAAe,cAAc,SAC7Ba,MAA2BxC,EAAI,MAAM,GAAG,EAAE,IAAI,KAAK,eAAe,iBAClEwC,MAA2BxC,EAAI,MAAM,GAAG,EAAE;AACpD,WAAI+C,KAAmBC,KAAwBP,EAAqBI,CAAa,IACtEL,IAEFK,EAAc,MAAM,KAAK,IACvB;AAAA,MACH,aAAa,CAAO,GAAGlB,IAAW,MAAM,EAAE,GAAGkB,CAAa,IAAIC,CAAc;AAAA,MAC5E,gBAAAA;AAAA,IACH,IAGM;AAAA,EAEnB;AACA;AACA,MAAMG,UAAmCZ,EAAkB;AAAA,EACvD,cAAcrC,GAAKwC,IAAyB,IAAI;AAC5C,QAAIxC,MAAQ,MACP,KAAK,eAAe,MAAMwC,CAAsB,MAAM,KACnD,KAAK,eAAe,cAAcA,GAAwB,EAAI,EAAE,MAAM,GAAG,EAAE,MAAM,KAAK,eAAe,cAAcxC,GAAK,EAAI;AAChI,aAAO;AAEX,UAAM2B,IAAW,KAAK,eAAe,WAAW3B,CAAG,GAC7CkD,IAAc,KAAK,eAAe,kBAAkBlD,CAAG,MAAM,KAC7D,KACA,CAAO,GAAG2B,IAAW,MAAM,EAAE,GAAG1B,EAAmB,KAAK,eAAe,WAAWD,CAAG,CAAC,CAAC,KAAM,KAAK,IAAI,IAAI,KAAK,eAAe,qBAAqB;AACzJ,WAAO;AAAA,MACH,aAAAkD;AAAA,MACA,gBAAgBA,EAAY,QAAQ,KAAK,eAAe,qBAAqB,EAAE,MAAM,CAAC,KAAK,eAAe,qBAAqB;AAAA,IAClI;AAAA,EACT;AACA;AAEA,MAAMC,IAAkB;AAAA,EACpB,QAAQ;AAAA,EACR,UAAU;AAAA,EACV,iBAAiB;AAAA,EACjB,8BAA8B;AAAA,EAC9B,2BAA2B;AAAA,EAC3B,oCAAoC;AAAA,EACpC,WAAW;AAAA,EACX,mBAAmB;AAAA,EACnB,YAAY;AAAA,EACZ,aAAa;AAAA,EACb,cAAc;AAClB;AACA,MAAMC,EAAc;AAAA,EAChB,YAAYC,GAAM;AACd,SAAK,KAAKA,EAAK,IACf,KAAK,UAAUA,EAAK,SACpB,KAAK,WAAWA,EAAK,UACrB,KAAK,iBAAkB,GACvB,KAAK,KAAKA,EAAK,OAAO;AAAA,EAC9B;AAAA,EACI,WAAW7C,GAAS;AAChB,SAAK,KAAKA,CAAO,GACjB,KAAK,OAAO,KAAK,eAAe,OAAO,KAAK,mBAAmB,KAAK,WAAW,CAAC,CAAC,GACjF,KAAK,SAAS,KAAK,UAAU;AAAA,EACrC;AAAA,EACI,WAAW;AAEP,WAAO,EAAE,QADW,KAAK,gBAAgB,KAAK,eAAe,OAAO,KAAK,UAAU,KAAK,aAAa,KAAK,YAAY,IAAI,KAAK,aACjG,WAAW,KAAK,eAAgB;AAAA,EACtE;AAAA,EACI,SAASwB,GAAO;AACZ,UAAMsB,IAAW,KAAK,iBAAiB,UAAatB,KAAS,OAAO,KAAK,QAAQA,GAAO,KAAK,YAAY,IAAIA;AAC7G,IAAIsB,MAAa,KAAK,gBAClB,KAAK,OAAO,KAAK,eAAe,OAAO,KAAK,mBAAmBA,CAAQ,CAAC,CAAC,GACzE,KAAK,SAAS,KAAK,UAAU;AAAA,EAEzC;AAAA,EACI,KAAK9C,GAAS;AACV,SAAK,UAAU;AAAA,MACX,GAAG2C;AAAA,MACH,GAAG3C;AAAA,IACN,GACG,KAAK,QAAQ,sBACb,KAAK,QAAQ,qCAAqC,KAEjD,KAAK,GAAG,aAAa,WAAW,KACjC,KAAK,GAAG,aAAa,aAAa,KAAK,QAAQ,oBAAoB,YAAY,SAAS,GAE5F,KAAK,iBAAiB,IAAID,EAAe,KAAK,OAAO,GACrD,KAAK,aAAa,KAAK,QAAQ,oBAAoB,IAAI0C,EAA2B,KAAK,cAAc,IAAI,IAAIV,EAAiB,KAAK,cAAc;AACjJ,UAAMgB,IAAsB;AAAA,MACxB,CAACzD,EAAa,SAAS,GAAG,KAAK,eAAe;AAAA,MAC9C,CAACA,EAAa,SAAS,GAAG;AAAA,MAC1B,CAACA,EAAa,QAAQ,GAAG;AAAA,MACzB,CAACA,EAAa,QAAQ,GAAG;AAAA,IAC5B;AACD,SAAK,eAAe,KAAK,QAAQ,eAAeyD,EAAoB,KAAK,QAAQ,YAAY,IAAI,QACjG,KAAK,6BACD,KAAK,iBAAiB,UAAa,KAAK,QAAQ,iBAAiBzD,EAAa,YACxE,KAAK,eAAe,KAAK,eAAe,wBACxC,KAAK,eAAe,uBAC9B,KAAK,WAAW,KAAK,YAAa,GAClC,KAAK,WAAW,KAAK,YAAa;AAAA,EAC1C;AAAA,EACI,cAAc;AACV,QAAIW,GAAIC;AACR,QAAI8C,IAAM,KAAK,QAAQ,CAAC,OAAO,gBAAgB;AAC/C,aAAM/C,IAAK,KAAK,QAAQ,gBAAgB,QAAQA,MAAO,SAAS,SAASA,EAAG,SAAS,WACjF+C,IAAM,KAAK,KAAK9C,IAAK,KAAK,QAAQ,gBAAgB,QAAQA,MAAO,SAAS,SAASA,EAAG,KAAK,KAAK,QAAQ,CAAC,OAAO,gBAAgB,CAAC,IAE9H8C;AAAA,EACf;AAAA,EACI,cAAc;AACV,QAAI/C,GAAIC;AACR,QAAI+C,IAAM,KAAK,QAAQ,OAAO,gBAAgB;AAC9C,aAAMhD,IAAK,KAAK,QAAQ,gBAAgB,QAAQA,MAAO,SAAS,SAASA,EAAG,SAAS,WACjFgD,IAAM,KAAK,KAAK/C,IAAK,KAAK,QAAQ,gBAAgB,QAAQA,MAAO,SAAS,SAASA,EAAG,KAAK,KAAK,QAAQ,OAAO,gBAAgB,CAAC,IAE7H+C;AAAA,EACf;AAAA,EACI,QAAQzB,GAAO0B,GAAmB;AAC9B,WAAO1B,IAAQ,KAAK,IAAI,IAAI0B,KAAiF,KAAK,0BAA0B;AAAA,EACpJ;AAAA,EACI,UAAU1B,GAAO0B,GAAmB;AAChC,WAAO,OAAO1B,EACT,QAAQ0B,KAAiF,KAAK,0BAA0B,EACxH,MAAM,GAAG,EACT,KAAK,EAAE,CAAC;AAAA,EACrB;AAAA,EACI,mBAAmB1B,GAAO;AACtB,WAAOA,KAAS,OAAO,KAAK,IAAI,KAAK,IAAIA,GAAO,KAAK,QAAQ,GAAG,KAAK,QAAQ,IAAIA;AAAA,EACzF;AAAA,EACI,OAAOA,GAAO2B,IAA8B,IAAO;AAC/C,QAAI3B,KAAS,MAAM;AACf,MAAI,KAAK,4BAA4B,WACjCA,IAAQ,KAAK,eAAe,0BAA0BA,GAAO,KAAK,uBAAuB,GACzF,KAAK,0BAA0B;AAEnC,YAAM4B,IAAiB,KAAK,WAAW,cAAc5B,GAAO,KAAK,cAAc;AAC/E,UAAI6B;AACJ,UAAI,OAAOD,KAAmB,UAAU;AACpC,cAAM,EAAE,aAAAV,GAAa,gBAAAJ,EAAc,IAAKc;AACxC,YAAI,EAAE,uBAAAE,GAAuB,uBAAAC,EAAuB,IAAG,KAAK;AAC5D,QAAI,KAAK,QACLA,IAAwBJ,IAClBb,EAAe,QAAQ,OAAO,EAAE,EAAE,SAClC,KAAK,IAAIgB,GAAuBhB,EAAe,MAAM,IAEtD,OAAO,UAAUI,CAAW,KAAK,CAAC,KAAK,QAAQ,sBAAsB,KAAK,QAAQ,cAAc,UAAaa,MAA0B,OAC5IA,IAAwBD,IAAwB,IAEpDD,IACI,KAAK,UAAU,KAAK,IAAIX,CAAW,CAAC,IAAI,OAAO,mBACzC,KAAK,iBACL,KAAK,eAAe,OAAOA,GAAa;AAAA,UACtC,aAAa,KAAK,QAAQ,gBAAgB,MAAS,EAAE,KAAK,SAAS,KAAK,QAAQ;AAAA,UAChF,uBAAAa;AAAA,UACA,uBAAAD;AAAA,QAC5B,CAAyB;AAAA,MACzB;AAEgB,QAAAD,IAAiBD;AAErB,MAAI,KAAK,YAAY,KAAK,CAAC,KAAK,eAAe,WAAWC,CAAc,KAAK,KAAK,eAAe,MAAMA,CAAc,MAAM,MACvHA,IAAiBA,EAAe,QAAQ,KAAK,eAAe,QAAQ,KAAK,eAAe,cAAc,IAEtG,KAAK,YAAY,MACjBA,IAAiBA,EAAe,QAAQ,KAAK,eAAe,gBAAgB,KAAK,eAAe,MAAM,KAEtG,KAAK,QAAQ,oBAAoBhE,EAAgB,UAAW,KAAK,SAAS,KAAK,QAAQ,+BACvFgE,IAAiBA,EACZ,QAAQ,KAAK,eAAe,gBAAgB,KAAK,eAAe,cAAc,SAAY,KAAK,eAAe,YAAY,GAAG,EAC7H,QAAQ,KAAK,eAAe,gBAAgB,KAAK,eAAe,cAAc,SAAY,KAAK,GAAG,EAClG,QAAQ,KAAK,eAAe,QAAQ,EAAE,EACtC,QAAQ,KAAK,eAAe,QAAQ,EAAE,IAE/C,KAAK,GAAG,QAAQA,GAChB,KAAK,cAAc,KAAK,eAAe,MAAMA,CAAc;AAAA,IACvE;AAEY,WAAK,GAAG,QAAQ,IAChB,KAAK,cAAc;AAEvB,SAAK,iBAAiB,KAAK,GAAG,OAC9B,KAAK,QAAQ,KAAK,UAAU;AAAA,EACpC;AAAA,EACI,mBAAmB;AACf,SAAK,GAAG,iBAAiB,SAAS,CAACG,MAAM;AACrC,YAAM,EAAE,OAAAhC,GAAO,gBAAAiC,EAAgB,IAAG,KAAK,IACjCC,IAAaF;AAKnB,UAJIC,KAAkBC,EAAW,QAAQ7D,EAAmB,SAAS6D,EAAW,IAAI,MAChF,KAAK,0BAA0BD,IAAiB,IAEpD,KAAK,OAAOjC,CAAK,GACb,KAAK,SAASiC,KAAkB,MAAM;AACtC,cAAME,IAA8B,MAAM;AACtC,gBAAM,EAAE,QAAAC,GAAQ,QAAAC,GAAQ,eAAAC,GAAe,uBAAAR,GAAuB,gBAAAS,EAAc,IAAK,KAAK;AACtF,cAAIC,IAAwBxC,EAAM,SAASiC;AAC3C,gBAAMQ,IAAiB,KAAK,eAAe;AAC3C,cAAI,KAAK,eAAe,cAAc,WAAczC,EAAM,WAAW,GAAG,KAAKA,EAAM,WAAW,GAAG,MAAM,CAACA,EAAM,SAAS,GAAG;AACtH,mBAAOyC,IAAiB,KAAK,eAAe,eAAe,SAAS,IAAI,KAAK,eAAe,UAAUR,CAAc,EAAE,SAAS;AAEnI,cAAI,KAAK,eAAe,UAAUA,GAAgB,CAAC,MAAMM,KACrDrE,EAAM,KAAK,gBAAgBqE,CAAc,MAAMrE,EAAM8B,GAAOuC,CAAc,IAAI;AAC9E,mBAAOE,IAAiBD,IAAwB;AAEpD,cAAIC,IAAiBD;AACjB,mBAAOP;AAEX,cAAIK,MAAkB,UAAatC,EAAM,QAAQsC,CAAa,MAAM,IAAI;AACpE,kBAAMI,IAAwB1C,EAAM,QAAQsC,CAAa,IAAI;AAC7D,gBAAI,KAAK,IAAIG,IAAiBzC,EAAM,MAAM,IAAI,KAAKiC,KAAkBS;AACjE,qBAAO,KAAK,eAAe,QAAQJ,CAAa,IAAI;AAGpD,YAAI,CAAC,KAAK,QAAQ,qBAAqBL,IAAiBS,KAChD,KAAK,eAAe,WAAW1C,EAAM,UAAU0C,CAAqB,CAAC,EAAE,SAAS,MAAMZ,MACtFU,KAAyB;AAAA,UAI7D;AACoB,iBAAO,KAAK,QAAQ,6BAA6B,KAAK,QAAQ,oBAAoB3E,EAAgB,SAC5F4E,IAAiBD,IACjB,KAAK,IAAIC,IAAiB,KAAK,IAAID,GAAuBH,EAAO,MAAM,GAAGD,EAAO,MAAM;AAAA,QAChG;AACD,aAAK,iBAAiBD,GAA6B;AAAA,MACnE;AAAA,IACA,CAAS,GACD,KAAK,GAAG,iBAAiB,SAAS,MAAM;AACpC,WAAK,QAAQ,IACb,KAAK,qBAAqB,KAAK,aAC/B,WAAW,MAAM;AACb,cAAM,EAAE,OAAAnC,GAAO,gBAAAiC,GAAgB,cAAAU,EAAc,IAAG,KAAK;AAErD,YADA,KAAK,OAAO3C,GAAO,KAAK,QAAQ,kCAAkC,GAC9DiC,KAAkB,QAAQU,KAAgB,QAAQ,KAAK,IAAIV,IAAiBU,CAAY,IAAI;AAC5F,eAAK,iBAAiB,GAAG,KAAK,GAAG,MAAM,MAAM;AAAA,iBAExCV,KAAkB,MAAM;AAC7B,gBAAMW,IAAuB,KAAK,wBAAwB5C,GAAOiC,CAAc;AAC/E,eAAK,iBAAiBW,CAAoB;AAAA,QAC9D;AAAA,MACA,CAAa;AAAA,IACb,CAAS,GACD,KAAK,GAAG,iBAAiB,QAAQ,MAAM;AACnC,WAAK,QAAQ,IACb,KAAK,OAAO,KAAK,eAAe,OAAO,KAAK,mBAAmB,KAAK,WAAW,CAAC,CAAC,GAC7E,KAAK,uBAAuB,KAAK,eACjC,KAAK,SAAS,KAAK,UAAU;AAAA,IAE7C,CAAS;AAAA,EACT;AAAA,EACI,wBAAwB5C,GAAOiC,GAAgB;AAC3C,QAAI,KAAK,eAAe;AACpB,aAAOA;AAEX,UAAM,EAAE,QAAAG,GAAQ,gBAAAS,GAAgB,QAAAR,GAAQ,gBAAAS,GAAgB,gBAAAP,GAAgB,UAAAxD,MAAa,KAAK,gBACpFgE,IAAa,KAAK,cAAc,GAChCC,IAAgBD,IAAaF,IAAiBT,GAC9Ca,IAAeD,EAAc;AACnC,QAAI,KAAK,QAAQ,6BAA6B,KAAK,QAAQ,oBAAoBnF,EAAgB;AAC3F,UAAIkF,GAAY;AACZ,YAAId,KAAkB;AAClB,iBAAO;AAEN,YAAIjC,EAAM,SAAS,GAAG,KAAKiC,IAAiBjC,EAAM,QAAQ,GAAG;AAC9D,iBAAO,KAAK,eAAe,SAAS;AAAA,MAExD;AAAA,WAEa;AACD,YAAMkD,IAAeH,IAAaD,EAAe,SAAST,EAAO;AACjE,UAAIJ,KAAkBjC,EAAM,SAASkD;AACjC,eAAO,KAAK,eAAe,SAASA;AAEnC,UAAIjB,IAAiBgB;AACtB,eAAOA;AAAA,IAEvB;AACQ,QAAIE,IAASlB;AACb,WAAI,KAAK,QAAQ,6BACb,KAAK,QAAQ,oBAAoBpE,EAAgB,UACjDoE,KAAkBgB,KAClBlE,MAAa,UACbiE,EAAc,SAASjE,CAAQ,MAC/BoE,KAAUF,GACNF,MACAI,KAAU,KAGd,KAAK,QAAQ,gCAAgCZ,MAAmB,WAChEY,KAAUjF,EAAM8B,EAAM,UAAU,GAAGiC,CAAc,GAAGM,CAAc,IAE/DY;AAAA,EACf;AAAA,EACI,iBAAiBC,GAAOC,IAAMD,GAAO;AACjC,SAAK,GAAG,kBAAkBA,GAAOC,CAAG;AAAA,EAC5C;AACA;AAEA,MAAMC,IAAY,CAACC,MAASA,KAAO,QAAiCA,EAAG,QAAQ,OAAO,IAAKA,IAAKA,KAAO,OAAwB,SAASA,EAAG,cAAc,OAAO;AAChK,SAASC,EAAiBhF,GAASiF,GAAU;AACzC,MAAIhF,GAAIC,GAAIC,GAAIC;AAChB,MAAI8E;AACJ,QAAMC,IAAWC,EAAI,IAAI,GACnB/B,IAAiB+B,EAAI,IAAI,GACzB1C,IAAc0C,EAAI,IAAI,GACtBC,IAAKC,EAAoB;AAClB,EAACD,KAAO,QAAiCA,EAAG,UAAWnF,KAAMD,IAAKoF,KAAO,OAAwB,SAASA,EAAG,WAAW,QAAQpF,MAAO,SAAS,SAASA,EAAG,WAAW,QAAQC,MAAO,UAAkBA,EAAG,KAAKmF,KAAO,OAAwB,SAASA,EAAG,KAAK;AAC7Q,QAAME,KAAUF,KAAO,OAAwB,SAASA,EAAG,YAAYlF,IAAKkF,KAAO,OAAwB,SAASA,EAAG,WAAW,QAAQlF,MAAO,SAAS,SAASA,EAAG,SAChKqF,IAASC,EAAQ,WAAW,GAAG;AACnB,EAAAD,OAAYpF,IAAKiF,KAAO,OAAwB,SAASA,EAAG,MAAM,oBAAoB,QAAQjF,MAAO,UAAkBA,EAAG;AAC5I,QAAMsF,IAAaC,EAAS,MAAMJ,KAAU,OAA2B,SAASA,EAAMC,IAAS,eAAe,OAAO,CAAC;AAGtH,SAAAI,EAAMT,GAAU,CAAC3D,MAAU;AACvB,QAAIvB;AACJ,QAAIuB,GAAO;AACP,YAAMuD,IAAKD,GAAW7E,IAAKuB,KAAU,OAA2B,SAASA,EAAM,SAAS,QAAQvB,MAAO,SAASA,IAAKuB,CAAK;AAC1H,MAAIuD,KACAG,IAAgB,IAAItC,EAAc;AAAA,QAC9B,IAAAmC;AAAA,QACA,SAAA/E;AAAA,QACA,SAAS,CAACwB,MAAU;AAIhB,UAAAkB,EAAY,QAAQlB,EAAM,QAC1B6B,EAAe,QAAQ7B,EAAM;AAAA,QAChC;AAAA,QACD,UAAU,CAACA,MAAU;AAAA,QAIzC;AAAA,MACA,CAAiB,GACD0D,EAAc,SAASQ,EAAW,KAAK,KAGvC,QAAQ,MAAM,iGAAiG;AAAA,IAE/H;AAEY,MAAAR,IAAgB;AAAA,EAE5B,CAAK,GACM;AAAA,IACH,UAAAC;AAAA,IACA,aAAAzC;AAAA,IACA,gBAAAW;AAAA,IACA,UAAU,CAAC7B,MAAU0D,KAAkB,OAAmC,SAASA,EAAc,SAAS1D,CAAK;AAAA,IAC/G,YAAY,CAACxB,MAAYkF,KAAkB,OAAmC,SAASA,EAAc,WAAWlF,CAAO;AAAA,EAC1H;AACL;;;;;;;;;;;;;;;;;;;;;;;;;;AC5hBE,UAAM6F,IAAoD;AAAA,MACxD,UAAU;AAAA,MACV,iBAAiBxG,EAAgB;AAAA,MACjC,WAAW;AAAA,MACX,2BAA2B;AAAA,MAC3B,8BAA8B;AAAA,MAC9B,oCAAoC;AAAA,MACpC,mBAAmB;AAAA,MACnB,aAAa;AAAA,MACb,gBAAgB;AAAA,IAClB,GAQMkG,IAAQO,GAWRC,IAAOC,GAOPC,IAAQC,EAAS,GAEjBC,IAAuBR,EAAS,OAC7B;AAAA,MACL,GAAGE;AAAA,MACH,GAAKO,EAAQb,EAAM,YAAY,IAAyB,CAAA,IAArBA,EAAM;AAAA,IAC3C,EACD,GAEK,EAAE,UAAUc,GAAS,YAAAC,GAAY,UAAAC,GAAU,aAAA7D,MAAgBsC,EAAiBmB,EAAqB,KAAY;AAEtG,IAAAK,EAAA,EAAE,SAAAH,GAAS,GAExBT;AAAA,MACE,MAAMlD,EAAY;AAAA,MAClB,CAACI,MAAqC;;AAChC,YAAA2D;AAEJ,QAAI,OAAO,GAAG3D,GAAU,EAAE,IACpB,OAAOqD,EAAqB,MAAM,aAAc,WAClDM,IAAc,QAAQ,IAAI,OAAON,EAAqB,MAAM,SAAS,IAErEM,IAAc,QAAQ,IAAI,SAAOxG,IAAAkG,EAAqB,MAAM,cAA3B,gBAAAlG,EAAsC,QAAO,CAAC,IAGjFwG,IAAc,OAAO3D,KAAa,WAAWA,EAAS,QAAQ,CAAC,IAAIA,GAGrEiD,EAAK,sBAAsBU,CAAW;AAAA,MAAA;AAAA,IAE1C,GAEAb;AAAA,MACE,MAAML,EAAM;AAAA,MACZ,CAACzC,MAAqC;AAChCJ,YAAAA;AAEA,QAAA,OAAOI,KAAa,WACtBJ,IAAc,WAAWI,KAAY,GAAG,IAExCJ,IAAcI,GAGhByD,EAAS7D,CAAW;AAAA,MAAA;AAAA,IAExB,GAEAkD;AAAA,MACE,MAAML,EAAM;AAAA,MACZ,MAAM;AACJ,QAAAe,EAAWH,EAAqB,KAAK;AAAA,MAAA;AAAA,IAEzC;AAEM,UAAAO,IAAaf,EAAS,MAAM;AAEhC,YAAM,EAAE,cAAcgB,GAAG,GAAGC,EAAqC,IAAArB;AAEjE,aAAO,EAAE,GAAGqB,GAAkC,GAAGX,EAAM;AAAA,IAAA,CACxD;;;;;;;;;;;;;;;;;;;","x_google_ignoreList":[0]}
|
|
1
|
+
{"version":3,"file":"CurrencyInput.js","sources":["../node_modules/.pnpm/vue-currency-input@3.1.0_vue@3.5.13_typescript@5.4.2_/node_modules/vue-currency-input/dist/index.mjs","../src/components/CurrencyInput/CurrencyInput.vue"],"sourcesContent":["/**\n * Vue Currency Input 3.1.0\n * (c) 2018-2024 Matthias Stiller\n * @license MIT\n */\nimport { ref, getCurrentInstance, version, computed, watch } from 'vue';\n\nvar CurrencyDisplay;\n(function (CurrencyDisplay) {\n CurrencyDisplay[\"symbol\"] = \"symbol\";\n CurrencyDisplay[\"narrowSymbol\"] = \"narrowSymbol\";\n CurrencyDisplay[\"code\"] = \"code\";\n CurrencyDisplay[\"name\"] = \"name\";\n CurrencyDisplay[\"hidden\"] = \"hidden\";\n})(CurrencyDisplay || (CurrencyDisplay = {}));\nvar ValueScaling;\n(function (ValueScaling) {\n ValueScaling[\"precision\"] = \"precision\";\n ValueScaling[\"thousands\"] = \"thousands\";\n ValueScaling[\"millions\"] = \"millions\";\n ValueScaling[\"billions\"] = \"billions\";\n})(ValueScaling || (ValueScaling = {}));\n\nconst escapeRegExp = (str) => {\n return str.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\$&');\n};\nconst removeLeadingZeros = (str) => {\n return str.replace(/^0+(0$|[^0])/, '$1');\n};\nconst count = (str, search) => {\n return (str.match(new RegExp(escapeRegExp(search), 'g')) || []).length;\n};\nconst substringBefore = (str, search) => {\n return str.substring(0, str.indexOf(search));\n};\n\nconst DECIMAL_SEPARATORS = [\n ',',\n '.',\n '٫',\n '。'\n];\nconst INTEGER_PATTERN = '(0|[1-9]\\\\d*)';\nclass CurrencyFormat {\n constructor(options) {\n var _a, _b, _c, _d, _e, _f;\n const { currency, currencyDisplay, locale, precision, accountingSign, useGrouping } = options;\n this.locale = locale;\n this.options = {\n currency,\n useGrouping,\n style: 'currency',\n currencySign: accountingSign ? 'accounting' : undefined,\n currencyDisplay: currencyDisplay !== CurrencyDisplay.hidden ? currencyDisplay : undefined\n };\n const numberFormat = new Intl.NumberFormat(locale, this.options);\n const formatParts = numberFormat.formatToParts(123456);\n this.currency = (_a = formatParts.find(({ type }) => type === 'currency')) === null || _a === void 0 ? void 0 : _a.value;\n this.digits = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9].map((i) => i.toLocaleString(locale));\n this.decimalSymbol = (_b = formatParts.find(({ type }) => type === 'decimal')) === null || _b === void 0 ? void 0 : _b.value;\n this.groupingSymbol = (_c = formatParts.find(({ type }) => type === 'group')) === null || _c === void 0 ? void 0 : _c.value;\n this.minusSign = (_d = numberFormat.formatToParts(-1).find(({ type }) => type === 'minusSign')) === null || _d === void 0 ? void 0 : _d.value;\n if (this.decimalSymbol === undefined) {\n this.minimumFractionDigits = this.maximumFractionDigits = 0;\n }\n else if (typeof precision === 'number') {\n this.minimumFractionDigits = this.maximumFractionDigits = precision;\n }\n else {\n this.minimumFractionDigits = (_e = precision === null || precision === void 0 ? void 0 : precision.min) !== null && _e !== void 0 ? _e : numberFormat.resolvedOptions().minimumFractionDigits;\n this.maximumFractionDigits = (_f = precision === null || precision === void 0 ? void 0 : precision.max) !== null && _f !== void 0 ? _f : numberFormat.resolvedOptions().maximumFractionDigits;\n }\n const getPrefix = (str) => {\n return substringBefore(str, this.digits[1]);\n };\n const getSuffix = (str) => {\n return str.substring(str.lastIndexOf(this.decimalSymbol ? this.digits[0] : this.digits[1]) + 1);\n };\n this.prefix = getPrefix(numberFormat.format(1));\n this.suffix = getSuffix(numberFormat.format(1));\n this.negativePrefix = getPrefix(numberFormat.format(-1));\n this.negativeSuffix = getSuffix(numberFormat.format(-1));\n }\n parse(str) {\n if (str) {\n const negative = this.isNegative(str);\n str = this.normalizeDigits(str);\n str = this.stripCurrency(str, negative);\n str = this.stripSignLiterals(str);\n const fraction = this.decimalSymbol ? `(?:${escapeRegExp(this.decimalSymbol)}(\\\\d*))?` : '';\n const match = this.stripGroupingSeparator(str).match(new RegExp(`^${INTEGER_PATTERN}${fraction}$`));\n if (match && this.isValidIntegerFormat(this.decimalSymbol ? str.split(this.decimalSymbol)[0] : str, Number(match[1]))) {\n return Number(`${negative ? '-' : ''}${this.onlyDigits(match[1])}.${this.onlyDigits(match[2] || '')}`);\n }\n }\n return null;\n }\n isValidIntegerFormat(formattedNumber, integerNumber) {\n const options = { ...this.options, minimumFractionDigits: 0 };\n return [\n this.stripCurrency(this.normalizeDigits(integerNumber.toLocaleString(this.locale, { ...options, useGrouping: true })), false),\n this.stripCurrency(this.normalizeDigits(integerNumber.toLocaleString(this.locale, { ...options, useGrouping: false })), false)\n ].includes(formattedNumber);\n }\n format(value, options = {\n minimumFractionDigits: this.minimumFractionDigits,\n maximumFractionDigits: this.maximumFractionDigits\n }) {\n return value != null ? value.toLocaleString(this.locale, { ...this.options, ...options }) : '';\n }\n toFraction(str) {\n return `${this.digits[0]}${this.decimalSymbol}${this.onlyLocaleDigits(str.substring(1)).substring(0, this.maximumFractionDigits)}`;\n }\n isFractionIncomplete(str) {\n return !!this.normalizeDigits(this.stripGroupingSeparator(str)).match(new RegExp(`^${INTEGER_PATTERN}${escapeRegExp(this.decimalSymbol)}$`));\n }\n isNegative(str) {\n return (str.startsWith(this.negativePrefix) ||\n (this.minusSign === undefined && (str.startsWith('(') || str.startsWith('-'))) ||\n (this.minusSign !== undefined && str.replace('-', this.minusSign).startsWith(this.minusSign)));\n }\n insertCurrency(str, negative) {\n return `${negative ? this.negativePrefix : this.prefix}${str}${negative ? this.negativeSuffix : this.suffix}`;\n }\n stripGroupingSeparator(str) {\n return this.groupingSymbol !== undefined ? str.replace(new RegExp(escapeRegExp(this.groupingSymbol), 'g'), '') : str;\n }\n stripSignLiterals(str) {\n if (this.minusSign !== undefined) {\n return str.replace('-', this.minusSign).replace(this.minusSign, '');\n }\n else {\n return str.replace(/[-()]/g, '');\n }\n }\n stripCurrency(str, negative) {\n return str.replace(negative ? this.negativePrefix : this.prefix, '').replace(negative ? this.negativeSuffix : this.suffix, '');\n }\n normalizeDecimalSeparator(str, from) {\n DECIMAL_SEPARATORS.forEach((s) => {\n str = str.substring(0, from) + str.substring(from).replace(s, this.decimalSymbol);\n });\n return str;\n }\n normalizeDigits(str) {\n if (this.digits[0] !== '0') {\n this.digits.forEach((digit, index) => {\n str = str.replace(new RegExp(digit, 'g'), String(index));\n });\n }\n return str;\n }\n onlyDigits(str) {\n return this.normalizeDigits(str).replace(/\\D+/g, '');\n }\n onlyLocaleDigits(str) {\n return str.replace(new RegExp(`[^${this.digits.join('')}]*`, 'g'), '');\n }\n}\n\nclass AbstractInputMask {\n constructor(currencyFormat) {\n this.currencyFormat = currencyFormat;\n }\n}\nclass DefaultInputMask extends AbstractInputMask {\n conformToMask(str, previousConformedValue = '') {\n const negative = this.currencyFormat.isNegative(str);\n const isEmptyNegativeValue = (str) => str === '' &&\n negative &&\n !(this.currencyFormat.minusSign === undefined\n ? previousConformedValue === this.currencyFormat.negativePrefix + this.currencyFormat.negativeSuffix\n : previousConformedValue === this.currencyFormat.negativePrefix);\n const checkIncompleteValue = (str) => {\n if (isEmptyNegativeValue(str)) {\n return '';\n }\n else if (this.currencyFormat.maximumFractionDigits > 0) {\n if (this.currencyFormat.isFractionIncomplete(str)) {\n return str;\n }\n else if (str.startsWith(this.currencyFormat.decimalSymbol)) {\n return this.currencyFormat.toFraction(str);\n }\n }\n return null;\n };\n let value = str;\n value = this.currencyFormat.stripCurrency(value, negative);\n value = this.currencyFormat.stripSignLiterals(value);\n const incompleteValue = checkIncompleteValue(value);\n if (incompleteValue != null) {\n return this.currencyFormat.insertCurrency(incompleteValue, negative);\n }\n const [integer, ...fraction] = value.split(this.currencyFormat.decimalSymbol);\n const integerDigits = removeLeadingZeros(this.currencyFormat.onlyDigits(integer));\n const fractionDigits = this.currencyFormat.onlyDigits(fraction.join('')).substring(0, this.currencyFormat.maximumFractionDigits);\n const invalidFraction = fraction.length > 0 && fractionDigits.length === 0;\n const invalidNegativeValue = integerDigits === '' &&\n negative &&\n (this.currencyFormat.minusSign === undefined\n ? previousConformedValue === str.slice(0, -2) + this.currencyFormat.negativeSuffix\n : previousConformedValue === str.slice(0, -1));\n if (invalidFraction || invalidNegativeValue || isEmptyNegativeValue(integerDigits)) {\n return previousConformedValue;\n }\n else if (integerDigits.match(/\\d+/)) {\n return {\n numberValue: Number(`${negative ? '-' : ''}${integerDigits}.${fractionDigits}`),\n fractionDigits\n };\n }\n else {\n return '';\n }\n }\n}\nclass AutoDecimalDigitsInputMask extends AbstractInputMask {\n conformToMask(str, previousConformedValue = '') {\n if (str === '' ||\n (this.currencyFormat.parse(previousConformedValue) === 0 &&\n this.currencyFormat.stripCurrency(previousConformedValue, true).slice(0, -1) === this.currencyFormat.stripCurrency(str, true))) {\n return '';\n }\n const negative = this.currencyFormat.isNegative(str);\n const numberValue = this.currencyFormat.stripSignLiterals(str) === ''\n ? -0\n : Number(`${negative ? '-' : ''}${removeLeadingZeros(this.currencyFormat.onlyDigits(str))}`) / Math.pow(10, this.currencyFormat.maximumFractionDigits);\n return {\n numberValue,\n fractionDigits: numberValue.toFixed(this.currencyFormat.maximumFractionDigits).slice(-this.currencyFormat.maximumFractionDigits)\n };\n }\n}\n\nconst DEFAULT_OPTIONS = {\n locale: undefined,\n currency: undefined,\n currencyDisplay: undefined,\n hideGroupingSeparatorOnFocus: true,\n hideCurrencySymbolOnFocus: true,\n hideNegligibleDecimalDigitsOnFocus: true,\n precision: undefined,\n autoDecimalDigits: false,\n valueRange: undefined,\n useGrouping: undefined,\n valueScaling: undefined\n};\nclass CurrencyInput {\n constructor(args) {\n this.el = args.el;\n this.onInput = args.onInput;\n this.onChange = args.onChange;\n this.addEventListener();\n this.init(args.options);\n }\n setOptions(options) {\n this.init(options);\n this.format(this.currencyFormat.format(this.validateValueRange(this.numberValue)));\n this.onChange(this.getValue());\n }\n getValue() {\n const numberValue = this.valueScaling && this.numberValue != null ? this.toInteger(this.numberValue, this.valueScaling) : this.numberValue;\n return { number: numberValue, formatted: this.formattedValue };\n }\n setValue(value) {\n const newValue = this.valueScaling !== undefined && value != null ? this.toFloat(value, this.valueScaling) : value;\n if (newValue !== this.numberValue) {\n this.format(this.currencyFormat.format(this.validateValueRange(newValue)));\n this.onChange(this.getValue());\n }\n }\n init(options) {\n this.options = {\n ...DEFAULT_OPTIONS,\n ...options\n };\n if (this.options.autoDecimalDigits) {\n this.options.hideNegligibleDecimalDigitsOnFocus = false;\n }\n if (!this.el.getAttribute('inputmode')) {\n this.el.setAttribute('inputmode', this.options.autoDecimalDigits ? 'numeric' : 'decimal');\n }\n this.currencyFormat = new CurrencyFormat(this.options);\n this.numberMask = this.options.autoDecimalDigits ? new AutoDecimalDigitsInputMask(this.currencyFormat) : new DefaultInputMask(this.currencyFormat);\n const valueScalingOptions = {\n [ValueScaling.precision]: this.currencyFormat.maximumFractionDigits,\n [ValueScaling.thousands]: 3,\n [ValueScaling.millions]: 6,\n [ValueScaling.billions]: 9\n };\n this.valueScaling = this.options.valueScaling ? valueScalingOptions[this.options.valueScaling] : undefined;\n this.valueScalingFractionDigits =\n this.valueScaling !== undefined && this.options.valueScaling !== ValueScaling.precision\n ? this.valueScaling + this.currencyFormat.maximumFractionDigits\n : this.currencyFormat.maximumFractionDigits;\n this.minValue = this.getMinValue();\n this.maxValue = this.getMaxValue();\n }\n getMinValue() {\n var _a, _b;\n let min = this.toFloat(-Number.MAX_SAFE_INTEGER);\n if (((_a = this.options.valueRange) === null || _a === void 0 ? void 0 : _a.min) !== undefined) {\n min = Math.max((_b = this.options.valueRange) === null || _b === void 0 ? void 0 : _b.min, this.toFloat(-Number.MAX_SAFE_INTEGER));\n }\n return min;\n }\n getMaxValue() {\n var _a, _b;\n let max = this.toFloat(Number.MAX_SAFE_INTEGER);\n if (((_a = this.options.valueRange) === null || _a === void 0 ? void 0 : _a.max) !== undefined) {\n max = Math.min((_b = this.options.valueRange) === null || _b === void 0 ? void 0 : _b.max, this.toFloat(Number.MAX_SAFE_INTEGER));\n }\n return max;\n }\n toFloat(value, maxFractionDigits) {\n return value / Math.pow(10, maxFractionDigits !== null && maxFractionDigits !== void 0 ? maxFractionDigits : this.valueScalingFractionDigits);\n }\n toInteger(value, maxFractionDigits) {\n return Number(value\n .toFixed(maxFractionDigits !== null && maxFractionDigits !== void 0 ? maxFractionDigits : this.valueScalingFractionDigits)\n .split('.')\n .join(''));\n }\n validateValueRange(value) {\n return value != null ? Math.min(Math.max(value, this.minValue), this.maxValue) : value;\n }\n format(value, hideNegligibleDecimalDigits = false) {\n if (value != null) {\n if (this.decimalSymbolInsertedAt !== undefined) {\n value = this.currencyFormat.normalizeDecimalSeparator(value, this.decimalSymbolInsertedAt);\n this.decimalSymbolInsertedAt = undefined;\n }\n const conformedValue = this.numberMask.conformToMask(value, this.formattedValue);\n let formattedValue;\n if (typeof conformedValue === 'object') {\n const { numberValue, fractionDigits } = conformedValue;\n let { maximumFractionDigits, minimumFractionDigits } = this.currencyFormat;\n if (this.focus) {\n minimumFractionDigits = hideNegligibleDecimalDigits\n ? fractionDigits.replace(/0+$/, '').length\n : Math.min(maximumFractionDigits, fractionDigits.length);\n }\n else if (Number.isInteger(numberValue) && !this.options.autoDecimalDigits && (this.options.precision === undefined || minimumFractionDigits === 0)) {\n minimumFractionDigits = maximumFractionDigits = 0;\n }\n formattedValue =\n this.toInteger(Math.abs(numberValue)) > Number.MAX_SAFE_INTEGER\n ? this.formattedValue\n : this.currencyFormat.format(numberValue, {\n useGrouping: this.options.useGrouping !== false && !(this.focus && this.options.hideGroupingSeparatorOnFocus),\n minimumFractionDigits,\n maximumFractionDigits\n });\n }\n else {\n formattedValue = conformedValue;\n }\n if (this.maxValue <= 0 && !this.currencyFormat.isNegative(formattedValue) && this.currencyFormat.parse(formattedValue) !== 0) {\n formattedValue = formattedValue.replace(this.currencyFormat.prefix, this.currencyFormat.negativePrefix);\n }\n if (this.minValue >= 0) {\n formattedValue = formattedValue.replace(this.currencyFormat.negativePrefix, this.currencyFormat.prefix);\n }\n if (this.options.currencyDisplay === CurrencyDisplay.hidden || (this.focus && this.options.hideCurrencySymbolOnFocus)) {\n formattedValue = formattedValue\n .replace(this.currencyFormat.negativePrefix, this.currencyFormat.minusSign !== undefined ? this.currencyFormat.minusSign : '(')\n .replace(this.currencyFormat.negativeSuffix, this.currencyFormat.minusSign !== undefined ? '' : ')')\n .replace(this.currencyFormat.prefix, '')\n .replace(this.currencyFormat.suffix, '');\n }\n this.el.value = formattedValue;\n this.numberValue = this.currencyFormat.parse(formattedValue);\n }\n else {\n this.el.value = '';\n this.numberValue = null;\n }\n this.formattedValue = this.el.value;\n this.onInput(this.getValue());\n }\n addEventListener() {\n this.el.addEventListener('input', (e) => {\n const { value, selectionStart } = this.el;\n const inputEvent = e;\n if (selectionStart && inputEvent.data && DECIMAL_SEPARATORS.includes(inputEvent.data)) {\n this.decimalSymbolInsertedAt = selectionStart - 1;\n }\n this.format(value);\n if (this.focus && selectionStart != null) {\n const getCaretPositionAfterFormat = () => {\n const { prefix, suffix, decimalSymbol, maximumFractionDigits, groupingSymbol } = this.currencyFormat;\n let caretPositionFromLeft = value.length - selectionStart;\n const newValueLength = this.formattedValue.length;\n if (this.currencyFormat.minusSign === undefined && (value.startsWith('(') || value.startsWith('-')) && !value.endsWith(')')) {\n return newValueLength - this.currencyFormat.negativeSuffix.length > 1 ? this.formattedValue.substring(selectionStart).length : 1;\n }\n if (this.formattedValue.substring(selectionStart, 1) === groupingSymbol &&\n count(this.formattedValue, groupingSymbol) === count(value, groupingSymbol) + 1) {\n return newValueLength - caretPositionFromLeft - 1;\n }\n if (newValueLength < caretPositionFromLeft) {\n return selectionStart;\n }\n if (decimalSymbol !== undefined && value.indexOf(decimalSymbol) !== -1) {\n const decimalSymbolPosition = value.indexOf(decimalSymbol) + 1;\n if (Math.abs(newValueLength - value.length) > 1 && selectionStart <= decimalSymbolPosition) {\n return this.formattedValue.indexOf(decimalSymbol) + 1;\n }\n else {\n if (!this.options.autoDecimalDigits && selectionStart > decimalSymbolPosition) {\n if (this.currencyFormat.onlyDigits(value.substring(decimalSymbolPosition)).length - 1 === maximumFractionDigits) {\n caretPositionFromLeft -= 1;\n }\n }\n }\n }\n return this.options.hideCurrencySymbolOnFocus || this.options.currencyDisplay === CurrencyDisplay.hidden\n ? newValueLength - caretPositionFromLeft\n : Math.max(newValueLength - Math.max(caretPositionFromLeft, suffix.length), prefix.length);\n };\n this.setCaretPosition(getCaretPositionAfterFormat());\n }\n });\n this.el.addEventListener('focus', () => {\n this.focus = true;\n this.numberValueOnFocus = this.numberValue;\n setTimeout(() => {\n const { value, selectionStart, selectionEnd } = this.el;\n this.format(value, this.options.hideNegligibleDecimalDigitsOnFocus);\n if (selectionStart != null && selectionEnd != null && Math.abs(selectionStart - selectionEnd) > 0) {\n this.setCaretPosition(0, this.el.value.length);\n }\n else if (selectionStart != null) {\n const caretPositionOnFocus = this.getCaretPositionOnFocus(value, selectionStart);\n this.setCaretPosition(caretPositionOnFocus);\n }\n });\n });\n this.el.addEventListener('blur', () => {\n this.focus = false;\n this.format(this.currencyFormat.format(this.validateValueRange(this.numberValue)));\n if (this.numberValueOnFocus !== this.numberValue) {\n this.onChange(this.getValue());\n }\n });\n }\n getCaretPositionOnFocus(value, selectionStart) {\n if (this.numberValue == null) {\n return selectionStart;\n }\n const { prefix, negativePrefix, suffix, negativeSuffix, groupingSymbol, currency } = this.currencyFormat;\n const isNegative = this.numberValue < 0;\n const currentPrefix = isNegative ? negativePrefix : prefix;\n const prefixLength = currentPrefix.length;\n if (this.options.hideCurrencySymbolOnFocus || this.options.currencyDisplay === CurrencyDisplay.hidden) {\n if (isNegative) {\n if (selectionStart <= 1) {\n return 1;\n }\n else if (value.endsWith(')') && selectionStart > value.indexOf(')')) {\n return this.formattedValue.length - 1;\n }\n }\n }\n else {\n const suffixLength = isNegative ? negativeSuffix.length : suffix.length;\n if (selectionStart >= value.length - suffixLength) {\n return this.formattedValue.length - suffixLength;\n }\n else if (selectionStart < prefixLength) {\n return prefixLength;\n }\n }\n let result = selectionStart;\n if (this.options.hideCurrencySymbolOnFocus &&\n this.options.currencyDisplay !== CurrencyDisplay.hidden &&\n selectionStart >= prefixLength &&\n currency !== undefined &&\n currentPrefix.includes(currency)) {\n result -= prefixLength;\n if (isNegative) {\n result += 1;\n }\n }\n if (this.options.hideGroupingSeparatorOnFocus && groupingSymbol !== undefined) {\n result -= count(value.substring(0, selectionStart), groupingSymbol);\n }\n return result;\n }\n setCaretPosition(start, end = start) {\n this.el.setSelectionRange(start, end);\n }\n}\n\nconst findInput = (el) => ((el === null || el === void 0 ? void 0 : el.matches('input')) ? el : el === null || el === void 0 ? void 0 : el.querySelector('input'));\nfunction useCurrencyInput(options, autoEmit) {\n var _a, _b, _c, _d;\n let currencyInput;\n const inputRef = ref(null);\n const formattedValue = ref(null);\n const numberValue = ref(null);\n const vm = getCurrentInstance();\n const emit = (vm === null || vm === void 0 ? void 0 : vm.emit) || ((_b = (_a = vm === null || vm === void 0 ? void 0 : vm.proxy) === null || _a === void 0 ? void 0 : _a.$emit) === null || _b === void 0 ? void 0 : _b.bind(vm === null || vm === void 0 ? void 0 : vm.proxy));\n const props = ((vm === null || vm === void 0 ? void 0 : vm.props) || ((_c = vm === null || vm === void 0 ? void 0 : vm.proxy) === null || _c === void 0 ? void 0 : _c.$props));\n const isVue3 = version.startsWith('3');\n const lazyModel = isVue3 && ((_d = vm === null || vm === void 0 ? void 0 : vm.attrs.modelModifiers) === null || _d === void 0 ? void 0 : _d.lazy);\n const modelValue = computed(() => props === null || props === void 0 ? void 0 : props[isVue3 ? 'modelValue' : 'value']);\n const inputEvent = isVue3 ? 'update:modelValue' : 'input';\n const changeEvent = lazyModel ? 'update:modelValue' : 'change';\n watch(inputRef, (value) => {\n var _a;\n if (value) {\n const el = findInput((_a = value === null || value === void 0 ? void 0 : value.$el) !== null && _a !== void 0 ? _a : value);\n if (el) {\n currencyInput = new CurrencyInput({\n el,\n options,\n onInput: (value) => {\n if (!lazyModel && autoEmit !== false && modelValue.value !== value.number) {\n emit === null || emit === void 0 ? void 0 : emit(inputEvent, value.number);\n }\n numberValue.value = value.number;\n formattedValue.value = value.formatted;\n },\n onChange: (value) => {\n if (autoEmit !== false) {\n emit === null || emit === void 0 ? void 0 : emit(changeEvent, value.number);\n }\n }\n });\n currencyInput.setValue(modelValue.value);\n }\n else {\n console.error('No input element found. Please make sure that the \"inputRef\" template ref is properly assigned.');\n }\n }\n else {\n currencyInput = null;\n }\n });\n return {\n inputRef,\n numberValue,\n formattedValue,\n setValue: (value) => currencyInput === null || currencyInput === void 0 ? void 0 : currencyInput.setValue(value),\n setOptions: (options) => currencyInput === null || currencyInput === void 0 ? void 0 : currencyInput.setOptions(options)\n };\n}\n\nexport { CurrencyDisplay, ValueScaling, useCurrencyInput };\n","<script lang=\"ts\" setup>\n import isEmpty from 'lodash-es/isEmpty';\n import { computed, useAttrs, watch } from 'vue';\n import { CurrencyDisplay, CurrencyInputOptions, useCurrencyInput } from 'vue-currency-input';\n\n import Icon from '../Icon/Icon.vue';\n import Input, { InputProps } from '../Input/Input.vue';\n\n const CURRENCY_INPUT_BASE_OPTIONS: CurrencyInputOptions = {\n currency: 'USD',\n currencyDisplay: CurrencyDisplay.hidden,\n precision: 2,\n hideCurrencySymbolOnFocus: true,\n hideGroupingSeparatorOnFocus: true,\n hideNegligibleDecimalDigitsOnFocus: false,\n autoDecimalDigits: true,\n useGrouping: true,\n accountingSign: false,\n };\n\n export interface CurrencyInputProps extends Omit<InputProps, 'modelValue' | 'type'> {\n inputOptions?: Partial<CurrencyInputOptions>;\n modelValue: string | null;\n hidePrepend?: boolean;\n }\n\n const props = withDefaults(defineProps<CurrencyInputProps>(), {\n // Todo: this default should be removed if its a required prop...\n modelValue: '',\n errorText: undefined,\n hintText: undefined,\n label: undefined,\n id: undefined,\n inputOptions: undefined,\n hidePrepend: false,\n });\n\n const emit = defineEmits<{\n /**\n * Emitted when the input value changes.\n */\n (e: 'update:model-value', v: CurrencyInputProps['modelValue']): void;\n }>();\n\n const attrs = useAttrs();\n\n const currencyInputOptions = computed(() => {\n return {\n ...CURRENCY_INPUT_BASE_OPTIONS,\n ...(!isEmpty(props.inputOptions) ? props.inputOptions : {}),\n };\n });\n\n const { inputRef: inputEl, setOptions, setValue, numberValue } = useCurrencyInput(currencyInputOptions.value, false);\n\n defineExpose({ inputEl });\n\n watch(\n () => numberValue.value,\n (newValue: number | null | string) => {\n let stringValue: string | null;\n\n if (Object.is(newValue, -0)) {\n if (typeof currencyInputOptions.value.precision === 'number') {\n stringValue = '-0.' + '0'.repeat(currencyInputOptions.value.precision);\n } else {\n stringValue = '-0.' + '0'.repeat(currencyInputOptions.value.precision?.min || 0);\n }\n } else {\n stringValue = typeof newValue === 'number' ? newValue.toFixed(2) : newValue;\n }\n\n emit('update:model-value', stringValue);\n },\n );\n\n watch(\n () => props.modelValue,\n (newValue: number | null | string) => {\n let numberValue: number | null;\n\n if (typeof newValue === 'string') {\n numberValue = parseFloat(newValue || '0');\n } else {\n numberValue = newValue;\n }\n\n setValue(numberValue);\n },\n );\n\n watch(\n () => props.inputOptions,\n () => {\n setOptions(currencyInputOptions.value);\n },\n );\n\n const inputAttrs = computed(() => {\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n const { inputOptions: _, ...propsWithoutCurrencyInputOptions } = props;\n\n return { ...propsWithoutCurrencyInputOptions, ...attrs } as typeof attrs & InputProps;\n });\n</script>\n\n<template>\n <Input\n v-bind=\"inputAttrs\"\n ref=\"inputEl\"\n class=\"stash-currency-input\"\n type=\"text\"\n data-test=\"stash-currency-input\"\n inputmode=\"decimal\"\n >\n <template v-if=\"!hidePrepend\" #prepend>\n <Icon name=\"sign-dollar\" />\n </template>\n </Input>\n</template>\n"],"names":["CurrencyDisplay","ValueScaling","escapeRegExp","str","removeLeadingZeros","count","search","substringBefore","DECIMAL_SEPARATORS","INTEGER_PATTERN","CurrencyFormat","options","_a","_b","_c","_d","_e","_f","currency","currencyDisplay","locale","precision","accountingSign","useGrouping","numberFormat","formatParts","type","i","getPrefix","getSuffix","negative","fraction","match","formattedNumber","integerNumber","value","from","s","digit","index","AbstractInputMask","currencyFormat","DefaultInputMask","previousConformedValue","isEmptyNegativeValue","checkIncompleteValue","incompleteValue","integer","integerDigits","fractionDigits","invalidFraction","invalidNegativeValue","AutoDecimalDigitsInputMask","numberValue","DEFAULT_OPTIONS","CurrencyInput","args","newValue","valueScalingOptions","min","max","maxFractionDigits","hideNegligibleDecimalDigits","conformedValue","formattedValue","maximumFractionDigits","minimumFractionDigits","e","selectionStart","inputEvent","getCaretPositionAfterFormat","prefix","suffix","decimalSymbol","groupingSymbol","caretPositionFromLeft","newValueLength","decimalSymbolPosition","selectionEnd","caretPositionOnFocus","negativePrefix","negativeSuffix","isNegative","currentPrefix","prefixLength","suffixLength","result","start","end","findInput","el","useCurrencyInput","autoEmit","currencyInput","inputRef","ref","vm","getCurrentInstance","props","isVue3","version","modelValue","computed","watch","CURRENCY_INPUT_BASE_OPTIONS","__props","emit","__emit","attrs","useAttrs","currencyInputOptions","isEmpty","inputEl","setOptions","setValue","__expose","stringValue","inputAttrs","_","propsWithoutCurrencyInputOptions"],"mappings":"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","x_google_ignoreList":[0]}
|
package/dist/CustomRender.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"CustomRender.js","sources":["../src/components/CustomRender/CustomRender.vue"],"sourcesContent":["<script>\n export default {\n name: 'll-custom-render',\n props: {\n render: {\n type: Function,\n required: true,\n },\n },\n\n setup(props) {\n return () => props.render();\n },\n };\n</script>\n"],"names":["_sfc_main","props"],"mappings":"AACO,MAAAA,IAAU;AAAA,EACb,MAAM;AAAA,EACN,OAAO;AAAA,IACL,QAAQ;AAAA,MACN,MAAM;AAAA,MACN,UAAU;AAAA,
|
|
1
|
+
{"version":3,"file":"CustomRender.js","sources":["../src/components/CustomRender/CustomRender.vue"],"sourcesContent":["<script>\n export default {\n name: 'll-custom-render',\n props: {\n render: {\n type: Function,\n required: true,\n },\n },\n\n setup(props) {\n return () => props.render();\n },\n };\n</script>\n"],"names":["_sfc_main","props"],"mappings":"AACO,MAAAA,IAAU;AAAA,EACb,MAAM;AAAA,EACN,OAAO;AAAA,IACL,QAAQ;AAAA,MACN,MAAM;AAAA,MACN,UAAU;AAAA;;EAId,MAAMC,GAAO;AACX,WAAO,MAAMA,EAAM,OAAM;AAAA,EAC3B;;"}
|
package/dist/DataView.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"DataView.js","sources":["../src/components/DataView/DataView.utils.ts","../src/components/DataView/DataView.types.ts","../src/components/DataView/DataView.vue"],"sourcesContent":["import { SortId, SortOrder, SortValue, SortValueDeserialized } from './DataView.types';\n\n/**\n * Receives a SortValue (ex: `'-product_name'`) and returns an object with a `id` and an `order`.\n */\nexport function deserializeSortValue(sort: SortValue): SortValueDeserialized {\n const order = sort[0] === '-' ? 'desc' : 'asc';\n const id = order === 'asc' ? sort : sort.slice(1);\n\n return { id, order };\n}\n\n/**\n * Receives an object with a `id` and an `order` and returns a SortValue (ex: `'-product_name'`).\n */\nexport function serializeSortValue({ id, order }: SortValueDeserialized): SortValue {\n return `${order === 'desc' ? '-' : ''}${id}`;\n}\n\ninterface GetNextSortArgs {\n newId: SortId | undefined;\n newOrder?: SortOrder;\n oldId?: SortId;\n oldOrder?: SortOrder;\n}\n\n/**\n * Given new and old sorting data, it returns the next sorting value using the following sorting cycle:\n *\n * \"unsorted --> ascending --> descending --> unsorted\"\n */\nexport function getNextSort({ newId, newOrder, oldId, oldOrder }: GetNextSortArgs): SortValue | undefined {\n if (!newId) {\n return undefined;\n }\n\n if (newId !== oldId) {\n // if sorting by a new field, sort ascending\n return serializeSortValue({ id: newId, order: newOrder || 'asc' });\n }\n\n /**\n * `newOrder` and `oldOrder` can each have 3 different values: undefined, 'asc', or 'desc'.\n * Therefore, there are 9 possible combinations (3 times 3). See below:\n */\n\n // #region newOrder: undefined\n if (!newOrder && !oldOrder) {\n return newId; // ascending\n }\n\n if (!newOrder && oldOrder === 'desc') {\n return undefined; // unsorted\n }\n\n if (!newOrder && oldOrder === 'asc') {\n return `-${newId}`; // descending\n }\n // #endregion\n\n // #region newOrder: asc\n if (newOrder === 'asc' && !oldOrder) {\n return newId;\n }\n\n if (newOrder === 'asc' && oldOrder === 'asc') {\n return undefined;\n }\n\n if (newOrder === 'asc' && oldOrder === 'desc') {\n return newId;\n }\n // #endregion\n\n // #region newOrder: desc\n if (newOrder === 'desc' && !oldOrder) {\n return `-${newId}`;\n }\n\n if (newOrder === 'desc' && oldOrder === 'desc') {\n return undefined;\n }\n\n if (newOrder === 'desc' && oldOrder === 'asc') {\n return `-${newId}`;\n }\n // #endregion\n}\n","import { ComputedRef, Ref } from 'vue';\n\nimport { SpacingDensities } from '../../../types/misc';\n\nexport enum DataViewVariant {\n Table = 'table',\n}\n\nexport type DataViewVariants = `${DataViewVariant}`;\n\n/**\n * A unique id for a sorting strategy. If the order is descending, it must begin with \"-\" (a hyphen/dash).\n *\n * Ex: `'product_name'` if ascending or `'-product_name'` if descending\n */\nexport type SortValue = string;\n\n/**\n * The SortValue with its leading hyphen/dash removed\n */\nexport type SortId = string;\n\n/**\n * Determined by whether or not there is a leading hyphen/dash in the SortValue\n */\nexport type SortOrder = 'asc' | 'desc';\n\n/**\n * A deserialized instance of a `SortValue`.\n */\nexport type SortValueDeserialized = {\n id: SortId;\n order: SortOrder;\n};\n\n/** Updates the DataView internal state with the given sortId */\nexport type UpdateCurrentSort = (\n sortId: SortId | undefined,\n options?: {\n sortOrder?: SortOrder;\n /** If true, emits the `update:currentSort` and `update` events from DataView */\n shouldEmit?: boolean;\n },\n) => void;\n\n/** Updates the DataView internal state with the given page */\nexport type SetPage = (\n page: number,\n options?: {\n /** If true, emits the `update:currentPage` and `update` events from DataView */\n shouldEmit?: boolean;\n },\n) => void;\n\n/** Updates the DataView internal state with the previous page */\nexport type GoPrevPage = (options?: {\n /** If true, emits the `update:currentPage` and `update` events from DataView */\n shouldEmit?: boolean;\n}) => void;\n\n/** Updates the DataView internal state with the next page */\nexport type GoNextPage = (options?: {\n /** If true, emits the `update:currentPage` and `update` events from DataView */\n shouldEmit?: boolean;\n}) => void;\n\n/** Updates the DataView internal state with the given searchTerm */\nexport type UpdateCurrentSearch = (\n searchTerm?: string,\n options?: {\n /** If true, emits the `update:currentSearch` and `update` events from DataView */\n shouldEmit?: boolean;\n },\n) => void;\n\n/** Updates the DataView internal state with the given filter values */\nexport type UpdateCurrentFilters<FilterValues = object> = (\n newFilters: FilterValues,\n options?: {\n /** If true, emits the `update:currentSearch` and `update` events from DataView */\n shouldEmit?: boolean;\n },\n) => void;\n\nexport interface UpdateEvent<FilterValues = object> {\n page?: number;\n pageSize?: number;\n ordering?: string;\n search?: string;\n filters?: FilterValues;\n}\n\nexport interface DataViewInjection {\n currentPage: ComputedRef<number>;\n\n /** Optional override for the next button disabled state */\n isPaginateNextDisabled: ComputedRef<boolean>;\n\n isPaginationEnabled: ComputedRef<boolean>;\n\n pageCount: ComputedRef<number>;\n\n pageSize: ComputedRef<number>;\n\n totalDataCount: ComputedRef<number>;\n\n /** Updates the DataView internal state with the given page */\n setPage: SetPage;\n\n /** Updates the DataView internal state with the previous page */\n goPrevPage: GoPrevPage;\n\n /** Updates the DataView internal state with the next page */\n goNextPage: GoNextPage;\n\n currentSortId: ComputedRef<SortId | undefined>;\n\n currentSortOrder: ComputedRef<SortOrder | undefined>;\n\n /** Updates the DataView internal state with the given sortId */\n updateCurrentSort: UpdateCurrentSort;\n\n currentSearch: ComputedRef<string>;\n\n /** Updates the DataView internal state with the given searchTerm */\n updateCurrentSearch: UpdateCurrentSearch;\n\n /**\n * The DataView's padding; the default value is \"comfortable\". On small screens, the density will always be \"compact\".\n */\n density: ComputedRef<SpacingDensities | undefined>;\n\n /**\n * Defines if a DataView has a Toolbar rendered. This prop is updated when DataViewToolbar exists and is mounted.\n */\n hasToolbar?: Ref<boolean>;\n\n /**\n * Enables certain loading indicators to be displayed within the DataView.\n */\n isLoading?: ComputedRef<boolean>;\n\n /**\n * Enables certain empty states to be displayed within the DataView.\n */\n isEmpty?: ComputedRef<boolean>;\n\n /**\n * Allows Table to control whether or not a DataViewToolbar should show a checkmark\n */\n isSelectable?: Ref<boolean>;\n\n /**\n * Whether or not the DataView is rendered within a Module; the value is inferred based on being\n * able to inject details from Module.\n *\n * Note: This is sent to DataView child components so they only need to worry about interfacing\n * with the DataViewInjection API.\n */\n isWithinModule: ComputedRef<boolean>;\n\n /**\n * The DataView's variant; the default value is undefined.\n */\n variant: ComputedRef<DataViewVariants | undefined>;\n}\n","<script lang=\"ts\">\n export * from './DataView.constants';\n export * from './DataView.keys';\n export * from './DataView.types';\n export * from './DataView.utils';\n</script>\n\n<script setup lang=\"ts\">\n import cloneDeep from 'lodash-es/cloneDeep';\n import { computed, inject, provide, ref, useCssModule, watch } from 'vue';\n\n import { SpacingDensities } from '../../../types/misc';\n import { MODULE_INJECTION } from '../Module/Module.keys';\n import Paginate from '../Paginate/Paginate.vue';\n import { DEFAULT_PAGE_SIZE } from './DataView.constants';\n import { DATA_VIEW_INJECTION } from './DataView.keys';\n import {\n DataViewVariants,\n GoNextPage,\n GoPrevPage,\n SetPage,\n SortId,\n SortOrder,\n SortValue,\n UpdateCurrentFilters,\n UpdateCurrentSearch,\n UpdateCurrentSort,\n UpdateEvent,\n } from './DataView.types';\n import { deserializeSortValue, getNextSort } from './DataView.utils';\n\n export interface DataViewProps {\n /**\n * Can be used to provide the initial page.\n * Also, it can be used to control the active page with `v-model:current-page=\"myPage\"`.\n */\n currentPage?: number;\n\n /**\n * Can be used to set the initial search term.\n * Also, it can be used to control the active search term with `v-model:current-search=\"mySearchTerm\"`.\n */\n currentSearch?: string;\n\n /**\n * Can be used to provide the initial sort order.\n * Also, it can be used to control the active sort order with `v-model:current-sort=\"mySortOrder\"`.\n */\n currentSort?: SortValue;\n\n /**\n * A list of records. If pagination is enabled, `data` must be only the current page of records.\n */\n data?: object[];\n\n /**\n * Controls the DataView's padding; the default value is \"comfortable\". On small screens, \"compact\" density is applied regardless of this prop's value.\n */\n density?: SpacingDensities;\n\n /**\n * The number of records to display per page.\n */\n pageSize?: number;\n\n /**\n * Opt-out of displaying pagination. Hides the pagination buttons and page stats.\n */\n disablePagination?: boolean;\n\n /**\n * Hides the bottom pagination without disabling the pagination from the toolbar\n */\n hideBottomPagination?: boolean;\n\n /**\n * The total number of records available.\n * Used to auto-enable pagination when results exist.\n * Use `Infinity` for activating 'n of many' pagination\n * DataView does not paginate data for you; instead, `props.data` should always show\n * the current page of results.\n */\n totalDataCount?: number;\n\n /**\n * Whether there is a next page of data or not as informed by the server.\n * This only applies when`totalDataCount=\"Infinity\"` to determine if the \"Next\" pagination button should be disabled.\n */\n hasNextPage?: boolean;\n\n /**\n * DataView variant. The default value is `undefined`. Will default to `table` when used within\n * a `<Module variant=\"table\">`.\n */\n variant?: DataViewVariants;\n\n isLoading?: boolean;\n }\n\n const props = withDefaults(defineProps<DataViewProps>(), {\n currentPage: 1,\n currentSearch: undefined,\n currentSort: undefined,\n data: () => [],\n density: 'comfortable',\n pageSize: DEFAULT_PAGE_SIZE,\n disablePagination: false,\n totalDataCount: 0,\n hasNextPage: undefined,\n hideBottomPagination: false,\n variant: undefined,\n });\n\n const emit = defineEmits<{\n (e: 'update', state: UpdateEvent): void;\n (e: 'update:currentFilters', newFilters: object): void;\n (e: 'update:currentPage', page: number, pageSize: number): void;\n (e: 'update:currentSearch', searchTerm?: string): void;\n (e: 'update:currentSort', payload?: SortValue): void;\n }>();\n\n const classes = useCssModule();\n const rootRef = ref<HTMLElement | null>(null);\n const moduleInjection = inject(MODULE_INJECTION.key, MODULE_INJECTION.defaults);\n const computedVariant = computed<DataViewVariants | undefined>(() => {\n if (props.variant) {\n return props.variant;\n }\n\n if (moduleInjection.variant?.value === 'table') {\n return 'table';\n }\n\n return undefined;\n });\n const isWithinModule = computed(() => moduleInjection.variant !== undefined);\n\n // #region pagination\n const internalPage = ref(1);\n const isPaginationEnabled = computed(() => !props.disablePagination && props.totalDataCount > 0);\n const isPaginateNextDisabled = computed(() => props.totalDataCount === Infinity && !props.hasNextPage);\n const pageCount = computed(() => Math.ceil(props.totalDataCount / props.pageSize));\n\n const setPage: SetPage = function (page: number, { shouldEmit } = {}) {\n internalPage.value = page;\n\n if (shouldEmit) {\n emitUpdate();\n emit('update:currentPage', page, props.pageSize);\n }\n\n if (Number(rootRef.value?.getBoundingClientRect().top) < 0) {\n rootRef.value?.scrollIntoView({ behavior: 'smooth', block: 'start' });\n }\n };\n\n const goPrevPage: GoPrevPage = function ({ shouldEmit } = {}) {\n const page = Math.max(internalPage.value - 1, 1);\n\n setPage(page, { shouldEmit });\n };\n\n /** Updates the DataView internal state with the previous page */\n const goNextPage: GoNextPage = function ({ shouldEmit } = {}) {\n const page = Math.min(internalPage.value + 1, pageCount.value);\n\n setPage(page, { shouldEmit });\n };\n\n watch(\n () => props.currentPage,\n () => {\n setPage(props.currentPage);\n },\n { immediate: true },\n );\n // #endregion pagination\n\n // #region sorting\n const internalSort = ref<SortValue | undefined>(undefined);\n\n const internalSortId = computed<SortId | undefined>(() =>\n internalSort.value ? deserializeSortValue(internalSort.value).id : undefined,\n );\n const internalSortOrder = computed<SortOrder | undefined>(() =>\n internalSort.value ? deserializeSortValue(internalSort.value).order : undefined,\n );\n\n const updateCurrentSort: UpdateCurrentSort = function (sortId, { sortOrder, shouldEmit } = {}) {\n const { id: oldId, order: oldOrder } = deserializeSortValue(internalSort.value || '');\n const nextSort = getNextSort({ newId: sortId, newOrder: sortOrder, oldId, oldOrder });\n\n internalSort.value = nextSort;\n setPage(1);\n\n if (shouldEmit) {\n emitUpdate();\n emit('update:currentSort', nextSort);\n }\n };\n\n watch(\n () => props.currentSort,\n () => {\n updateCurrentSort(props.currentSort);\n },\n { immediate: true },\n );\n // #endregion sorting\n\n // #region search\n const internalSearch = ref('');\n\n const hasToolbar = ref(false);\n const isSelectable = ref(false);\n\n const updateCurrentSearch: UpdateCurrentSearch = function (searchTerm, { shouldEmit } = {}) {\n internalSearch.value = searchTerm || '';\n setPage(1);\n\n if (shouldEmit) {\n emitUpdate();\n emit('update:currentSearch', searchTerm);\n }\n };\n\n watch(\n () => props.currentSearch,\n () => {\n updateCurrentSearch(props.currentSearch);\n },\n { immediate: true },\n );\n // #endregion search\n\n // #region filters\n const internalFilters = ref<object>({});\n\n const updateCurrentFilters: UpdateCurrentFilters = function (newFilters: object, { shouldEmit } = {}) {\n internalFilters.value = newFilters;\n setPage(1);\n\n if (shouldEmit) {\n emitUpdate();\n emit('update:currentFilters', newFilters);\n }\n };\n // #endregion filters\n\n function emitUpdate() {\n emit('update', {\n page: internalPage.value,\n pageSize: props.pageSize,\n ordering: internalSort.value,\n search: internalSearch.value,\n filters: cloneDeep(internalFilters.value),\n });\n }\n\n provide(\n DATA_VIEW_INJECTION.key,\n Object.freeze({\n // Pagination\n currentPage: computed(() => internalPage.value),\n isPaginationEnabled,\n isPaginateNextDisabled,\n pageCount,\n pageSize: computed(() => props.pageSize),\n totalDataCount: computed(() => props.totalDataCount),\n setPage,\n goPrevPage,\n goNextPage,\n\n // Sorting\n currentSortId: internalSortId,\n currentSortOrder: internalSortOrder,\n updateCurrentSort,\n\n // Search\n currentSearch: computed(() => internalSearch.value),\n updateCurrentSearch,\n\n // Miscellaneous\n density: computed(() => props.density),\n hasToolbar,\n isEmpty: computed(() => props.data.length === 0),\n isSelectable,\n isLoading: computed(() => props.isLoading),\n isWithinModule,\n variant: computedVariant,\n }),\n );\n\n defineExpose({\n page: computed(() => internalPage.value),\n pageSize: computed(() => props.pageSize),\n setPage,\n goPrevPage,\n goNextPage,\n ordering: computed(() => internalSort.value),\n updateCurrentSort,\n search: computed(() => internalSearch.value),\n updateCurrentSearch,\n filters: computed(() => internalFilters.value),\n updateCurrentFilters,\n });\n</script>\n\n<template>\n <div ref=\"rootRef\" class=\"stash-data-view tw-relative\" data-test=\"stash-data-view\">\n <!-- @slot default -->\n <slot\n :current-page=\"internalPage\"\n :current-sort-id=\"internalSortId\"\n :current-sort-order=\"internalSortOrder\"\n :data=\"data\"\n :go-prev-page=\"goPrevPage\"\n :go-next-page=\"goNextPage\"\n :page-count=\"pageCount\"\n :set-page=\"setPage\"\n :total-data-count=\"props.totalDataCount\"\n :update-current-sort=\"updateCurrentSort\"\n :update-current-search=\"updateCurrentSearch\"\n ></slot>\n\n <Paginate\n v-if=\"isPaginationEnabled && !isWithinModule && pageCount > 1 && !props.hideBottomPagination\"\n class=\"tw-mt-6\"\n :class=\"classes.paginate\"\n :current-page=\"internalPage\"\n :is-next-disabled=\"isLoading || isPaginateNextDisabled\"\n :list-length=\"props.totalDataCount\"\n :page-size=\"props.pageSize\"\n :variant=\"props.totalDataCount === Infinity ? 'stats' : 'standard'\"\n @set-page=\"(page: number) => setPage(page, { shouldEmit: true })\"\n />\n </div>\n</template>\n\n<style module>\n .paginate ul {\n margin: 0;\n }\n</style>\n"],"names":["deserializeSortValue","sort","order","serializeSortValue","id","getNextSort","newId","newOrder","oldId","oldOrder","DataViewVariant","props","__props","emit","__emit","classes","useCssModule","rootRef","ref","moduleInjection","inject","MODULE_INJECTION","computedVariant","computed","_a","isWithinModule","internalPage","isPaginationEnabled","isPaginateNextDisabled","pageCount","setPage","page","shouldEmit","emitUpdate","_b","goPrevPage","goNextPage","watch","internalSort","internalSortId","internalSortOrder","updateCurrentSort","sortId","sortOrder","nextSort","internalSearch","hasToolbar","isSelectable","updateCurrentSearch","searchTerm","internalFilters","updateCurrentFilters","newFilters","cloneDeep","provide","DATA_VIEW_INJECTION","__expose"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"DataView.js","sources":["../src/components/DataView/DataView.utils.ts","../src/components/DataView/DataView.types.ts","../src/components/DataView/DataView.vue"],"sourcesContent":["import { SortId, SortOrder, SortValue, SortValueDeserialized } from './DataView.types';\n\n/**\n * Receives a SortValue (ex: `'-product_name'`) and returns an object with a `id` and an `order`.\n */\nexport function deserializeSortValue(sort: SortValue): SortValueDeserialized {\n const order = sort[0] === '-' ? 'desc' : 'asc';\n const id = order === 'asc' ? sort : sort.slice(1);\n\n return { id, order };\n}\n\n/**\n * Receives an object with a `id` and an `order` and returns a SortValue (ex: `'-product_name'`).\n */\nexport function serializeSortValue({ id, order }: SortValueDeserialized): SortValue {\n return `${order === 'desc' ? '-' : ''}${id}`;\n}\n\ninterface GetNextSortArgs {\n newId: SortId | undefined;\n newOrder?: SortOrder;\n oldId?: SortId;\n oldOrder?: SortOrder;\n}\n\n/**\n * Given new and old sorting data, it returns the next sorting value using the following sorting cycle:\n *\n * \"unsorted --> ascending --> descending --> unsorted\"\n */\nexport function getNextSort({ newId, newOrder, oldId, oldOrder }: GetNextSortArgs): SortValue | undefined {\n if (!newId) {\n return undefined;\n }\n\n if (newId !== oldId) {\n // if sorting by a new field, sort ascending\n return serializeSortValue({ id: newId, order: newOrder || 'asc' });\n }\n\n /**\n * `newOrder` and `oldOrder` can each have 3 different values: undefined, 'asc', or 'desc'.\n * Therefore, there are 9 possible combinations (3 times 3). See below:\n */\n\n // #region newOrder: undefined\n if (!newOrder && !oldOrder) {\n return newId; // ascending\n }\n\n if (!newOrder && oldOrder === 'desc') {\n return undefined; // unsorted\n }\n\n if (!newOrder && oldOrder === 'asc') {\n return `-${newId}`; // descending\n }\n // #endregion\n\n // #region newOrder: asc\n if (newOrder === 'asc' && !oldOrder) {\n return newId;\n }\n\n if (newOrder === 'asc' && oldOrder === 'asc') {\n return undefined;\n }\n\n if (newOrder === 'asc' && oldOrder === 'desc') {\n return newId;\n }\n // #endregion\n\n // #region newOrder: desc\n if (newOrder === 'desc' && !oldOrder) {\n return `-${newId}`;\n }\n\n if (newOrder === 'desc' && oldOrder === 'desc') {\n return undefined;\n }\n\n if (newOrder === 'desc' && oldOrder === 'asc') {\n return `-${newId}`;\n }\n // #endregion\n}\n","import { ComputedRef, Ref } from 'vue';\n\nimport { SpacingDensities } from '../../../types/misc';\n\nexport enum DataViewVariant {\n Table = 'table',\n}\n\nexport type DataViewVariants = `${DataViewVariant}`;\n\n/**\n * A unique id for a sorting strategy. If the order is descending, it must begin with \"-\" (a hyphen/dash).\n *\n * Ex: `'product_name'` if ascending or `'-product_name'` if descending\n */\nexport type SortValue = string;\n\n/**\n * The SortValue with its leading hyphen/dash removed\n */\nexport type SortId = string;\n\n/**\n * Determined by whether or not there is a leading hyphen/dash in the SortValue\n */\nexport type SortOrder = 'asc' | 'desc';\n\n/**\n * A deserialized instance of a `SortValue`.\n */\nexport type SortValueDeserialized = {\n id: SortId;\n order: SortOrder;\n};\n\n/** Updates the DataView internal state with the given sortId */\nexport type UpdateCurrentSort = (\n sortId: SortId | undefined,\n options?: {\n sortOrder?: SortOrder;\n /** If true, emits the `update:currentSort` and `update` events from DataView */\n shouldEmit?: boolean;\n },\n) => void;\n\n/** Updates the DataView internal state with the given page */\nexport type SetPage = (\n page: number,\n options?: {\n /** If true, emits the `update:currentPage` and `update` events from DataView */\n shouldEmit?: boolean;\n },\n) => void;\n\n/** Updates the DataView internal state with the previous page */\nexport type GoPrevPage = (options?: {\n /** If true, emits the `update:currentPage` and `update` events from DataView */\n shouldEmit?: boolean;\n}) => void;\n\n/** Updates the DataView internal state with the next page */\nexport type GoNextPage = (options?: {\n /** If true, emits the `update:currentPage` and `update` events from DataView */\n shouldEmit?: boolean;\n}) => void;\n\n/** Updates the DataView internal state with the given searchTerm */\nexport type UpdateCurrentSearch = (\n searchTerm?: string,\n options?: {\n /** If true, emits the `update:currentSearch` and `update` events from DataView */\n shouldEmit?: boolean;\n },\n) => void;\n\n/** Updates the DataView internal state with the given filter values */\nexport type UpdateCurrentFilters<FilterValues = object> = (\n newFilters: FilterValues,\n options?: {\n /** If true, emits the `update:currentSearch` and `update` events from DataView */\n shouldEmit?: boolean;\n },\n) => void;\n\nexport interface UpdateEvent<FilterValues = object> {\n page?: number;\n pageSize?: number;\n ordering?: string;\n search?: string;\n filters?: FilterValues;\n}\n\nexport interface DataViewInjection {\n currentPage: ComputedRef<number>;\n\n /** Optional override for the next button disabled state */\n isPaginateNextDisabled: ComputedRef<boolean>;\n\n isPaginationEnabled: ComputedRef<boolean>;\n\n pageCount: ComputedRef<number>;\n\n pageSize: ComputedRef<number>;\n\n totalDataCount: ComputedRef<number>;\n\n /** Updates the DataView internal state with the given page */\n setPage: SetPage;\n\n /** Updates the DataView internal state with the previous page */\n goPrevPage: GoPrevPage;\n\n /** Updates the DataView internal state with the next page */\n goNextPage: GoNextPage;\n\n currentSortId: ComputedRef<SortId | undefined>;\n\n currentSortOrder: ComputedRef<SortOrder | undefined>;\n\n /** Updates the DataView internal state with the given sortId */\n updateCurrentSort: UpdateCurrentSort;\n\n currentSearch: ComputedRef<string>;\n\n /** Updates the DataView internal state with the given searchTerm */\n updateCurrentSearch: UpdateCurrentSearch;\n\n /**\n * The DataView's padding; the default value is \"comfortable\". On small screens, the density will always be \"compact\".\n */\n density: ComputedRef<SpacingDensities | undefined>;\n\n /**\n * Defines if a DataView has a Toolbar rendered. This prop is updated when DataViewToolbar exists and is mounted.\n */\n hasToolbar?: Ref<boolean>;\n\n /**\n * Enables certain loading indicators to be displayed within the DataView.\n */\n isLoading?: ComputedRef<boolean>;\n\n /**\n * Enables certain empty states to be displayed within the DataView.\n */\n isEmpty?: ComputedRef<boolean>;\n\n /**\n * Allows Table to control whether or not a DataViewToolbar should show a checkmark\n */\n isSelectable?: Ref<boolean>;\n\n /**\n * Whether or not the DataView is rendered within a Module; the value is inferred based on being\n * able to inject details from Module.\n *\n * Note: This is sent to DataView child components so they only need to worry about interfacing\n * with the DataViewInjection API.\n */\n isWithinModule: ComputedRef<boolean>;\n\n /**\n * The DataView's variant; the default value is undefined.\n */\n variant: ComputedRef<DataViewVariants | undefined>;\n}\n","<script lang=\"ts\">\n export * from './DataView.constants';\n export * from './DataView.keys';\n export * from './DataView.types';\n export * from './DataView.utils';\n</script>\n\n<script setup lang=\"ts\">\n import cloneDeep from 'lodash-es/cloneDeep';\n import { computed, inject, provide, ref, useCssModule, watch } from 'vue';\n\n import { SpacingDensities } from '../../../types/misc';\n import { MODULE_INJECTION } from '../Module/Module.keys';\n import Paginate from '../Paginate/Paginate.vue';\n import { DEFAULT_PAGE_SIZE } from './DataView.constants';\n import { DATA_VIEW_INJECTION } from './DataView.keys';\n import {\n DataViewVariants,\n GoNextPage,\n GoPrevPage,\n SetPage,\n SortId,\n SortOrder,\n SortValue,\n UpdateCurrentFilters,\n UpdateCurrentSearch,\n UpdateCurrentSort,\n UpdateEvent,\n } from './DataView.types';\n import { deserializeSortValue, getNextSort } from './DataView.utils';\n\n export interface DataViewProps {\n /**\n * Can be used to provide the initial page.\n * Also, it can be used to control the active page with `v-model:current-page=\"myPage\"`.\n */\n currentPage?: number;\n\n /**\n * Can be used to set the initial search term.\n * Also, it can be used to control the active search term with `v-model:current-search=\"mySearchTerm\"`.\n */\n currentSearch?: string;\n\n /**\n * Can be used to provide the initial sort order.\n * Also, it can be used to control the active sort order with `v-model:current-sort=\"mySortOrder\"`.\n */\n currentSort?: SortValue;\n\n /**\n * A list of records. If pagination is enabled, `data` must be only the current page of records.\n */\n data?: object[];\n\n /**\n * Controls the DataView's padding; the default value is \"comfortable\". On small screens, \"compact\" density is applied regardless of this prop's value.\n */\n density?: SpacingDensities;\n\n /**\n * The number of records to display per page.\n */\n pageSize?: number;\n\n /**\n * Opt-out of displaying pagination. Hides the pagination buttons and page stats.\n */\n disablePagination?: boolean;\n\n /**\n * Hides the bottom pagination without disabling the pagination from the toolbar\n */\n hideBottomPagination?: boolean;\n\n /**\n * The total number of records available.\n * Used to auto-enable pagination when results exist.\n * Use `Infinity` for activating 'n of many' pagination\n * DataView does not paginate data for you; instead, `props.data` should always show\n * the current page of results.\n */\n totalDataCount?: number;\n\n /**\n * Whether there is a next page of data or not as informed by the server.\n * This only applies when`totalDataCount=\"Infinity\"` to determine if the \"Next\" pagination button should be disabled.\n */\n hasNextPage?: boolean;\n\n /**\n * DataView variant. The default value is `undefined`. Will default to `table` when used within\n * a `<Module variant=\"table\">`.\n */\n variant?: DataViewVariants;\n\n isLoading?: boolean;\n }\n\n const props = withDefaults(defineProps<DataViewProps>(), {\n currentPage: 1,\n currentSearch: undefined,\n currentSort: undefined,\n data: () => [],\n density: 'comfortable',\n pageSize: DEFAULT_PAGE_SIZE,\n disablePagination: false,\n totalDataCount: 0,\n hasNextPage: undefined,\n hideBottomPagination: false,\n variant: undefined,\n });\n\n const emit = defineEmits<{\n (e: 'update', state: UpdateEvent): void;\n (e: 'update:currentFilters', newFilters: object): void;\n (e: 'update:currentPage', page: number, pageSize: number): void;\n (e: 'update:currentSearch', searchTerm?: string): void;\n (e: 'update:currentSort', payload?: SortValue): void;\n }>();\n\n const classes = useCssModule();\n const rootRef = ref<HTMLElement | null>(null);\n const moduleInjection = inject(MODULE_INJECTION.key, MODULE_INJECTION.defaults);\n const computedVariant = computed<DataViewVariants | undefined>(() => {\n if (props.variant) {\n return props.variant;\n }\n\n if (moduleInjection.variant?.value === 'table') {\n return 'table';\n }\n\n return undefined;\n });\n const isWithinModule = computed(() => moduleInjection.variant !== undefined);\n\n // #region pagination\n const internalPage = ref(1);\n const isPaginationEnabled = computed(() => !props.disablePagination && props.totalDataCount > 0);\n const isPaginateNextDisabled = computed(() => props.totalDataCount === Infinity && !props.hasNextPage);\n const pageCount = computed(() => Math.ceil(props.totalDataCount / props.pageSize));\n\n const setPage: SetPage = function (page: number, { shouldEmit } = {}) {\n internalPage.value = page;\n\n if (shouldEmit) {\n emitUpdate();\n emit('update:currentPage', page, props.pageSize);\n }\n\n if (Number(rootRef.value?.getBoundingClientRect().top) < 0) {\n rootRef.value?.scrollIntoView({ behavior: 'smooth', block: 'start' });\n }\n };\n\n const goPrevPage: GoPrevPage = function ({ shouldEmit } = {}) {\n const page = Math.max(internalPage.value - 1, 1);\n\n setPage(page, { shouldEmit });\n };\n\n /** Updates the DataView internal state with the previous page */\n const goNextPage: GoNextPage = function ({ shouldEmit } = {}) {\n const page = Math.min(internalPage.value + 1, pageCount.value);\n\n setPage(page, { shouldEmit });\n };\n\n watch(\n () => props.currentPage,\n () => {\n setPage(props.currentPage);\n },\n { immediate: true },\n );\n // #endregion pagination\n\n // #region sorting\n const internalSort = ref<SortValue | undefined>(undefined);\n\n const internalSortId = computed<SortId | undefined>(() =>\n internalSort.value ? deserializeSortValue(internalSort.value).id : undefined,\n );\n const internalSortOrder = computed<SortOrder | undefined>(() =>\n internalSort.value ? deserializeSortValue(internalSort.value).order : undefined,\n );\n\n const updateCurrentSort: UpdateCurrentSort = function (sortId, { sortOrder, shouldEmit } = {}) {\n const { id: oldId, order: oldOrder } = deserializeSortValue(internalSort.value || '');\n const nextSort = getNextSort({ newId: sortId, newOrder: sortOrder, oldId, oldOrder });\n\n internalSort.value = nextSort;\n setPage(1);\n\n if (shouldEmit) {\n emitUpdate();\n emit('update:currentSort', nextSort);\n }\n };\n\n watch(\n () => props.currentSort,\n () => {\n updateCurrentSort(props.currentSort);\n },\n { immediate: true },\n );\n // #endregion sorting\n\n // #region search\n const internalSearch = ref('');\n\n const hasToolbar = ref(false);\n const isSelectable = ref(false);\n\n const updateCurrentSearch: UpdateCurrentSearch = function (searchTerm, { shouldEmit } = {}) {\n internalSearch.value = searchTerm || '';\n setPage(1);\n\n if (shouldEmit) {\n emitUpdate();\n emit('update:currentSearch', searchTerm);\n }\n };\n\n watch(\n () => props.currentSearch,\n () => {\n updateCurrentSearch(props.currentSearch);\n },\n { immediate: true },\n );\n // #endregion search\n\n // #region filters\n const internalFilters = ref<object>({});\n\n const updateCurrentFilters: UpdateCurrentFilters = function (newFilters: object, { shouldEmit } = {}) {\n internalFilters.value = newFilters;\n setPage(1);\n\n if (shouldEmit) {\n emitUpdate();\n emit('update:currentFilters', newFilters);\n }\n };\n // #endregion filters\n\n function emitUpdate() {\n emit('update', {\n page: internalPage.value,\n pageSize: props.pageSize,\n ordering: internalSort.value,\n search: internalSearch.value,\n filters: cloneDeep(internalFilters.value),\n });\n }\n\n provide(\n DATA_VIEW_INJECTION.key,\n Object.freeze({\n // Pagination\n currentPage: computed(() => internalPage.value),\n isPaginationEnabled,\n isPaginateNextDisabled,\n pageCount,\n pageSize: computed(() => props.pageSize),\n totalDataCount: computed(() => props.totalDataCount),\n setPage,\n goPrevPage,\n goNextPage,\n\n // Sorting\n currentSortId: internalSortId,\n currentSortOrder: internalSortOrder,\n updateCurrentSort,\n\n // Search\n currentSearch: computed(() => internalSearch.value),\n updateCurrentSearch,\n\n // Miscellaneous\n density: computed(() => props.density),\n hasToolbar,\n isEmpty: computed(() => props.data.length === 0),\n isSelectable,\n isLoading: computed(() => props.isLoading),\n isWithinModule,\n variant: computedVariant,\n }),\n );\n\n defineExpose({\n page: computed(() => internalPage.value),\n pageSize: computed(() => props.pageSize),\n setPage,\n goPrevPage,\n goNextPage,\n ordering: computed(() => internalSort.value),\n updateCurrentSort,\n search: computed(() => internalSearch.value),\n updateCurrentSearch,\n filters: computed(() => internalFilters.value),\n updateCurrentFilters,\n });\n</script>\n\n<template>\n <div ref=\"rootRef\" class=\"stash-data-view tw-relative\" data-test=\"stash-data-view\">\n <!-- @slot default -->\n <slot\n :current-page=\"internalPage\"\n :current-sort-id=\"internalSortId\"\n :current-sort-order=\"internalSortOrder\"\n :data=\"data\"\n :go-prev-page=\"goPrevPage\"\n :go-next-page=\"goNextPage\"\n :page-count=\"pageCount\"\n :set-page=\"setPage\"\n :total-data-count=\"props.totalDataCount\"\n :update-current-sort=\"updateCurrentSort\"\n :update-current-search=\"updateCurrentSearch\"\n ></slot>\n\n <Paginate\n v-if=\"isPaginationEnabled && !isWithinModule && pageCount > 1 && !props.hideBottomPagination\"\n class=\"tw-mt-6\"\n :class=\"classes.paginate\"\n :current-page=\"internalPage\"\n :is-next-disabled=\"isLoading || isPaginateNextDisabled\"\n :list-length=\"props.totalDataCount\"\n :page-size=\"props.pageSize\"\n :variant=\"props.totalDataCount === Infinity ? 'stats' : 'standard'\"\n @set-page=\"(page: number) => setPage(page, { shouldEmit: true })\"\n />\n </div>\n</template>\n\n<style module>\n .paginate ul {\n margin: 0;\n }\n</style>\n"],"names":["deserializeSortValue","sort","order","serializeSortValue","id","getNextSort","newId","newOrder","oldId","oldOrder","DataViewVariant","props","__props","emit","__emit","classes","useCssModule","rootRef","ref","moduleInjection","inject","MODULE_INJECTION","computedVariant","computed","_a","isWithinModule","internalPage","isPaginationEnabled","isPaginateNextDisabled","pageCount","setPage","page","shouldEmit","emitUpdate","_b","goPrevPage","goNextPage","watch","internalSort","internalSortId","internalSortOrder","updateCurrentSort","sortId","sortOrder","nextSort","internalSearch","hasToolbar","isSelectable","updateCurrentSearch","searchTerm","internalFilters","updateCurrentFilters","newFilters","cloneDeep","provide","DATA_VIEW_INJECTION","__expose"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"DataView.keys-aSOnA4AD.js","sources":["../src/components/DataView/DataView.constants.ts","../src/components/DataView/DataView.keys.ts"],"sourcesContent":["export const DEFAULT_PAGE_SIZE = 12;\n","import { computed, ref } from 'vue';\n\nimport { InjectionWithDefaults } from '../../../types/utils';\nimport { DEFAULT_PAGE_SIZE } from './DataView.constants';\nimport { DataViewInjection } from './DataView.types';\n\n// See: https://vuejs.org/guide/typescript/composition-api.html#typing-provide-inject\n\n/**\n * Miscellaneous data that is not related to pagination, sorting, or searching.\n * TODO: merge all DataView injections into one. https://leaflink.atlassian.net/browse/STASH-507\n */\nexport const DATA_VIEW_INJECTION: InjectionWithDefaults<DataViewInjection> = Object.freeze({\n key: Symbol('DATA_VIEW_INJECTION_KEY'),\n defaults: Object.freeze({\n // Pagination\n currentPage: computed(() => 1),\n isPaginateNextDisabled: computed(() => false),\n isPaginationEnabled: computed(() => false),\n pageCount: computed(() => 1),\n pageSize: computed(() => DEFAULT_PAGE_SIZE),\n totalDataCount: computed(() => 0),\n setPage() {},\n goPrevPage() {},\n goNextPage() {},\n\n // Sorting\n currentSortId: computed(() => undefined),\n currentSortOrder: computed(() => undefined),\n updateCurrentSort() {},\n\n // Search\n currentSearch: computed(() => ''),\n updateCurrentSearch() {},\n\n // Miscellanous\n density: computed(() => undefined),\n isEmpty: computed(() => false),\n isLoading: computed(() => false),\n isSelectable: ref(false),\n isWithinModule: computed(() => false),\n variant: computed(() => undefined),\n }),\n});\n"],"names":["DEFAULT_PAGE_SIZE","DATA_VIEW_INJECTION","computed","ref"],"mappings":";AAAO,MAAMA,IAAoB,ICYpBC,IAAgE,OAAO,OAAO;AAAA,EACzF,KAAK,OAAO,yBAAyB;AAAA,EACrC,UAAU,OAAO,OAAO;AAAA;AAAA,IAEtB,aAAaC,EAAS,MAAM,CAAC;AAAA,IAC7B,wBAAwBA,EAAS,MAAM,EAAK;AAAA,IAC5C,qBAAqBA,EAAS,MAAM,EAAK;AAAA,IACzC,WAAWA,EAAS,MAAM,CAAC;AAAA,IAC3B,UAAUA,EAAS,MAAMF,CAAiB;AAAA,IAC1C,gBAAgBE,EAAS,MAAM,CAAC;AAAA,IAChC,UAAU;AAAA,IAAC;AAAA,IACX,aAAa;AAAA,IAAC;AAAA,IACd,aAAa;AAAA,IAAC;AAAA;AAAA,IAGd,eAAeA,EAAS,MAAA;AAAA,KAAe;AAAA,IACvC,kBAAkBA,EAAS,MAAA;AAAA,KAAe;AAAA,IAC1C,oBAAoB;AAAA,IAAC;AAAA;AAAA,IAGrB,eAAeA,EAAS,MAAM,EAAE;AAAA,IAChC,sBAAsB;AAAA,IAAC;AAAA;AAAA,IAGvB,SAASA,EAAS,MAAA;AAAA,KAAe;AAAA,IACjC,SAASA,EAAS,MAAM,EAAK;AAAA,IAC7B,WAAWA,EAAS,MAAM,EAAK;AAAA,IAC/B,cAAcC,EAAI,EAAK;AAAA,IACvB,gBAAgBD,EAAS,MAAM,EAAK;AAAA,IACpC,SAASA,EAAS;KAAe;AAAA,
|
|
1
|
+
{"version":3,"file":"DataView.keys-aSOnA4AD.js","sources":["../src/components/DataView/DataView.constants.ts","../src/components/DataView/DataView.keys.ts"],"sourcesContent":["export const DEFAULT_PAGE_SIZE = 12;\n","import { computed, ref } from 'vue';\n\nimport { InjectionWithDefaults } from '../../../types/utils';\nimport { DEFAULT_PAGE_SIZE } from './DataView.constants';\nimport { DataViewInjection } from './DataView.types';\n\n// See: https://vuejs.org/guide/typescript/composition-api.html#typing-provide-inject\n\n/**\n * Miscellaneous data that is not related to pagination, sorting, or searching.\n * TODO: merge all DataView injections into one. https://leaflink.atlassian.net/browse/STASH-507\n */\nexport const DATA_VIEW_INJECTION: InjectionWithDefaults<DataViewInjection> = Object.freeze({\n key: Symbol('DATA_VIEW_INJECTION_KEY'),\n defaults: Object.freeze({\n // Pagination\n currentPage: computed(() => 1),\n isPaginateNextDisabled: computed(() => false),\n isPaginationEnabled: computed(() => false),\n pageCount: computed(() => 1),\n pageSize: computed(() => DEFAULT_PAGE_SIZE),\n totalDataCount: computed(() => 0),\n setPage() {},\n goPrevPage() {},\n goNextPage() {},\n\n // Sorting\n currentSortId: computed(() => undefined),\n currentSortOrder: computed(() => undefined),\n updateCurrentSort() {},\n\n // Search\n currentSearch: computed(() => ''),\n updateCurrentSearch() {},\n\n // Miscellanous\n density: computed(() => undefined),\n isEmpty: computed(() => false),\n isLoading: computed(() => false),\n isSelectable: ref(false),\n isWithinModule: computed(() => false),\n variant: computed(() => undefined),\n }),\n});\n"],"names":["DEFAULT_PAGE_SIZE","DATA_VIEW_INJECTION","computed","ref"],"mappings":";AAAO,MAAMA,IAAoB,ICYpBC,IAAgE,OAAO,OAAO;AAAA,EACzF,KAAK,OAAO,yBAAyB;AAAA,EACrC,UAAU,OAAO,OAAO;AAAA;AAAA,IAEtB,aAAaC,EAAS,MAAM,CAAC;AAAA,IAC7B,wBAAwBA,EAAS,MAAM,EAAK;AAAA,IAC5C,qBAAqBA,EAAS,MAAM,EAAK;AAAA,IACzC,WAAWA,EAAS,MAAM,CAAC;AAAA,IAC3B,UAAUA,EAAS,MAAMF,CAAiB;AAAA,IAC1C,gBAAgBE,EAAS,MAAM,CAAC;AAAA,IAChC,UAAU;AAAA,IAAC;AAAA,IACX,aAAa;AAAA,IAAC;AAAA,IACd,aAAa;AAAA,IAAC;AAAA;AAAA,IAGd,eAAeA,EAAS,MAAA;AAAA,KAAe;AAAA,IACvC,kBAAkBA,EAAS,MAAA;AAAA,KAAe;AAAA,IAC1C,oBAAoB;AAAA,IAAC;AAAA;AAAA,IAGrB,eAAeA,EAAS,MAAM,EAAE;AAAA,IAChC,sBAAsB;AAAA,IAAC;AAAA;AAAA,IAGvB,SAASA,EAAS,MAAA;AAAA,KAAe;AAAA,IACjC,SAASA,EAAS,MAAM,EAAK;AAAA,IAC7B,WAAWA,EAAS,MAAM,EAAK;AAAA,IAC/B,cAAcC,EAAI,EAAK;AAAA,IACvB,gBAAgBD,EAAS,MAAM,EAAK;AAAA,IACpC,SAASA,EAAS;KAAe;AAAA,EAAA,CAClC;AACH,CAAC;"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"DataViewFilters.js","sources":["../src/components/DataViewFilters/DataViewFilters.types.ts","../src/components/DataViewFilters/useFilters.ts","../src/components/DataViewFilters/DataViewFilters.vue"],"sourcesContent":["import { UseFiltersReturnType } from './useFilters';\n\n/**\n * A function that is called when the user clicks one of the \"Apply\" buttons in DataViewFilters.\n *\n * A return value of `{ preventDismiss: true }` can be used to prevent the DataViewFilters drawer or a FilterDropdown from closing, such as when some filters have invalid values.\n */\nexport type OnApplyFilters = () => Promise<{ preventDismiss?: boolean } | void> | { preventDismiss?: boolean } | void;\n\nexport enum DrawerStyle {\n /** Displays all groups and their fields without the need for navigating submenus. */\n Cascade = 'cascade',\n /** Displays only group names or fields; navigation between the group names and a submenu of fields is required. */\n Nested = 'nested',\n}\n\nexport type DrawerStyles = `${DrawerStyle}`;\n\nexport interface DataViewFiltersUtilsInjection {\n useFiltersInstance?: UseFiltersReturnType;\n drawerStyle?: DrawerStyles;\n}\n","import cloneDeep from 'lodash-es/cloneDeep';\nimport { computed, ComputedRef, Ref, ref } from 'vue';\n\nimport isDefined from '../../composables/useValidation/utils/isDefined';\nimport DataView from '../DataView/DataView.vue';\n\ntype DataViewInstance = InstanceType<typeof DataView>;\n\n/**\n * Contains metadata and configuration for the filters.\n * @see https://www.typescriptlang.org/docs/handbook/2/mapped-types.html\n */\nexport type UseFiltersSchema<Values extends object, Groups extends string> = {\n [Property in keyof Values]: {\n defaultValue?: Values[Property];\n group?: Groups;\n isActive?: (value: Values[Property]) => boolean;\n };\n};\n\nexport interface UseFiltersArgs<Values extends object, Groups extends string> {\n schema: UseFiltersSchema<Values, Groups>;\n /** A ref for an instance of DataView */\n dataViewRef: Ref<unknown>; // Note: using `Ref<InstanceType<typeof DataView>>` here causes type errors when providing a value for this argument\n}\n\nexport interface UseFiltersReturnType<Values = object, Groups extends string = string> {\n applyFilters: () => void;\n resetAllFilters: () => void;\n resetFilterGroup: (group: string) => void; // Note: group is intentionally not typed as `Groups` since there is no way to pass in a Groups type to UseFiltersReturnType within DataViewFilters.vue\n undoWorkingFilters: () => void;\n activeFiltersCounts: ComputedRef<Record<Groups, number>>;\n totalActiveFiltersCount: ComputedRef<number>;\n appliedFilters: Ref<Values>;\n workingFilters: Ref<Values>;\n}\n\n/**\n * Provides utility functions for working with `DataViewFilters`.\n */\nexport function useFilters<Values extends object, Groups extends string>({\n schema,\n dataViewRef,\n}: UseFiltersArgs<Values, Groups>): UseFiltersReturnType<Values, Groups> {\n const appliedFilters = ref({}) as Ref<Values>;\n const workingFilters = ref({}) as Ref<Values>;\n\n for (const filterName in schema) {\n // @ts-expect-error \"could be instantiated with an arbitrary type\"; TODO: figure out how to resolve the types\n appliedFilters.value[filterName] = schema[filterName].defaultValue;\n // @ts-expect-error \"could be instantiated with an arbitrary type\"; TODO: figure out how to resolve the types\n workingFilters.value[filterName] = schema[filterName].defaultValue;\n }\n\n const dvRef = dataViewRef as Ref<DataViewInstance>;\n\n /**\n * For when an \"Apply\" button is clicked. It does the following:\n * 1) applies the working filter state\n * 2) sets the current page to 1\n * 3) emits the \"update\" event from DataView\n */\n function applyFilters() {\n appliedFilters.value = cloneDeep(workingFilters.value);\n dvRef.value.updateCurrentFilters(appliedFilters.value, { shouldEmit: true });\n }\n\n /**\n * For when a \"Reset all\" button is clicked. It does the following:\n * 1) applies the defaultValue filter values to all filters\n * 2) sets the current page to 1\n * 3) emits the \"update\" event from DataView\n */\n function resetAllFilters() {\n for (const filterName in schema) {\n // @ts-expect-error \"could be instantiated with an arbitrary type\"; TODO: figure out how to resolve the types\n appliedFilters.value[filterName] = schema[filterName].defaultValue;\n // @ts-expect-error \"could be instantiated with an arbitrary type\"; TODO: figure out how to resolve the types\n workingFilters.value[filterName] = schema[filterName].defaultValue;\n }\n\n dvRef.value.updateCurrentFilters(appliedFilters.value, { shouldEmit: true });\n }\n\n /**\n * For when a \"Reset\" button is clicked. It does the following:\n * 1) applies the defaultValue filter values to the given filter group\n * 2) sets the current page to 1\n * 3) emits the \"update\" event from DataView\n */\n function resetFilterGroup(group: Groups) {\n for (const filterName in schema) {\n if (schema[filterName].group === group) {\n // @ts-expect-error \"could be instantiated with an arbitrary type\"; TODO: figure out how to resolve the types\n appliedFilters.value[filterName] = schema[filterName].defaultValue;\n // @ts-expect-error \"could be instantiated with an arbitrary type\"; TODO: figure out how to resolve the types\n workingFilters.value[filterName] = schema[filterName].defaultValue;\n }\n }\n\n dvRef.value.updateCurrentFilters(appliedFilters.value, { shouldEmit: true });\n }\n\n /**\n * Resets the `workingFilters` to match the `appliedFilters`. This can be used when the FilterDrawer or a FilterDropdown is dismissed without clicking \"Reset\" or \"Apply\".\n */\n function undoWorkingFilters() {\n workingFilters.value = cloneDeep(appliedFilters.value);\n }\n\n const activeFiltersCounts = computed(() => {\n const counts = {} as Record<Groups, number>;\n\n for (const filterName in schema) {\n const config = schema[filterName];\n const value = appliedFilters.value[filterName];\n const isActive = config.isActive?.(value) || isDefined(value);\n\n if (isActive && config.group) {\n counts[config.group] = (counts[config.group] ?? 0) + 1;\n }\n }\n\n return counts;\n });\n\n const totalActiveFiltersCount = computed(() => {\n let count = 0;\n\n for (const filterName in schema) {\n const config = schema[filterName];\n const value = appliedFilters.value[filterName];\n const isActive = config.isActive?.(value) || isDefined(value);\n\n if (isActive) {\n count += 1;\n }\n }\n\n return count;\n });\n\n return {\n applyFilters,\n resetAllFilters,\n // @ts-expect-error \"could be instantiated with a different subtype\": TODO: figure out how to resolve the types\n resetFilterGroup,\n undoWorkingFilters,\n activeFiltersCounts,\n totalActiveFiltersCount,\n appliedFilters,\n workingFilters,\n };\n}\n\nexport default useFilters;\n","<script lang=\"ts\">\n export * from './DataViewFilters.keys';\n export * from './DataViewFilters.types';\n export * from './useFilters';\n</script>\n\n<script setup lang=\"ts\">\n import { computed, inject, provide, ref, watch } from 'vue';\n\n import useMediaQuery from '../../composables/useMediaQuery/useMediaQuery';\n import { SCREEN_SIZES } from '../../constants';\n import { t } from '../../locale';\n import Box from '../Box/Box.vue';\n import Button from '../Button/Button.vue';\n import { DATA_VIEW_INJECTION } from '../DataView/DataView.vue';\n import FilterChip from '../FilterChip/FilterChip.vue';\n import Icon from '../Icon/Icon.vue';\n import Label from '../Label/Label.vue';\n import Modal, { type ModalProps } from '../Modal/Modal.vue';\n import SearchBar, { SearchBarProps } from '../SearchBar/SearchBar.vue';\n import { DATA_VIEW_FILTERS_UTILS_INJECTION } from './DataViewFilters.keys';\n import type { DrawerStyles, OnApplyFilters } from './DataViewFilters.types';\n import type { UseFiltersReturnType } from './useFilters';\n\n export interface DataViewFiltersProps {\n filtersLabelText?: string;\n /**\n * Props to pass to the `SearchBar` component.\n */\n searchBarProps?: SearchBarProps;\n showSearch?: boolean;\n /** 'cascade' displays all fields within every filter group; 'nested' displays only the group names and requires clicking a group to view its fields. */\n drawerStyle?: DrawerStyles;\n drawerProps?: ModalProps;\n /**\n * @deprecated The `activeGroup` prop is a sufficient replacement for this prop. A falsy `activeGroup` will hide the button and a truthy `activeGroup` will show it (when the `drawerStyle` is 'nested').\n *\n * **Note:** This prop has no effect when using a \"cascade\" `drawerStyle`.\n */\n showDrawerPreviousButton?: boolean;\n /**\n * Required when using filters. This prop should contain the return value of the `useFilters()` composable.\n */\n useFiltersInstance?: UseFiltersReturnType;\n onApply?: OnApplyFilters;\n /**\n * The name of the active filter group. The active filter group is determined by which instance of FilterDropdown or FilterDrawerItem is open.\n *\n * **Note:** This prop is required when using a \"nested\" `drawerStyle`, but has no effect when using a \"cascade\" `drawerStyle`.\n */\n activeGroup?: string;\n }\n\n export interface DataViewFiltersSlots {\n default?: () => unknown;\n drawer?: () => unknown;\n 'filters-label'?: () => unknown;\n }\n\n const props = withDefaults(defineProps<DataViewFiltersProps>(), {\n filtersLabelText: t('ll.filterBy'),\n isLoading: false,\n drawerStyle: 'cascade',\n drawerProps: undefined,\n searchBarProps: undefined,\n showDrawerPreviousButton: false,\n showSearch: true,\n useFiltersInstance: undefined,\n onApply: undefined,\n activeGroup: undefined,\n });\n\n const emit = defineEmits<{\n /** When the drawer is opened */\n (e: 'open-drawer'): void;\n /** When the drawer is dismissed */\n (e: 'dismiss'): void;\n /** When the \"Previous\" button in the header is clicked */\n (e: 'previous'): void;\n /** When the \"Reset\" button is clicked while viewing a filter group */\n (e: 'reset-group'): void;\n /** When one of the \"Reset All\" buttons is clicked */\n (e: 'reset-all'): void;\n }>();\n\n const slots = defineSlots<DataViewFiltersSlots>();\n\n const isDesktop = useMediaQuery(`(min-width: ${SCREEN_SIZES.lg})`);\n const isViewingGroupsMenu = computed(() => props.drawerStyle === 'nested' && !props.activeGroup);\n const isViewingSingleGroup = computed(() => props.drawerStyle === 'nested' && props.activeGroup);\n\n const {\n density,\n isLoading: isDataViewLoading,\n isWithinModule,\n currentSearch,\n updateCurrentSearch,\n } = inject(DATA_VIEW_INJECTION.key, DATA_VIEW_INJECTION.defaults);\n\n provide(DATA_VIEW_FILTERS_UTILS_INJECTION.key, {\n useFiltersInstance: props.useFiltersInstance,\n drawerStyle: props.drawerStyle,\n });\n\n const totalActiveFiltersCount = computed(() => props.useFiltersInstance?.totalActiveFiltersCount.value ?? 0);\n /** The number of active filters in the currently active group. This is only used when the drawerStyle is 'nested'. */\n const activeGroupActiveFiltersCount = computed(\n () => Number(props.activeGroup && props.useFiltersInstance?.activeFiltersCounts.value[props.activeGroup]) || 0,\n );\n const isDrawerOpen = ref(false);\n\n async function handleApplyClick() {\n const { preventDismiss } = (await props.onApply?.()) || props.useFiltersInstance?.applyFilters() || {};\n\n if (!preventDismiss) {\n isDrawerOpen.value = false;\n }\n }\n\n function handleResetGroupClick() {\n if (!props.activeGroup) {\n return;\n }\n\n props.useFiltersInstance?.resetFilterGroup(props.activeGroup);\n emit('reset-group');\n isDrawerOpen.value = false;\n }\n\n function handleResetAllClick() {\n props.useFiltersInstance?.resetAllFilters();\n emit('reset-all');\n isDrawerOpen.value = false;\n }\n\n function onDismiss() {\n props.useFiltersInstance?.undoWorkingFilters();\n isDrawerOpen.value = false;\n emit('dismiss');\n }\n\n watch(isDrawerOpen, () => {\n if (isDrawerOpen.value) {\n emit('open-drawer');\n }\n });\n</script>\n\n<template>\n <Box\n class=\"stash-data-view-filters tw-grid tw-grid-cols-12 tw-gap-6 tw-p-3\"\n :class=\"{ 'lg:tw-p-6': density === 'comfortable', 'tw-mb-3': !isWithinModule }\"\n :radius=\"isWithinModule ? 'none' : 'rounded'\"\n data-test=\"stash-data-view-filters\"\n disable-padding\n >\n <SearchBar\n v-if=\"props.showSearch\"\n class=\"tw-col-span-12 md:tw-col-span-6 lg:tw-col-span-4\"\n data-test=\"stash-data-view-filters|search-bar\"\n :is-loading=\"isDataViewLoading\"\n :label=\"t('ll.search')\"\n :model-value=\"currentSearch\"\n v-bind=\"props.searchBarProps\"\n @search=\"(searchTerm) => updateCurrentSearch(searchTerm, { shouldEmit: true })\"\n />\n <div\n v-if=\"slots.default\"\n class=\"tw-col-span-12 tw-row-start-2 md:tw-col-start-7 md:tw-row-start-1 lg:tw-col-span-8 lg:tw-col-start-5\"\n >\n <div class=\"tw-hidden md:tw-block\">\n <slot name=\"filters-label\">\n <Label>{{ props.filtersLabelText }}</Label>\n </slot>\n </div>\n <div class=\"tw-flex tw-gap-4\">\n <FilterChip\n secondary\n class=\"!tw-flex tw-w-full tw-justify-center tw-gap-4 md:!tw-inline-flex md:tw-w-auto\"\n data-test=\"stash-data-view-filters|drawer-toggle-button\"\n :filter-count=\"totalActiveFiltersCount\"\n @click=\"isDrawerOpen = true\"\n >\n <span class=\"tw-inline-flex tw-items-center tw-gap-3\">\n <Icon name=\"filter-line\" class=\"tw-text-ice-700\" />\n <span>{{ t('ll.filters') }}</span>\n </span>\n </FilterChip>\n <slot v-if=\"isDesktop\"></slot>\n <Button v-if=\"totalActiveFiltersCount > 0 && isDesktop\" inline @click=\"handleResetAllClick\">\n {{ t('ll.resetAll') }}\n </Button>\n </div>\n </div>\n <Modal\n v-if=\"slots.drawer\"\n data-test=\"stash-data-view-filters|drawer\"\n disable-body-padding\n position=\"right\"\n size=\"narrow\"\n :is-open=\"isDrawerOpen\"\n :title=\"t('ll.allFilters')\"\n v-bind=\"props.drawerProps\"\n @dismiss=\"onDismiss\"\n >\n <template #headerAction>\n <Button\n v-if=\"isViewingSingleGroup\"\n icon\n class=\"tw-text-ice-100\"\n data-test=\"stash-data-view-filters|drawer-previous-button\"\n :aria-label=\"t('ll.previous')\"\n :title=\"t('ll.previous')\"\n @click=\"emit('previous')\"\n >\n <Icon name=\"chevron-left\" />\n </Button>\n </template>\n\n <slot name=\"drawer\"></slot>\n\n <template #footer>\n <div class=\"tw-flex tw-justify-end tw-gap-gutter\">\n <Button v-if=\"totalActiveFiltersCount === 0\" secondary @click=\"onDismiss\">\n {{ t('ll.cancel') }}\n </Button>\n <Button\n v-if=\"(isViewingGroupsMenu || props.drawerStyle === 'cascade') && totalActiveFiltersCount > 0\"\n secondary\n :disabled=\"isDataViewLoading\"\n @click=\"handleResetAllClick\"\n >\n {{ t('ll.resetAll') }}\n </Button>\n <Button\n v-if=\"isViewingSingleGroup && activeGroupActiveFiltersCount > 0\"\n secondary\n :disabled=\"isDataViewLoading\"\n @click=\"handleResetGroupClick\"\n >\n {{ t('ll.reset') }}\n </Button>\n <Button\n v-if=\"isViewingSingleGroup || props.drawerStyle === 'cascade'\"\n :disabled=\"isDataViewLoading\"\n @click=\"handleApplyClick\"\n >\n {{ t('ll.apply') }}\n </Button>\n </div>\n </template>\n </Modal>\n </Box>\n</template>\n"],"names":["DrawerStyle","useFilters","schema","dataViewRef","appliedFilters","ref","workingFilters","filterName","dvRef","applyFilters","cloneDeep","resetAllFilters","resetFilterGroup","group","undoWorkingFilters","activeFiltersCounts","computed","counts","config","value","_a","isDefined","totalActiveFiltersCount","count","props","__props","emit","__emit","slots","_useSlots","isDesktop","useMediaQuery","SCREEN_SIZES","isViewingGroupsMenu","isViewingSingleGroup","density","isDataViewLoading","isWithinModule","currentSearch","updateCurrentSearch","inject","DATA_VIEW_INJECTION","provide","DATA_VIEW_FILTERS_UTILS_INJECTION","activeGroupActiveFiltersCount","isDrawerOpen","handleApplyClick","preventDismiss","_b","handleResetGroupClick","handleResetAllClick","onDismiss","watch"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"DataViewFilters.js","sources":["../src/components/DataViewFilters/DataViewFilters.types.ts","../src/components/DataViewFilters/useFilters.ts","../src/components/DataViewFilters/DataViewFilters.vue"],"sourcesContent":["import { UseFiltersReturnType } from './useFilters';\n\n/**\n * A function that is called when the user clicks one of the \"Apply\" buttons in DataViewFilters.\n *\n * A return value of `{ preventDismiss: true }` can be used to prevent the DataViewFilters drawer or a FilterDropdown from closing, such as when some filters have invalid values.\n */\nexport type OnApplyFilters = () => Promise<{ preventDismiss?: boolean } | void> | { preventDismiss?: boolean } | void;\n\nexport enum DrawerStyle {\n /** Displays all groups and their fields without the need for navigating submenus. */\n Cascade = 'cascade',\n /** Displays only group names or fields; navigation between the group names and a submenu of fields is required. */\n Nested = 'nested',\n}\n\nexport type DrawerStyles = `${DrawerStyle}`;\n\nexport interface DataViewFiltersUtilsInjection {\n useFiltersInstance?: UseFiltersReturnType;\n drawerStyle?: DrawerStyles;\n}\n","import cloneDeep from 'lodash-es/cloneDeep';\nimport { computed, ComputedRef, Ref, ref } from 'vue';\n\nimport isDefined from '../../composables/useValidation/utils/isDefined';\nimport DataView from '../DataView/DataView.vue';\n\ntype DataViewInstance = InstanceType<typeof DataView>;\n\n/**\n * Contains metadata and configuration for the filters.\n * @see https://www.typescriptlang.org/docs/handbook/2/mapped-types.html\n */\nexport type UseFiltersSchema<Values extends object, Groups extends string> = {\n [Property in keyof Values]: {\n defaultValue?: Values[Property];\n group?: Groups;\n isActive?: (value: Values[Property]) => boolean;\n };\n};\n\nexport interface UseFiltersArgs<Values extends object, Groups extends string> {\n schema: UseFiltersSchema<Values, Groups>;\n /** A ref for an instance of DataView */\n dataViewRef: Ref<unknown>; // Note: using `Ref<InstanceType<typeof DataView>>` here causes type errors when providing a value for this argument\n}\n\nexport interface UseFiltersReturnType<Values = object, Groups extends string = string> {\n applyFilters: () => void;\n resetAllFilters: () => void;\n resetFilterGroup: (group: string) => void; // Note: group is intentionally not typed as `Groups` since there is no way to pass in a Groups type to UseFiltersReturnType within DataViewFilters.vue\n undoWorkingFilters: () => void;\n activeFiltersCounts: ComputedRef<Record<Groups, number>>;\n totalActiveFiltersCount: ComputedRef<number>;\n appliedFilters: Ref<Values>;\n workingFilters: Ref<Values>;\n}\n\n/**\n * Provides utility functions for working with `DataViewFilters`.\n */\nexport function useFilters<Values extends object, Groups extends string>({\n schema,\n dataViewRef,\n}: UseFiltersArgs<Values, Groups>): UseFiltersReturnType<Values, Groups> {\n const appliedFilters = ref({}) as Ref<Values>;\n const workingFilters = ref({}) as Ref<Values>;\n\n for (const filterName in schema) {\n // @ts-expect-error \"could be instantiated with an arbitrary type\"; TODO: figure out how to resolve the types\n appliedFilters.value[filterName] = schema[filterName].defaultValue;\n // @ts-expect-error \"could be instantiated with an arbitrary type\"; TODO: figure out how to resolve the types\n workingFilters.value[filterName] = schema[filterName].defaultValue;\n }\n\n const dvRef = dataViewRef as Ref<DataViewInstance>;\n\n /**\n * For when an \"Apply\" button is clicked. It does the following:\n * 1) applies the working filter state\n * 2) sets the current page to 1\n * 3) emits the \"update\" event from DataView\n */\n function applyFilters() {\n appliedFilters.value = cloneDeep(workingFilters.value);\n dvRef.value.updateCurrentFilters(appliedFilters.value, { shouldEmit: true });\n }\n\n /**\n * For when a \"Reset all\" button is clicked. It does the following:\n * 1) applies the defaultValue filter values to all filters\n * 2) sets the current page to 1\n * 3) emits the \"update\" event from DataView\n */\n function resetAllFilters() {\n for (const filterName in schema) {\n // @ts-expect-error \"could be instantiated with an arbitrary type\"; TODO: figure out how to resolve the types\n appliedFilters.value[filterName] = schema[filterName].defaultValue;\n // @ts-expect-error \"could be instantiated with an arbitrary type\"; TODO: figure out how to resolve the types\n workingFilters.value[filterName] = schema[filterName].defaultValue;\n }\n\n dvRef.value.updateCurrentFilters(appliedFilters.value, { shouldEmit: true });\n }\n\n /**\n * For when a \"Reset\" button is clicked. It does the following:\n * 1) applies the defaultValue filter values to the given filter group\n * 2) sets the current page to 1\n * 3) emits the \"update\" event from DataView\n */\n function resetFilterGroup(group: Groups) {\n for (const filterName in schema) {\n if (schema[filterName].group === group) {\n // @ts-expect-error \"could be instantiated with an arbitrary type\"; TODO: figure out how to resolve the types\n appliedFilters.value[filterName] = schema[filterName].defaultValue;\n // @ts-expect-error \"could be instantiated with an arbitrary type\"; TODO: figure out how to resolve the types\n workingFilters.value[filterName] = schema[filterName].defaultValue;\n }\n }\n\n dvRef.value.updateCurrentFilters(appliedFilters.value, { shouldEmit: true });\n }\n\n /**\n * Resets the `workingFilters` to match the `appliedFilters`. This can be used when the FilterDrawer or a FilterDropdown is dismissed without clicking \"Reset\" or \"Apply\".\n */\n function undoWorkingFilters() {\n workingFilters.value = cloneDeep(appliedFilters.value);\n }\n\n const activeFiltersCounts = computed(() => {\n const counts = {} as Record<Groups, number>;\n\n for (const filterName in schema) {\n const config = schema[filterName];\n const value = appliedFilters.value[filterName];\n const isActive = config.isActive?.(value) || isDefined(value);\n\n if (isActive && config.group) {\n counts[config.group] = (counts[config.group] ?? 0) + 1;\n }\n }\n\n return counts;\n });\n\n const totalActiveFiltersCount = computed(() => {\n let count = 0;\n\n for (const filterName in schema) {\n const config = schema[filterName];\n const value = appliedFilters.value[filterName];\n const isActive = config.isActive?.(value) || isDefined(value);\n\n if (isActive) {\n count += 1;\n }\n }\n\n return count;\n });\n\n return {\n applyFilters,\n resetAllFilters,\n // @ts-expect-error \"could be instantiated with a different subtype\": TODO: figure out how to resolve the types\n resetFilterGroup,\n undoWorkingFilters,\n activeFiltersCounts,\n totalActiveFiltersCount,\n appliedFilters,\n workingFilters,\n };\n}\n\nexport default useFilters;\n","<script lang=\"ts\">\n export * from './DataViewFilters.keys';\n export * from './DataViewFilters.types';\n export * from './useFilters';\n</script>\n\n<script setup lang=\"ts\">\n import { computed, inject, provide, ref, watch } from 'vue';\n\n import useMediaQuery from '../../composables/useMediaQuery/useMediaQuery';\n import { SCREEN_SIZES } from '../../constants';\n import { t } from '../../locale';\n import Box from '../Box/Box.vue';\n import Button from '../Button/Button.vue';\n import { DATA_VIEW_INJECTION } from '../DataView/DataView.vue';\n import FilterChip from '../FilterChip/FilterChip.vue';\n import Icon from '../Icon/Icon.vue';\n import Label from '../Label/Label.vue';\n import Modal, { type ModalProps } from '../Modal/Modal.vue';\n import SearchBar, { SearchBarProps } from '../SearchBar/SearchBar.vue';\n import { DATA_VIEW_FILTERS_UTILS_INJECTION } from './DataViewFilters.keys';\n import type { DrawerStyles, OnApplyFilters } from './DataViewFilters.types';\n import type { UseFiltersReturnType } from './useFilters';\n\n export interface DataViewFiltersProps {\n filtersLabelText?: string;\n /**\n * Props to pass to the `SearchBar` component.\n */\n searchBarProps?: SearchBarProps;\n showSearch?: boolean;\n /** 'cascade' displays all fields within every filter group; 'nested' displays only the group names and requires clicking a group to view its fields. */\n drawerStyle?: DrawerStyles;\n drawerProps?: ModalProps;\n /**\n * @deprecated The `activeGroup` prop is a sufficient replacement for this prop. A falsy `activeGroup` will hide the button and a truthy `activeGroup` will show it (when the `drawerStyle` is 'nested').\n *\n * **Note:** This prop has no effect when using a \"cascade\" `drawerStyle`.\n */\n showDrawerPreviousButton?: boolean;\n /**\n * Required when using filters. This prop should contain the return value of the `useFilters()` composable.\n */\n useFiltersInstance?: UseFiltersReturnType;\n onApply?: OnApplyFilters;\n /**\n * The name of the active filter group. The active filter group is determined by which instance of FilterDropdown or FilterDrawerItem is open.\n *\n * **Note:** This prop is required when using a \"nested\" `drawerStyle`, but has no effect when using a \"cascade\" `drawerStyle`.\n */\n activeGroup?: string;\n }\n\n export interface DataViewFiltersSlots {\n default?: () => unknown;\n drawer?: () => unknown;\n 'filters-label'?: () => unknown;\n }\n\n const props = withDefaults(defineProps<DataViewFiltersProps>(), {\n filtersLabelText: t('ll.filterBy'),\n isLoading: false,\n drawerStyle: 'cascade',\n drawerProps: undefined,\n searchBarProps: undefined,\n showDrawerPreviousButton: false,\n showSearch: true,\n useFiltersInstance: undefined,\n onApply: undefined,\n activeGroup: undefined,\n });\n\n const emit = defineEmits<{\n /** When the drawer is opened */\n (e: 'open-drawer'): void;\n /** When the drawer is dismissed */\n (e: 'dismiss'): void;\n /** When the \"Previous\" button in the header is clicked */\n (e: 'previous'): void;\n /** When the \"Reset\" button is clicked while viewing a filter group */\n (e: 'reset-group'): void;\n /** When one of the \"Reset All\" buttons is clicked */\n (e: 'reset-all'): void;\n }>();\n\n const slots = defineSlots<DataViewFiltersSlots>();\n\n const isDesktop = useMediaQuery(`(min-width: ${SCREEN_SIZES.lg})`);\n const isViewingGroupsMenu = computed(() => props.drawerStyle === 'nested' && !props.activeGroup);\n const isViewingSingleGroup = computed(() => props.drawerStyle === 'nested' && props.activeGroup);\n\n const {\n density,\n isLoading: isDataViewLoading,\n isWithinModule,\n currentSearch,\n updateCurrentSearch,\n } = inject(DATA_VIEW_INJECTION.key, DATA_VIEW_INJECTION.defaults);\n\n provide(DATA_VIEW_FILTERS_UTILS_INJECTION.key, {\n useFiltersInstance: props.useFiltersInstance,\n drawerStyle: props.drawerStyle,\n });\n\n const totalActiveFiltersCount = computed(() => props.useFiltersInstance?.totalActiveFiltersCount.value ?? 0);\n /** The number of active filters in the currently active group. This is only used when the drawerStyle is 'nested'. */\n const activeGroupActiveFiltersCount = computed(\n () => Number(props.activeGroup && props.useFiltersInstance?.activeFiltersCounts.value[props.activeGroup]) || 0,\n );\n const isDrawerOpen = ref(false);\n\n async function handleApplyClick() {\n const { preventDismiss } = (await props.onApply?.()) || props.useFiltersInstance?.applyFilters() || {};\n\n if (!preventDismiss) {\n isDrawerOpen.value = false;\n }\n }\n\n function handleResetGroupClick() {\n if (!props.activeGroup) {\n return;\n }\n\n props.useFiltersInstance?.resetFilterGroup(props.activeGroup);\n emit('reset-group');\n isDrawerOpen.value = false;\n }\n\n function handleResetAllClick() {\n props.useFiltersInstance?.resetAllFilters();\n emit('reset-all');\n isDrawerOpen.value = false;\n }\n\n function onDismiss() {\n props.useFiltersInstance?.undoWorkingFilters();\n isDrawerOpen.value = false;\n emit('dismiss');\n }\n\n watch(isDrawerOpen, () => {\n if (isDrawerOpen.value) {\n emit('open-drawer');\n }\n });\n</script>\n\n<template>\n <Box\n class=\"stash-data-view-filters tw-grid tw-grid-cols-12 tw-gap-6 tw-p-3\"\n :class=\"{ 'lg:tw-p-6': density === 'comfortable', 'tw-mb-3': !isWithinModule }\"\n :radius=\"isWithinModule ? 'none' : 'rounded'\"\n data-test=\"stash-data-view-filters\"\n disable-padding\n >\n <SearchBar\n v-if=\"props.showSearch\"\n class=\"tw-col-span-12 md:tw-col-span-6 lg:tw-col-span-4\"\n data-test=\"stash-data-view-filters|search-bar\"\n :is-loading=\"isDataViewLoading\"\n :label=\"t('ll.search')\"\n :model-value=\"currentSearch\"\n v-bind=\"props.searchBarProps\"\n @search=\"(searchTerm) => updateCurrentSearch(searchTerm, { shouldEmit: true })\"\n />\n <div\n v-if=\"slots.default\"\n class=\"tw-col-span-12 tw-row-start-2 md:tw-col-start-7 md:tw-row-start-1 lg:tw-col-span-8 lg:tw-col-start-5\"\n >\n <div class=\"tw-hidden md:tw-block\">\n <slot name=\"filters-label\">\n <Label>{{ props.filtersLabelText }}</Label>\n </slot>\n </div>\n <div class=\"tw-flex tw-gap-4\">\n <FilterChip\n secondary\n class=\"!tw-flex tw-w-full tw-justify-center tw-gap-4 md:!tw-inline-flex md:tw-w-auto\"\n data-test=\"stash-data-view-filters|drawer-toggle-button\"\n :filter-count=\"totalActiveFiltersCount\"\n @click=\"isDrawerOpen = true\"\n >\n <span class=\"tw-inline-flex tw-items-center tw-gap-3\">\n <Icon name=\"filter-line\" class=\"tw-text-ice-700\" />\n <span>{{ t('ll.filters') }}</span>\n </span>\n </FilterChip>\n <slot v-if=\"isDesktop\"></slot>\n <Button v-if=\"totalActiveFiltersCount > 0 && isDesktop\" inline @click=\"handleResetAllClick\">\n {{ t('ll.resetAll') }}\n </Button>\n </div>\n </div>\n <Modal\n v-if=\"slots.drawer\"\n data-test=\"stash-data-view-filters|drawer\"\n disable-body-padding\n position=\"right\"\n size=\"narrow\"\n :is-open=\"isDrawerOpen\"\n :title=\"t('ll.allFilters')\"\n v-bind=\"props.drawerProps\"\n @dismiss=\"onDismiss\"\n >\n <template #headerAction>\n <Button\n v-if=\"isViewingSingleGroup\"\n icon\n class=\"tw-text-ice-100\"\n data-test=\"stash-data-view-filters|drawer-previous-button\"\n :aria-label=\"t('ll.previous')\"\n :title=\"t('ll.previous')\"\n @click=\"emit('previous')\"\n >\n <Icon name=\"chevron-left\" />\n </Button>\n </template>\n\n <slot name=\"drawer\"></slot>\n\n <template #footer>\n <div class=\"tw-flex tw-justify-end tw-gap-gutter\">\n <Button v-if=\"totalActiveFiltersCount === 0\" secondary @click=\"onDismiss\">\n {{ t('ll.cancel') }}\n </Button>\n <Button\n v-if=\"(isViewingGroupsMenu || props.drawerStyle === 'cascade') && totalActiveFiltersCount > 0\"\n secondary\n :disabled=\"isDataViewLoading\"\n @click=\"handleResetAllClick\"\n >\n {{ t('ll.resetAll') }}\n </Button>\n <Button\n v-if=\"isViewingSingleGroup && activeGroupActiveFiltersCount > 0\"\n secondary\n :disabled=\"isDataViewLoading\"\n @click=\"handleResetGroupClick\"\n >\n {{ t('ll.reset') }}\n </Button>\n <Button\n v-if=\"isViewingSingleGroup || props.drawerStyle === 'cascade'\"\n :disabled=\"isDataViewLoading\"\n @click=\"handleApplyClick\"\n >\n {{ t('ll.apply') }}\n </Button>\n </div>\n </template>\n </Modal>\n </Box>\n</template>\n"],"names":["DrawerStyle","useFilters","schema","dataViewRef","appliedFilters","ref","workingFilters","filterName","dvRef","applyFilters","cloneDeep","resetAllFilters","resetFilterGroup","group","undoWorkingFilters","activeFiltersCounts","computed","counts","config","value","_a","isDefined","totalActiveFiltersCount","count","props","__props","emit","__emit","slots","_useSlots","isDesktop","useMediaQuery","SCREEN_SIZES","isViewingGroupsMenu","isViewingSingleGroup","density","isDataViewLoading","isWithinModule","currentSearch","updateCurrentSearch","inject","DATA_VIEW_INJECTION","provide","DATA_VIEW_FILTERS_UTILS_INJECTION","activeGroupActiveFiltersCount","isDrawerOpen","handleApplyClick","preventDismiss","_b","handleResetGroupClick","handleResetAllClick","onDismiss","watch"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"DataViewFilters.keys-BLu07FiP.js","sources":["../src/components/DataViewFilters/DataViewFilters.keys.ts"],"sourcesContent":["import { Injection } from '../../../types/utils';\nimport { DataViewFiltersUtilsInjection } from './DataViewFilters.types';\n\n// See: https://vuejs.org/guide/typescript/composition-api.html#typing-provide-inject\n\nexport const DATA_VIEW_FILTERS_UTILS_INJECTION: Injection<DataViewFiltersUtilsInjection> = Object.freeze({\n key: Symbol('DATA_VIEW_FILTERS_UTILS_INJECTION_KEY'),\n});\n"],"names":["DATA_VIEW_FILTERS_UTILS_INJECTION"],"mappings":"
|
|
1
|
+
{"version":3,"file":"DataViewFilters.keys-BLu07FiP.js","sources":["../src/components/DataViewFilters/DataViewFilters.keys.ts"],"sourcesContent":["import { Injection } from '../../../types/utils';\nimport { DataViewFiltersUtilsInjection } from './DataViewFilters.types';\n\n// See: https://vuejs.org/guide/typescript/composition-api.html#typing-provide-inject\n\nexport const DATA_VIEW_FILTERS_UTILS_INJECTION: Injection<DataViewFiltersUtilsInjection> = Object.freeze({\n key: Symbol('DATA_VIEW_FILTERS_UTILS_INJECTION_KEY'),\n});\n"],"names":["DATA_VIEW_FILTERS_UTILS_INJECTION"],"mappings":"AAKO,MAAMA,IAA8E,OAAO,OAAO;AAAA,EACvG,KAAK,OAAO,uCAAuC;AACrD,CAAC;"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"DataViewSortButton.js","sources":["../src/components/DataViewSortButton/DataViewSortButton.vue"],"sourcesContent":["<script lang=\"ts\" setup>\n import { inject, useCssModule } from 'vue';\n\n import { t } from '../../locale';\n import Button from '../Button/Button.vue';\n import { DATA_VIEW_INJECTION } from '../DataView/DataView.vue';\n import Dropdown from '../Dropdown/Dropdown.vue';\n import Icon from '../Icon/Icon.vue';\n import IconLabel from '../IconLabel/IconLabel.vue';\n import { SortOption } from './DataViewSortButton.types';\n\n export interface DataViewToolbarProps {\n /**\n * An array of sort options to display in the dropdown.\n */\n sortOptions?: SortOption[];\n }\n\n const props = withDefaults(defineProps<DataViewToolbarProps>(), {\n sortOptions: () => [],\n });\n const classes = useCssModule();\n\n const { currentSortId, currentSortOrder, updateCurrentSort } = inject(\n DATA_VIEW_INJECTION.key,\n DATA_VIEW_INJECTION.defaults,\n );\n</script>\n\n<template>\n <Dropdown\n v-if=\"props.sortOptions.length\"\n align=\"left\"\n class=\"stash-data-view-sort-button\"\n data-test=\"stash-data-view-sort-button\"\n >\n <template #toggle=\"{ isActive, toggle }\">\n <Button\n icon-label\n :aria-expanded=\"isActive.toString()\"\n class=\"tw-text-blue-500\"\n data-test=\"stash-data-view-sort-button|sort-menu-button\"\n @click=\"toggle\"\n >\n <IconLabel icon=\"sort\" stacked>\n {{ t('ll.sort') }}\n </IconLabel>\n </Button>\n </template>\n <ul class=\"dropdown__list\" data-test=\"stash-data-view-sort-button|sort-menu\">\n <template v-for=\"sortOption in props.sortOptions\" :key=\"sortOption.id\">\n <li\n class=\"dropdown__item tw-rounded\"\n :class=\"[\n classes.dropdown__item,\n { 'tw-bg-blue-100 tw-text-ice-700': sortOption.id === currentSortId && currentSortOrder === 'asc' },\n ]\"\n @click=\"() => updateCurrentSort(sortOption.id, { sortOrder: 'asc', shouldEmit: true })\"\n >\n <Button inline class=\"tw-h-9\">\n {{ sortOption.labelAsc }}\n <Icon\n v-if=\"sortOption.id === currentSortId && currentSortOrder === 'asc'\"\n name=\"check\"\n class=\"tw-ml-auto tw-text-blue-500\"\n />\n </Button>\n </li>\n <li\n class=\"dropdown__item tw-rounded\"\n :class=\"[\n classes.dropdown__item,\n { 'tw-bg-blue-100 tw-text-ice-700': sortOption.id === currentSortId && currentSortOrder === 'desc' },\n ]\"\n @click=\"() => updateCurrentSort(sortOption.id, { sortOrder: 'desc', shouldEmit: true })\"\n >\n <Button inline class=\"tw-h-9\">\n {{ sortOption.labelDesc }}\n <Icon\n v-if=\"sortOption.id === currentSortId && currentSortOrder === 'desc'\"\n name=\"check\"\n class=\"tw-ml-auto tw-text-blue-500\"\n />\n </Button>\n </li>\n </template>\n </ul>\n </Dropdown>\n</template>\n\n<style module>\n .dropdown__item > button {\n display: flex;\n justify-content: space-between;\n align-items: center;\n }\n</style>\n"],"names":["props","__props","classes","useCssModule","currentSortId","currentSortOrder","updateCurrentSort","inject","DATA_VIEW_INJECTION"],"mappings":";;;;;;;;;;;;;;;;;;AAkBE,UAAMA,IAAQC,GAGRC,IAAUC,
|
|
1
|
+
{"version":3,"file":"DataViewSortButton.js","sources":["../src/components/DataViewSortButton/DataViewSortButton.vue"],"sourcesContent":["<script lang=\"ts\" setup>\n import { inject, useCssModule } from 'vue';\n\n import { t } from '../../locale';\n import Button from '../Button/Button.vue';\n import { DATA_VIEW_INJECTION } from '../DataView/DataView.vue';\n import Dropdown from '../Dropdown/Dropdown.vue';\n import Icon from '../Icon/Icon.vue';\n import IconLabel from '../IconLabel/IconLabel.vue';\n import { SortOption } from './DataViewSortButton.types';\n\n export interface DataViewToolbarProps {\n /**\n * An array of sort options to display in the dropdown.\n */\n sortOptions?: SortOption[];\n }\n\n const props = withDefaults(defineProps<DataViewToolbarProps>(), {\n sortOptions: () => [],\n });\n const classes = useCssModule();\n\n const { currentSortId, currentSortOrder, updateCurrentSort } = inject(\n DATA_VIEW_INJECTION.key,\n DATA_VIEW_INJECTION.defaults,\n );\n</script>\n\n<template>\n <Dropdown\n v-if=\"props.sortOptions.length\"\n align=\"left\"\n class=\"stash-data-view-sort-button\"\n data-test=\"stash-data-view-sort-button\"\n >\n <template #toggle=\"{ isActive, toggle }\">\n <Button\n icon-label\n :aria-expanded=\"isActive.toString()\"\n class=\"tw-text-blue-500\"\n data-test=\"stash-data-view-sort-button|sort-menu-button\"\n @click=\"toggle\"\n >\n <IconLabel icon=\"sort\" stacked>\n {{ t('ll.sort') }}\n </IconLabel>\n </Button>\n </template>\n <ul class=\"dropdown__list\" data-test=\"stash-data-view-sort-button|sort-menu\">\n <template v-for=\"sortOption in props.sortOptions\" :key=\"sortOption.id\">\n <li\n class=\"dropdown__item tw-rounded\"\n :class=\"[\n classes.dropdown__item,\n { 'tw-bg-blue-100 tw-text-ice-700': sortOption.id === currentSortId && currentSortOrder === 'asc' },\n ]\"\n @click=\"() => updateCurrentSort(sortOption.id, { sortOrder: 'asc', shouldEmit: true })\"\n >\n <Button inline class=\"tw-h-9\">\n {{ sortOption.labelAsc }}\n <Icon\n v-if=\"sortOption.id === currentSortId && currentSortOrder === 'asc'\"\n name=\"check\"\n class=\"tw-ml-auto tw-text-blue-500\"\n />\n </Button>\n </li>\n <li\n class=\"dropdown__item tw-rounded\"\n :class=\"[\n classes.dropdown__item,\n { 'tw-bg-blue-100 tw-text-ice-700': sortOption.id === currentSortId && currentSortOrder === 'desc' },\n ]\"\n @click=\"() => updateCurrentSort(sortOption.id, { sortOrder: 'desc', shouldEmit: true })\"\n >\n <Button inline class=\"tw-h-9\">\n {{ sortOption.labelDesc }}\n <Icon\n v-if=\"sortOption.id === currentSortId && currentSortOrder === 'desc'\"\n name=\"check\"\n class=\"tw-ml-auto tw-text-blue-500\"\n />\n </Button>\n </li>\n </template>\n </ul>\n </Dropdown>\n</template>\n\n<style module>\n .dropdown__item > button {\n display: flex;\n justify-content: space-between;\n align-items: center;\n }\n</style>\n"],"names":["props","__props","classes","useCssModule","currentSortId","currentSortOrder","updateCurrentSort","inject","DATA_VIEW_INJECTION"],"mappings":";;;;;;;;;;;;;;;;;;AAkBE,UAAMA,IAAQC,GAGRC,IAAUC,EAAA,GAEV,EAAE,eAAAC,GAAe,kBAAAC,GAAkB,mBAAAC,EAAA,IAAsBC;AAAA,MAC7DC,EAAoB;AAAA,MACpBA,EAAoB;AAAA,IAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
|