@leaflink/stash 52.0.2 → 53.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 (259) hide show
  1. package/README.md +50 -49
  2. package/dist/Accordion.js +16 -16
  3. package/dist/Accordion.js.map +1 -1
  4. package/dist/AccordionGroup.js +7 -7
  5. package/dist/AccordionGroup.js.map +1 -1
  6. package/dist/ActionsDropdown.js +16 -16
  7. package/dist/ActionsDropdown.js.map +1 -1
  8. package/dist/AddressSelect.js.map +1 -1
  9. package/dist/AddressSelect.vue.d.ts +1 -1
  10. package/dist/Alert.js +34 -34
  11. package/dist/Alert.js.map +1 -1
  12. package/dist/AppNavigationItem.js +31 -31
  13. package/dist/AppNavigationItem.js.map +1 -1
  14. package/dist/AppSidebar.js +19 -19
  15. package/dist/AppSidebar.js.map +1 -1
  16. package/dist/AppTopbar.js +32 -32
  17. package/dist/AppTopbar.js.map +1 -1
  18. package/dist/Avatar.js +18 -18
  19. package/dist/Avatar.js.map +1 -1
  20. package/dist/Backdrop.js +5 -5
  21. package/dist/Backdrop.js.map +1 -1
  22. package/dist/Badge.js +38 -38
  23. package/dist/Badge.js.map +1 -1
  24. package/dist/Box.js +1 -1
  25. package/dist/{Box.vue_vue_type_script_setup_true_lang-rFnvwLVY.js → Box.vue_vue_type_script_setup_true_lang-dFFZN40_.js} +6 -6
  26. package/dist/{Box.vue_vue_type_script_setup_true_lang-rFnvwLVY.js.map → Box.vue_vue_type_script_setup_true_lang-dFFZN40_.js.map} +1 -1
  27. package/dist/Button.js +21 -21
  28. package/dist/Button.js.map +1 -1
  29. package/dist/ButtonGroup.js +26 -26
  30. package/dist/ButtonGroup.js.map +1 -1
  31. package/dist/Card.js +14 -14
  32. package/dist/Card.js.map +1 -1
  33. package/dist/CardContent.js +1 -1
  34. package/dist/CardContent.js.map +1 -1
  35. package/dist/CardFooter.js +1 -1
  36. package/dist/CardFooter.js.map +1 -1
  37. package/dist/CardHeader.js +4 -4
  38. package/dist/CardHeader.js.map +1 -1
  39. package/dist/CardMedia.js +20 -20
  40. package/dist/CardMedia.js.map +1 -1
  41. package/dist/Carousel.js +88 -93
  42. package/dist/Carousel.js.map +1 -1
  43. package/dist/Checkbox.js +30 -30
  44. package/dist/Checkbox.js.map +1 -1
  45. package/dist/Checkbox.vue.d.ts +0 -3
  46. package/dist/Chip.js +33 -33
  47. package/dist/Chip.js.map +1 -1
  48. package/dist/ConfirmationCodeInput.js +72 -72
  49. package/dist/ConfirmationCodeInput.js.map +1 -1
  50. package/dist/ContextSwitcher.js +27 -27
  51. package/dist/ContextSwitcher.js.map +1 -1
  52. package/dist/Copy.js +47 -48
  53. package/dist/Copy.js.map +1 -1
  54. package/dist/CurrencyInput.js +1 -1
  55. package/dist/CurrencyInput.js.map +1 -1
  56. package/dist/CurrencyInput.vue.d.ts +5 -5
  57. package/dist/DataView.js +23 -23
  58. package/dist/DataView.js.map +1 -1
  59. package/dist/DataViewFilters.js +26 -26
  60. package/dist/DataViewFilters.js.map +1 -1
  61. package/dist/DataViewSortButton.js +22 -22
  62. package/dist/DataViewSortButton.js.map +1 -1
  63. package/dist/DataViewToolbar.js +52 -52
  64. package/dist/DataViewToolbar.js.map +1 -1
  65. package/dist/DatePicker.js +10 -10
  66. package/dist/DatePicker.js.map +1 -1
  67. package/dist/DescriptionList.js +2 -2
  68. package/dist/DescriptionList.js.map +1 -1
  69. package/dist/DescriptionListDetail.js +2 -2
  70. package/dist/DescriptionListDetail.js.map +1 -1
  71. package/dist/DescriptionListGroup.js +9 -9
  72. package/dist/DescriptionListGroup.js.map +1 -1
  73. package/dist/DescriptionListTerm.js +8 -8
  74. package/dist/DescriptionListTerm.js.map +1 -1
  75. package/dist/Dialog.js +47 -47
  76. package/dist/Dialog.js.map +1 -1
  77. package/dist/Divider.js +6 -6
  78. package/dist/Divider.js.map +1 -1
  79. package/dist/Dropdown.js +20 -20
  80. package/dist/Dropdown.js.map +1 -1
  81. package/dist/EmptyState.js +26 -26
  82. package/dist/EmptyState.js.map +1 -1
  83. package/dist/Field.js +1 -1
  84. package/dist/{Field.vue_vue_type_script_setup_true_lang-DI6z3AE9.js → Field.vue_vue_type_script_setup_true_lang-dAGKfjf5.js} +17 -17
  85. package/dist/Field.vue_vue_type_script_setup_true_lang-dAGKfjf5.js.map +1 -0
  86. package/dist/FileUpload.js +47 -49
  87. package/dist/FileUpload.js.map +1 -1
  88. package/dist/FilterChip.js +20 -20
  89. package/dist/FilterChip.js.map +1 -1
  90. package/dist/FilterDrawerItem.js +13 -13
  91. package/dist/FilterDrawerItem.js.map +1 -1
  92. package/dist/FilterDropdown.js +27 -27
  93. package/dist/FilterDropdown.js.map +1 -1
  94. package/dist/FilterSelect.js +33 -33
  95. package/dist/FilterSelect.js.map +1 -1
  96. package/dist/Filters.js +29 -29
  97. package/dist/Filters.js.map +1 -1
  98. package/dist/Filters.vue.d.ts +2 -8
  99. package/dist/HttpError.js +29 -29
  100. package/dist/HttpError.js.map +1 -1
  101. package/dist/HttpError.vue.d.ts +0 -3
  102. package/dist/Icon.js +12 -12
  103. package/dist/Icon.js.map +1 -1
  104. package/dist/IconLabel.js +19 -19
  105. package/dist/IconLabel.js.map +1 -1
  106. package/dist/IconLabel.vue.d.ts +1 -1
  107. package/dist/Illustration.js +2 -2
  108. package/dist/{Illustration.vue_vue_type_script_setup_true_lang-BrqEF8xe.js → Illustration.vue_vue_type_script_setup_true_lang-C1bPkWZZ.js} +4 -4
  109. package/dist/{Illustration.vue_vue_type_script_setup_true_lang-BrqEF8xe.js.map → Illustration.vue_vue_type_script_setup_true_lang-C1bPkWZZ.js.map} +1 -1
  110. package/dist/Image.js +2 -2
  111. package/dist/Image.vue.d.ts +0 -3
  112. package/dist/{Image.vue_vue_type_script_setup_true_lang-D5u4av0_.js → Image.vue_vue_type_script_setup_true_lang-CAj0FH9h.js} +11 -11
  113. package/dist/Image.vue_vue_type_script_setup_true_lang-CAj0FH9h.js.map +1 -0
  114. package/dist/InlineEdit.js +8 -8
  115. package/dist/InlineEdit.js.map +1 -1
  116. package/dist/Input.js +29 -29
  117. package/dist/Input.js.map +1 -1
  118. package/dist/InputOptions.js +87 -84
  119. package/dist/InputOptions.js.map +1 -1
  120. package/dist/InputOptions.vue.d.ts +2 -2
  121. package/dist/IntegrationIcon.js +11 -11
  122. package/dist/IntegrationIcon.js.map +1 -1
  123. package/dist/Label.js +1 -1
  124. package/dist/{Label.vue_vue_type_script_setup_true_lang-CNquF3AP.js → Label.vue_vue_type_script_setup_true_lang-xwY3X-iV.js} +16 -16
  125. package/dist/{Label.vue_vue_type_script_setup_true_lang-CNquF3AP.js.map → Label.vue_vue_type_script_setup_true_lang-xwY3X-iV.js.map} +1 -1
  126. package/dist/ListItem.js +14 -14
  127. package/dist/ListItem.js.map +1 -1
  128. package/dist/ListItem.vue.d.ts +0 -6
  129. package/dist/ListItemCell.js +9 -9
  130. package/dist/ListItemCell.js.map +1 -1
  131. package/dist/ListView.js +138 -141
  132. package/dist/ListView.js.map +1 -1
  133. package/dist/ListView.vue.d.ts +2 -26
  134. package/dist/Loading.js +8 -8
  135. package/dist/Loading.js.map +1 -1
  136. package/dist/Logo.js +1 -1
  137. package/dist/{Logo.vue_vue_type_script_setup_true_lang-Dz8c98sc.js → Logo.vue_vue_type_script_setup_true_lang-DghNC_k6.js} +3 -3
  138. package/dist/{Logo.vue_vue_type_script_setup_true_lang-Dz8c98sc.js.map → Logo.vue_vue_type_script_setup_true_lang-DghNC_k6.js.map} +1 -1
  139. package/dist/Menu.js +5 -5
  140. package/dist/Menu.js.map +1 -1
  141. package/dist/MenuItem.js +12 -12
  142. package/dist/MenuItem.js.map +1 -1
  143. package/dist/Metric.js +24 -24
  144. package/dist/Metric.js.map +1 -1
  145. package/dist/Modal.js +60 -60
  146. package/dist/Modal.js.map +1 -1
  147. package/dist/Modals.js +1 -1
  148. package/dist/Modals.js.map +1 -1
  149. package/dist/Module.js +6 -6
  150. package/dist/Module.js.map +1 -1
  151. package/dist/ModuleContent.js +16 -16
  152. package/dist/ModuleContent.js.map +1 -1
  153. package/dist/ModuleFooter.js +13 -13
  154. package/dist/ModuleFooter.js.map +1 -1
  155. package/dist/ModuleHeader.js +29 -29
  156. package/dist/ModuleHeader.js.map +1 -1
  157. package/dist/MoreActions.js +81 -84
  158. package/dist/MoreActions.js.map +1 -1
  159. package/dist/ObfuscateText.js +4 -4
  160. package/dist/ObfuscateText.js.map +1 -1
  161. package/dist/PageContent.js +13 -13
  162. package/dist/PageContent.js.map +1 -1
  163. package/dist/PageHeader.js +28 -28
  164. package/dist/PageHeader.js.map +1 -1
  165. package/dist/PageNavigation.js +1 -1
  166. package/dist/Paginate.js +45 -45
  167. package/dist/Paginate.js.map +1 -1
  168. package/dist/QuickAction.js +18 -18
  169. package/dist/QuickAction.js.map +1 -1
  170. package/dist/Radio.js +17 -17
  171. package/dist/Radio.js.map +1 -1
  172. package/dist/RadioGroup.js +158 -154
  173. package/dist/RadioGroup.js.map +1 -1
  174. package/dist/RadioNew.js +80 -80
  175. package/dist/RadioNew.js.map +1 -1
  176. package/dist/RadioNew.vue.d.ts +0 -3
  177. package/dist/RangeInput.js +2 -2
  178. package/dist/RangeInput.js.map +1 -1
  179. package/dist/SearchBar.js +9 -9
  180. package/dist/SearchBar.js.map +1 -1
  181. package/dist/SectionHeader.js +14 -14
  182. package/dist/SectionHeader.js.map +1 -1
  183. package/dist/Select.js +369 -366
  184. package/dist/Select.js.map +1 -1
  185. package/dist/SelectStatus.js +26 -27
  186. package/dist/SelectStatus.js.map +1 -1
  187. package/dist/Skeleton.js +20 -20
  188. package/dist/Skeleton.js.map +1 -1
  189. package/dist/Step.js +37 -40
  190. package/dist/Step.js.map +1 -1
  191. package/dist/Stepper.js +17 -17
  192. package/dist/Stepper.js.map +1 -1
  193. package/dist/Switch.js +57 -57
  194. package/dist/Switch.js.map +1 -1
  195. package/dist/Tab.js +17 -19
  196. package/dist/Tab.js.map +1 -1
  197. package/dist/TabPanel.js +1 -1
  198. package/dist/TabPanel.js.map +1 -1
  199. package/dist/Table.js +22 -22
  200. package/dist/Table.js.map +1 -1
  201. package/dist/TableCell.js +32 -32
  202. package/dist/TableCell.js.map +1 -1
  203. package/dist/TableHeaderCell.js +35 -35
  204. package/dist/TableHeaderCell.js.map +1 -1
  205. package/dist/TableHeaderRow.js +10 -10
  206. package/dist/TableHeaderRow.js.map +1 -1
  207. package/dist/TableRow.js +51 -51
  208. package/dist/TableRow.js.map +1 -1
  209. package/dist/Tabs.js +2 -2
  210. package/dist/{Tabs.vue_vue_type_script_setup_true_lang-B3Irnlcd.js → Tabs.vue_vue_type_script_setup_true_lang-BVTCcK6M.js} +33 -33
  211. package/dist/Tabs.vue_vue_type_script_setup_true_lang-BVTCcK6M.js.map +1 -0
  212. package/dist/TextEditor.js +8 -8
  213. package/dist/TextEditor.js.map +1 -1
  214. package/dist/Textarea.js +15 -15
  215. package/dist/Textarea.js.map +1 -1
  216. package/dist/Thumbnail.js +41 -41
  217. package/dist/Thumbnail.js.map +1 -1
  218. package/dist/ThumbnailEmpty.js +3 -3
  219. package/dist/ThumbnailEmpty.js.map +1 -1
  220. package/dist/ThumbnailGroup.js +22 -22
  221. package/dist/ThumbnailGroup.js.map +1 -1
  222. package/dist/Timeline.js +3 -3
  223. package/dist/Timeline.js.map +1 -1
  224. package/dist/TimelineItem.js +22 -22
  225. package/dist/TimelineItem.js.map +1 -1
  226. package/dist/Toast.js +29 -29
  227. package/dist/Toast.js.map +1 -1
  228. package/dist/Toast.vue.d.ts +3 -0
  229. package/dist/Toasts.js +11 -11
  230. package/dist/Toasts.js.map +1 -1
  231. package/dist/Tooltip.js +2 -81
  232. package/dist/Tooltip.js.map +1 -1
  233. package/dist/Tooltip.vue.d.ts +1 -1
  234. package/dist/Tooltip.vue_vue_type_script_setup_true_lang-mzBLSXy3.js +84 -0
  235. package/dist/Tooltip.vue_vue_type_script_setup_true_lang-mzBLSXy3.js.map +1 -0
  236. package/dist/components.css +2 -2
  237. package/dist/constants.d.ts +9 -9
  238. package/dist/constants.js +17 -17
  239. package/dist/constants.js.map +1 -1
  240. package/dist/directives/tooltip.js +2 -2
  241. package/dist/directives/tooltip.js.map +1 -1
  242. package/dist/{index-C14LhAwV.js → index-DBV9Uz0C.js} +3 -3
  243. package/dist/{index-C14LhAwV.js.map → index-DBV9Uz0C.js.map} +1 -1
  244. package/dist/tailwind-base.js.d.ts +12 -0
  245. package/dist/tailwind-base.js.map +1 -1
  246. package/dist/useSortable.js +1 -1
  247. package/dist/utils/helpers.js +15 -15
  248. package/dist/utils/helpers.js.map +1 -1
  249. package/package.json +15 -15
  250. package/styles/backwards-compat.css +373 -2851
  251. package/styles/main.css +8 -0
  252. package/styles/sofia-font.css +23 -27
  253. package/styles/theme.css +1033 -0
  254. package/dist/Field.vue_vue_type_script_setup_true_lang-DI6z3AE9.js.map +0 -1
  255. package/dist/Image.vue_vue_type_script_setup_true_lang-D5u4av0_.js.map +0 -1
  256. package/dist/Tabs.vue_vue_type_script_setup_true_lang-B3Irnlcd.js.map +0 -1
  257. package/dist/tailwind-base.d.ts +0 -333
  258. package/styles/base.css +0 -902
  259. package/tailwind-base.ts +0 -455
