@leaflink/stash 42.8.1 → 43.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (131) hide show
  1. package/README.md +1 -1
  2. package/dist/AddressSelect.js +9 -10
  3. package/dist/AddressSelect.js.map +1 -1
  4. package/dist/Alert.js +9 -9
  5. package/dist/Alert.js.map +1 -1
  6. package/dist/AppSidebar.js +11 -11
  7. package/dist/AppSidebar.js.map +1 -1
  8. package/dist/Avatar.js +33 -32
  9. package/dist/Avatar.js.map +1 -1
  10. package/dist/Avatar.vue.d.ts +16 -95
  11. package/dist/Badge.js +2 -2
  12. package/dist/Badge.js.map +1 -1
  13. package/dist/Checkbox.js +4 -4
  14. package/dist/Checkbox.js.map +1 -1
  15. package/dist/{Checkbox.vue_vue_type_style_index_0_scoped_0cd31c8f_lang-4ed993c7.js → Checkbox.vue_vue_type_style_index_0_scoped_0d7e7fd0_lang-4ed993c7.js} +1 -1
  16. package/dist/Checkbox.vue_vue_type_style_index_0_scoped_0d7e7fd0_lang-4ed993c7.js.map +1 -0
  17. package/dist/Chip.js +32 -30
  18. package/dist/Chip.js.map +1 -1
  19. package/dist/Chip.vue.d.ts +16 -95
  20. package/dist/ConfirmationCodeInput.js +23 -23
  21. package/dist/ConfirmationCodeInput.js.map +1 -1
  22. package/dist/ContextSwitcher.js +2 -2
  23. package/dist/ContextSwitcher.js.map +1 -1
  24. package/dist/Copy.js +1 -1
  25. package/dist/Copy.js.map +1 -1
  26. package/dist/DataView.js +1 -1
  27. package/dist/DataViewFilters.js +23 -24
  28. package/dist/DataViewFilters.js.map +1 -1
  29. package/dist/DataViewSortButton.js +11 -11
  30. package/dist/DataViewSortButton.js.map +1 -1
  31. package/dist/DataViewToolbar.js +1 -1
  32. package/dist/Dialog.js +10 -10
  33. package/dist/Dialog.js.map +1 -1
  34. package/dist/Dropdown.js +7 -7
  35. package/dist/Dropdown.js.map +1 -1
  36. package/dist/FilterChip.js +2 -3
  37. package/dist/FilterChip.js.map +1 -1
  38. package/dist/FilterDrawerItem.js +5 -6
  39. package/dist/FilterDrawerItem.js.map +1 -1
  40. package/dist/FilterDropdown.js +3 -4
  41. package/dist/FilterDropdown.js.map +1 -1
  42. package/dist/FilterSelect.js +26 -27
  43. package/dist/FilterSelect.js.map +1 -1
  44. package/dist/Filters.js +3 -4
  45. package/dist/Filters.js.map +1 -1
  46. package/dist/HttpError.js +18 -18
  47. package/dist/HttpError.js.map +1 -1
  48. package/dist/IconLabel.js +12 -13
  49. package/dist/IconLabel.js.map +1 -1
  50. package/dist/IconLabel.vue.d.ts +9 -75
  51. package/dist/Illustration.js +1 -1
  52. package/dist/Illustration.js.map +1 -1
  53. package/dist/Illustration.vue.d.ts +19 -14
  54. package/dist/InputOptions.js +7 -8
  55. package/dist/InputOptions.js.map +1 -1
  56. package/dist/LicenseChip.js +32 -26
  57. package/dist/LicenseChip.js.map +1 -1
  58. package/dist/LicenseChip.vue.d.ts +2 -4
  59. package/dist/ListItem.js +1 -1
  60. package/dist/ListView.js +30 -31
  61. package/dist/ListView.js.map +1 -1
  62. package/dist/MenuItem.js +4 -4
  63. package/dist/MenuItem.js.map +1 -1
  64. package/dist/Metric.js +1 -1
  65. package/dist/Metric.js.map +1 -1
  66. package/dist/Metric.vue.d.ts +8 -74
  67. package/dist/Modal.js +13 -13
  68. package/dist/Modal.js.map +1 -1
  69. package/dist/Module.js +1 -1
  70. package/dist/Module.js.map +1 -1
  71. package/dist/ModuleFooter.js +1 -1
  72. package/dist/ModuleFooter.js.map +1 -1
  73. package/dist/ModuleHeader.js +1 -1
  74. package/dist/ModuleHeader.js.map +1 -1
  75. package/dist/PageNavigation.js +28 -29
  76. package/dist/PageNavigation.js.map +1 -1
  77. package/dist/Paginate.js +1 -1
  78. package/dist/Paginate.js.map +1 -1
  79. package/dist/Paginate.vue_used_vue_type_style_index_0_lang.module-bfccf992.js +11 -0
  80. package/dist/Paginate.vue_used_vue_type_style_index_0_lang.module-bfccf992.js.map +1 -0
  81. package/dist/QuickAction.js +14 -14
  82. package/dist/QuickAction.js.map +1 -1
  83. package/dist/RadioNew.js +14 -14
  84. package/dist/SearchBar.js +15 -15
  85. package/dist/SearchBar.js.map +1 -1
  86. package/dist/Select.js +92 -93
  87. package/dist/Select.js.map +1 -1
  88. package/dist/SelectStatus.js +53 -51
  89. package/dist/SelectStatus.js.map +1 -1
  90. package/dist/SelectStatus.vue.d.ts +52 -1
  91. package/dist/Step.js +28 -28
  92. package/dist/Step.js.map +1 -1
  93. package/dist/Tab.js +1 -1
  94. package/dist/Table.js +2 -2
  95. package/dist/TableCell.js +2 -2
  96. package/dist/TableHeaderCell.js +2 -2
  97. package/dist/TableHeaderRow.js +2 -2
  98. package/dist/TableRow.js +2 -2
  99. package/dist/Tabs.js +2 -2
  100. package/dist/{Tabs.vue_vue_type_script_setup_true_lang-aca4f8b8.js → Tabs.vue_vue_type_script_setup_true_lang-56e85faa.js} +3 -3
  101. package/dist/Tabs.vue_vue_type_script_setup_true_lang-56e85faa.js.map +1 -0
  102. package/dist/Textarea.js +1 -1
  103. package/dist/Textarea.js.map +1 -1
  104. package/dist/Toast.js +1 -1
  105. package/dist/Toasts.js +1 -1
  106. package/dist/ToastsPlugin.js +1 -1
  107. package/dist/colorScheme.d.ts +3 -16
  108. package/dist/components.css +1 -1
  109. package/dist/index.d.ts +64 -25
  110. package/dist/index.js +188 -186
  111. package/dist/index.js.map +1 -1
  112. package/dist/statusLevels-a8b041f4.js +7 -0
  113. package/dist/statusLevels-a8b041f4.js.map +1 -0
  114. package/dist/tailwind-base.d.ts +0 -10
  115. package/dist/tailwind-base.js +22 -20
  116. package/dist/tailwind-base.js.map +1 -1
  117. package/dist/utils/colorScheme.js +1 -1
  118. package/dist/utils/colorScheme.js.map +1 -1
  119. package/package.json +1 -1
  120. package/styles/base.css +2 -2
  121. package/tailwind-base.ts +22 -21
  122. package/types/colors.ts +84 -26
  123. package/types/statusLevels.ts +4 -4
  124. package/dist/Checkbox.vue_vue_type_style_index_0_scoped_0cd31c8f_lang-4ed993c7.js.map +0 -1
  125. package/dist/Paginate.vue_used_vue_type_style_index_0_lang.module-e579235f.js +0 -11
  126. package/dist/Paginate.vue_used_vue_type_style_index_0_lang.module-e579235f.js.map +0 -1
  127. package/dist/Tabs.vue_vue_type_script_setup_true_lang-aca4f8b8.js.map +0 -1
  128. package/dist/colors-13e95ebf.js +0 -6
  129. package/dist/colors-13e95ebf.js.map +0 -1
  130. package/dist/statusLevels-aabf1e3c.js +0 -7
  131. package/dist/statusLevels-aabf1e3c.js.map +0 -1
@@ -56,12 +56,12 @@ const R = {
56
56
  }, [
57
57
  t.hasBaseRoute ? (s(), l("a", {
58
58
  key: 0,
59
- class: d(["!tw-capitalize !tw-no-underline tw-w-1/2 tw-leading-none tw-font-semibold tw-py-2.5 tw-rounded-full tw-cursor-pointer", e.activeApp === t.app ? "tw-text-white tw-bg-royal" : "tw-text-ice"]),
59
+ class: d(["!tw-capitalize !tw-no-underline tw-w-1/2 tw-leading-none tw-font-semibold tw-py-2.5 tw-rounded-full tw-cursor-pointer", e.activeApp === t.app ? "tw-text-white tw-bg-royal-500" : "tw-text-ice-500"]),
60
60
  href: `/${t.name}`,
61
61
  onClick: (c) => m(c, t.app)
62
62
  }, f(t.app), 11, N)) : (s(), x(r, {
63
63
  key: 1,
64
- class: d(["!tw-capitalize !tw-no-underline tw-w-1/2 tw-leading-none tw-font-semibold tw-py-2.5 tw-rounded-full tw-cursor-pointer", e.activeApp === t.app ? "tw-text-white tw-bg-royal" : "tw-text-ice"]),
64
+ class: d(["!tw-capitalize !tw-no-underline tw-w-1/2 tw-leading-none tw-font-semibold tw-py-2.5 tw-rounded-full tw-cursor-pointer", e.activeApp === t.app ? "tw-text-white tw-bg-royal-500" : "tw-text-ice-500"]),
65
65
  to: { name: t.name, query: o.routeQuery },
66
66
  "data-test-route": JSON.stringify({ name: t.name, query: o.routeQuery }),
67
67
  onClick: (c) => m(c, t.app)
@@ -1 +1 @@
1
- {"version":3,"file":"ContextSwitcher.js","sources":["../src/components/ContextSwitcher/ContextSwitcher.vue"],"sourcesContent":["<script setup lang=\"ts\">\n import { computed } from 'vue';\n import type { LocationQuery } from 'vue-router';\n\n import { APPS } from '../../constants';\n import { getPersistentItem, removePersistentItem, setPersistentItem } from '../../utils/storage';\n\n defineOptions({\n name: 'll-context-switcher',\n });\n\n type AppValues = typeof APPS[keyof typeof APPS];\n\n export interface ContextSwitcherProps {\n /**\n * The current app that is active. Choices are 'marketplace' | 'payments'.\n */\n activeApp: AppValues;\n\n /**\n * Portal access to both marketplace and payments.\n */\n portalAccess?: {\n commercePortal: boolean;\n paymentsPortal: boolean;\n };\n\n /**\n * Url to replace the other app if current user does not have portal access.\n */\n limitedAccessUrl: string;\n\n routeQuery?: LocationQuery;\n }\n\n const props = withDefaults(defineProps<ContextSwitcherProps>(), {\n portalAccess: () => ({\n commercePortal: false,\n paymentsPortal: false,\n }),\n routeQuery: () => ({}),\n });\n\n const emit =\n defineEmits<{\n /**\n * Fires on click of the context switcher.\n * @deprecated Use `switch` instead.\n */\n (e: 'click', urlInfo: { from: string; to: string }): void;\n /**\n * Fires on click of the context switcher.\n */\n (e: 'switch', evt: MouseEvent, urlInfo: { from: string; to: string }): void;\n }>();\n\n interface ContextItem {\n app: AppValues;\n name: string;\n hasBaseRoute: boolean;\n }\n\n const CONTEXT_SWITCHER_STORAGE_KEY = '-last-session';\n\n const routes = computed<ContextItem[]>(() => {\n return [\n {\n app: APPS.MARKETPLACE,\n name: props.portalAccess.commercePortal ? 'dashboard' : props.limitedAccessUrl,\n hasBaseRoute: props.portalAccess.commercePortal,\n },\n {\n app: APPS.PAYMENTS,\n name: props.portalAccess.paymentsPortal ? 'payments' : props.limitedAccessUrl,\n hasBaseRoute: false,\n },\n ];\n });\n\n /**\n * Saves the current url in local storage before leaving the current app, if user has access to both apps\n * If a previous session url exists, redirect users there instead then remove the local storage item afterward.\n *\n * @param event - Event from user click.\n * @param app - App name of the clicked link, is a key of `APPS`.\n */\n function handleClick(event: MouseEvent, app: AppValues) {\n if (app === props.activeApp) {\n return;\n }\n\n const currentLocation = window.location.href;\n let destination = (event.target as HTMLAnchorElement).href;\n\n if (props.portalAccess.paymentsPortal && props.portalAccess.commercePortal) {\n const appRoute = app === APPS.PAYMENTS ? APPS.MARKETPLACE : APPS.PAYMENTS;\n const currentSessionName = `${appRoute}${CONTEXT_SWITCHER_STORAGE_KEY}`;\n const prevSessionName = `${app}${CONTEXT_SWITCHER_STORAGE_KEY}`;\n\n // save the current url in local storage\n setPersistentItem(currentSessionName, currentLocation, { global: true });\n\n // get the other app's url from local storage\n const prevSessionUrl = getPersistentItem(prevSessionName, { global: true });\n\n // if it exists, redirect users to such location and remove the item from local storage\n if (prevSessionUrl) {\n event.preventDefault();\n destination = prevSessionUrl;\n window.location.href = prevSessionUrl;\n removePersistentItem(prevSessionName, { global: true });\n }\n }\n\n emit('click', { from: currentLocation, to: destination });\n emit('switch', event, { from: currentLocation, to: destination });\n }\n</script>\n\n<template>\n <div\n class=\"\n stash-context-switcher\n tw-bg-purple-700 tw-flex tw-text-center tw-p-1.5 tw-mx-auto tw-w-64 tw-rounded-full tw-border tw-border-white/10\n \"\n data-test=\"stash-context-switcher\"\n >\n <template v-for=\"route in routes\" :key=\"route.app\">\n <!-- render anchor tag to override base route in Payments -->\n <a\n v-if=\"route.hasBaseRoute\"\n class=\"\n !tw-capitalize !tw-no-underline\n tw-w-1/2 tw-leading-none tw-font-semibold tw-py-2.5 tw-rounded-full tw-cursor-pointer\n \"\n :class=\"props.activeApp === route.app ? 'tw-text-white tw-bg-royal' : 'tw-text-ice'\"\n :href=\"`/${route.name}`\"\n @click=\"(evt) => handleClick(evt, route.app)\"\n >\n {{ route.app }}\n </a>\n\n <router-link\n v-else\n class=\"\n !tw-capitalize !tw-no-underline\n tw-w-1/2 tw-leading-none tw-font-semibold tw-py-2.5 tw-rounded-full tw-cursor-pointer\n \"\n :class=\"props.activeApp === route.app ? 'tw-text-white tw-bg-royal' : 'tw-text-ice'\"\n :to=\"{ name: route.name, query: routeQuery }\"\n :data-test-route=\"JSON.stringify({ name: route.name, query: routeQuery })\"\n @click=\"(evt) => handleClick(evt, route.app)\"\n >\n {{ route.app }}\n </router-link>\n </template>\n </div>\n</template>\n"],"names":["CONTEXT_SWITCHER_STORAGE_KEY","routes","computed","APPS","props","handleClick","event","app","currentLocation","destination","currentSessionName","prevSessionName","setPersistentItem","prevSessionUrl","getPersistentItem","removePersistentItem","emit"],"mappings":";;;;;;;;;;;4BA8DQA,IAA+B;;;;;;;;;;;;;;iBAE/BC,IAASC,EAAwB,MAC9B;AAAA,MACL;AAAA,QACE,KAAKC,EAAK;AAAA,QACV,MAAMC,EAAM,aAAa,iBAAiB,cAAcA,EAAM;AAAA,QAC9D,cAAcA,EAAM,aAAa;AAAA,MACnC;AAAA,MACA;AAAA,QACE,KAAKD,EAAK;AAAA,QACV,MAAMC,EAAM,aAAa,iBAAiB,aAAaA,EAAM;AAAA,QAC7D,cAAc;AAAA,MAChB;AAAA,IAAA,CAEH;AASQ,aAAAC,EAAYC,GAAmBC,GAAgB;AAClD,UAAAA,MAAQH,EAAM;AAChB;AAGI,YAAAI,IAAkB,OAAO,SAAS;AACpC,UAAAC,IAAeH,EAAM,OAA6B;AAEtD,UAAIF,EAAM,aAAa,kBAAkBA,EAAM,aAAa,gBAAgB;AAE1E,cAAMM,IAAqB,GADVH,MAAQJ,EAAK,WAAWA,EAAK,cAAcA,EAAK,QAC3B,GAAGH,CAA4B,IAC/DW,IAAkB,GAAGJ,CAAG,GAAGP,CAA4B;AAG7D,QAAAY,EAAkBF,GAAoBF,GAAiB,EAAE,QAAQ,GAAM,CAAA;AAGvE,cAAMK,IAAiBC,EAAkBH,GAAiB,EAAE,QAAQ,IAAM;AAG1E,QAAIE,MACFP,EAAM,eAAe,GACPG,IAAAI,GACd,OAAO,SAAS,OAAOA,GACvBE,EAAqBJ,GAAiB,EAAE,QAAQ,GAAM,CAAA;AAAA,MAE1D;AAEA,MAAAK,EAAK,SAAS,EAAE,MAAMR,GAAiB,IAAIC,GAAa,GACxDO,EAAK,UAAUV,GAAO,EAAE,MAAME,GAAiB,IAAIC,GAAa;AAAA,IAClE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
1
+ {"version":3,"file":"ContextSwitcher.js","sources":["../src/components/ContextSwitcher/ContextSwitcher.vue"],"sourcesContent":["<script setup lang=\"ts\">\n import { computed } from 'vue';\n import type { LocationQuery } from 'vue-router';\n\n import { APPS } from '../../constants';\n import { getPersistentItem, removePersistentItem, setPersistentItem } from '../../utils/storage';\n\n defineOptions({\n name: 'll-context-switcher',\n });\n\n type AppValues = typeof APPS[keyof typeof APPS];\n\n export interface ContextSwitcherProps {\n /**\n * The current app that is active. Choices are 'marketplace' | 'payments'.\n */\n activeApp: AppValues;\n\n /**\n * Portal access to both marketplace and payments.\n */\n portalAccess?: {\n commercePortal: boolean;\n paymentsPortal: boolean;\n };\n\n /**\n * Url to replace the other app if current user does not have portal access.\n */\n limitedAccessUrl: string;\n\n routeQuery?: LocationQuery;\n }\n\n const props = withDefaults(defineProps<ContextSwitcherProps>(), {\n portalAccess: () => ({\n commercePortal: false,\n paymentsPortal: false,\n }),\n routeQuery: () => ({}),\n });\n\n const emit =\n defineEmits<{\n /**\n * Fires on click of the context switcher.\n * @deprecated Use `switch` instead.\n */\n (e: 'click', urlInfo: { from: string; to: string }): void;\n /**\n * Fires on click of the context switcher.\n */\n (e: 'switch', evt: MouseEvent, urlInfo: { from: string; to: string }): void;\n }>();\n\n interface ContextItem {\n app: AppValues;\n name: string;\n hasBaseRoute: boolean;\n }\n\n const CONTEXT_SWITCHER_STORAGE_KEY = '-last-session';\n\n const routes = computed<ContextItem[]>(() => {\n return [\n {\n app: APPS.MARKETPLACE,\n name: props.portalAccess.commercePortal ? 'dashboard' : props.limitedAccessUrl,\n hasBaseRoute: props.portalAccess.commercePortal,\n },\n {\n app: APPS.PAYMENTS,\n name: props.portalAccess.paymentsPortal ? 'payments' : props.limitedAccessUrl,\n hasBaseRoute: false,\n },\n ];\n });\n\n /**\n * Saves the current url in local storage before leaving the current app, if user has access to both apps\n * If a previous session url exists, redirect users there instead then remove the local storage item afterward.\n *\n * @param event - Event from user click.\n * @param app - App name of the clicked link, is a key of `APPS`.\n */\n function handleClick(event: MouseEvent, app: AppValues) {\n if (app === props.activeApp) {\n return;\n }\n\n const currentLocation = window.location.href;\n let destination = (event.target as HTMLAnchorElement).href;\n\n if (props.portalAccess.paymentsPortal && props.portalAccess.commercePortal) {\n const appRoute = app === APPS.PAYMENTS ? APPS.MARKETPLACE : APPS.PAYMENTS;\n const currentSessionName = `${appRoute}${CONTEXT_SWITCHER_STORAGE_KEY}`;\n const prevSessionName = `${app}${CONTEXT_SWITCHER_STORAGE_KEY}`;\n\n // save the current url in local storage\n setPersistentItem(currentSessionName, currentLocation, { global: true });\n\n // get the other app's url from local storage\n const prevSessionUrl = getPersistentItem(prevSessionName, { global: true });\n\n // if it exists, redirect users to such location and remove the item from local storage\n if (prevSessionUrl) {\n event.preventDefault();\n destination = prevSessionUrl;\n window.location.href = prevSessionUrl;\n removePersistentItem(prevSessionName, { global: true });\n }\n }\n\n emit('click', { from: currentLocation, to: destination });\n emit('switch', event, { from: currentLocation, to: destination });\n }\n</script>\n\n<template>\n <div\n class=\"\n stash-context-switcher\n tw-bg-purple-700 tw-flex tw-text-center tw-p-1.5 tw-mx-auto tw-w-64 tw-rounded-full tw-border tw-border-white/10\n \"\n data-test=\"stash-context-switcher\"\n >\n <template v-for=\"route in routes\" :key=\"route.app\">\n <!-- render anchor tag to override base route in Payments -->\n <a\n v-if=\"route.hasBaseRoute\"\n class=\"\n !tw-capitalize !tw-no-underline\n tw-w-1/2 tw-leading-none tw-font-semibold tw-py-2.5 tw-rounded-full tw-cursor-pointer\n \"\n :class=\"props.activeApp === route.app ? 'tw-text-white tw-bg-royal-500' : 'tw-text-ice-500'\"\n :href=\"`/${route.name}`\"\n @click=\"(evt) => handleClick(evt, route.app)\"\n >\n {{ route.app }}\n </a>\n\n <router-link\n v-else\n class=\"\n !tw-capitalize !tw-no-underline\n tw-w-1/2 tw-leading-none tw-font-semibold tw-py-2.5 tw-rounded-full tw-cursor-pointer\n \"\n :class=\"props.activeApp === route.app ? 'tw-text-white tw-bg-royal-500' : 'tw-text-ice-500'\"\n :to=\"{ name: route.name, query: routeQuery }\"\n :data-test-route=\"JSON.stringify({ name: route.name, query: routeQuery })\"\n @click=\"(evt) => handleClick(evt, route.app)\"\n >\n {{ route.app }}\n </router-link>\n </template>\n </div>\n</template>\n"],"names":["CONTEXT_SWITCHER_STORAGE_KEY","routes","computed","APPS","props","handleClick","event","app","currentLocation","destination","currentSessionName","prevSessionName","setPersistentItem","prevSessionUrl","getPersistentItem","removePersistentItem","emit"],"mappings":";;;;;;;;;;;4BA8DQA,IAA+B;;;;;;;;;;;;;;iBAE/BC,IAASC,EAAwB,MAC9B;AAAA,MACL;AAAA,QACE,KAAKC,EAAK;AAAA,QACV,MAAMC,EAAM,aAAa,iBAAiB,cAAcA,EAAM;AAAA,QAC9D,cAAcA,EAAM,aAAa;AAAA,MACnC;AAAA,MACA;AAAA,QACE,KAAKD,EAAK;AAAA,QACV,MAAMC,EAAM,aAAa,iBAAiB,aAAaA,EAAM;AAAA,QAC7D,cAAc;AAAA,MAChB;AAAA,IAAA,CAEH;AASQ,aAAAC,EAAYC,GAAmBC,GAAgB;AAClD,UAAAA,MAAQH,EAAM;AAChB;AAGI,YAAAI,IAAkB,OAAO,SAAS;AACpC,UAAAC,IAAeH,EAAM,OAA6B;AAEtD,UAAIF,EAAM,aAAa,kBAAkBA,EAAM,aAAa,gBAAgB;AAE1E,cAAMM,IAAqB,GADVH,MAAQJ,EAAK,WAAWA,EAAK,cAAcA,EAAK,QAC3B,GAAGH,CAA4B,IAC/DW,IAAkB,GAAGJ,CAAG,GAAGP,CAA4B;AAG7D,QAAAY,EAAkBF,GAAoBF,GAAiB,EAAE,QAAQ,GAAM,CAAA;AAGvE,cAAMK,IAAiBC,EAAkBH,GAAiB,EAAE,QAAQ,IAAM;AAG1E,QAAIE,MACFP,EAAM,eAAe,GACPG,IAAAI,GACd,OAAO,SAAS,OAAOA,GACvBE,EAAqBJ,GAAiB,EAAE,QAAQ,GAAM,CAAA;AAAA,MAE1D;AAEA,MAAAK,EAAK,SAAS,EAAE,MAAMR,GAAiB,IAAIC,GAAa,GACxDO,EAAK,UAAUV,GAAO,EAAE,MAAME,GAAiB,IAAIC,GAAa;AAAA,IAClE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
package/dist/Copy.js CHANGED
@@ -41,7 +41,7 @@ const M = /* @__PURE__ */ u({
41
41
  }, [
42
42
  e.value ? (o(), c(n, {
43
43
  key: 0,
44
- class: "stash-copy__success-icon tw-text-green",
44
+ class: "stash-copy__success-icon tw-text-green-500",
45
45
  name: "circle-check",
46
46
  "data-test": "stash-copy|success-icon"
47
47
  })) : t.text ? (o(), c(g, {
package/dist/Copy.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"Copy.js","sources":["../src/components/Copy/Copy.vue"],"sourcesContent":["<script setup lang=\"ts\">\n import { computed, ref, useCssModule } from 'vue';\n\n import { UI_TIMEOUT } from '../../constants';\n import vTooltip from '../../directives/tooltip/tooltip';\n import { t } from '../../locale';\n import Button from '../Button/Button.vue';\n import Icon from '../Icon/Icon.vue';\n\n export interface CopyProps {\n /**\n * Optional text to display instead of icon.\n */\n text?: string;\n\n /**\n * The value to copy to clipboard.\n */\n value?: string;\n\n /**\n * Sets the copy icon or text to always be visible. By default, icon/text only appears when hovering over slot content.\n */\n visible?: boolean;\n }\n\n const props = withDefaults(defineProps<CopyProps>(), {\n text: undefined,\n value: '', // Todo - We should default this to the content of the default slot so you can do <Copy>631f67a</Copy>.\n visible: false,\n });\n const classes = useCssModule();\n\n // Flag to indicate whether a user successfully copied the text to their clipboard.\n // Note: We reset this flag after a timeout to allow the user to copy the text multiple times.\n const isCopied = ref(false);\n\n const tooltip = computed(() => {\n return isCopied.value ? t('ll.copy.copied') : !props.text ? t('ll.copy.copyToClipboard') : null;\n });\n\n function handleCopy() {\n navigator.clipboard.writeText(props.value);\n isCopied.value = true;\n\n setTimeout(() => {\n isCopied.value = false;\n }, UI_TIMEOUT);\n }\n</script>\n\n<template>\n <div class=\"stash-copy tw-flex tw-items-center\" :class=\"{ [classes.hidden]: !props.visible }\" data-test=\"stash-copy\">\n <!-- @slot Anything you want to render. This is not what will be copied to the clipboard. -->\n <slot></slot>\n <div\n v-tooltip.top=\"tooltip\"\n class=\"stash-copy__copy-zone tw-ml-3 tw-cursor-pointer\"\n :class=\"classes.copy\"\n data-test=\"stash-copy|copy-zone\"\n >\n <Icon\n v-if=\"isCopied\"\n class=\"stash-copy__success-icon tw-text-green\"\n name=\"circle-check\"\n data-test=\"stash-copy|success-icon\"\n />\n <Button\n v-else-if=\"props.text\"\n class=\"stash-copy__copy-text\"\n inline\n data-test=\"stash-copy|copy-target\"\n @click=\"handleCopy\"\n >\n {{ props.text }}\n </Button>\n <Icon\n v-else\n class=\"stash-copy__copy-icon\"\n name=\"copy\"\n title=\"Copy to clipboard\"\n data-test=\"stash-copy|copy-target\"\n @click=\"handleCopy\"\n />\n </div>\n </div>\n</template>\n\n<style module>\n .hidden {\n .copy {\n visibility: hidden;\n }\n\n &:hover {\n .copy {\n visibility: visible;\n }\n }\n }\n</style>\n"],"names":["classes","useCssModule","isCopied","ref","tooltip","computed","t","props","handleCopy","UI_TIMEOUT"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;iBA+BQA,IAAUC,KAIVC,IAAWC,EAAI,EAAK,GAEpBC,IAAUC,EAAS,MAChBH,EAAS,QAAQI,EAAE,gBAAgB,IAAKC,EAAM,OAAsC,OAA/BD,EAAE,yBAAyB,CACxF;AAED,aAASE,IAAa;AACV,gBAAA,UAAU,UAAUD,EAAM,KAAK,GACzCL,EAAS,QAAQ,IAEjB,WAAW,MAAM;AACf,QAAAA,EAAS,QAAQ;AAAA,SAChBO,CAAU;AAAA,IACf;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
1
+ {"version":3,"file":"Copy.js","sources":["../src/components/Copy/Copy.vue"],"sourcesContent":["<script setup lang=\"ts\">\n import { computed, ref, useCssModule } from 'vue';\n\n import { UI_TIMEOUT } from '../../constants';\n import vTooltip from '../../directives/tooltip/tooltip';\n import { t } from '../../locale';\n import Button from '../Button/Button.vue';\n import Icon from '../Icon/Icon.vue';\n\n export interface CopyProps {\n /**\n * Optional text to display instead of icon.\n */\n text?: string;\n\n /**\n * The value to copy to clipboard.\n */\n value?: string;\n\n /**\n * Sets the copy icon or text to always be visible. By default, icon/text only appears when hovering over slot content.\n */\n visible?: boolean;\n }\n\n const props = withDefaults(defineProps<CopyProps>(), {\n text: undefined,\n value: '', // Todo - We should default this to the content of the default slot so you can do <Copy>631f67a</Copy>.\n visible: false,\n });\n const classes = useCssModule();\n\n // Flag to indicate whether a user successfully copied the text to their clipboard.\n // Note: We reset this flag after a timeout to allow the user to copy the text multiple times.\n const isCopied = ref(false);\n\n const tooltip = computed(() => {\n return isCopied.value ? t('ll.copy.copied') : !props.text ? t('ll.copy.copyToClipboard') : null;\n });\n\n function handleCopy() {\n navigator.clipboard.writeText(props.value);\n isCopied.value = true;\n\n setTimeout(() => {\n isCopied.value = false;\n }, UI_TIMEOUT);\n }\n</script>\n\n<template>\n <div class=\"stash-copy tw-flex tw-items-center\" :class=\"{ [classes.hidden]: !props.visible }\" data-test=\"stash-copy\">\n <!-- @slot Anything you want to render. This is not what will be copied to the clipboard. -->\n <slot></slot>\n <div\n v-tooltip.top=\"tooltip\"\n class=\"stash-copy__copy-zone tw-ml-3 tw-cursor-pointer\"\n :class=\"classes.copy\"\n data-test=\"stash-copy|copy-zone\"\n >\n <Icon\n v-if=\"isCopied\"\n class=\"stash-copy__success-icon tw-text-green-500\"\n name=\"circle-check\"\n data-test=\"stash-copy|success-icon\"\n />\n <Button\n v-else-if=\"props.text\"\n class=\"stash-copy__copy-text\"\n inline\n data-test=\"stash-copy|copy-target\"\n @click=\"handleCopy\"\n >\n {{ props.text }}\n </Button>\n <Icon\n v-else\n class=\"stash-copy__copy-icon\"\n name=\"copy\"\n title=\"Copy to clipboard\"\n data-test=\"stash-copy|copy-target\"\n @click=\"handleCopy\"\n />\n </div>\n </div>\n</template>\n\n<style module>\n .hidden {\n .copy {\n visibility: hidden;\n }\n\n &:hover {\n .copy {\n visibility: visible;\n }\n }\n }\n</style>\n"],"names":["classes","useCssModule","isCopied","ref","tooltip","computed","t","props","handleCopy","UI_TIMEOUT"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;iBA+BQA,IAAUC,KAIVC,IAAWC,EAAI,EAAK,GAEpBC,IAAUC,EAAS,MAChBH,EAAS,QAAQI,EAAE,gBAAgB,IAAKC,EAAM,OAAsC,OAA/BD,EAAE,yBAAyB,CACxF;AAED,aAASE,IAAa;AACV,gBAAA,UAAU,UAAUD,EAAM,KAAK,GACzCL,EAAS,QAAQ,IAEjB,WAAW,MAAM;AACf,QAAAA,EAAS,QAAQ;AAAA,SAChBO,CAAU;AAAA,IACf;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
package/dist/DataView.js CHANGED
@@ -8,7 +8,7 @@ import "./Icon.js";
8
8
  import "lodash-es/uniqueId";
9
9
  import "./index-79ce320f.js";
10
10
  import "./Icon.vue_used_vue_type_style_index_0_lang.module-eb359559.js";
11
- import "./Paginate.vue_used_vue_type_style_index_0_lang.module-e579235f.js";
11
+ import "./Paginate.vue_used_vue_type_style_index_0_lang.module-bfccf992.js";
12
12
  function _(e) {
13
13
  const n = e[0] === "-" ? "desc" : "asc";
14
14
  return { id: n === "asc" ? e : e.slice(1), order: n };
@@ -1,4 +1,4 @@
1
- import { ref as x, computed as D, defineComponent as R, useSlots as W, inject as j, provide as M, watch as O, openBlock as c, createBlock as v, normalizeClass as J, unref as t, withCtx as a, mergeProps as P, createCommentVNode as p, createElementBlock as z, createElementVNode as C, renderSlot as V, createVNode as I, createTextVNode as h, toDisplayString as _ } from "vue";
1
+ import { ref as x, computed as D, defineComponent as R, useSlots as W, inject as j, provide as M, watch as O, openBlock as c, createBlock as v, normalizeClass as J, unref as t, withCtx as o, mergeProps as P, createCommentVNode as p, createElementBlock as z, createElementVNode as C, renderSlot as V, createVNode as I, createTextVNode as h, toDisplayString as _ } from "vue";
2
2
  import Q from "./useMediaQuery.js";
3
3
  import { SCREEN_SIZES as U } from "./constants.js";
4
4
  import { t as n } from "./locale.js";
@@ -6,7 +6,7 @@ import { _ as Z } from "./Box.vue_vue_type_script_setup_true_lang-69e5176b.js";
6
6
  import A from "./Button.js";
7
7
  import T from "lodash-es/cloneDeep";
8
8
  import $ from "./Icon.js";
9
- import "./Paginate.vue_used_vue_type_style_index_0_lang.module-e579235f.js";
9
+ import "./Paginate.vue_used_vue_type_style_index_0_lang.module-bfccf992.js";
10
10
  import { D as G } from "./DataView.vue_used_vue_type_style_index_0_lang.module-d878ca9a.js";
11
11
  import q from "./FilterChip.js";
12
12
  import { _ as H } from "./Label.vue_vue_type_script_setup_true_lang-1d29d98a.js";
@@ -21,14 +21,13 @@ import "lodash-es/uniqueId";
21
21
  import "./index-79ce320f.js";
22
22
  import "./Icon.vue_used_vue_type_style_index_0_lang.module-eb359559.js";
23
23
  import "./Chip.js";
24
- import "./colors-13e95ebf.js";
25
24
  import "./utils/colorScheme.js";
26
25
  import "./Backdrop.js";
27
26
  import "./Input.js";
28
27
  import "lodash-es/isNil";
29
28
  import "./utils/i18n.js";
30
29
  import "./Field.vue_vue_type_script_setup_true_lang-475832fe.js";
31
- function Te({
30
+ function Pe({
32
31
  schema: i,
33
32
  dataViewRef: w
34
33
  }) {
@@ -56,16 +55,16 @@ function Te({
56
55
  var r;
57
56
  const l = {};
58
57
  for (const m in i) {
59
- const o = i[m], f = e.value[m];
60
- (((r = o.isActive) == null ? void 0 : r.call(o, f)) || L(f)) && o.group && (l[o.group] = (l[o.group] ?? 0) + 1);
58
+ const a = i[m], f = e.value[m];
59
+ (((r = a.isActive) == null ? void 0 : r.call(a, f)) || L(f)) && a.group && (l[a.group] = (l[a.group] ?? 0) + 1);
61
60
  }
62
61
  return l;
63
62
  }), k = D(() => {
64
63
  var r;
65
64
  let l = 0;
66
65
  for (const m in i) {
67
- const o = i[m], f = e.value[m];
68
- (((r = o.isActive) == null ? void 0 : r.call(o, f)) || L(f)) && (l += 1);
66
+ const a = i[m], f = e.value[m];
67
+ (((r = a.isActive) == null ? void 0 : r.call(a, f)) || L(f)) && (l += 1);
69
68
  }
70
69
  return l;
71
70
  });
@@ -84,7 +83,7 @@ function Te({
84
83
  const ee = {
85
84
  key: 1,
86
85
  class: "tw-col-span-12 tw-row-start-2 md:tw-row-start-1 md:tw-col-start-7 lg:tw-col-start-5 lg:tw-col-span-8"
87
- }, te = { class: "tw-hidden md:tw-block" }, le = { class: "tw-flex tw-gap-4" }, re = { class: "tw-inline-flex tw-items-center tw-gap-3" }, se = { class: "tw-flex tw-flex-col-reverse lg:tw-flex-row lg:tw-justify-end tw-gap-gutter" }, $e = /* @__PURE__ */ R({
86
+ }, te = { class: "tw-hidden md:tw-block" }, le = { class: "tw-flex tw-gap-4" }, re = { class: "tw-inline-flex tw-items-center tw-gap-3" }, se = { class: "tw-flex tw-flex-col-reverse lg:tw-flex-row lg:tw-justify-end tw-gap-gutter" }, Te = /* @__PURE__ */ R({
88
87
  __name: "DataViewFilters",
89
88
  props: {
90
89
  filtersLabelText: { default: n("ll.filterBy") },
@@ -120,7 +119,7 @@ const ee = {
120
119
  const { preventDismiss: s } = await ((d = e.onApply) == null ? void 0 : d.call(e)) || ((y = e.useFiltersInstance) == null ? void 0 : y.applyFilters()) || {};
121
120
  s || (r.value = !1);
122
121
  }
123
- function o() {
122
+ function a() {
124
123
  var s;
125
124
  (s = e.useFiltersInstance) == null || s.resetFilterGroup(e.activeGroup), w("reset-group"), r.value = !1;
126
125
  }
@@ -140,7 +139,7 @@ const ee = {
140
139
  "data-test": "stash-data-view-filters",
141
140
  "disable-padding": ""
142
141
  }, {
143
- default: a(() => [
142
+ default: o(() => [
144
143
  e.showSearch ? (c(), v(X, P({
145
144
  key: 0,
146
145
  class: "tw-col-span-12 md:tw-col-span-6 lg:tw-col-span-4",
@@ -155,7 +154,7 @@ const ee = {
155
154
  C("div", te, [
156
155
  V(s.$slots, "filters-label", {}, () => [
157
156
  I(H, null, {
158
- default: a(() => [
157
+ default: o(() => [
159
158
  h(_(e.filtersLabelText), 1)
160
159
  ]),
161
160
  _: 1
@@ -170,7 +169,7 @@ const ee = {
170
169
  "filter-count": k.value,
171
170
  onClick: d[1] || (d[1] = (y) => r.value = !0)
172
171
  }, {
173
- default: a(() => [
172
+ default: o(() => [
174
173
  C("span", re, [
175
174
  I($, {
176
175
  name: "filter-line",
@@ -187,7 +186,7 @@ const ee = {
187
186
  inline: "",
188
187
  onClick: f
189
188
  }, {
190
- default: a(() => [
189
+ default: o(() => [
191
190
  h(_(t(n)("ll.resetAll")), 1)
192
191
  ]),
193
192
  _: 1
@@ -202,7 +201,7 @@ const ee = {
202
201
  "is-open": r.value,
203
202
  title: t(n)("ll.allFilters")
204
203
  }, e.drawerProps, { onDismiss: S }), {
205
- headerAction: a(() => [
204
+ headerAction: o(() => [
206
205
  e.showDrawerPreviousButton ? (c(), v(A, {
207
206
  key: 0,
208
207
  icon: "",
@@ -212,13 +211,13 @@ const ee = {
212
211
  title: t(n)("ll.previous"),
213
212
  onClick: d[2] || (d[2] = (y) => w("previous"))
214
213
  }, {
215
- default: a(() => [
214
+ default: o(() => [
216
215
  I($, { name: "chevron-left" })
217
216
  ]),
218
217
  _: 1
219
218
  }, 8, ["aria-label", "title"])) : p("", !0)
220
219
  ]),
221
- footer: a(() => [
220
+ footer: o(() => [
222
221
  C("div", se, [
223
222
  !e.showDrawerPreviousButton && k.value > 0 ? (c(), v(A, {
224
223
  key: 0,
@@ -226,7 +225,7 @@ const ee = {
226
225
  disabled: t(g),
227
226
  onClick: f
228
227
  }, {
229
- default: a(() => [
228
+ default: o(() => [
230
229
  h(_(t(n)("ll.resetAll")), 1)
231
230
  ]),
232
231
  _: 1
@@ -235,9 +234,9 @@ const ee = {
235
234
  key: 1,
236
235
  secondary: "",
237
236
  disabled: t(g),
238
- onClick: o
237
+ onClick: a
239
238
  }, {
240
- default: a(() => [
239
+ default: o(() => [
241
240
  h(_(t(n)("ll.reset")), 1)
242
241
  ]),
243
242
  _: 1
@@ -247,14 +246,14 @@ const ee = {
247
246
  disabled: t(g),
248
247
  onClick: m
249
248
  }, {
250
- default: a(() => [
249
+ default: o(() => [
251
250
  h(_(t(n)("ll.apply")), 1)
252
251
  ]),
253
252
  _: 1
254
253
  }, 8, ["disabled"])) : p("", !0)
255
254
  ])
256
255
  ]),
257
- default: a(() => [
256
+ default: o(() => [
258
257
  V(s.$slots, "drawer")
259
258
  ]),
260
259
  _: 3
@@ -266,7 +265,7 @@ const ee = {
266
265
  });
267
266
  export {
268
267
  Y as DATA_VIEW_FILTERS_UTILS_INJECTION,
269
- $e as default,
270
- Te as useFilters
268
+ Te as default,
269
+ Pe as useFilters
271
270
  };
272
271
  //# sourceMappingURL=DataViewFilters.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"DataViewFilters.js","sources":["../src/components/DataViewFilters/useFilters.ts","../src/components/DataViewFilters/DataViewFilters.vue"],"sourcesContent":["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 { 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 drawerProps?: ModalProps;\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 /** The name of the active filter group. The active filter group is determined by which instance of FilterDropdown or FilterDrawerItem is open. */\n activeGroup?: string;\n }\n\n export interface DataViewFiltersSlots {\n default?: void;\n drawer?: void;\n 'filters-label'?: void;\n }\n\n const props = withDefaults(defineProps<DataViewFiltersProps>(), {\n filtersLabelText: t('ll.filterBy'),\n isLoading: false,\n drawerProps: undefined,\n searchBarProps: undefined,\n showDrawerPreviousButton: false,\n showSearch: true,\n useFiltersInstance: undefined,\n onApply: undefined,\n activeGroup: '',\n });\n\n const emit =\n 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\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, { useFiltersInstance: props.useFiltersInstance });\n\n const totalActiveFiltersCount = computed(() => props.useFiltersInstance?.totalActiveFiltersCount.value ?? 0);\n const activeGroupActiveFiltersCount = computed(\n () => 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 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-p-3 tw-gap-6\"\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-row-start-1 md:tw-col-start-7 lg:tw-col-start-5 lg:tw-col-span-8\"\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 :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=\"props.showDrawerPreviousButton\"\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-flex-col-reverse lg:tw-flex-row lg:tw-justify-end tw-gap-gutter\">\n <Button\n v-if=\"!props.showDrawerPreviousButton && totalActiveFiltersCount > 0\"\n secondary\n :disabled=\"isDataViewLoading\"\n @click=\"handleResetAllClick\"\n >\n {{ t('ll.resetAll') }}\n </Button>\n <Button\n v-if=\"props.showDrawerPreviousButton && activeGroupActiveFiltersCount > 0\"\n secondary\n :disabled=\"isDataViewLoading\"\n @click=\"handleResetGroupClick\"\n >\n {{ t('ll.reset') }}\n </Button>\n <Button v-if=\"props.showDrawerPreviousButton\" :disabled=\"isDataViewLoading\" @click=\"handleApplyClick\">\n {{ t('ll.apply') }}\n </Button>\n </div>\n </template>\n </Modal>\n </Box>\n</template>\n"],"names":["useFilters","schema","dataViewRef","appliedFilters","ref","workingFilters","filterName","dvRef","applyFilters","cloneDeep","resetAllFilters","resetFilterGroup","group","undoWorkingFilters","activeFiltersCounts","computed","counts","config","value","_a","isDefined","totalActiveFiltersCount","count","slots","_useSlots","isDesktop","useMediaQuery","SCREEN_SIZES","density","isDataViewLoading","isWithinModule","currentSearch","updateCurrentSearch","inject","DATA_VIEW_INJECTION","provide","DATA_VIEW_FILTERS_UTILS_INJECTION","props","activeGroupActiveFiltersCount","isDrawerOpen","handleApplyClick","preventDismiss","_b","handleResetGroupClick","emit","handleResetAllClick","onDismiss","watch"],"mappings":"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"}
1
+ {"version":3,"file":"DataViewFilters.js","sources":["../src/components/DataViewFilters/useFilters.ts","../src/components/DataViewFilters/DataViewFilters.vue"],"sourcesContent":["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 { 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 drawerProps?: ModalProps;\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 /** The name of the active filter group. The active filter group is determined by which instance of FilterDropdown or FilterDrawerItem is open. */\n activeGroup?: string;\n }\n\n export interface DataViewFiltersSlots {\n default?: void;\n drawer?: void;\n 'filters-label'?: void;\n }\n\n const props = withDefaults(defineProps<DataViewFiltersProps>(), {\n filtersLabelText: t('ll.filterBy'),\n isLoading: false,\n drawerProps: undefined,\n searchBarProps: undefined,\n showDrawerPreviousButton: false,\n showSearch: true,\n useFiltersInstance: undefined,\n onApply: undefined,\n activeGroup: '',\n });\n\n const emit =\n 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\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, { useFiltersInstance: props.useFiltersInstance });\n\n const totalActiveFiltersCount = computed(() => props.useFiltersInstance?.totalActiveFiltersCount.value ?? 0);\n const activeGroupActiveFiltersCount = computed(\n () => 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 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-p-3 tw-gap-6\"\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-row-start-1 md:tw-col-start-7 lg:tw-col-start-5 lg:tw-col-span-8\"\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 :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=\"props.showDrawerPreviousButton\"\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-flex-col-reverse lg:tw-flex-row lg:tw-justify-end tw-gap-gutter\">\n <Button\n v-if=\"!props.showDrawerPreviousButton && totalActiveFiltersCount > 0\"\n secondary\n :disabled=\"isDataViewLoading\"\n @click=\"handleResetAllClick\"\n >\n {{ t('ll.resetAll') }}\n </Button>\n <Button\n v-if=\"props.showDrawerPreviousButton && activeGroupActiveFiltersCount > 0\"\n secondary\n :disabled=\"isDataViewLoading\"\n @click=\"handleResetGroupClick\"\n >\n {{ t('ll.reset') }}\n </Button>\n <Button v-if=\"props.showDrawerPreviousButton\" :disabled=\"isDataViewLoading\" @click=\"handleApplyClick\">\n {{ t('ll.apply') }}\n </Button>\n </div>\n </template>\n </Modal>\n </Box>\n</template>\n"],"names":["useFilters","schema","dataViewRef","appliedFilters","ref","workingFilters","filterName","dvRef","applyFilters","cloneDeep","resetAllFilters","resetFilterGroup","group","undoWorkingFilters","activeFiltersCounts","computed","counts","config","value","_a","isDefined","totalActiveFiltersCount","count","slots","_useSlots","isDesktop","useMediaQuery","SCREEN_SIZES","density","isDataViewLoading","isWithinModule","currentSearch","updateCurrentSearch","inject","DATA_VIEW_INJECTION","provide","DATA_VIEW_FILTERS_UTILS_INJECTION","props","activeGroupActiveFiltersCount","isDrawerOpen","handleApplyClick","preventDismiss","_b","handleResetGroupClick","emit","handleResetAllClick","onDismiss","watch"],"mappings":"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"}
@@ -2,9 +2,9 @@ import { defineComponent as g, inject as y, openBlock as r, createBlock as n, wi
2
2
  import { t as S } from "./locale.js";
3
3
  import u from "./Button.js";
4
4
  import "lodash-es/cloneDeep";
5
- import b from "./Icon.js";
6
- import "./Paginate.vue_used_vue_type_style_index_0_lang.module-e579235f.js";
7
- import { D as h } from "./DataView.vue_used_vue_type_style_index_0_lang.module-d878ca9a.js";
5
+ import h from "./Icon.js";
6
+ import "./Paginate.vue_used_vue_type_style_index_0_lang.module-bfccf992.js";
7
+ import { D as b } from "./DataView.vue_used_vue_type_style_index_0_lang.module-d878ca9a.js";
8
8
  import V from "./Dropdown.js";
9
9
  import v from "./IconLabel.js";
10
10
  import { _ as B } from "./_plugin-vue_export-helper-dad06003.js";
@@ -30,8 +30,8 @@ const I = {
30
30
  },
31
31
  setup(C) {
32
32
  const _ = C, { currentSortId: a, currentSortOrder: s, updateCurrentSort: p } = y(
33
- h.key,
34
- h.defaults
33
+ b.key,
34
+ b.defaults
35
35
  );
36
36
  return (T, L) => _.sortOptions.length ? (r(), n(V, {
37
37
  key: 0,
@@ -43,7 +43,7 @@ const I = {
43
43
  i(u, {
44
44
  "icon-label": "",
45
45
  "aria-expanded": t.toString(),
46
- class: "tw-text-blue",
46
+ class: "tw-text-blue-500",
47
47
  "data-test": "stash-data-view-sort-button|sort-menu-button",
48
48
  onClick: x
49
49
  }, {
@@ -76,10 +76,10 @@ const I = {
76
76
  }, {
77
77
  default: o(() => [
78
78
  d(l(t.labelAsc) + " ", 1),
79
- t.id === e(a) && e(s) === "asc" ? (r(), n(b, {
79
+ t.id === e(a) && e(s) === "asc" ? (r(), n(h, {
80
80
  key: 0,
81
81
  name: "check",
82
- class: "tw-text-blue tw-ml-auto"
82
+ class: "tw-text-blue-500 tw-ml-auto"
83
83
  })) : m("", !0)
84
84
  ]),
85
85
  _: 2
@@ -95,10 +95,10 @@ const I = {
95
95
  }, {
96
96
  default: o(() => [
97
97
  d(l(t.labelDesc) + " ", 1),
98
- t.id === e(a) && e(s) === "desc" ? (r(), n(b, {
98
+ t.id === e(a) && e(s) === "desc" ? (r(), n(h, {
99
99
  key: 0,
100
100
  name: "check",
101
- class: "tw-text-blue tw-ml-auto"
101
+ class: "tw-text-blue-500 tw-ml-auto"
102
102
  })) : m("", !0)
103
103
  ]),
104
104
  _: 2
@@ -111,7 +111,7 @@ const I = {
111
111
  })) : m("", !0);
112
112
  }
113
113
  });
114
- const rt = /* @__PURE__ */ B(A, [["__scopeId", "data-v-1bb03502"]]);
114
+ const rt = /* @__PURE__ */ B(A, [["__scopeId", "data-v-e33a9680"]]);
115
115
  export {
116
116
  rt as default
117
117
  };
@@ -1 +1 @@
1
- {"version":3,"file":"DataViewSortButton.js","sources":["../src/components/DataViewSortButton/DataViewSortButton.vue"],"sourcesContent":["<script lang=\"ts\" setup>\n import { inject } 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\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\"\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 rounded\"\n :class=\"{ 'is-selected': sortOption.id === currentSortId && currentSortOrder === 'asc' }\"\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-text-blue tw-ml-auto\"\n />\n </Button>\n </li>\n <li\n class=\"dropdown__item rounded\"\n :class=\"{ 'is-selected': sortOption.id === currentSortId && currentSortOrder === 'desc' }\"\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-text-blue tw-ml-auto\"\n />\n </Button>\n </li>\n </template>\n </ul>\n </Dropdown>\n</template>\n\n<style scoped>\n .dropdown__item > button {\n display: flex;\n justify-content: space-between;\n align-items: center;\n }\n</style>\n"],"names":["currentSortId","currentSortOrder","updateCurrentSort","inject","DATA_VIEW_INJECTION"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBAsBQ,EAAE,eAAAA,GAAe,kBAAAC,GAAkB,mBAAAC,EAAsB,IAAAC;AAAA,MAC7DC,EAAoB;AAAA,MACpBA,EAAoB;AAAA,IAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
1
+ {"version":3,"file":"DataViewSortButton.js","sources":["../src/components/DataViewSortButton/DataViewSortButton.vue"],"sourcesContent":["<script lang=\"ts\" setup>\n import { inject } 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\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 rounded\"\n :class=\"{ 'is-selected': sortOption.id === currentSortId && currentSortOrder === 'asc' }\"\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-text-blue-500 tw-ml-auto\"\n />\n </Button>\n </li>\n <li\n class=\"dropdown__item rounded\"\n :class=\"{ 'is-selected': sortOption.id === currentSortId && currentSortOrder === 'desc' }\"\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-text-blue-500 tw-ml-auto\"\n />\n </Button>\n </li>\n </template>\n </ul>\n </Dropdown>\n</template>\n\n<style scoped>\n .dropdown__item > button {\n display: flex;\n justify-content: space-between;\n align-items: center;\n }\n</style>\n"],"names":["currentSortId","currentSortOrder","updateCurrentSort","inject","DATA_VIEW_INJECTION"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBAsBQ,EAAE,eAAAA,GAAe,kBAAAC,GAAkB,mBAAAC,EAAsB,IAAAC;AAAA,MAC7DC,EAAoB;AAAA,MACpBA,EAAoB;AAAA,IAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
@@ -3,7 +3,7 @@ import { t as z } from "./locale.js";
3
3
  import h from "./Button.js";
4
4
  import "lodash-es/cloneDeep";
5
5
  import x from "./Icon.js";
6
- import "./Paginate.vue_used_vue_type_style_index_0_lang.module-e579235f.js";
6
+ import "./Paginate.vue_used_vue_type_style_index_0_lang.module-bfccf992.js";
7
7
  import { D as y } from "./DataView.vue_used_vue_type_style_index_0_lang.module-d878ca9a.js";
8
8
  import { _ as j } from "./_plugin-vue_export-helper-dad06003.js";
9
9
  import "lodash-es/get";
package/dist/Dialog.js CHANGED
@@ -1,7 +1,7 @@
1
1
  import { defineComponent as V, useSlots as $, useAttrs as K, useCssModule as Z, ref as C, computed as n, watchEffect as z, nextTick as A, openBlock as s, createBlock as f, Transition as H, withCtx as m, createElementBlock as p, mergeProps as L, unref as e, withKeys as P, createElementVNode as a, normalizeClass as o, createCommentVNode as r, toDisplayString as _, renderSlot as Y, createTextVNode as T, createVNode as F } from "vue";
2
2
  import S from "lodash-es/capitalize";
3
3
  import G from "lodash-es/uniqueId";
4
- import { S as B, a as I, b as J } from "./statusLevels-aabf1e3c.js";
4
+ import { S as B, a as I, b as J } from "./statusLevels-a8b041f4.js";
5
5
  import { t as c } from "./locale.js";
6
6
  import q from "./Button.js";
7
7
  import O from "./Icon.js";
@@ -13,7 +13,7 @@ import "./Icon.vue_used_vue_type_style_index_0_lang.module-eb359559.js";
13
13
  const R = ["open", "aria-labelledby", "data-test", "onKeydown"], U = ["id"], W = {
14
14
  key: 0,
15
15
  class: "tw-mb-0"
16
- }, X = ["innerHTML"], tt = { class: "text-right" }, et = /* @__PURE__ */ V({
16
+ }, X = ["innerHTML"], tt = { class: "tw-text-right" }, et = /* @__PURE__ */ V({
17
17
  name: "ll-dialog",
18
18
  inheritAttrs: !1,
19
19
  __name: "Dialog",
@@ -35,19 +35,19 @@ const R = ["open", "aria-labelledby", "data-test", "onKeydown"], U = ["id"], W =
35
35
  ), v = n(
36
36
  () => t.status ? I[S(t.status)] : I.Info
37
37
  ), E = n(() => t.dangerZone || t.status === J.Error);
38
- function x() {
38
+ function w() {
39
39
  y("update:open", !1), y("cancel");
40
40
  }
41
41
  async function N(u) {
42
42
  d.value = !0;
43
- const w = i.onConfirm;
44
- await w(u), d.value = !1;
43
+ const x = i.onConfirm;
44
+ await x(u), d.value = !1;
45
45
  }
46
46
  return z(() => {
47
47
  t.open && A(function() {
48
48
  k.value.focus();
49
49
  });
50
- }), (u, w) => (s(), f(H, { name: "fade" }, {
50
+ }), (u, x) => (s(), f(H, { name: "fade" }, {
51
51
  default: m(() => [
52
52
  t.open ? (s(), p("dialog", L({
53
53
  key: 0,
@@ -60,7 +60,7 @@ const R = ["open", "aria-labelledby", "data-test", "onKeydown"], U = ["id"], W =
60
60
  class: e(l).dialog,
61
61
  "data-test": e(i)["data-test"] || "ll-dialog"
62
62
  }, e(i), {
63
- onKeydown: P(x, ["esc"])
63
+ onKeydown: P(w, ["esc"])
64
64
  }), [
65
65
  a("div", {
66
66
  class: o([
@@ -75,7 +75,7 @@ const R = ["open", "aria-labelledby", "data-test", "onKeydown"], U = ["id"], W =
75
75
  class: o(e(l).content)
76
76
  }, [
77
77
  a("div", {
78
- class: o(["flex items-center", h.value && "tw-mb-1.5"])
78
+ class: o(["tw-flex tw-items-center", h.value && "tw-mb-1.5"])
79
79
  }, [
80
80
  t.status ? (s(), f(O, {
81
81
  key: 0,
@@ -106,7 +106,7 @@ const R = ["open", "aria-labelledby", "data-test", "onKeydown"], U = ["id"], W =
106
106
  key: 0,
107
107
  "data-test": "button|cancel",
108
108
  secondary: "",
109
- onClick: x
109
+ onClick: w
110
110
  }, {
111
111
  default: m(() => [
112
112
  T(_(t.cancelText), 1)
@@ -118,7 +118,7 @@ const R = ["open", "aria-labelledby", "data-test", "onKeydown"], U = ["id"], W =
118
118
  disabled: t.disabled || d.value,
119
119
  color: E.value ? "red" : "blue",
120
120
  class: o({
121
- "w-full": t.alert
121
+ "tw-w-full": t.alert
122
122
  }),
123
123
  onClick: N
124
124
  }, {
@@ -1 +1 @@
1
- {"version":3,"file":"Dialog.js","sources":["../src/components/Dialog/Dialog.vue"],"sourcesContent":["<script setup lang=\"ts\">\n import capitalize from 'lodash-es/capitalize';\n import uniqueId from 'lodash-es/uniqueId';\n import { computed, nextTick, ref, useAttrs, useCssModule, useSlots, watchEffect } from 'vue';\n\n import {\n StatusColor,\n StatusColors,\n StatusIcon,\n StatusIcons,\n StatusSeverities,\n StatusSeverity,\n } from '../../../types/statusLevels';\n import { t } from '../../locale';\n import Button from '../Button/Button.vue';\n import Icon from '../Icon/Icon.vue';\n\n export interface DialogProps {\n /**\n * Shows or hides the dialog.\n * Usage: v-model:open=\"isOpen\"\n */\n open?: boolean;\n\n /**\n * Whether the confirmation button is enabled or not.\n */\n disabled?: boolean;\n\n /**\n * Is this a dangerous action? Will turn the confirmation button red.\n */\n dangerZone?: boolean;\n\n /**\n * Header text.\n */\n header?: string;\n\n /**\n * Description text.\n */\n description?: string;\n\n /**\n * Cancel button text.\n */\n cancelText?: string;\n\n /**\n * Confirm button text.\n */\n confirmText?: string;\n\n /**\n * Treats it like an Alert Dialog, with only the confirmation button showing.\n *\n * @see {@link https://developer.mozilla.org/en-US/docs/Web/API/Window/alert}\n */\n alert?: boolean;\n\n /**\n * Adds a top accent border and icon next to the header.\n * This behaves similarly to the Alert component in respect to the levels, icons, and colors\n * passing `error` will treat the dialog the same as `dangerZone`\n */\n status?: StatusSeverity;\n }\n\n const props = withDefaults(defineProps<DialogProps>(), {\n open: false,\n disabled: false,\n dangerZone: false,\n header: t('ll.areYouSure'),\n description: '',\n cancelText: t('ll.cancel'),\n confirmText: '',\n alert: false,\n status: undefined,\n });\n\n defineOptions({\n name: 'll-dialog',\n inheritAttrs: false,\n });\n\n const emits =\n defineEmits<{\n (e: 'update:open', value: boolean): void;\n (e: 'cancel'): void;\n }>();\n\n const slots = useSlots();\n const attrs = useAttrs();\n const classes = useCssModule();\n const headerId = uniqueId('dialog-header-');\n\n const isConfirming = ref(false);\n const root = ref();\n\n /**\n * Set the default confirm button text to \"Confirm\".\n * If the `alert` prop is true, the default text is \"Okay\".\n * If the `confirmText` prop is provided, `confirmText` is used whether or not\n * the alert prop is true.\n */\n const modifiedConfirmText = computed(() => props.confirmText || (props.alert ? t('ll.okay') : t('ll.confirm')));\n\n const hasDescription = computed(() => !!slots.default || props.description);\n\n const statusIcon = computed<StatusIcon>(() =>\n props.status ? StatusIcons[capitalize(props.status)] : StatusIcons.Info,\n );\n const statusColor = computed<StatusColor>(() =>\n props.status ? StatusColors[capitalize(props.status)] : StatusColors.Info,\n );\n\n const computedDangerZone = computed(() => props.dangerZone || props.status === StatusSeverities.Error);\n\n function cancel() {\n emits('update:open', false);\n emits('cancel');\n }\n\n async function handleConfirm(event: Event) {\n isConfirming.value = true;\n\n // useAttrs returns a Record<string, unknown> type, which causes\n // TS errors when trying to call a passed listener\n const onConfirm = attrs.onConfirm as (event: Event) => void;\n\n // Call the parent confirm listener and await it. Using Async/Await lets\n // us await even non-promises. Pass the event so modifiers can work.\n await onConfirm(event);\n isConfirming.value = false;\n }\n\n watchEffect(() => {\n if (props.open) {\n // Move focus to confirm button\n nextTick(function () {\n root.value.focus();\n });\n }\n });\n</script>\n\n<template>\n <transition name=\"fade\">\n <dialog\n v-if=\"props.open\"\n ref=\"root\"\n :open=\"props.open\"\n tabindex=\"0\"\n :aria-labelledby=\"headerId\"\n aria-modal=\"true\"\n :class=\"classes.dialog\"\n :data-test=\"attrs['data-test'] || 'll-dialog'\"\n v-bind=\"attrs\"\n @keydown.esc=\"cancel\"\n >\n <div\n :class=\"[\n classes.body,\n `tw-border-${statusColor}`,\n {\n 'tw-border-t-6': props.status,\n },\n ]\"\n >\n <div :class=\"classes.content\">\n <div class=\"flex items-center\" :class=\"hasDescription && 'tw-mb-1.5'\">\n <Icon\n v-if=\"props.status\"\n data-test=\"dialog-status-icon\"\n :name=\"statusIcon\"\n :class=\"`tw-text-${statusColor}`\"\n />\n <h3 :id=\"headerId\" :class=\"{ 'tw-ml-1.5 tw-mt-px': props.status }\">{{ props.header }}</h3>\n </div>\n\n <p v-if=\"hasDescription\" class=\"tw-mb-0\">\n <slot v-if=\"slots.default\"></slot>\n <span v-else v-html=\"props.description\"></span>\n </p>\n </div>\n\n <footer :class=\"classes.footer\">\n <div class=\"text-right\">\n <div :class=\"{ 'button-grid': !props.alert }\">\n <Button v-if=\"!props.alert\" data-test=\"button|cancel\" secondary @click=\"cancel\">\n {{ props.cancelText }}\n </Button>\n\n <Button\n data-test=\"button|confirm\"\n :disabled=\"props.disabled || isConfirming\"\n :color=\"computedDangerZone ? 'red' : 'blue'\"\n :class=\"{\n 'w-full': props.alert,\n }\"\n @click=\"handleConfirm\"\n >\n {{ modifiedConfirmText }}\n </Button>\n </div>\n </div>\n </footer>\n </div>\n </dialog>\n </transition>\n</template>\n\n<style lang=\"scss\" module>\n .dialog {\n background: rgb(0 0 0 / 30%);\n bottom: 0;\n display: flex;\n flex-direction: column;\n left: 0;\n overflow: auto;\n -webkit-overflow-scrolling: touch;\n place-content: center;\n position: fixed;\n right: 0;\n top: 0;\n z-index: z-index('dialog');\n width: 100%;\n height: 100vh;\n }\n\n .body {\n @include elevation('low');\n\n background: var(--color-white);\n border-radius: $border-radius;\n color: var(--color-ice-700);\n display: flex;\n flex-direction: column;\n margin: 0 auto;\n max-height: 100vh;\n max-width: 360px;\n transition: transform $primary-transition;\n width: 100%;\n\n &.grey {\n background: var(--color-ice-200);\n border-radius: $border-radius;\n }\n }\n\n .content {\n flex-grow: 1;\n padding: space(3) var(--grid-gutter);\n }\n\n .footer {\n background: var(--color-ice-200);\n border-top: border('thin', var(--color-ice));\n display: initial; // TEMP. Will need to fix marketplace `footer` style\n padding: space(3) var(--grid-gutter);\n\n @include breakpoint('md') {\n border-bottom-left-radius: $border-radius;\n border-bottom-right-radius: $border-radius;\n }\n }\n\n :global(.fade-enter-from),\n :global(.fade-leave-active) {\n .body {\n transform: translate3d(0, #{space(2)}, 0);\n }\n }\n</style>\n"],"names":["slots","useSlots","attrs","useAttrs","classes","useCssModule","headerId","uniqueId","isConfirming","ref","root","modifiedConfirmText","computed","props","t","hasDescription","statusIcon","StatusIcons","capitalize","statusColor","StatusColors","computedDangerZone","StatusSeverities","cancel","emits","handleConfirm","event","onConfirm","watchEffect","nextTick"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBA4FQA,IAAQC,KACRC,IAAQC,KACRC,IAAUC,KACVC,IAAWC,EAAS,gBAAgB,GAEpCC,IAAeC,EAAI,EAAK,GACxBC,IAAOD,KAQPE,IAAsBC,EAAS,MAAMC,EAAM,gBAAgBA,EAAM,QAAQC,EAAE,SAAS,IAAIA,EAAE,YAAY,EAAE,GAExGC,IAAiBH,EAAS,MAAM,CAAC,CAACZ,EAAM,WAAWa,EAAM,WAAW,GAEpEG,IAAaJ;AAAA,MAAqB,MACtCC,EAAM,SAASI,EAAYC,EAAWL,EAAM,MAAM,CAAC,IAAII,EAAY;AAAA,IAAA,GAE/DE,IAAcP;AAAA,MAAsB,MACxCC,EAAM,SAASO,EAAaF,EAAWL,EAAM,MAAM,CAAC,IAAIO,EAAa;AAAA,IAAA,GAGjEC,IAAqBT,EAAS,MAAMC,EAAM,cAAcA,EAAM,WAAWS,EAAiB,KAAK;AAErG,aAASC,IAAS;AAChB,MAAAC,EAAM,eAAe,EAAK,GAC1BA,EAAM,QAAQ;AAAA,IAChB;AAEA,mBAAeC,EAAcC,GAAc;AACzC,MAAAlB,EAAa,QAAQ;AAIrB,YAAMmB,IAAYzB,EAAM;AAIxB,YAAMyB,EAAUD,CAAK,GACrBlB,EAAa,QAAQ;AAAA,IACvB;AAEA,WAAAoB,EAAY,MAAM;AAChB,MAAIf,EAAM,QAERgB,EAAS,WAAY;AACnB,QAAAnB,EAAK,MAAM;MAAM,CAClB;AAAA,IACH,CACD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
1
+ {"version":3,"file":"Dialog.js","sources":["../src/components/Dialog/Dialog.vue"],"sourcesContent":["<script setup lang=\"ts\">\n import capitalize from 'lodash-es/capitalize';\n import uniqueId from 'lodash-es/uniqueId';\n import { computed, nextTick, ref, useAttrs, useCssModule, useSlots, watchEffect } from 'vue';\n\n import {\n StatusColor,\n StatusColors,\n StatusIcon,\n StatusIcons,\n StatusSeverities,\n StatusSeverity,\n } from '../../../types/statusLevels';\n import { t } from '../../locale';\n import Button from '../Button/Button.vue';\n import Icon from '../Icon/Icon.vue';\n\n export interface DialogProps {\n /**\n * Shows or hides the dialog.\n * Usage: v-model:open=\"isOpen\"\n */\n open?: boolean;\n\n /**\n * Whether the confirmation button is enabled or not.\n */\n disabled?: boolean;\n\n /**\n * Is this a dangerous action? Will turn the confirmation button red.\n */\n dangerZone?: boolean;\n\n /**\n * Header text.\n */\n header?: string;\n\n /**\n * Description text.\n */\n description?: string;\n\n /**\n * Cancel button text.\n */\n cancelText?: string;\n\n /**\n * Confirm button text.\n */\n confirmText?: string;\n\n /**\n * Treats it like an Alert Dialog, with only the confirmation button showing.\n *\n * @see {@link https://developer.mozilla.org/en-US/docs/Web/API/Window/alert}\n */\n alert?: boolean;\n\n /**\n * Adds a top accent border and icon next to the header.\n * This behaves similarly to the Alert component in respect to the levels, icons, and colors\n * passing `error` will treat the dialog the same as `dangerZone`\n */\n status?: StatusSeverity;\n }\n\n const props = withDefaults(defineProps<DialogProps>(), {\n open: false,\n disabled: false,\n dangerZone: false,\n header: t('ll.areYouSure'),\n description: '',\n cancelText: t('ll.cancel'),\n confirmText: '',\n alert: false,\n status: undefined,\n });\n\n defineOptions({\n name: 'll-dialog',\n inheritAttrs: false,\n });\n\n const emits =\n defineEmits<{\n (e: 'update:open', value: boolean): void;\n (e: 'cancel'): void;\n }>();\n\n const slots = useSlots();\n const attrs = useAttrs();\n const classes = useCssModule();\n const headerId = uniqueId('dialog-header-');\n\n const isConfirming = ref(false);\n const root = ref();\n\n /**\n * Set the default confirm button text to \"Confirm\".\n * If the `alert` prop is true, the default text is \"Okay\".\n * If the `confirmText` prop is provided, `confirmText` is used whether or not\n * the alert prop is true.\n */\n const modifiedConfirmText = computed(() => props.confirmText || (props.alert ? t('ll.okay') : t('ll.confirm')));\n\n const hasDescription = computed(() => !!slots.default || props.description);\n\n const statusIcon = computed<StatusIcon>(() =>\n props.status ? StatusIcons[capitalize(props.status)] : StatusIcons.Info,\n );\n const statusColor = computed<StatusColor>(() =>\n props.status ? StatusColors[capitalize(props.status)] : StatusColors.Info,\n );\n\n const computedDangerZone = computed(() => props.dangerZone || props.status === StatusSeverities.Error);\n\n function cancel() {\n emits('update:open', false);\n emits('cancel');\n }\n\n async function handleConfirm(event: Event) {\n isConfirming.value = true;\n\n // useAttrs returns a Record<string, unknown> type, which causes\n // TS errors when trying to call a passed listener\n const onConfirm = attrs.onConfirm as (event: Event) => void;\n\n // Call the parent confirm listener and await it. Using Async/Await lets\n // us await even non-promises. Pass the event so modifiers can work.\n await onConfirm(event);\n isConfirming.value = false;\n }\n\n watchEffect(() => {\n if (props.open) {\n // Move focus to confirm button\n nextTick(function () {\n root.value.focus();\n });\n }\n });\n</script>\n\n<template>\n <transition name=\"fade\">\n <dialog\n v-if=\"props.open\"\n ref=\"root\"\n :open=\"props.open\"\n tabindex=\"0\"\n :aria-labelledby=\"headerId\"\n aria-modal=\"true\"\n :class=\"classes.dialog\"\n :data-test=\"attrs['data-test'] || 'll-dialog'\"\n v-bind=\"attrs\"\n @keydown.esc=\"cancel\"\n >\n <div\n :class=\"[\n classes.body,\n `tw-border-${statusColor}`,\n {\n 'tw-border-t-6': props.status,\n },\n ]\"\n >\n <div :class=\"classes.content\">\n <div class=\"tw-flex tw-items-center\" :class=\"hasDescription && 'tw-mb-1.5'\">\n <Icon\n v-if=\"props.status\"\n data-test=\"dialog-status-icon\"\n :name=\"statusIcon\"\n :class=\"`tw-text-${statusColor}`\"\n />\n <h3 :id=\"headerId\" :class=\"{ 'tw-ml-1.5 tw-mt-px': props.status }\">{{ props.header }}</h3>\n </div>\n\n <p v-if=\"hasDescription\" class=\"tw-mb-0\">\n <slot v-if=\"slots.default\"></slot>\n <span v-else v-html=\"props.description\"></span>\n </p>\n </div>\n\n <footer :class=\"classes.footer\">\n <div class=\"tw-text-right\">\n <div :class=\"{ 'button-grid': !props.alert }\">\n <Button v-if=\"!props.alert\" data-test=\"button|cancel\" secondary @click=\"cancel\">\n {{ props.cancelText }}\n </Button>\n\n <Button\n data-test=\"button|confirm\"\n :disabled=\"props.disabled || isConfirming\"\n :color=\"computedDangerZone ? 'red' : 'blue'\"\n :class=\"{\n 'tw-w-full': props.alert,\n }\"\n @click=\"handleConfirm\"\n >\n {{ modifiedConfirmText }}\n </Button>\n </div>\n </div>\n </footer>\n </div>\n </dialog>\n </transition>\n</template>\n\n<style lang=\"scss\" module>\n .dialog {\n background: rgb(0 0 0 / 30%);\n bottom: 0;\n display: flex;\n flex-direction: column;\n left: 0;\n overflow: auto;\n -webkit-overflow-scrolling: touch;\n place-content: center;\n position: fixed;\n right: 0;\n top: 0;\n z-index: z-index('dialog');\n width: 100%;\n height: 100vh;\n }\n\n .body {\n @include elevation('low');\n\n background: var(--color-white);\n border-radius: $border-radius;\n color: var(--color-ice-700);\n display: flex;\n flex-direction: column;\n margin: 0 auto;\n max-height: 100vh;\n max-width: 360px;\n transition: transform $primary-transition;\n width: 100%;\n\n &.grey {\n background: var(--color-ice-200);\n border-radius: $border-radius;\n }\n }\n\n .content {\n flex-grow: 1;\n padding: space(3) var(--grid-gutter);\n }\n\n .footer {\n background: var(--color-ice-200);\n border-top: border('thin', var(--color-ice));\n display: initial; // TEMP. Will need to fix marketplace `footer` style\n padding: space(3) var(--grid-gutter);\n\n @include breakpoint('md') {\n border-bottom-left-radius: $border-radius;\n border-bottom-right-radius: $border-radius;\n }\n }\n\n :global(.fade-enter-from),\n :global(.fade-leave-active) {\n .body {\n transform: translate3d(0, #{space(2)}, 0);\n }\n }\n</style>\n"],"names":["slots","useSlots","attrs","useAttrs","classes","useCssModule","headerId","uniqueId","isConfirming","ref","root","modifiedConfirmText","computed","props","t","hasDescription","statusIcon","StatusIcons","capitalize","statusColor","StatusColors","computedDangerZone","StatusSeverities","cancel","emits","handleConfirm","event","onConfirm","watchEffect","nextTick"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBA4FQA,IAAQC,KACRC,IAAQC,KACRC,IAAUC,KACVC,IAAWC,EAAS,gBAAgB,GAEpCC,IAAeC,EAAI,EAAK,GACxBC,IAAOD,KAQPE,IAAsBC,EAAS,MAAMC,EAAM,gBAAgBA,EAAM,QAAQC,EAAE,SAAS,IAAIA,EAAE,YAAY,EAAE,GAExGC,IAAiBH,EAAS,MAAM,CAAC,CAACZ,EAAM,WAAWa,EAAM,WAAW,GAEpEG,IAAaJ;AAAA,MAAqB,MACtCC,EAAM,SAASI,EAAYC,EAAWL,EAAM,MAAM,CAAC,IAAII,EAAY;AAAA,IAAA,GAE/DE,IAAcP;AAAA,MAAsB,MACxCC,EAAM,SAASO,EAAaF,EAAWL,EAAM,MAAM,CAAC,IAAIO,EAAa;AAAA,IAAA,GAGjEC,IAAqBT,EAAS,MAAMC,EAAM,cAAcA,EAAM,WAAWS,EAAiB,KAAK;AAErG,aAASC,IAAS;AAChB,MAAAC,EAAM,eAAe,EAAK,GAC1BA,EAAM,QAAQ;AAAA,IAChB;AAEA,mBAAeC,EAAcC,GAAc;AACzC,MAAAlB,EAAa,QAAQ;AAIrB,YAAMmB,IAAYzB,EAAM;AAIxB,YAAMyB,EAAUD,CAAK,GACrBlB,EAAa,QAAQ;AAAA,IACvB;AAEA,WAAAoB,EAAY,MAAM;AAChB,MAAIf,EAAM,QAERgB,EAAS,WAAY;AACnB,QAAAnB,EAAK,MAAM;MAAM,CAClB;AAAA,IACH,CACD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}