package/README.md CHANGED
@@ -25,6 +25,7 @@ level. This project is intended to be used across our digital product portfolio.
25
25
  - [Legacy Styles](#legacy-styles)
26
26
  - [Tailwind](#tailwind)
27
27
  - [Configuration](#configuration)
28
+ - [VSCode](#vscode)
28
29
  - [Resources](#resources)
29
30
  - [Core files & Entry Points](#core-files--entry-points)
30
31
  - [à la carte](#%C3%A0-la-carte)
@@ -67,7 +68,7 @@ pnpm install
67
68
 
68
69
  ## Quick Start
69
70
 
70
- Stash requires Vue 3 and Tailwind CSS 3. To get started, install the package and its peer dependencies:
71
+ Stash requires Vue 3 and Tailwind CSS v4. To get started, install the package and its peer dependencies:
71
72
 
72
73
  ```sh
73
74
  npx install-peerdeps @leaflink/stash
@@ -81,7 +82,7 @@ import { createApp } from 'vue';
81
82
  import stash from '@leaflink/stash';
82
83
 
83
84
  // stash styles
84
- import '@leaflink/stash/styles/base.css';
85
+ import '@leaflink/stash/styles/theme.css';
85
86
  import '@leaflink/stash/components.css';
86
87
 
87
88
  // app styles
@@ -92,30 +93,23 @@ const app = createApp(App);
92
93
  app.use(stash);
93
94
  ```
94
95
 
95
- Your app styles should be loaded after the Stash styles to ensure that they override the Stash styles. At minimum, your
96
- app styles should include the following:
96
+ Your app styles should be loaded after the Stash styles to ensure that they override the Stash styles. **Tailwind v4:**
97
+ Stash uses Tailwind v4 with CSS-first configuration. Simply import Stash's theme styles and add your content sources:
97
98
 
98
99
  ```css filename="app.css"
99
- @tailwind base;
100
- @tailwind components;
101
- @tailwind utilities;
100
+ @layer theme, base, components, utilities;
101
+ @import 'tailwindcss/theme.css' layer(theme);
102
+ @import '@leaflink/stash/styles/backwards-compat.css' layer(base) source(none); /* optional */
103
+ @import '@leaflink/stash/components.css';
104
+ @import 'tailwindcss/utilities.css' layer(utilities) source(none);
105
+ @import '@leaflink/stash/styles/sofia-font.css' layer(base) source(none);
106
+ @import '@leaflink/stash/styles/theme.css';
107
+
108
+ /* Scan your app files for Tailwind classes */
109
+ @source "./src/**/*.{vue,ts,js}";
102
110
  ```
103
111
 
104
- Configure Tailwind in your app by creating a `tailwind.config.ts` file. It should include the Stash files in the
105
- `content` setting.
106
-
107
- ```ts filename="tailwind.config.ts"
108
- import stashPreset from '@leaflink/stash/tailwind-base';
109
-
110
- /** @type {import('tailwindcss').Config} */
111
- export default {
112
- presets: [stashPreset],
113
-
114
- content: ['./src/**/*.{vue,ts,js}', './node_modules/@leaflink/stash/dist/*.js'],
115
- };
116
- ```
117
-
118
- See the [Tailwind](#tailwind) section for more details on how to configure it in your app.
112
+ No `tailwind.config.ts` needed! See the [Tailwind](#tailwind) section and `TAILWIND_V4_MIGRATION.md` for more details.
119
113
 
120
114
  > [!NOTE] For apps still requiring deprecated css & utility classes, you can include the backwards compat styles from
121
115
  > Stash:
@@ -123,7 +117,7 @@ See the [Tailwind](#tailwind) section for more details on how to configure it in
123
117
  ```ts filename="main.ts"
124
118
  import '@leaflink/stash/styles/backwards-compat.css'; // Add this line before the base and components styles.
125
119
  import '@leaflink/stash/styles/sofia-font.css'; // Add this line before the base and components styles if you're using the Sofia font.
126
- import '@leaflink/stash/styles/base.css';
120
+ import '@leaflink/stash/styles/theme.css';
127
121
  import '@leaflink/stash/components.css';
128
122
  import './app.css';
129
123
  ```
@@ -151,7 +145,7 @@ export default defineConfig(({ mode }) => {
151
145
 
152
146
  `@leaflink/stash` is a Vue component library that implements
153
147
  [Leaflink's Stash Design System](https://stash.leaflink.com). So every one of LeafLink's colors, typography, shadows,
154
- etc. can be accessible via tailwind utility classes like `tw-text-blue-500 tw-text-sm`.
148
+ etc. can be accessible via tailwind utility classes like `text-blue-500 text-sm`.
155
149
 
156
150
  Stash is a Vue plugin that can be installed in your app. You **do not need to install the plugin in order to use the
157
151
  components**, but it is required if you need to configure the framework to suit your specific needs.
@@ -278,7 +272,7 @@ import '@leaflink/stash/styles/backwards-compat.css';
278
272
  import '@leaflink/stash/styles/sofia-font.css';
279
273
 
280
274
  /* stash styles */
281
- import '@leaflink/stash/styles/base.css';
275
+ import '@leaflink/stash/styles/theme.css';
282
276
  import '@leaflink/stash/components.css';
283
277
 
284
278
  import './app.css';
@@ -289,15 +283,11 @@ import './app.css';
289
283
  `@leaflink/stash` uses [Tailwind](https://tailwindcss.com/) behind the scene to style its components. It's currently
290
284
  required to **run this library downstream in order to avoid issues with css duplication & ordering**.
291
285
 
292
- In order to avoid class name clashes with legacy utilities, `@leaflink/stash` prefixes Tailwind utility classes with
293
- `tw-`. This may change in the future when all LeafLink apps no longer need deprecated styles. For now, when needing to
294
- use a tailwind class, just add the `tw` prefix like so: `tw-flex md:tw-text-blue`.
295
-
296
286
  ```jsx
297
287
  import Button from '@leaflink/stash/Button.vue';
298
288
  import IconLabel from '@leaflink/stash/IconLabel.vue';
299
289
 
300
- <Button icon-label class="tw-hidden md:tw-inline tw-ml-3">
290
+ <Button icon-label class="hidden md:inline ml-3">
301
291
  <IconLabel icon="user-add" title="Add Recipient" size="dense" stacked>
302
292
  Add Recipient
303
293
  </IconLabel>
@@ -306,30 +296,41 @@ import IconLabel from '@leaflink/stash/IconLabel.vue';
306
296
 
307
297
  ### Configuration
308
298
 
309
- In order to properly use Tailwind with Stash, it's necessary to add Stash's base styles as a preset of your project.
310
-
311
- ```ts
312
- // tailwind.config.ts
299
+ **Tailwind v4 Configuration:**
313
300
 
314
- import stashPreset from '@leaflink/stash/tailwind-base';
301
+ Stash uses Tailwind v4 with CSS-first configuration. Import Stash's base styles in your main CSS file:
315
302
 
316
- /** @type {import('tailwindcss').Config} */
317
- export default {
318
- presets: [stashPreset],
303
+ ```css
304
+ /* app.css */
305
+ @layer theme, base, components, utilities;
306
+ @import 'tailwindcss/theme.css' layer(theme);
307
+ @import '@leaflink/stash/styles/backwards-compat.css' layer(base) source(none); /* optional */
308
+ @import '@leaflink/stash/components.css';
309
+ @import 'tailwindcss/utilities.css' layer(utilities) source(none);
310
+ @import '@leaflink/stash/styles/sofia-font.css' layer(base) source(none);
311
+ @import '@leaflink/stash/styles/theme.css';
319
312
 
320
- content: ['./src/**/*.{vue,ts,js}', './node_modules/@leaflink/stash/dist/*.js'],
313
+ /* Scan your app files */
314
+ @source "./src/**/*.{vue,ts,js}";
321
315
 
322
- theme: {
323
- extend: {
324
- // Add this to your tailwind config to use the DM Sans font instead of the legacy Sofia font.
325
- fontFamily: {
326
- sans: ['DM Sans', 'sans-serif'],
327
- },
328
- },
329
- },
330
- };
316
+ /* Optional: Override theme values */
317
+ @theme {
318
+ /* Use DM Sans instead of Sofia */
319
+ --font-family-sans: 'DM Sans', sans-serif;
320
+ }
331
321
  ```
332
322
 
323
+ ### VSCode
324
+
325
+ To avoid warnings from VSCode (and Cursor) saying "Unknown at rule" for `@reference`, `@apply`, and others from
326
+ tailwind:
327
+
328
+ 1. Create a `.vscode/` directory (it is gitignored)
329
+ 2. Add a `settings.json` file inside of it unless one already exists
330
+ 3. Create a `custom-css.json` file in the `.vscode` directory
331
+ 4. In the `custom-css.json` file, copy-paste its content from
332
+ [here](https://github.com/tailwindlabs/tailwindcss/discussions/5258#discussioncomment-13239940)
333
+
333
334
  ## Resources
334
335
 
335
336
  - **index.js**: This is the "install" entry point, for use with `app.use(...)`.
@@ -382,7 +383,7 @@ package itself.
382
383
  Required compatibility with this package on version **^4.x**.
383
384
 
384
385
  - `tailwindcss`: Our utility-first CSS framework used for building our responsive and customizable components. Required
385
- compatibility with this package on version **^3.3.1** or higher.
386
+ compatibility with this package on version **^4.x.x**.
386
387
 
387
388
  - `vue-router`: The official router for Vue.js applications. Required compatibility with this package on version
388
389
  **^4.x** or higher.
package/dist/Accordion.js CHANGED
@@ -1,14 +1,14 @@
1
- import { defineComponent as v, useSlots as x, useCssModule as y, ref as E, watch as b, createElementBlock as a, openBlock as c, createElementVNode as s, withDirectives as k, createVNode as i, withKeys as h, normalizeClass as w, withModifiers as C, unref as l, renderSlot as _, Fragment as M, toDisplayString as S, vShow as $, withCtx as z } from "vue";
1
+ import { defineComponent as x, useSlots as w, useCssModule as y, ref as E, watch as b, createElementBlock as a, openBlock as c, createElementVNode as s, withDirectives as k, createVNode as i, withKeys as h, normalizeClass as _, withModifiers as C, unref as l, renderSlot as m, Fragment as M, toDisplayString as S, vShow as $, withCtx as z } from "vue";
2
2
  import { _ as B } from "./Expand.vue_vue_type_script_setup_true_lang-CiONJfAp.js";
3
- import m from "./Icon.js";
3
+ import g from "./Icon.js";
4
4
  import { _ as K } from "./_plugin-vue_export-helper-CHgC5LLL.js";
5
5
  const A = {
6
- class: "stash-accordion tw-rounded tw-border tw-border-ice-500 tw-bg-white",
6
+ class: "stash-accordion rounded border border-ice-500 bg-white",
7
7
  "data-test": "stash-accordion"
8
- }, D = ["onKeypress"], I = { key: 0 }, N = { class: "tw-flex-1 tw-select-none tw-font-medium tw-leading-5 tw-text-ice-900" }, V = { class: "tw-mx-[18px] tw-h-px tw-bg-ice-200" }, j = {
9
- class: "stash-accordion__content tw-p-[18px]",
8
+ }, D = ["onKeypress"], I = { key: 0 }, N = { class: "flex-1 select-none font-medium leading-5 text-ice-900" }, V = { class: "mx-[18px] border-ice-200" }, j = {
9
+ class: "stash-accordion__content p-[18px]",
10
10
  "data-test": "stash-accordion|content"
11
- }, F = /* @__PURE__ */ v({
11
+ }, F = /* @__PURE__ */ x({
12
12
  __name: "Accordion",
13
13
  props: {
14
14
  icon: { default: "circle-info" },
@@ -16,8 +16,8 @@ const A = {
16
16
  isExpanded: { type: Boolean, default: !1 }
17
17
  },
18
18
  emits: ["toggle", "open", "close"],
19
- setup(g, { emit: f }) {
20
- const t = g, d = x(), r = f, p = y();
19
+ setup(f, { emit: v }) {
20
+ const t = f, d = w(), r = v, p = y();
21
21
  if (!t.title && !d.header)
22
22
  throw new Error("Either a title prop or header slot must be provided");
23
23
  const e = E(t.isExpanded);
@@ -36,7 +36,7 @@ const A = {
36
36
  s("div", {
37
37
  tabindex: "0",
38
38
  "data-test": "stash-accordion|toggle",
39
- class: w(["stash-accordion__toggle tw-flex tw-items-center", [l(p).toggle, e.value && l(p)["toggle--open"]]]),
39
+ class: _(["stash-accordion__toggle flex items-center", [l(p).toggle, e.value && l(p)["toggle--open"]]]),
40
40
  onClick: n,
41
41
  onKeypress: [
42
42
  h(n, ["enter"]),
@@ -44,18 +44,18 @@ const A = {
44
44
  ]
45
45
  }, [
46
46
  l(d).header ? (c(), a("div", I, [
47
- _(o.$slots, "header")
47
+ m(o.$slots, "header")
48
48
  ])) : (c(), a(M, { key: 1 }, [
49
- i(m, {
50
- class: "tw-text-blue-500",
49
+ i(g, {
50
+ class: "text-blue-500",
51
51
  size: "dense",
52
52
  name: t.icon,
53
53
  "data-test": "stash-accordion|toggle-icon"
54
54
  }, null, 8, ["name"]),
55
55
  s("div", N, S(t.title), 1)
56
56
  ], 64)),
57
- i(m, {
58
- class: w(["tw-ml-auto tw-justify-center tw-text-ice-900 tw-transition-transform tw-duration-300", { "tw-rotate-180": e.value }]),
57
+ i(g, {
58
+ class: _(["ml-auto justify-center text-ice-900 transition-transform duration-300", { "rotate-180": e.value }]),
59
59
  size: "dense",
60
60
  name: "chevron-down",
61
61
  "data-test": "stash-accordion|toggle-chevron"
@@ -67,14 +67,14 @@ const A = {
67
67
  i(B, { "is-expanded": e.value }, {
68
68
  default: z(() => [
69
69
  s("div", j, [
70
- _(o.$slots, "default")
70
+ m(o.$slots, "default")
71
71
  ])
72
72
  ]),
73
73
  _: 3
74
74
  }, 8, ["is-expanded"])
75
75
  ]));
76
76
  }
77
- }), q = "_toggle_1lu5k_2", G = {
77
+ }), q = "_toggle_iohx0_5", G = {
78
78
  toggle: q
79
79
  }, H = {
80
80
  $style: G
@@ -1 +1 @@
1
- {"version":3,"file":"Accordion.js","sources":["../src/components/Accordion/Accordion.vue"],"sourcesContent":["<script setup lang=\"ts\">\n import { ref, useCssModule, useSlots, watch } from 'vue';\n\n import Expand from '../Expand/Expand.vue';\n import { IconName } from '../Icon/Icon.types';\n import Icon from '../Icon/Icon.vue';\n\n export interface AccordionProps {\n /**\n * The filename of the icon that will be displayed on the left side of the header\n */\n icon?: IconName;\n\n /**\n * Title of the Accordion, displayed in the header\n */\n title?: string;\n\n /**\n * Whether the Accordion is expanded or not\n */\n isExpanded?: boolean;\n }\n\n type ToggleState = {\n isExpanded: boolean;\n };\n\n const props = withDefaults(defineProps<AccordionProps>(), {\n icon: 'circle-info',\n title: undefined,\n isExpanded: false,\n });\n const slots = useSlots();\n\n const emit = defineEmits<{\n (e: 'toggle', state: ToggleState): void;\n (e: 'open' | 'close'): void;\n }>();\n\n const classes = useCssModule();\n\n if (!props.title && !slots.header) {\n throw new Error('Either a title prop or header slot must be provided');\n }\n\n const localIsExpanded = ref(props.isExpanded);\n\n function emitEvents() {\n emit('toggle', { isExpanded: localIsExpanded.value });\n emit(localIsExpanded.value ? 'open' : 'close');\n }\n\n const toggle = () => {\n localIsExpanded.value = !localIsExpanded.value;\n emitEvents();\n };\n\n watch(\n () => props.isExpanded,\n (newVal) => {\n localIsExpanded.value = newVal;\n emitEvents();\n },\n );\n</script>\n\n<template>\n <div class=\"stash-accordion tw-rounded tw-border tw-border-ice-500 tw-bg-white\" data-test=\"stash-accordion\">\n <div\n tabindex=\"0\"\n data-test=\"stash-accordion|toggle\"\n class=\"stash-accordion__toggle tw-flex tw-items-center\"\n :class=\"[classes.toggle, localIsExpanded && classes['toggle--open']]\"\n @click=\"toggle\"\n @keypress.enter=\"toggle\"\n @keypress.space.prevent=\"toggle\"\n >\n <div v-if=\"slots.header\">\n <!-- @slot Accordion header -->\n <slot name=\"header\"> </slot>\n </div>\n <template v-else>\n <Icon class=\"tw-text-blue-500\" size=\"dense\" :name=\"props.icon\" data-test=\"stash-accordion|toggle-icon\" />\n <div class=\"tw-flex-1 tw-select-none tw-font-medium tw-leading-5 tw-text-ice-900\">\n {{ props.title }}\n </div>\n </template>\n\n <Icon\n class=\"tw-ml-auto tw-justify-center tw-text-ice-900 tw-transition-transform tw-duration-300\"\n size=\"dense\"\n name=\"chevron-down\"\n data-test=\"stash-accordion|toggle-chevron\"\n :class=\"{ 'tw-rotate-180': localIsExpanded }\"\n />\n </div>\n <hr v-show=\"localIsExpanded\" class=\"tw-mx-[18px] tw-h-px tw-bg-ice-200\" />\n <Expand :is-expanded=\"localIsExpanded\">\n <div class=\"stash-accordion__content tw-p-[18px]\" data-test=\"stash-accordion|content\">\n <!-- @slot Accordion content -->\n <slot></slot>\n </div>\n </Expand>\n </div>\n</template>\n\n<style module>\n .toggle {\n @apply tw-outline-none tw-ring-blue-500 tw-ring-opacity-15;\n\n display: flex;\n cursor: pointer;\n gap: theme('gap[1.5]');\n padding: 17px;\n outline: none;\n border-radius: theme('borderRadius.DEFAULT');\n\n &:focus-visible {\n @apply tw-ring-4;\n border-color: var(--color-ice-900);\n padding: 15px;\n border-width: 2px;\n }\n\n &--open {\n border-bottom-right-radius: 0;\n border-bottom-left-radius: 0;\n }\n\n @media (hover: hover) {\n &:hover {\n background-color: var(--color-ice-100);\n }\n }\n\n &:active {\n background-color: var(--color-ice-200);\n }\n\n &:active + hr,\n &:hover + hr {\n opacity: 0;\n }\n }\n</style>\n"],"names":["props","__props","slots","useSlots","emit","__emit","classes","useCssModule","localIsExpanded","ref","emitEvents","toggle","watch","newVal"],"mappings":";;;;;;;;;;;;;;;;;;;AA4BE,UAAMA,IAAQC,GAKRC,IAAQC,EAAA,GAERC,IAAOC,GAKPC,IAAUC,EAAA;AAEhB,QAAI,CAACP,EAAM,SAAS,CAACE,EAAM;AACzB,YAAM,IAAI,MAAM,qDAAqD;AAGvE,UAAMM,IAAkBC,EAAIT,EAAM,UAAU;AAE5C,aAASU,IAAa;AACpB,MAAAN,EAAK,UAAU,EAAE,YAAYI,EAAgB,OAAO,GACpDJ,EAAKI,EAAgB,QAAQ,SAAS,OAAO;AAAA,IAC/C;AAEA,UAAMG,IAAS,MAAM;AACnB,MAAAH,EAAgB,QAAQ,CAACA,EAAgB,OACzCE,EAAA;AAAA,IACF;AAEA,WAAAE;AAAA,MACE,MAAMZ,EAAM;AAAA,MACZ,CAACa,MAAW;AACV,QAAAL,EAAgB,QAAQK,GACxBH,EAAA;AAAA,MACF;AAAA,IAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
1
+ {"version":3,"file":"Accordion.js","sources":["../src/components/Accordion/Accordion.vue"],"sourcesContent":["<script setup lang=\"ts\">\n import { ref, useCssModule, useSlots, watch } from 'vue';\n\n import Expand from '../Expand/Expand.vue';\n import { IconName } from '../Icon/Icon.types';\n import Icon from '../Icon/Icon.vue';\n\n export interface AccordionProps {\n /**\n * The filename of the icon that will be displayed on the left side of the header\n */\n icon?: IconName;\n\n /**\n * Title of the Accordion, displayed in the header\n */\n title?: string;\n\n /**\n * Whether the Accordion is expanded or not\n */\n isExpanded?: boolean;\n }\n\n type ToggleState = {\n isExpanded: boolean;\n };\n\n const props = withDefaults(defineProps<AccordionProps>(), {\n icon: 'circle-info',\n title: undefined,\n isExpanded: false,\n });\n const slots = useSlots();\n\n const emit = defineEmits<{\n (e: 'toggle', state: ToggleState): void;\n (e: 'open' | 'close'): void;\n }>();\n\n const classes = useCssModule();\n\n if (!props.title && !slots.header) {\n throw new Error('Either a title prop or header slot must be provided');\n }\n\n const localIsExpanded = ref(props.isExpanded);\n\n function emitEvents() {\n emit('toggle', { isExpanded: localIsExpanded.value });\n emit(localIsExpanded.value ? 'open' : 'close');\n }\n\n const toggle = () => {\n localIsExpanded.value = !localIsExpanded.value;\n emitEvents();\n };\n\n watch(\n () => props.isExpanded,\n (newVal) => {\n localIsExpanded.value = newVal;\n emitEvents();\n },\n );\n</script>\n\n<template>\n <div class=\"stash-accordion rounded border border-ice-500 bg-white\" data-test=\"stash-accordion\">\n <div\n tabindex=\"0\"\n data-test=\"stash-accordion|toggle\"\n class=\"stash-accordion__toggle flex items-center\"\n :class=\"[classes.toggle, localIsExpanded && classes['toggle--open']]\"\n @click=\"toggle\"\n @keypress.enter=\"toggle\"\n @keypress.space.prevent=\"toggle\"\n >\n <div v-if=\"slots.header\">\n <!-- @slot Accordion header -->\n <slot name=\"header\"> </slot>\n </div>\n <template v-else>\n <Icon class=\"text-blue-500\" size=\"dense\" :name=\"props.icon\" data-test=\"stash-accordion|toggle-icon\" />\n <div class=\"flex-1 select-none font-medium leading-5 text-ice-900\">\n {{ props.title }}\n </div>\n </template>\n\n <Icon\n class=\"ml-auto justify-center text-ice-900 transition-transform duration-300\"\n size=\"dense\"\n name=\"chevron-down\"\n data-test=\"stash-accordion|toggle-chevron\"\n :class=\"{ 'rotate-180': localIsExpanded }\"\n />\n </div>\n <hr v-show=\"localIsExpanded\" class=\"mx-[18px] border-ice-200\" />\n <Expand :is-expanded=\"localIsExpanded\">\n <div class=\"stash-accordion__content p-[18px]\" data-test=\"stash-accordion|content\">\n <!-- @slot Accordion content -->\n <slot></slot>\n </div>\n </Expand>\n </div>\n</template>\n\n<style module>\n @reference \"../../../styles/main.css\";\n\n @layer utilities {\n .toggle {\n @apply outline-none ring-blue-500/15;\n\n display: flex;\n cursor: pointer;\n gap: --spacing(1.5);\n padding: 17px;\n outline: none;\n border-radius: var(--radius-sm);\n\n &:focus-visible {\n @apply ring-4;\n border-color: var(--color-ice-900);\n padding: 15px;\n border-width: 2px;\n }\n\n &--open {\n border-bottom-right-radius: 0;\n border-bottom-left-radius: 0;\n }\n\n @media (hover: hover) {\n &:hover {\n background-color: var(--color-ice-100);\n }\n }\n\n &:active {\n background-color: var(--color-ice-200);\n }\n\n &:active + hr,\n &:hover + hr {\n opacity: 0;\n }\n }\n }\n</style>\n"],"names":["props","__props","slots","useSlots","emit","__emit","classes","useCssModule","localIsExpanded","ref","emitEvents","toggle","watch","newVal"],"mappings":";;;;;;;;;;;;;;;;;;;AA4BE,UAAMA,IAAQC,GAKRC,IAAQC,EAAA,GAERC,IAAOC,GAKPC,IAAUC,EAAA;AAEhB,QAAI,CAACP,EAAM,SAAS,CAACE,EAAM;AACzB,YAAM,IAAI,MAAM,qDAAqD;AAGvE,UAAMM,IAAkBC,EAAIT,EAAM,UAAU;AAE5C,aAASU,IAAa;AACpB,MAAAN,EAAK,UAAU,EAAE,YAAYI,EAAgB,OAAO,GACpDJ,EAAKI,EAAgB,QAAQ,SAAS,OAAO;AAAA,IAC/C;AAEA,UAAMG,IAAS,MAAM;AACnB,MAAAH,EAAgB,QAAQ,CAACA,EAAgB,OACzCE,EAAA;AAAA,IACF;AAEA,WAAAE;AAAA,MACE,MAAMZ,EAAM;AAAA,MACZ,CAACa,MAAW;AACV,QAAAL,EAAgB,QAAQK,GACxBH,EAAA;AAAA,MACF;AAAA,IAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
@@ -1,16 +1,16 @@
1
- import { createElementBlock as t, openBlock as r, renderSlot as c } from "vue";
2
- import { _ as e } from "./_plugin-vue_export-helper-CHgC5LLL.js";
1
+ import { createElementBlock as e, openBlock as r, renderSlot as t } from "vue";
2
+ import { _ as c } from "./_plugin-vue_export-helper-CHgC5LLL.js";
3
3
  const s = {}, a = {
4
- class: "stash-accordion-group tw-space-y-2",
4
+ class: "stash-accordion-group flex flex-col gap-y-2",
5
5
  "data-test": "stash-accordion-group"
6
6
  };
7
7
  function n(o, d) {
8
- return r(), t("div", a, [
9
- c(o.$slots, "default")
8
+ return r(), e("div", a, [
9
+ t(o.$slots, "default")
10
10
  ]);
11
11
  }
12
- const p = /* @__PURE__ */ e(s, [["render", n]]);
12
+ const _ = /* @__PURE__ */ c(s, [["render", n]]);
13
13
  export {
14
- p as default
14
+ _ as default
15
15
  };
16
16
  //# sourceMappingURL=AccordionGroup.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"AccordionGroup.js","sources":["../src/components/AccordionGroup/AccordionGroup.vue"],"sourcesContent":["<template>\n <div class=\"stash-accordion-group tw-space-y-2\" data-test=\"stash-accordion-group\">\n <slot></slot>\n </div>\n</template>\n"],"names":["_hoisted_1","_sfc_render","_ctx","_cache","_openBlock","_createElementBlock"],"mappings":";;cACOA,IAAM;AAAA,EAAqC,OAAA;AAAA;;AAAhD,SAAAC,EAAAC,GAAAC,GAAA;SACEC,EAAa,GAAAC,EAAA,OAAAL,GAAA;AAAA;;;;"}
1
+ {"version":3,"file":"AccordionGroup.js","sources":["../src/components/AccordionGroup/AccordionGroup.vue"],"sourcesContent":["<template>\n <div class=\"stash-accordion-group flex flex-col gap-y-2\" data-test=\"stash-accordion-group\">\n <slot></slot>\n </div>\n</template>\n"],"names":["_hoisted_1","_sfc_render","_ctx","_cache","_openBlock","_createElementBlock"],"mappings":";;cACOA,IAAM;AAAA,EAA8C,OAAA;AAAA;;AAAzD,SAAAC,EAAAC,GAAAC,GAAA;SACEC,EAAa,GAAAC,EAAA,OAAAL,GAAA;AAAA;;;;"}
@@ -1,4 +1,4 @@
1
- import { defineComponent as i, useCssModule as p, createBlock as u, openBlock as f, normalizeClass as s, unref as n, createSlots as w, withCtx as e, createVNode as a, createTextVNode as _, toDisplayString as m, renderSlot as b } from "vue";
1
+ import { defineComponent as i, useCssModule as p, createBlock as u, openBlock as f, normalizeClass as s, unref as n, createSlots as _, withCtx as e, createVNode as a, createTextVNode as m, toDisplayString as b, renderSlot as w } from "vue";
2
2
  import { t as C } from "./locale.js";
3
3
  import x from "./Button.js";
4
4
  import g from "./Dropdown.js";
@@ -14,24 +14,24 @@ const y = /* @__PURE__ */ i({
14
14
  buttonText: { default: () => C("ll.actions") }
15
15
  },
16
16
  setup(d) {
17
- const t = d, o = p();
17
+ const o = d, t = p();
18
18
  return (l, N) => (f(), u(g, {
19
- align: t.align,
20
- "content-class": [n(o).dropdownContent, t.contentClass],
21
- class: s(n(o).actionsDropdown)
22
- }, w({
23
- toggle: e(({ isActive: r, toggle: c }) => [
19
+ align: o.align,
20
+ "content-class": [n(t).dropdownContent, o.contentClass],
21
+ class: s(n(t).actionsDropdown)
22
+ }, _({
23
+ toggle: e(({ isActive: c, toggle: r }) => [
24
24
  a(x, {
25
- class: s(["button tw-flex tw-w-full tw-items-center tw-justify-between tw-border tw-border-blue-500 tw-text-blue-500", [n(o).actionButton, { [n(o).disabled]: t.disabled }]]),
25
+ class: s(["button flex w-full items-center justify-between border border-blue-500 text-blue-500", [n(t).actionButton, { [n(t).disabled]: o.disabled }]]),
26
26
  secondary: "",
27
- "aria-expanded": r.toString(),
28
- disabled: t.disabled,
29
- onClick: c
27
+ "aria-expanded": c.toString(),
28
+ disabled: o.disabled,
29
+ onClick: r
30
30
  }, {
31
31
  default: e(() => [
32
- _(m(t.buttonText) + " ", 1),
32
+ m(b(o.buttonText) + " ", 1),
33
33
  a(B, {
34
- class: "tw-ml-1.5",
34
+ class: "ml-1.5",
35
35
  name: "caret-down"
36
36
  })
37
37
  ]),
@@ -40,16 +40,16 @@ const y = /* @__PURE__ */ i({
40
40
  ]),
41
41
  _: 2
42
42
  }, [
43
- t.disabled ? void 0 : {
43
+ o.disabled ? void 0 : {
44
44
  name: "default",
45
45
  fn: e(() => [
46
- b(l.$slots, "default")
46
+ w(l.$slots, "default")
47
47
  ]),
48
48
  key: "0"
49
49
  }
50
50
  ]), 1032, ["align", "content-class", "class"]));
51
51
  }
52
- }), k = "_actionButton_144dr_2", S = "_disabled_144dr_12", M = "_dropdownContent_144dr_18", T = "_actionsDropdown_144dr_33", h = {
52
+ }), k = "_actionButton_1i07n_5", S = "_disabled_1i07n_15", M = "_dropdownContent_1i07n_21", T = "_actionsDropdown_1i07n_36", h = {
53
53
  actionButton: k,
54
54
  disabled: S,
55
55
  dropdownContent: M,
@@ -1 +1 @@
1
- {"version":3,"file":"ActionsDropdown.js","sources":["../src/components/ActionsDropdown/ActionsDropdown.vue"],"sourcesContent":["<script lang=\"ts\" setup>\n import { useCssModule } from 'vue';\n\n import { t } from '../../locale';\n import Button from '../Button/Button.vue';\n import Dropdown from '../Dropdown/Dropdown.vue';\n import Icon from '../Icon/Icon.vue';\n\n defineOptions({\n name: 'll-actions-dropdown',\n });\n\n export interface ActionsDropdownProps {\n /**\n * Used to position the dropdown relative to target\n * Options: left, right\n */\n align?: 'left' | 'right';\n /**\n * Indicates whether the trigger button is disabled or not\n */\n disabled?: boolean;\n /**\n * Class to be applied to the dropdown content\n */\n contentClass?: string;\n /**\n * Text to be displayed on the trigger button\n */\n buttonText?: string;\n }\n\n const props = withDefaults(defineProps<ActionsDropdownProps>(), {\n align: 'left',\n disabled: false,\n contentClass: '',\n buttonText: () => t('ll.actions'),\n });\n\n const classes = useCssModule();\n</script>\n\n<template>\n <Dropdown\n :align=\"props.align\"\n :content-class=\"[classes.dropdownContent, props.contentClass]\"\n :class=\"classes.actionsDropdown\"\n >\n <template #toggle=\"{ isActive, toggle }\">\n <Button\n class=\"button tw-flex tw-w-full tw-items-center tw-justify-between tw-border tw-border-blue-500 tw-text-blue-500\"\n secondary\n :aria-expanded=\"isActive.toString()\"\n :class=\"[classes.actionButton, { [classes.disabled]: props.disabled }]\"\n :disabled=\"props.disabled\"\n @click=\"toggle\"\n >\n {{ props.buttonText }} <Icon class=\"tw-ml-1.5\" name=\"caret-down\" />\n </Button>\n </template>\n\n <template v-if=\"!props.disabled\" #default>\n <!-- @slot Dropdown content -->\n <slot></slot>\n </template>\n </Dropdown>\n</template>\n\n<style module>\n .actionButton {\n min-width: 156px;\n white-space: normal;\n }\n\n .actionButton:hover {\n background-color: var(--color-blue-100);\n border-color: var(--color-blue-500) !important;\n }\n\n .disabled {\n background-color: var(--color-ice-100) !important;\n border-color: var(--color-ice-500) !important;\n color: var(--color-ice-500) !important;\n }\n\n .dropdownContent {\n margin-top: 4px;\n }\n\n .dropdownContent:global(.dropdown__content) {\n margin-left: 0;\n margin-right: 0;\n max-width: 90vw;\n }\n\n .dropdownContent:global(.dropdown__content)::after {\n display: none;\n }\n\n @media screen('md') {\n .actionsDropdown {\n min-width: 156px;\n }\n\n .dropdownContent:global(.dropdown__content) {\n min-width: 156px;\n }\n }\n</style>\n"],"names":["props","__props","classes","useCssModule"],"mappings":";;;;;;;;;;;;;;;;AAgCE,UAAMA,IAAQC,GAORC,IAAUC,EAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
1
+ {"version":3,"file":"ActionsDropdown.js","sources":["../src/components/ActionsDropdown/ActionsDropdown.vue"],"sourcesContent":["<script lang=\"ts\" setup>\n import { useCssModule } from 'vue';\n\n import { t } from '../../locale';\n import Button from '../Button/Button.vue';\n import Dropdown from '../Dropdown/Dropdown.vue';\n import Icon from '../Icon/Icon.vue';\n\n defineOptions({\n name: 'll-actions-dropdown',\n });\n\n export interface ActionsDropdownProps {\n /**\n * Used to position the dropdown relative to target\n * Options: left, right\n */\n align?: 'left' | 'right';\n /**\n * Indicates whether the trigger button is disabled or not\n */\n disabled?: boolean;\n /**\n * Class to be applied to the dropdown content\n */\n contentClass?: string;\n /**\n * Text to be displayed on the trigger button\n */\n buttonText?: string;\n }\n\n const props = withDefaults(defineProps<ActionsDropdownProps>(), {\n align: 'left',\n disabled: false,\n contentClass: '',\n buttonText: () => t('ll.actions'),\n });\n\n const classes = useCssModule();\n</script>\n\n<template>\n <Dropdown\n :align=\"props.align\"\n :content-class=\"[classes.dropdownContent, props.contentClass]\"\n :class=\"classes.actionsDropdown\"\n >\n <template #toggle=\"{ isActive, toggle }\">\n <Button\n class=\"button flex w-full items-center justify-between border border-blue-500 text-blue-500\"\n secondary\n :aria-expanded=\"isActive.toString()\"\n :class=\"[classes.actionButton, { [classes.disabled]: props.disabled }]\"\n :disabled=\"props.disabled\"\n @click=\"toggle\"\n >\n {{ props.buttonText }} <Icon class=\"ml-1.5\" name=\"caret-down\" />\n </Button>\n </template>\n\n <template v-if=\"!props.disabled\" #default>\n <!-- @slot Dropdown content -->\n <slot></slot>\n </template>\n </Dropdown>\n</template>\n\n<style module>\n @reference \"../../../styles/main.css\";\n\n @layer utilities {\n .actionButton {\n min-width: 156px;\n white-space: normal;\n }\n\n .actionButton:hover {\n background-color: var(--color-blue-100);\n border-color: var(--color-blue-500) !important;\n }\n\n .disabled {\n background-color: var(--color-ice-100) !important;\n border-color: var(--color-ice-500) !important;\n color: var(--color-ice-500) !important;\n }\n\n .dropdownContent {\n margin-top: 4px;\n }\n\n .dropdownContent:global(.dropdown__content) {\n margin-left: 0;\n margin-right: 0;\n max-width: 90vw;\n }\n\n .dropdownContent:global(.dropdown__content)::after {\n display: none;\n }\n\n @media (width >= theme(--breakpoint-md)) {\n .actionsDropdown {\n min-width: 156px;\n }\n\n .dropdownContent:global(.dropdown__content) {\n min-width: 156px;\n }\n }\n }\n</style>\n"],"names":["props","__props","classes","useCssModule"],"mappings":";;;;;;;;;;;;;;;;AAgCE,UAAMA,IAAQC,GAORC,IAAUC,EAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
@@ -1 +1 @@
1
- {"version":3,"file":"AddressSelect.js","sources":["../src/components/AddressSelect/AddressSelect.vue"],"sourcesContent":["<script setup lang=\"ts\">\n import debounce from 'lodash-es/debounce';\n import uniqueId from 'lodash-es/uniqueId';\n import { computed, inject, ref, useSlots, watch } from 'vue';\n\n import { StashProvideState } from '../../../types/misc';\n import useGoogleMaps, { type Address, type AddressOption } from '../../composables/useGoogleMaps/useGoogleMaps';\n import { DEBOUNCE } from '../../constants';\n import Select from '../Select/Select.vue';\n\n export interface AddressSelectProps {\n /**\n * Google Maps API Key. This takes precedence over the key defined in stashOptions\n */\n apiKey?: string;\n /**\n * Wether the Select is disabled or not\n */\n disabled?: boolean;\n /**\n * Select placeholder\n */\n placeholder?: string;\n /**\n * Debounce time in milliseconds to perform API requests on search\n */\n debounceTime?: number;\n /**\n * Model value address\n */\n modelValue: Address;\n /**\n * Hint text to be passed down to Select component\n */\n hintText?: string;\n /**\n * Error text to be passed down to Select component\n */\n errorText?: string;\n /**\n * Label text to be passed down to Select component\n */\n label?: string;\n /**\n * Disallows values from being de-selected\n */\n preventEmpty?: boolean;\n }\n\n const props = withDefaults(defineProps<AddressSelectProps>(), {\n disabled: false,\n placeholder: 'Type an address',\n debounceTime: DEBOUNCE.MEDIUM,\n modelValue: () => ({\n street_address: undefined,\n extended_address: undefined,\n city: undefined,\n state: undefined,\n postal_code: undefined,\n country: undefined,\n }),\n hintText: undefined,\n errorText: undefined,\n label: undefined,\n preventEmpty: false,\n apiKey: undefined,\n });\n\n const emit = defineEmits<{\n /**\n * Emitted when the model value changes\n */\n (e: 'update:modelValue', value: Address): void;\n /**\n * Emitted when an error occurs while reaching out to Google's API\n */\n (e: 'error', value: unknown): void;\n }>();\n\n const slots = useSlots();\n const stashOptions = inject<StashProvideState>('stashOptions');\n\n const googleMapsApiKey = computed(() => props.apiKey || stashOptions?.googleMapsApiKey);\n\n if (!googleMapsApiKey.value) {\n throw new Error('Google Maps API key is required');\n }\n\n const { getPlaceDetails, getPlacePredictions } = useGoogleMaps(googleMapsApiKey.value);\n\n const ID_PREFIX = 'address-select-';\n\n const isLoading = ref(false);\n const options = ref<Array<AddressOption>>();\n const internalValue = ref<AddressOption>();\n\n const debouncedSearch = debounce(search, props.debounceTime);\n\n const formattedAddress = computed(() => {\n const formattedAddress = [\n [props.modelValue?.street_address, props.modelValue?.extended_address].filter(Boolean).join(' '),\n props.modelValue?.city,\n [props.modelValue?.state, props.modelValue?.postal_code].filter(Boolean).join(' '),\n props.modelValue?.country,\n ]\n .filter(Boolean)\n .join(', ');\n\n return formattedAddress;\n });\n\n // When we don't have options just yet, we need to create them on our own\n watch(\n () => props.modelValue,\n () => {\n if (formattedAddress.value && !options.value?.length) {\n const option = {\n id: props.modelValue.place_id || uniqueId(ID_PREFIX),\n name: formattedAddress.value,\n address: props.modelValue,\n };\n\n options.value = [option];\n internalValue.value = option;\n } else if (!formattedAddress.value) {\n internalValue.value = undefined;\n options.value = [];\n }\n },\n { immediate: true },\n );\n\n async function search(query: string) {\n isLoading.value = true;\n\n try {\n options.value = await getPlacePredictions(query);\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n } catch (error: any) {\n options.value = [];\n if (error?.isGoogleMapsError) {\n emit('error', error);\n } else {\n throw error;\n }\n } finally {\n isLoading.value = false;\n }\n }\n\n async function select(option: AddressOption) {\n internalValue.value = option;\n\n // When an option is de-selected, the option will be undefined\n if (!option) {\n emit('update:modelValue', {\n street_address: undefined,\n extended_address: undefined,\n city: undefined,\n state: undefined,\n postal_code: undefined,\n country: undefined,\n });\n return;\n }\n\n // When an option does not have a google place id, we don't want to fetch it's details\n if (option.id.startsWith(ID_PREFIX) && option.address) {\n emit('update:modelValue', option.address);\n return;\n }\n\n try {\n const address = await getPlaceDetails(option.id);\n emit('update:modelValue', address);\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n } catch (error: any) {\n if (error?.isGoogleMapsError) {\n emit('error', error);\n } else {\n throw error;\n }\n }\n }\n</script>\n\n<template>\n <Select\n single\n data-test=\"select|address\"\n :disabled=\"props.disabled\"\n :loading=\"isLoading\"\n :options=\"options\"\n :placeholder=\"props.placeholder\"\n :label=\"props.label\"\n :hint-text=\"props.hintText\"\n :error=\"props.errorText\"\n :model-value=\"internalValue\"\n :prevent-empty=\"props.preventEmpty\"\n disable-filtering\n @search=\"debouncedSearch\"\n @update:model-value=\"select\"\n >\n <template v-if=\"slots.hint\" #hint>\n <slot name=\"hint\"></slot>\n </template>\n </Select>\n</template>\n"],"names":["ID_PREFIX","props","__props","emit","__emit","slots","useSlots","stashOptions","inject","googleMapsApiKey","computed","getPlaceDetails","getPlacePredictions","useGoogleMaps","isLoading","ref","options","internalValue","debouncedSearch","debounce","search","formattedAddress","_a","_b","_c","_d","_e","_f","watch","option","uniqueId","query","error","select","address"],"mappings":"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"}
1
+ {"version":3,"file":"AddressSelect.js","sources":["../src/components/AddressSelect/AddressSelect.vue"],"sourcesContent":["<script setup lang=\"ts\">\n import debounce from 'lodash-es/debounce';\n import uniqueId from 'lodash-es/uniqueId';\n import { computed, inject, ref, useSlots, watch } from 'vue';\n\n import { StashProvideState } from '../../../types/misc';\n import useGoogleMaps, { type Address, type AddressOption } from '../../composables/useGoogleMaps/useGoogleMaps';\n import { DEBOUNCE } from '../../constants';\n import Select from '../Select/Select.vue';\n\n export interface AddressSelectProps {\n /**\n * Google Maps API Key. This takes precedence over the key defined in stashOptions\n */\n apiKey?: string;\n /**\n * Wether the Select is disabled or not\n */\n disabled?: boolean;\n /**\n * Select placeholder\n */\n placeholder?: string;\n /**\n * Debounce time in milliseconds to perform API requests on search\n */\n debounceTime?: number;\n /**\n * Model value address\n */\n modelValue?: Address;\n /**\n * Hint text to be passed down to Select component\n */\n hintText?: string;\n /**\n * Error text to be passed down to Select component\n */\n errorText?: string;\n /**\n * Label text to be passed down to Select component\n */\n label?: string;\n /**\n * Disallows values from being de-selected\n */\n preventEmpty?: boolean;\n }\n\n const props = withDefaults(defineProps<AddressSelectProps>(), {\n disabled: false,\n placeholder: 'Type an address',\n debounceTime: DEBOUNCE.MEDIUM,\n modelValue: () => ({\n street_address: undefined,\n extended_address: undefined,\n city: undefined,\n state: undefined,\n postal_code: undefined,\n country: undefined,\n }),\n hintText: undefined,\n errorText: undefined,\n label: undefined,\n preventEmpty: false,\n apiKey: undefined,\n });\n\n const emit = defineEmits<{\n /**\n * Emitted when the model value changes\n */\n (e: 'update:modelValue', value: Address): void;\n /**\n * Emitted when an error occurs while reaching out to Google's API\n */\n (e: 'error', value: unknown): void;\n }>();\n\n const slots = useSlots();\n const stashOptions = inject<StashProvideState>('stashOptions');\n\n const googleMapsApiKey = computed(() => props.apiKey || stashOptions?.googleMapsApiKey);\n\n if (!googleMapsApiKey.value) {\n throw new Error('Google Maps API key is required');\n }\n\n const { getPlaceDetails, getPlacePredictions } = useGoogleMaps(googleMapsApiKey.value);\n\n const ID_PREFIX = 'address-select-';\n\n const isLoading = ref(false);\n const options = ref<Array<AddressOption>>();\n const internalValue = ref<AddressOption>();\n\n const debouncedSearch = debounce(search, props.debounceTime);\n\n const formattedAddress = computed(() => {\n const formattedAddress = [\n [props.modelValue?.street_address, props.modelValue?.extended_address].filter(Boolean).join(' '),\n props.modelValue?.city,\n [props.modelValue?.state, props.modelValue?.postal_code].filter(Boolean).join(' '),\n props.modelValue?.country,\n ]\n .filter(Boolean)\n .join(', ');\n\n return formattedAddress;\n });\n\n // When we don't have options just yet, we need to create them on our own\n watch(\n () => props.modelValue,\n () => {\n if (formattedAddress.value && !options.value?.length) {\n const option = {\n id: props.modelValue.place_id || uniqueId(ID_PREFIX),\n name: formattedAddress.value,\n address: props.modelValue,\n };\n\n options.value = [option];\n internalValue.value = option;\n } else if (!formattedAddress.value) {\n internalValue.value = undefined;\n options.value = [];\n }\n },\n { immediate: true },\n );\n\n async function search(query: string) {\n isLoading.value = true;\n\n try {\n options.value = await getPlacePredictions(query);\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n } catch (error: any) {\n options.value = [];\n if (error?.isGoogleMapsError) {\n emit('error', error);\n } else {\n throw error;\n }\n } finally {\n isLoading.value = false;\n }\n }\n\n async function select(option: AddressOption) {\n internalValue.value = option;\n\n // When an option is de-selected, the option will be undefined\n if (!option) {\n emit('update:modelValue', {\n street_address: undefined,\n extended_address: undefined,\n city: undefined,\n state: undefined,\n postal_code: undefined,\n country: undefined,\n });\n return;\n }\n\n // When an option does not have a google place id, we don't want to fetch it's details\n if (option.id.startsWith(ID_PREFIX) && option.address) {\n emit('update:modelValue', option.address);\n return;\n }\n\n try {\n const address = await getPlaceDetails(option.id);\n emit('update:modelValue', address);\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n } catch (error: any) {\n if (error?.isGoogleMapsError) {\n emit('error', error);\n } else {\n throw error;\n }\n }\n }\n</script>\n\n<template>\n <Select\n single\n data-test=\"select|address\"\n :disabled=\"props.disabled\"\n :loading=\"isLoading\"\n :options=\"options\"\n :placeholder=\"props.placeholder\"\n :label=\"props.label\"\n :hint-text=\"props.hintText\"\n :error=\"props.errorText\"\n :model-value=\"internalValue\"\n :prevent-empty=\"props.preventEmpty\"\n disable-filtering\n @search=\"debouncedSearch\"\n @update:model-value=\"select\"\n >\n <template v-if=\"slots.hint\" #hint>\n <slot name=\"hint\"></slot>\n </template>\n </Select>\n</template>\n"],"names":["ID_PREFIX","props","__props","emit","__emit","slots","useSlots","stashOptions","inject","googleMapsApiKey","computed","getPlaceDetails","getPlacePredictions","useGoogleMaps","isLoading","ref","options","internalValue","debouncedSearch","debounce","search","formattedAddress","_a","_b","_c","_d","_e","_f","watch","option","uniqueId","query","error","select","address"],"mappings":"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"}
@@ -91,7 +91,7 @@ export declare interface AddressSelectProps {
91
91
  /**
92
92
  * Model value address
93
93
  */
94
- modelValue: Address;
94
+ modelValue?: Address;
95
95
  /**
96
96
  * Hint text to be passed down to Select component
97
97
  */
package/dist/Alert.js CHANGED
@@ -1,11 +1,11 @@
1
- import { defineComponent as x, useSlots as $, useCssModule as C, ref as I, computed as s, withDirectives as S, createCommentVNode as i, createElementBlock as l, openBlock as o, normalizeClass as r, createVNode as w, createElementVNode as f, unref as t, renderSlot as m } from "vue";
2
- import y from "lodash-es/capitalize";
1
+ import { defineComponent as w, useSlots as $, useCssModule as C, ref as I, computed as s, withDirectives as S, createCommentVNode as i, createElementBlock as l, openBlock as o, normalizeClass as r, createVNode as f, createElementVNode as m, unref as t, renderSlot as y } from "vue";
2
+ import p from "lodash-es/capitalize";
3
3
  import B from "lodash-es/uniqueId";
4
4
  import { S as M, a as N } from "./statusLevels-D8EgtE_L.js";
5
5
  import V from "./directives/sticky.js";
6
- import p from "./Icon.js";
6
+ import b from "./Icon.js";
7
7
  import { _ as j } from "./_plugin-vue_export-helper-CHgC5LLL.js";
8
- const z = { class: "tw-m-0" }, A = /* @__PURE__ */ x({
8
+ const z = { class: "m-0" }, A = /* @__PURE__ */ w({
9
9
  name: "ll-alert",
10
10
  __name: "Alert",
11
11
  props: {
@@ -16,55 +16,55 @@ const z = { class: "tw-m-0" }, A = /* @__PURE__ */ x({
16
16
  sticky: { default: null },
17
17
  variant: { default: "outlined" }
18
18
  },
19
- setup(b) {
20
- const e = b, g = B("close-icon"), _ = $(), a = C(), c = I(!0), u = s(() => M[y(e.severity)]), h = s(() => N[y(e.severity)]), k = s(() => e.variant === "filled" && ["warning", "success"].includes(e.severity) ? "tw-text-ice-900" : e.variant === "filled" && ["info", "error"].includes(e.severity) ? "tw-text-white" : `tw-text-${h.value}`), n = s(() => e.variant === "filled" && ["info", "error"].includes(e.severity) ? "tw-text-white" : "tw-text-ice-900");
19
+ setup(g) {
20
+ const e = g, _ = B("close-icon"), h = $(), a = C(), c = I(!0), u = s(() => M[p(e.severity)]), k = s(() => N[p(e.severity)]), x = s(() => e.variant === "filled" && ["warning", "success"].includes(e.severity) ? "text-ice-900" : e.variant === "filled" && ["info", "error"].includes(e.severity) ? "text-white" : `text-${k.value}`), n = s(() => e.variant === "filled" && ["info", "error"].includes(e.severity) ? "text-white" : "text-ice-900");
21
21
  return (d, v) => c.value ? S((o(), l("div", {
22
22
  key: 0,
23
- class: r(["stash-alert tw-relative tw-flex tw-items-center tw-border tw-border-solid tw-p-3 tw-leading-6", [
23
+ class: r(["stash-alert relative flex items-center border border-solid p-3 leading-6", [
24
24
  `stash-alert--${e.severity}`,
25
25
  `stash-alert--${e.variant}`,
26
26
  n.value,
27
27
  {
28
- "tw-my-6": e.variant === "outlined",
28
+ "my-6": e.variant === "outlined",
29
29
  // Todo - this makes ZERO sense. We should remove this altogether and let the consumer handle the margin.
30
- "tw-rounded": e.radius === "standard",
31
- "tw-border-red-500": e.severity === "error",
32
- "tw-border-orange-500": e.severity === "warning",
33
- "tw-border-blue-500": e.severity === "info",
34
- "tw-border-green-500": e.severity === "success",
35
- "tw-bg-red-500": e.severity === "error" && e.variant === "filled",
36
- "tw-bg-orange-500": e.severity === "warning" && e.variant === "filled",
37
- "tw-bg-blue-500": e.severity === "info" && e.variant === "filled",
38
- "tw-bg-green-500": e.severity === "success" && e.variant === "filled",
39
- "tw-bg-red-100": e.severity === "error" && e.variant === "outlined",
40
- "tw-bg-orange-100": e.severity === "warning" && e.variant === "outlined",
41
- "tw-bg-blue-100": e.severity === "info" && e.variant === "outlined",
42
- "tw-bg-green-100": e.severity === "success" && e.variant === "outlined"
30
+ rounded: e.radius === "standard",
31
+ "border-red-500": e.severity === "error",
32
+ "border-orange-500": e.severity === "warning",
33
+ "border-blue-500": e.severity === "info",
34
+ "border-green-500": e.severity === "success",
35
+ "bg-red-500": e.severity === "error" && e.variant === "filled",
36
+ "bg-orange-500": e.severity === "warning" && e.variant === "filled",
37
+ "bg-blue-500": e.severity === "info" && e.variant === "filled",
38
+ "bg-green-500": e.severity === "success" && e.variant === "filled",
39
+ "bg-red-100": e.severity === "error" && e.variant === "outlined",
40
+ "bg-orange-100": e.severity === "warning" && e.variant === "outlined",
41
+ "bg-blue-100": e.severity === "info" && e.variant === "outlined",
42
+ "bg-green-100": e.severity === "success" && e.variant === "outlined"
43
43
  }
44
44
  ]]),
45
45
  "data-test": "stash-alert"
46
46
  }, [
47
- w(p, {
48
- class: r(["stash-alert__icon", [t(a).iconInfo, k.value, `stash-alert__icon--${u.value}`]]),
47
+ f(b, {
48
+ class: r(["stash-alert__icon", [t(a).iconInfo, x.value, `stash-alert__icon--${u.value}`]]),
49
49
  name: u.value,
50
50
  title: `${e.severity} icon`,
51
51
  "data-test": "stash-alert|status-icon"
52
52
  }, null, 8, ["class", "name", "title"]),
53
- f("div", {
54
- class: r(["tw-flex tw-flex-1 tw-flex-wrap tw-px-2", {
55
- "tw-justify-center": e.centered,
56
- "tw-justify-between": !e.centered
53
+ m("div", {
54
+ class: r(["flex flex-1 flex-wrap px-2", {
55
+ "justify-center": e.centered,
56
+ "justify-between": !e.centered
57
57
  }])
58
58
  }, [
59
- f("p", z, [
60
- m(d.$slots, "default")
59
+ m("p", z, [
60
+ y(d.$slots, "default")
61
61
  ]),
62
- t(_).link ? (o(), l("div", {
62
+ t(h).link ? (o(), l("div", {
63
63
  key: 0,
64
- class: r(["stash-alert__link tw-cursor-pointer tw-underline hover:tw-no-underline", [t(a).link, n.value, { "tw-ml-2": e.centered }]]),
64
+ class: r(["stash-alert__link cursor-pointer underline hover:no-underline", [t(a).link, n.value, { "ml-2": e.centered }]]),
65
65
  "data-test": "stash-alert|link"
66
66
  }, [
67
- m(d.$slots, "link")
67
+ y(d.$slots, "link")
68
68
  ], 2)) : i("", !0)
69
69
  ], 2),
70
70
  e.permanent ? i("", !0) : (o(), l("button", {
@@ -74,8 +74,8 @@ const z = { class: "tw-m-0" }, A = /* @__PURE__ */ x({
74
74
  "data-test": "stash-alert|close",
75
75
  onClick: v[0] || (v[0] = (q) => c.value = !1)
76
76
  }, [
77
- w(p, {
78
- id: t(g),
77
+ f(b, {
78
+ id: t(_),
79
79
  name: "close",
80
80
  title: "Dismiss alert"
81
81
  }, null, 8, ["id"])
package/dist/Alert.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"Alert.js","sources":["../src/components/Alert/Alert.vue"],"sourcesContent":["<script setup lang=\"ts\">\n import capitalize from 'lodash-es/capitalize';\n import uniqueId from 'lodash-es/uniqueId';\n import { computed, ref, useCssModule, useSlots } from 'vue';\n\n import { StatusColor, StatusColors, StatusIcon, StatusIcons, StatusSeverity } from '../../../types/statusLevels';\n import vSticky from '../../directives/sticky/sticky';\n import Icon from '../Icon/Icon.vue';\n\n defineOptions({\n name: 'll-alert',\n });\n\n export interface AlertProps {\n /**\n * Determines if the alert is centered\n */\n centered?: boolean;\n\n /**\n * Determines if the alert is permanent (doesn't have a close button).\n */\n permanent?: boolean;\n\n /**\n * The type of border radius to use. Available types:\n *\n * - `none` - no border radius\n * - `standard` - 4px border radius\n */\n radius?: 'none' | 'standard';\n\n /**\n * The type of alert. Available types:\n *\n * - `info`\n * - `success`\n * - `warning`\n * - `error`\n */\n severity?: StatusSeverity;\n\n /**\n * Determines if the alert is sticky. By default, it's not sticky. The provided `number` value is a top offset of alert.\n */\n sticky?: number | null;\n\n /**\n * The variant of alert. Available variants:\n *\n * - `filled` - previously alert component\n * - `outlined` - previously banner component\n */\n variant?: 'outlined' | 'filled';\n }\n\n const props = withDefaults(defineProps<AlertProps>(), {\n centered: false,\n permanent: false,\n radius: 'standard',\n severity: 'info',\n sticky: null,\n variant: 'outlined',\n });\n\n const iconId = uniqueId('close-icon');\n const slots = useSlots();\n const classes = useCssModule();\n const show = ref(true);\n const icon = computed<StatusIcon>(() => StatusIcons[capitalize(props.severity)]);\n const color = computed<StatusColor>(() => StatusColors[capitalize(props.severity)]);\n\n const iconColor = computed<string>(() => {\n if (props.variant === 'filled' && ['warning', 'success'].includes(props.severity)) {\n return 'tw-text-ice-900';\n }\n\n if (props.variant === 'filled' && ['info', 'error'].includes(props.severity)) {\n return 'tw-text-white';\n }\n\n return `tw-text-${color.value}`;\n });\n\n const computedTextColor = computed<string>(() => {\n if (props.variant === 'filled' && ['info', 'error'].includes(props.severity)) {\n return 'tw-text-white';\n }\n\n return 'tw-text-ice-900';\n });\n</script>\n\n<template>\n <div\n v-if=\"show\"\n v-sticky=\"props.sticky\"\n class=\"stash-alert tw-relative tw-flex tw-items-center tw-border tw-border-solid tw-p-3 tw-leading-6\"\n :class=\"[\n `stash-alert--${props.severity}`,\n `stash-alert--${props.variant}`,\n computedTextColor,\n {\n 'tw-my-6': props.variant === 'outlined', // Todo - this makes ZERO sense. We should remove this altogether and let the consumer handle the margin.\n 'tw-rounded': props.radius === 'standard',\n 'tw-border-red-500': props.severity === 'error',\n 'tw-border-orange-500': props.severity === 'warning',\n 'tw-border-blue-500': props.severity === 'info',\n 'tw-border-green-500': props.severity === 'success',\n 'tw-bg-red-500': props.severity === 'error' && props.variant === 'filled',\n 'tw-bg-orange-500': props.severity === 'warning' && props.variant === 'filled',\n 'tw-bg-blue-500': props.severity === 'info' && props.variant === 'filled',\n 'tw-bg-green-500': props.severity === 'success' && props.variant === 'filled',\n 'tw-bg-red-100': props.severity === 'error' && props.variant === 'outlined',\n 'tw-bg-orange-100': props.severity === 'warning' && props.variant === 'outlined',\n 'tw-bg-blue-100': props.severity === 'info' && props.variant === 'outlined',\n 'tw-bg-green-100': props.severity === 'success' && props.variant === 'outlined',\n },\n ]\"\n data-test=\"stash-alert\"\n >\n <Icon\n class=\"stash-alert__icon\"\n :class=\"[classes.iconInfo, iconColor, `stash-alert__icon--${icon}`]\"\n :name=\"icon\"\n :title=\"`${props.severity} icon`\"\n data-test=\"stash-alert|status-icon\"\n />\n\n <!-- Alert text elements -->\n <div\n class=\"tw-flex tw-flex-1 tw-flex-wrap tw-px-2\"\n :class=\"{\n 'tw-justify-center': props.centered,\n 'tw-justify-between': !props.centered,\n }\"\n >\n <p class=\"tw-m-0\">\n <slot></slot>\n </p>\n\n <div\n v-if=\"slots.link\"\n class=\"stash-alert__link tw-cursor-pointer tw-underline hover:tw-no-underline\"\n :class=\"[classes.link, computedTextColor, { 'tw-ml-2': props.centered }]\"\n data-test=\"stash-alert|link\"\n >\n <slot name=\"link\"></slot>\n </div>\n </div>\n\n <button\n v-if=\"!props.permanent\"\n class=\"stash-alert__close\"\n :class=\"[classes.button, computedTextColor]\"\n type=\"button\"\n data-test=\"stash-alert|close\"\n @click=\"show = false\"\n >\n <Icon :id=\"iconId\" name=\"close\" title=\"Dismiss alert\" />\n </button>\n </div>\n</template>\n\n<style module>\n :global(.stash-alert__link) {\n a,\n button {\n color: var(--color-ice-900);\n cursor: pointer;\n text-decoration: underline;\n\n &:hover {\n text-decoration: none;\n }\n }\n }\n\n :global(.stash-alert--filled.stash-alert--error),\n :global(.stash-alert--filled.stash-alert--info) {\n :global(.stash-alert__link) a,\n :global(.stash-alert__link) button {\n color: theme('colors.white');\n }\n }\n</style>\n"],"names":["props","__props","iconId","uniqueId","slots","useSlots","classes","useCssModule","show","ref","icon","computed","StatusIcons","capitalize","color","StatusColors","iconColor","computedTextColor"],"mappings":";;;;;;;;;;;;;;;;;;;AAwDE,UAAMA,IAAQC,GASRC,IAASC,EAAS,YAAY,GAC9BC,IAAQC,EAAA,GACRC,IAAUC,EAAA,GACVC,IAAOC,EAAI,EAAI,GACfC,IAAOC,EAAqB,MAAMC,EAAYC,EAAWb,EAAM,QAAQ,CAAC,CAAC,GACzEc,IAAQH,EAAsB,MAAMI,EAAaF,EAAWb,EAAM,QAAQ,CAAC,CAAC,GAE5EgB,IAAYL,EAAiB,MAC7BX,EAAM,YAAY,YAAY,CAAC,WAAW,SAAS,EAAE,SAASA,EAAM,QAAQ,IACvE,oBAGLA,EAAM,YAAY,YAAY,CAAC,QAAQ,OAAO,EAAE,SAASA,EAAM,QAAQ,IAClE,kBAGF,WAAWc,EAAM,KAAK,EAC9B,GAEKG,IAAoBN,EAAiB,MACrCX,EAAM,YAAY,YAAY,CAAC,QAAQ,OAAO,EAAE,SAASA,EAAM,QAAQ,IAClE,kBAGF,iBACR;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
1
+ {"version":3,"file":"Alert.js","sources":["../src/components/Alert/Alert.vue"],"sourcesContent":["<script setup lang=\"ts\">\n import capitalize from 'lodash-es/capitalize';\n import uniqueId from 'lodash-es/uniqueId';\n import { computed, ref, useCssModule, useSlots } from 'vue';\n\n import { StatusColor, StatusColors, StatusIcon, StatusIcons, StatusSeverity } from '../../../types/statusLevels';\n import vSticky from '../../directives/sticky/sticky';\n import Icon from '../Icon/Icon.vue';\n\n defineOptions({\n name: 'll-alert',\n });\n\n export interface AlertProps {\n /**\n * Determines if the alert is centered\n */\n centered?: boolean;\n\n /**\n * Determines if the alert is permanent (doesn't have a close button).\n */\n permanent?: boolean;\n\n /**\n * The type of border radius to use. Available types:\n *\n * - `none` - no border radius\n * - `standard` - 4px border radius\n */\n radius?: 'none' | 'standard';\n\n /**\n * The type of alert. Available types:\n *\n * - `info`\n * - `success`\n * - `warning`\n * - `error`\n */\n severity?: StatusSeverity;\n\n /**\n * Determines if the alert is sticky. By default, it's not sticky. The provided `number` value is a top offset of alert.\n */\n sticky?: number | null;\n\n /**\n * The variant of alert. Available variants:\n *\n * - `filled` - previously alert component\n * - `outlined` - previously banner component\n */\n variant?: 'outlined' | 'filled';\n }\n\n const props = withDefaults(defineProps<AlertProps>(), {\n centered: false,\n permanent: false,\n radius: 'standard',\n severity: 'info',\n sticky: null,\n variant: 'outlined',\n });\n\n const iconId = uniqueId('close-icon');\n const slots = useSlots();\n const classes = useCssModule();\n const show = ref(true);\n const icon = computed<StatusIcon>(() => StatusIcons[capitalize(props.severity)]);\n const color = computed<StatusColor>(() => StatusColors[capitalize(props.severity)]);\n\n const iconColor = computed<string>(() => {\n if (props.variant === 'filled' && ['warning', 'success'].includes(props.severity)) {\n return 'text-ice-900';\n }\n\n if (props.variant === 'filled' && ['info', 'error'].includes(props.severity)) {\n return 'text-white';\n }\n\n return `text-${color.value}`;\n });\n\n const computedTextColor = computed<string>(() => {\n if (props.variant === 'filled' && ['info', 'error'].includes(props.severity)) {\n return 'text-white';\n }\n\n return 'text-ice-900';\n });\n</script>\n\n<template>\n <div\n v-if=\"show\"\n v-sticky=\"props.sticky\"\n class=\"stash-alert relative flex items-center border border-solid p-3 leading-6\"\n :class=\"[\n `stash-alert--${props.severity}`,\n `stash-alert--${props.variant}`,\n computedTextColor,\n {\n 'my-6': props.variant === 'outlined', // Todo - this makes ZERO sense. We should remove this altogether and let the consumer handle the margin.\n rounded: props.radius === 'standard',\n 'border-red-500': props.severity === 'error',\n 'border-orange-500': props.severity === 'warning',\n 'border-blue-500': props.severity === 'info',\n 'border-green-500': props.severity === 'success',\n 'bg-red-500': props.severity === 'error' && props.variant === 'filled',\n 'bg-orange-500': props.severity === 'warning' && props.variant === 'filled',\n 'bg-blue-500': props.severity === 'info' && props.variant === 'filled',\n 'bg-green-500': props.severity === 'success' && props.variant === 'filled',\n 'bg-red-100': props.severity === 'error' && props.variant === 'outlined',\n 'bg-orange-100': props.severity === 'warning' && props.variant === 'outlined',\n 'bg-blue-100': props.severity === 'info' && props.variant === 'outlined',\n 'bg-green-100': props.severity === 'success' && props.variant === 'outlined',\n },\n ]\"\n data-test=\"stash-alert\"\n >\n <Icon\n class=\"stash-alert__icon\"\n :class=\"[classes.iconInfo, iconColor, `stash-alert__icon--${icon}`]\"\n :name=\"icon\"\n :title=\"`${props.severity} icon`\"\n data-test=\"stash-alert|status-icon\"\n />\n\n <!-- Alert text elements -->\n <div\n class=\"flex flex-1 flex-wrap px-2\"\n :class=\"{\n 'justify-center': props.centered,\n 'justify-between': !props.centered,\n }\"\n >\n <p class=\"m-0\">\n <slot></slot>\n </p>\n\n <div\n v-if=\"slots.link\"\n class=\"stash-alert__link cursor-pointer underline hover:no-underline\"\n :class=\"[classes.link, computedTextColor, { 'ml-2': props.centered }]\"\n data-test=\"stash-alert|link\"\n >\n <slot name=\"link\"></slot>\n </div>\n </div>\n\n <button\n v-if=\"!props.permanent\"\n class=\"stash-alert__close\"\n :class=\"[classes.button, computedTextColor]\"\n type=\"button\"\n data-test=\"stash-alert|close\"\n @click=\"show = false\"\n >\n <Icon :id=\"iconId\" name=\"close\" title=\"Dismiss alert\" />\n </button>\n </div>\n</template>\n\n<style module>\n @layer utilities {\n :global(.stash-alert__link) {\n a,\n button {\n color: var(--color-ice-900);\n cursor: pointer;\n text-decoration: underline;\n\n &:hover {\n text-decoration: none;\n }\n }\n }\n\n :global(.stash-alert--filled.stash-alert--error),\n :global(.stash-alert--filled.stash-alert--info) {\n :global(.stash-alert__link) a,\n :global(.stash-alert__link) button {\n color: var(--color-white);\n }\n }\n }\n</style>\n"],"names":["props","__props","iconId","uniqueId","slots","useSlots","classes","useCssModule","show","ref","icon","computed","StatusIcons","capitalize","color","StatusColors","iconColor","computedTextColor"],"mappings":";;;;;;;;;;;;;;;;;;;AAwDE,UAAMA,IAAQC,GASRC,IAASC,EAAS,YAAY,GAC9BC,IAAQC,EAAA,GACRC,IAAUC,EAAA,GACVC,IAAOC,EAAI,EAAI,GACfC,IAAOC,EAAqB,MAAMC,EAAYC,EAAWb,EAAM,QAAQ,CAAC,CAAC,GACzEc,IAAQH,EAAsB,MAAMI,EAAaF,EAAWb,EAAM,QAAQ,CAAC,CAAC,GAE5EgB,IAAYL,EAAiB,MAC7BX,EAAM,YAAY,YAAY,CAAC,WAAW,SAAS,EAAE,SAASA,EAAM,QAAQ,IACvE,iBAGLA,EAAM,YAAY,YAAY,CAAC,QAAQ,OAAO,EAAE,SAASA,EAAM,QAAQ,IAClE,eAGF,QAAQc,EAAM,KAAK,EAC3B,GAEKG,IAAoBN,EAAiB,MACrCX,EAAM,YAAY,YAAY,CAAC,QAAQ,OAAO,EAAE,SAASA,EAAM,QAAQ,IAClE,eAGF,cACR;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}