@leaflink/stash 44.0.0-beta.6 → 44.0.0-beta.8

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 (164) hide show
  1. package/README.md +107 -39
  2. package/dist/ActionsDropdown.js +2 -2
  3. package/dist/ActionsDropdown.js.map +1 -1
  4. package/dist/AddressSelect.js +2 -2
  5. package/dist/AppNavigationItem.js +1 -1
  6. package/dist/AppSidebar.js +13 -13
  7. package/dist/AppSidebar.js.map +1 -1
  8. package/dist/Badge.vue.d.ts +1 -1
  9. package/dist/Button.js +1 -1
  10. package/dist/Button.js.map +1 -1
  11. package/dist/Button.vue_used_vue_type_style_index_0_lang.module-63d31dc0.js +17 -0
  12. package/dist/Button.vue_used_vue_type_style_index_0_lang.module-63d31dc0.js.map +1 -0
  13. package/dist/ButtonGroup.js +19 -19
  14. package/dist/ButtonGroup.js.map +1 -1
  15. package/dist/Carousel.js +258 -246
  16. package/dist/Carousel.js.map +1 -1
  17. package/dist/Checkbox.js +57 -46
  18. package/dist/Checkbox.js.map +1 -1
  19. package/dist/Checkbox.vue.d.ts +2 -0
  20. package/dist/Checkbox.vue_used_vue_type_style_index_0_lang.module-fa8d9c06.js +9 -0
  21. package/dist/Checkbox.vue_used_vue_type_style_index_0_lang.module-fa8d9c06.js.map +1 -0
  22. package/dist/ChevronToggle.js +1 -1
  23. package/dist/Copy.js +1 -1
  24. package/dist/CurrencyInput.js +2 -2
  25. package/dist/DataView.js +1 -1
  26. package/dist/DataViewFilters.js +4 -4
  27. package/dist/DataViewSortButton.js +47 -38
  28. package/dist/DataViewSortButton.js.map +1 -1
  29. package/dist/DataViewToolbar.js +2 -2
  30. package/dist/DatePicker.js +9 -9
  31. package/dist/DatePicker.js.map +1 -1
  32. package/dist/DescriptionListTerm.js +1 -1
  33. package/dist/DescriptionListTerm.js.map +1 -1
  34. package/dist/Dialog.js +33 -33
  35. package/dist/Dialog.js.map +1 -1
  36. package/dist/Divider.js +4 -4
  37. package/dist/Divider.js.map +1 -1
  38. package/dist/Expand.js +1 -1
  39. package/dist/{Expand.vue_vue_type_script_setup_true_lang-5fe03d51.js → Expand.vue_vue_type_script_setup_true_lang-1751f4a6.js} +14 -15
  40. package/dist/Expand.vue_vue_type_script_setup_true_lang-1751f4a6.js.map +1 -0
  41. package/dist/Field.js +2 -2
  42. package/dist/Field.vue.d.ts +1 -1
  43. package/dist/{Field.vue_vue_type_script_setup_true_lang-4483019d.js → Field.vue_vue_type_script_setup_true_lang-42ba3c5a.js} +2 -2
  44. package/dist/Field.vue_vue_type_script_setup_true_lang-42ba3c5a.js.map +1 -0
  45. package/dist/FileUpload.js +7 -7
  46. package/dist/FileUpload.js.map +1 -1
  47. package/dist/FilterChip.js +30 -30
  48. package/dist/FilterChip.js.map +1 -1
  49. package/dist/FilterDropdown.js +2 -2
  50. package/dist/FilterSelect.js +27 -27
  51. package/dist/FilterSelect.js.map +1 -1
  52. package/dist/Filters.js +39 -39
  53. package/dist/Filters.js.map +1 -1
  54. package/dist/HttpError.js +6 -6
  55. package/dist/IconLabel.js +6 -6
  56. package/dist/IconLabel.js.map +1 -1
  57. package/dist/IconLabel.vue.d.ts +1 -1
  58. package/dist/Illustration.js +10 -60
  59. package/dist/Illustration.js.map +1 -1
  60. package/dist/Illustration.vue_vue_type_script_setup_true_lang-d6a94e17.js +56 -0
  61. package/dist/Illustration.vue_vue_type_script_setup_true_lang-d6a94e17.js.map +1 -0
  62. package/dist/Image.js +67 -72
  63. package/dist/Image.js.map +1 -1
  64. package/dist/InlineEdit.js +2 -2
  65. package/dist/Input.js +53 -53
  66. package/dist/Input.js.map +1 -1
  67. package/dist/InputOptions.js +2 -2
  68. package/dist/Label.js +1 -1
  69. package/dist/Label.vue.d.ts +13 -2
  70. package/dist/{Label.vue_vue_type_script_setup_true_lang-2de35913.js → Label.vue_vue_type_script_setup_true_lang-4b02087f.js} +12 -11
  71. package/dist/Label.vue_vue_type_script_setup_true_lang-4b02087f.js.map +1 -0
  72. package/dist/ListItem.js +11 -11
  73. package/dist/ListItem.js.map +1 -1
  74. package/dist/ListItemCell.js +9 -9
  75. package/dist/ListItemCell.js.map +1 -1
  76. package/dist/ListView.js +55 -52
  77. package/dist/ListView.js.map +1 -1
  78. package/dist/Loading.js +17 -10
  79. package/dist/Loading.js.map +1 -1
  80. package/dist/Loading.vue_used_vue_type_style_index_0_lang.module-ef5a3bc6.js +8 -0
  81. package/dist/Loading.vue_used_vue_type_style_index_0_lang.module-ef5a3bc6.js.map +1 -0
  82. package/dist/MenuItem.js +20 -14
  83. package/dist/MenuItem.js.map +1 -1
  84. package/dist/Modal.js +2 -2
  85. package/dist/Modal.js.map +1 -1
  86. package/dist/ObfuscateText.js +30 -32
  87. package/dist/ObfuscateText.js.map +1 -1
  88. package/dist/ObfuscateText.vue.d.ts +1 -1
  89. package/dist/PageContent.js +9 -9
  90. package/dist/PageContent.js.map +1 -1
  91. package/dist/PageHeader.js +22 -22
  92. package/dist/PageHeader.js.map +1 -1
  93. package/dist/PageNavigation.js +3 -3
  94. package/dist/PageNavigation.js.map +1 -1
  95. package/dist/Paginate.js +1 -1
  96. package/dist/Paginate.js.map +1 -1
  97. package/dist/Paginate.vue_used_vue_type_style_index_0_lang.module-18343da7.js +11 -0
  98. package/dist/Paginate.vue_used_vue_type_style_index_0_lang.module-18343da7.js.map +1 -0
  99. package/dist/QuickAction.js +22 -19
  100. package/dist/QuickAction.js.map +1 -1
  101. package/dist/Radio.js +30 -15
  102. package/dist/Radio.js.map +1 -1
  103. package/dist/RadioGroup.js +135 -106
  104. package/dist/RadioGroup.js.map +1 -1
  105. package/dist/RadioNew.js +118 -91
  106. package/dist/RadioNew.js.map +1 -1
  107. package/dist/SearchBar.js +32 -32
  108. package/dist/SearchBar.js.map +1 -1
  109. package/dist/Select.js +7 -7
  110. package/dist/Select.js.map +1 -1
  111. package/dist/SelectStatus.js +2 -2
  112. package/dist/Switch.js +41 -34
  113. package/dist/Switch.js.map +1 -1
  114. package/dist/Tab.js +2 -2
  115. package/dist/{Tab.vue_vue_type_script_setup_true_lang-4a40f015.js → Tab.vue_vue_type_script_setup_true_lang-69d1b046.js} +2 -2
  116. package/dist/{Tab.vue_vue_type_script_setup_true_lang-4a40f015.js.map → Tab.vue_vue_type_script_setup_true_lang-69d1b046.js.map} +1 -1
  117. package/dist/Table.js +6 -6
  118. package/dist/Table.keys-cf93df19.js +27 -0
  119. package/dist/{Table.keys-1ebe4ecb.js.map → Table.keys-cf93df19.js.map} +1 -1
  120. package/dist/TableCell.js +5 -5
  121. package/dist/TableCell.js.map +1 -1
  122. package/dist/TableHeaderCell.js +32 -32
  123. package/dist/TableHeaderCell.js.map +1 -1
  124. package/dist/TableHeaderRow.js +10 -10
  125. package/dist/TableHeaderRow.js.map +1 -1
  126. package/dist/TableRow.js +42 -41
  127. package/dist/TableRow.js.map +1 -1
  128. package/dist/Tabs.js +2 -2
  129. package/dist/{Tabs.vue_used_vue_type_style_index_0_lang.module-0af1e1cf.js → Tabs.vue_used_vue_type_style_index_0_lang.module-2a131332.js} +25 -25
  130. package/dist/Tabs.vue_used_vue_type_style_index_0_lang.module-2a131332.js.map +1 -0
  131. package/dist/Textarea.js +49 -41
  132. package/dist/Textarea.js.map +1 -1
  133. package/dist/Toast.js +23 -23
  134. package/dist/Toast.js.map +1 -1
  135. package/dist/components.css +1 -1
  136. package/dist/constants.d.ts +26 -19
  137. package/dist/constants.js +41 -26
  138. package/dist/constants.js.map +1 -1
  139. package/dist/index.js +1 -1
  140. package/dist/tailwind-base.d.ts +16 -16
  141. package/dist/tailwind-base.js +16 -6
  142. package/dist/tailwind-base.js.map +1 -1
  143. package/package.json +2 -2
  144. package/styles/backwards-compat.css +41 -104
  145. package/styles/base.css +258 -112
  146. package/tailwind-base.ts +6 -1
  147. package/dist/Button.vue_used_vue_type_style_index_0_lang.module-b2ee90e6.js +0 -17
  148. package/dist/Button.vue_used_vue_type_style_index_0_lang.module-b2ee90e6.js.map +0 -1
  149. package/dist/Checkbox.vue_vue_type_style_index_0_scoped_dbd26d7f_lang-4ed993c7.js +0 -2
  150. package/dist/Checkbox.vue_vue_type_style_index_0_scoped_dbd26d7f_lang-4ed993c7.js.map +0 -1
  151. package/dist/Expand.vue_vue_type_script_setup_true_lang-5fe03d51.js.map +0 -1
  152. package/dist/Field.vue_vue_type_script_setup_true_lang-4483019d.js.map +0 -1
  153. package/dist/Label.vue_vue_type_script_setup_true_lang-2de35913.js.map +0 -1
  154. package/dist/Loading.vue_vue_type_style_index_0_scoped_bb8d5f15_lang-4ed993c7.js +0 -2
  155. package/dist/Loading.vue_vue_type_style_index_0_scoped_bb8d5f15_lang-4ed993c7.js.map +0 -1
  156. package/dist/Paginate.vue_used_vue_type_style_index_0_lang.module-1a2084f9.js +0 -11
  157. package/dist/Paginate.vue_used_vue_type_style_index_0_lang.module-1a2084f9.js.map +0 -1
  158. package/dist/Table.keys-1ebe4ecb.js +0 -27
  159. package/dist/Tabs.vue_used_vue_type_style_index_0_lang.module-0af1e1cf.js.map +0 -1
  160. package/styles/_base.scss +0 -493
  161. package/styles/elements/_links.scss +0 -32
  162. package/styles/elements/_lists.scss +0 -31
  163. package/styles/elements/_misc.scss +0 -16
  164. package/styles/main.scss +0 -38
package/README.md CHANGED
@@ -36,25 +36,100 @@ Stash is a collection of primitive, product-agnostic elements that help encapsul
36
36
 
37
37
  <!-- END doctoc generated TOC please keep comment here to allow auto update -->
38
38
 
39
- ## Getting Started
39
+ ## Quick Start
40
+
41
+ Stash requires Vue 3 and Tailwind CSS 3. To get started, install the package and its peer dependencies:
40
42
 
41
43
  ```sh
42
- npm install @leaflink/stash
44
+ npm install @leaflink/stash tailwindcss@3
43
45
  ```
44
46
 
45
- ```js
46
- // src/main.ts
47
+ Then, import the package and its styles in your app. Load the base and components styles from Stash, and then add your
48
+ app's styles after them.
49
+
50
+ ```ts filename="main.ts"
47
51
  import { createApp } from 'vue';
48
52
  import stash from '@leaflink/stash';
49
53
 
54
+ // stash styles
55
+ import '@leaflink/stash/styles/base.css';
56
+ import '@leaflink/stash/components.css';
57
+
58
+ // app styles
59
+ import './app.css';
60
+
50
61
  const app = createApp(App);
51
62
 
52
63
  app.use(stash);
53
64
  ```
54
65
 
66
+ Your app styles should be loaded after the Stash styles to ensure that they override the Stash styles. At minimum, your
67
+ app styles should include the following:
68
+
69
+ ```css filename="app.css"
70
+ @tailwind base;
71
+ @tailwind components;
72
+ @tailwind utilities;
73
+ ```
74
+
75
+ Configure Tailwind in your app by creating a `tailwind.config.ts` file. It should include the Stash files in the
76
+ `content` setting.
77
+
78
+ ```ts filename="tailwind.config.ts"
79
+ import stashPreset from '@leaflink/stash/tailwind-base';
80
+
81
+ /** @type {import('tailwindcss').Config} */
82
+ export default {
83
+ presets: [stashPreset],
84
+
85
+ content: ['./src/**/*.{vue,ts,js}', './node_modules/@leaflink/stash/dist/*.js'],
86
+ };
87
+ ```
88
+
89
+ See the [Tailwind](#tailwind) section for more details on how to configure it in your app.
90
+
91
+ > [!INFO]
92
+ > For apps still requiring deprecated css & utility classes, you can include the backwards compat styles from Stash:
93
+
94
+ ```ts filename="main.ts"
95
+ import '@leaflink/stash/styles/backwards-compat.css'; // Add this line before the base and components styles.
96
+ import '@leaflink/stash/styles/base.css';
97
+ import '@leaflink/stash/components.css';
98
+
99
+ import './app.css';
100
+ ```
101
+
102
+ Also, if you still need legacy Stash sass variables, functions, and mixins in your components, you can configure Vite to
103
+ import them:
104
+
105
+ ```ts filename="vite.config.ts"
106
+ export default defineConfig(({ mode }) => {
107
+ const env = loadEnv(mode, process.cwd(), '');
108
+
109
+ return {
110
+ css: {
111
+ preprocessorOptions: {
112
+ scss: {
113
+ additionalData: '@use "sass:map"; @import "@leaflink/stash/styles/core";',
114
+ },
115
+ },
116
+ },
117
+ };
118
+ });
119
+ ```
120
+
55
121
  ## Usage
56
122
 
57
- There are several ways to configure the framework to suit your specific needs.
123
+ `@leaflink/stash` is a Vue component library that implements [Leaflink's Stash Design System](https://stash.leaflink.com). So every one of LeafLink's colors, typography, shadows, etc. can be accessible via tailwind utility classes like `tw-text-blue-500 tw-text-sm`.
124
+
125
+ 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 components**, but it is required if you need to configure the framework to suit your specific needs.
126
+
127
+ There are several options to configure the framework to suit your specific needs, and they are all optional. Any options
128
+ you pass to the plugin will be merged with the default options & applied to the entire framework.
129
+
130
+ > [!WARNING]
131
+ > If you don't install the plugin in your app, you will need to manually setup [modals](https://stash.leaflink.com/guides/modals.html#installation), [toasts](https://stash.leaflink.com/guides/toasts.html#installation), and other features that
132
+ > require some setup that's normally done for you by the Stash plugin.
58
133
 
59
134
  ```ts
60
135
  interface StashPluginOptions {
@@ -130,11 +205,11 @@ app.use(stash, {
130
205
  locale,
131
206
  t: (key, value) => i18n.t(key, value)
132
207
  },
133
- googleMapsApiKey: import.meta.env.VITE_GOOGLE_MAPS_API
208
+ googleMapsApiKey: import.meta.env.VITE_GOOGLE_MAPS_API,
134
209
  });
135
210
  ```
136
211
 
137
- This example will load the core i18n options and google maps api key.
212
+ This example will load the core i18n options and Google Maps api key.
138
213
 
139
214
  ### npm scripts
140
215
 
@@ -151,40 +226,37 @@ A few commonly used commands are:
151
226
  - `npm run build` will build the application and prepare it for production.
152
227
  - `npm run build-ts` will build the application, perform a static analysis to find any type errors and prepare it for production.
153
228
 
154
- ## Styles
229
+ ## Legacy Styles
155
230
 
156
- `@leaflink/stash` exposes its core and components styles to be used downstream. It's required to import these styles in order for the components to have it's styles correctly applied.
157
-
158
- ```ts
159
- // main.ts
231
+ `@leaflink/stash` exposes a stylesheet for backwards compatibility with legacy stash utilities. This stylesheet includes
232
+ styles for components that have been deprecated or removed from the Stash Design System. It is not required for
233
+ greenfield projects.
160
234
 
235
+ ```ts filename="main.ts"
161
236
  /* legacy stash styles - not required for greenfield projects */
162
- import '@leaflink/stash/styles/main.scss'; // once backwards-compat.css is filled out, this can be removed
163
237
  import '@leaflink/stash/styles/backwards-compat.css';
164
238
 
165
239
  /* stash styles */
166
240
  import '@leaflink/stash/styles/base.css';
167
241
  import '@leaflink/stash/components.css';
168
242
 
169
- /* any other styles */
170
- @tailwind base;
171
- @tailwind components;
172
- @tailwind utilities;
243
+ import './app.css';
173
244
  ```
174
245
 
175
- > Tailwind CSS is required in order to run Stash. See below for details on [how to configure it](#tailwind) in your app.
176
-
177
- ### Tailwind
246
+ ## Tailwind
178
247
 
179
- `@leaflink/stash` uses [Tailwind](https://tailwindcss.com/) behind the scene to style its components. It's currently required to run this library downstream in order to generate styles for stash's tw classes used. This helps avoiding issues with duplications & css ordering.
248
+ `@leaflink/stash` uses [Tailwind](https://tailwindcss.com/) behind the scene to style its components. It's currently
249
+ required to **run this library downstream in order to avoid issues with css duplication & ordering**.
180
250
 
181
- In order to avoid class name clashes, `@leaflink/stash` prefixes Tailwind utility classes with `tw-`. So when needed to use a tailwind class, just use like this `tw-flex md:tw-text-blue`.
251
+ In order to avoid class name clashes with legacy utilities, `@leaflink/stash` prefixes Tailwind utility classes with
252
+ `tw-`. This may change in the future when all LeafLink apps no longer need deprecated styles. For now, when needing to
253
+ use a tailwind class, just add the `tw` prefix like so: `tw-flex md:tw-text-blue`.
182
254
 
183
- ```js
184
- import Button from "@leaflink/stash/Button.vue"
185
- import IconLabel from "@leaflink/stash/IconLabel.vue"
255
+ ```jsx
256
+ import Button from '@leaflink/stash/Button.vue';
257
+ import IconLabel from '@leaflink/stash/IconLabel.vue';
186
258
 
187
- <Button icon-label class="tw-text-blue-500 tw-ml-3">
259
+ <Button icon-label class="tw-hidden md:tw-inline tw-ml-3">
188
260
  <IconLabel icon="user-add" title="Add Recipient" size="dense" stacked>Add Recipient</IconLabel>
189
261
  </Button>
190
262
  ```
@@ -206,21 +278,17 @@ export default {
206
278
  };
207
279
  ```
208
280
 
209
- ### Design System
210
-
211
- `@leaflink/stash` is a Vue component library that implements [Leaflink's Stash Design System](https://leaflink.atlassian.net/wiki/spaces/EN/pages/2394063290/Stash+Design+System). So every one of LeafLink's colors, typography, shadows, etc. can be accessible via tailwind utility classes like `tw-text-blue-500 tw-text-sm`.
212
-
213
281
  ## Resources
214
282
 
215
- * **index.js**: This is the "install" entry point, for use with `app.use(...)`.
216
- * **components**: All components
217
- * **composables**: Similar to mixins or React's "Hooks", but for a Vue component
218
- * **constants**: LeafLink global constants
219
- * **directives**: [Vue directives](https://vuejs.org/guide/reusability/custom-directives#custom-directives)
220
- * **plugins**: [Vue plugins](https://vuejs.org/guide/reusability/plugins.html#plugins)
221
- * **styles**: SCSS, CSS, style utils, etc.
222
- * **types**: TypeScript type declarations
223
- * **utils**: Includes various helpers for internal and external use
283
+ * **index.js**: This is the "install" entry point, for use with `app.use(...)`.
284
+ * **components**: All components
285
+ * **composables**: Similar to mixins or React's "Hooks", but for a Vue component
286
+ * **constants**: LeafLink global constants
287
+ * **directives**: [Vue directives](https://vuejs.org/guide/reusability/custom-directives#custom-directives)
288
+ * **plugins**: [Vue plugins](https://vuejs.org/guide/reusability/plugins.html#plugins)
289
+ * **styles**: SCSS, CSS, style utils, etc.
290
+ * **types**: TypeScript type declarations
291
+ * **utils**: Includes various helpers for internal and external use
224
292
 
225
293
  ## Core files & Entry Points
226
294
 
@@ -5,7 +5,7 @@ import g from "./Dropdown.js";
5
5
  import B from "./Icon.js";
6
6
  import { _ as D } from "./_plugin-vue_export-helper-dad06003.js";
7
7
  import "lodash-es/get";
8
- import "./Button.vue_used_vue_type_style_index_0_lang.module-b2ee90e6.js";
8
+ import "./Button.vue_used_vue_type_style_index_0_lang.module-63d31dc0.js";
9
9
  import "./constants.js";
10
10
  import "./clickoutside.js";
11
11
  import "./utils/calculateElementOverflow.js";
@@ -61,7 +61,7 @@ const y = /* @__PURE__ */ c({
61
61
  }
62
62
  ]), 1032, ["align", "content-class", "class"]));
63
63
  }
64
- }), k = "_actionButton_184sp_2", S = "_disabled_184sp_12", M = "_dropdownContent_184sp_18", T = "_actionsDropdown_184sp_33", h = {
64
+ }), k = "_actionButton_144dr_2", S = "_disabled_144dr_12", M = "_dropdownContent_144dr_18", T = "_actionsDropdown_144dr_33", h = {
65
65
  actionButton: k,
66
66
  disabled: S,
67
67
  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=\"\n button\n tw-flex tw-w-full tw-items-center tw-justify-between tw-border tw-border-blue-500 tw-text-blue-500\n \"\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":["classes","useCssModule"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;iBAuCQA,IAAUC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
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=\"\n button\n tw-flex tw-w-full tw-items-center tw-justify-between tw-border tw-border-blue-500 tw-text-blue-500\n \"\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":["classes","useCssModule"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;iBAuCQA,IAAUC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
@@ -24,8 +24,8 @@ import "./Icon.js";
24
24
  import "./index-79ce320f.js";
25
25
  import "./Icon.vue_used_vue_type_style_index_0_lang.module-eb359559.js";
26
26
  import "./_plugin-vue_export-helper-dad06003.js";
27
- import "./Field.vue_vue_type_script_setup_true_lang-4483019d.js";
28
- import "./Label.vue_vue_type_script_setup_true_lang-2de35913.js";
27
+ import "./Field.vue_vue_type_script_setup_true_lang-42ba3c5a.js";
28
+ import "./Label.vue_vue_type_script_setup_true_lang-4b02087f.js";
29
29
  import "./locale.js";
30
30
  const _ = "address-select-", ve = /* @__PURE__ */ M({
31
31
  __name: "AddressSelect",
@@ -1,5 +1,5 @@
1
1
  import { defineComponent as _, ref as v, useSlots as y, resolveComponent as $, openBlock as a, createElementBlock as r, unref as b, createBlock as h, normalizeClass as n, withCtx as m, createElementVNode as s, createVNode as o, toDisplayString as d, renderSlot as p } from "vue";
2
- import { _ as k } from "./Expand.vue_vue_type_script_setup_true_lang-5fe03d51.js";
2
+ import { _ as k } from "./Expand.vue_vue_type_script_setup_true_lang-1751f4a6.js";
3
3
  import i from "./Icon.js";
4
4
  import { _ as x } from "./_plugin-vue_export-helper-dad06003.js";
5
5
  import "lodash-es/uniqueId";
@@ -1,9 +1,9 @@
1
- import { defineComponent as k, useSlots as x, computed as m, ref as C, watchEffect as E, openBlock as a, createElementBlock as o, normalizeClass as B, createVNode as i, Transition as w, withCtx as b, withDirectives as g, withModifiers as O, vShow as y, createElementVNode as v, unref as d, renderSlot as n, createCommentVNode as u, pushScopeId as I, popScopeId as V } from "vue";
1
+ import { defineComponent as k, useSlots as x, computed as m, ref as C, watchEffect as E, openBlock as a, createElementBlock as o, normalizeClass as B, createVNode as i, Transition as w, withCtx as b, withDirectives as g, withModifiers as O, vShow as y, createElementVNode as v, unref as c, renderSlot as n, createCommentVNode as u, pushScopeId as I, popScopeId as V } from "vue";
2
2
  import $ from "./useMediaQuery.js";
3
3
  import z from "./Backdrop.js";
4
4
  import A from "./Divider.js";
5
5
  import { _ as N } from "./_plugin-vue_export-helper-dad06003.js";
6
- const j = (t) => (I("data-v-7ac3c3ee"), t = t(), V(), t), D = {
6
+ const j = (t) => (I("data-v-78582cf0"), t = t(), V(), t), D = {
7
7
  class: "stash-app-sidebar__aside tw-fixed tw-flex tw-h-screen tw-flex-col tw-bg-purple-500",
8
8
  "data-test": "stash-app-sidebar__aside"
9
9
  }, M = {
@@ -25,18 +25,18 @@ const j = (t) => (I("data-v-7ac3c3ee"), t = t(), V(), t), D = {
25
25
  },
26
26
  emits: ["dismiss", "update:is-open"],
27
27
  setup(t, { emit: _ }) {
28
- const h = t, r = x(), l = $("screen and (min-width: 1321px)"), e = m(() => h.isOpen && !l.value), p = C({ height: "", overflow: "" }), f = m(() => h.isOpen || l.value);
28
+ const f = t, r = x(), l = $("screen and (min-width: 1321px)"), e = m(() => f.isOpen && !l.value), p = C({ height: "", overflow: "" }), h = m(() => f.isOpen || l.value);
29
29
  function S() {
30
30
  _("dismiss"), _("update:is-open", !1);
31
31
  }
32
- function c() {
32
+ function d() {
33
33
  return document.scrollingElement || document.body;
34
34
  }
35
35
  return E(() => {
36
36
  l.value || (e.value && Object.assign(p.value, {
37
- overflow: c().style.overflow,
38
- height: c().style.height
39
- }), Object.assign(c().style, {
37
+ overflow: d().style.overflow,
38
+ height: d().style.height
39
+ }), Object.assign(d().style, {
40
40
  overflow: e.value ? "hidden" : p.value.overflow,
41
41
  // Prevents page from scrolling when AppSidebar is open
42
42
  height: e.value ? "100%" : p.value.height
@@ -45,7 +45,7 @@ const j = (t) => (I("data-v-7ac3c3ee"), t = t(), V(), t), D = {
45
45
  }), (s, F) => (a(), o("div", {
46
46
  id: "stash-app-sidebar",
47
47
  class: B(["stash-app-sidebar tw-relative", {
48
- "stash-app-sidebar--is-open": f.value,
48
+ "stash-app-sidebar--is-open": h.value,
49
49
  "tw-z-modal": e.value,
50
50
  "tw-z-[301]": !e.value
51
51
  }]),
@@ -66,13 +66,13 @@ const j = (t) => (I("data-v-7ac3c3ee"), t = t(), V(), t), D = {
66
66
  default: b(() => [
67
67
  g(v("aside", D, [
68
68
  i(A, { class: "stash-app-sidebar__divider" }),
69
- d(r)["app-context"] ? (a(), o("div", M, [
69
+ c(r)["app-context"] ? (a(), o("div", M, [
70
70
  n(s.$slots, "app-context", {}, void 0, !0)
71
71
  ])) : u("", !0),
72
- d(r)["company-context"] ? (a(), o("div", P, [
72
+ c(r)["company-context"] ? (a(), o("div", P, [
73
73
  n(s.$slots, "company-context", {}, void 0, !0)
74
74
  ])) : u("", !0),
75
- d(r).navigation ? (a(), o("nav", L, [
75
+ c(r).navigation ? (a(), o("nav", L, [
76
76
  v("ul", Q, [
77
77
  n(s.$slots, "navigation", {}, void 0, !0)
78
78
  ])
@@ -80,7 +80,7 @@ const j = (t) => (I("data-v-7ac3c3ee"), t = t(), V(), t), D = {
80
80
  T,
81
81
  n(s.$slots, "footer", {}, void 0, !0)
82
82
  ], 512), [
83
- [y, f.value]
83
+ [y, h.value]
84
84
  ])
85
85
  ]),
86
86
  _: 3
@@ -88,7 +88,7 @@ const j = (t) => (I("data-v-7ac3c3ee"), t = t(), V(), t), D = {
88
88
  ], 2));
89
89
  }
90
90
  });
91
- const U = /* @__PURE__ */ N(q, [["__scopeId", "data-v-7ac3c3ee"]]);
91
+ const U = /* @__PURE__ */ N(q, [["__scopeId", "data-v-78582cf0"]]);
92
92
  export {
93
93
  U as default
94
94
  };
@@ -1 +1 @@
1
- {"version":3,"file":"AppSidebar.js","sources":["../src/components/AppSidebar/AppSidebar.vue"],"sourcesContent":["<script setup lang=\"ts\">\n import { computed, ref, useSlots, watchEffect } from 'vue';\n\n import useMediaQuery from '../../composables/useMediaQuery/useMediaQuery';\n import Backdrop from '../Backdrop/Backdrop.vue';\n import Divider from '../Divider/Divider.vue';\n\n export interface AppSidebarProps {\n /**\n * Controls wether the sidebar is opened or not\n */\n isOpen?: boolean;\n }\n\n const props = withDefaults(defineProps<AppSidebarProps>(), {\n isOpen: false,\n });\n\n const slots = useSlots();\n\n const emit =\n defineEmits<{\n /**\n * @deprecated Use the `update:is-open` event instead\n */\n (e: 'dismiss'): void;\n (e: 'update:is-open', isOpen: boolean): void;\n }>();\n\n const isExtraLargeScreen = useMediaQuery('screen and (min-width: 1321px)');\n const isBackdropVisible = computed(() => props.isOpen && !isExtraLargeScreen.value);\n const initialPageScrollingElementStyle = ref({ height: '', overflow: '' });\n const isSidebarOpen = computed(() => props.isOpen || isExtraLargeScreen.value);\n\n function onBackdropClick() {\n emit('dismiss');\n emit('update:is-open', false);\n }\n\n function getPageScrollingElement() {\n return (document.scrollingElement || document.body) as HTMLElement;\n }\n\n watchEffect(() => {\n if (isExtraLargeScreen.value) {\n return;\n }\n\n if (isBackdropVisible.value) {\n Object.assign(initialPageScrollingElementStyle.value, {\n overflow: getPageScrollingElement().style.overflow,\n height: getPageScrollingElement().style.height,\n });\n }\n\n Object.assign(getPageScrollingElement().style, {\n overflow: isBackdropVisible.value ? 'hidden' : initialPageScrollingElementStyle.value.overflow, // Prevents page from scrolling when AppSidebar is open\n height: isBackdropVisible.value ? '100%' : initialPageScrollingElementStyle.value.height, // Ensures the backdrop covers the entire page when AppSidebar is open\n });\n });\n</script>\n\n<template>\n <div\n id=\"stash-app-sidebar\"\n class=\"stash-app-sidebar tw-relative\"\n :class=\"{\n 'stash-app-sidebar--is-open': isSidebarOpen,\n 'tw-z-modal': isBackdropVisible,\n 'tw-z-[301]': !isBackdropVisible,\n }\"\n data-test=\"stash-app-sidebar\"\n >\n <Transition name=\"backdrop\">\n <Backdrop v-show=\"isBackdropVisible\" class=\"stash-app-sidebar__backdrop\" @click.stop=\"onBackdropClick\" />\n </Transition>\n <Transition name=\"aside\">\n <aside\n v-show=\"isSidebarOpen\"\n class=\"stash-app-sidebar__aside tw-fixed tw-flex tw-h-screen tw-flex-col tw-bg-purple-500\"\n data-test=\"stash-app-sidebar__aside\"\n >\n <Divider class=\"stash-app-sidebar__divider\" />\n <div v-if=\"slots['app-context']\" class=\"tw-px-3 tw-pt-6\">\n <!-- @slot App Context component slot, ideally for rendering the context switcher -->\n <slot name=\"app-context\"></slot>\n </div>\n <div v-if=\"slots['company-context']\" class=\"tw-px-3 tw-pt-6\">\n <!-- @slot Company Context component slot, ideally for rendering the company picker -->\n <slot name=\"company-context\"></slot>\n </div>\n <nav v-if=\"slots['navigation']\" class=\"tw-pt-6\">\n <ul role=\"menubar\" aria-orientation=\"vertical\">\n <!-- @slot Navigation component slot, for rendering navigation items -->\n <slot name=\"navigation\"></slot>\n </ul>\n </nav>\n <div class=\"tw-flex-1\"></div>\n <!-- @slot Footer component slot, for rendering version/environment notes -->\n <slot name=\"footer\"></slot>\n </aside>\n </Transition>\n </div>\n</template>\n\n<style scoped>\n .stash-app-sidebar__aside {\n padding-top: calc(var(--top-header-height) - 1px); /* -1px to compensate for the border height */\n width: var(--sidebar-width);\n }\n\n .stash-app-sidebar__divider::before,\n .stash-app-sidebar__divider::after {\n border-bottom: 1px solid rgb(255 255 255 / 12%);\n }\n\n .backdrop-enter-active,\n .backdrop-leave-active {\n transition: opacity 200ms ease-in-out;\n }\n\n .backdrop-enter-from,\n .backdrop-leave-to {\n opacity: 0;\n }\n\n .aside-enter-active,\n .aside-leave-active {\n transition: opacity 200ms ease-in-out, transform 200ms ease-in-out;\n }\n\n .aside-enter-from,\n .aside-leave-to {\n opacity: 0;\n transform: translateX(-20%);\n }\n</style>\n"],"names":["slots","useSlots","isExtraLargeScreen","useMediaQuery","isBackdropVisible","computed","props","initialPageScrollingElementStyle","ref","isSidebarOpen","onBackdropClick","emit","getPageScrollingElement","watchEffect"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;iBAkBQA,IAAQC,KAWRC,IAAqBC,EAAc,gCAAgC,GACnEC,IAAoBC,EAAS,MAAMC,EAAM,UAAU,CAACJ,EAAmB,KAAK,GAC5EK,IAAmCC,EAAI,EAAE,QAAQ,IAAI,UAAU,IAAI,GACnEC,IAAgBJ,EAAS,MAAMC,EAAM,UAAUJ,EAAmB,KAAK;AAE7E,aAASQ,IAAkB;AACzB,MAAAC,EAAK,SAAS,GACdA,EAAK,kBAAkB,EAAK;AAAA,IAC9B;AAEA,aAASC,IAA0B;AACzB,aAAA,SAAS,oBAAoB,SAAS;AAAA,IAChD;AAEA,WAAAC,EAAY,MAAM;AAChB,MAAIX,EAAmB,UAInBE,EAAkB,SACb,OAAA,OAAOG,EAAiC,OAAO;AAAA,QACpD,UAAUK,IAA0B,MAAM;AAAA,QAC1C,QAAQA,IAA0B,MAAM;AAAA,MAAA,CACzC,GAGI,OAAA,OAAOA,EAAwB,EAAE,OAAO;AAAA,QAC7C,UAAUR,EAAkB,QAAQ,WAAWG,EAAiC,MAAM;AAAA;AAAA,QACtF,QAAQH,EAAkB,QAAQ,SAASG,EAAiC,MAAM;AAAA;AAAA,MAAA,CACnF;AAAA,IAAA,CACF;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
1
+ {"version":3,"file":"AppSidebar.js","sources":["../src/components/AppSidebar/AppSidebar.vue"],"sourcesContent":["<script setup lang=\"ts\">\n import { computed, ref, useSlots, watchEffect } from 'vue';\n\n import useMediaQuery from '../../composables/useMediaQuery/useMediaQuery';\n import Backdrop from '../Backdrop/Backdrop.vue';\n import Divider from '../Divider/Divider.vue';\n\n export interface AppSidebarProps {\n /**\n * Controls wether the sidebar is opened or not\n */\n isOpen?: boolean;\n }\n\n const props = withDefaults(defineProps<AppSidebarProps>(), {\n isOpen: false,\n });\n\n const slots = useSlots();\n\n const emit =\n defineEmits<{\n /**\n * @deprecated Use the `update:is-open` event instead\n */\n (e: 'dismiss'): void;\n (e: 'update:is-open', isOpen: boolean): void;\n }>();\n\n const isExtraLargeScreen = useMediaQuery('screen and (min-width: 1321px)');\n const isBackdropVisible = computed(() => props.isOpen && !isExtraLargeScreen.value);\n const initialPageScrollingElementStyle = ref({ height: '', overflow: '' });\n const isSidebarOpen = computed(() => props.isOpen || isExtraLargeScreen.value);\n\n function onBackdropClick() {\n emit('dismiss');\n emit('update:is-open', false);\n }\n\n function getPageScrollingElement() {\n return (document.scrollingElement || document.body) as HTMLElement;\n }\n\n watchEffect(() => {\n if (isExtraLargeScreen.value) {\n return;\n }\n\n if (isBackdropVisible.value) {\n Object.assign(initialPageScrollingElementStyle.value, {\n overflow: getPageScrollingElement().style.overflow,\n height: getPageScrollingElement().style.height,\n });\n }\n\n Object.assign(getPageScrollingElement().style, {\n overflow: isBackdropVisible.value ? 'hidden' : initialPageScrollingElementStyle.value.overflow, // Prevents page from scrolling when AppSidebar is open\n height: isBackdropVisible.value ? '100%' : initialPageScrollingElementStyle.value.height, // Ensures the backdrop covers the entire page when AppSidebar is open\n });\n });\n</script>\n\n<template>\n <div\n id=\"stash-app-sidebar\"\n class=\"stash-app-sidebar tw-relative\"\n :class=\"{\n 'stash-app-sidebar--is-open': isSidebarOpen,\n 'tw-z-modal': isBackdropVisible,\n 'tw-z-[301]': !isBackdropVisible,\n }\"\n data-test=\"stash-app-sidebar\"\n >\n <Transition name=\"backdrop\">\n <Backdrop v-show=\"isBackdropVisible\" class=\"stash-app-sidebar__backdrop\" @click.stop=\"onBackdropClick\" />\n </Transition>\n <Transition name=\"aside\">\n <aside\n v-show=\"isSidebarOpen\"\n class=\"stash-app-sidebar__aside tw-fixed tw-flex tw-h-screen tw-flex-col tw-bg-purple-500\"\n data-test=\"stash-app-sidebar__aside\"\n >\n <Divider class=\"stash-app-sidebar__divider\" />\n <div v-if=\"slots['app-context']\" class=\"tw-px-3 tw-pt-6\">\n <!-- @slot App Context component slot, ideally for rendering the context switcher -->\n <slot name=\"app-context\"></slot>\n </div>\n <div v-if=\"slots['company-context']\" class=\"tw-px-3 tw-pt-6\">\n <!-- @slot Company Context component slot, ideally for rendering the company picker -->\n <slot name=\"company-context\"></slot>\n </div>\n <nav v-if=\"slots['navigation']\" class=\"tw-pt-6\">\n <ul role=\"menubar\" aria-orientation=\"vertical\">\n <!-- @slot Navigation component slot, for rendering navigation items -->\n <slot name=\"navigation\"></slot>\n </ul>\n </nav>\n <div class=\"tw-flex-1\"></div>\n <!-- @slot Footer component slot, for rendering version/environment notes -->\n <slot name=\"footer\"></slot>\n </aside>\n </Transition>\n </div>\n</template>\n\n<style scoped>\n .stash-app-sidebar__aside {\n padding-top: calc(theme('height.topbar') - 1px); /* -1px to compensate for the border height */\n width: theme('width.sidebar');\n }\n\n .stash-app-sidebar__divider::before,\n .stash-app-sidebar__divider::after {\n border-bottom: 1px solid rgb(255 255 255 / 12%);\n }\n\n .backdrop-enter-active,\n .backdrop-leave-active {\n transition: opacity 200ms ease-in-out;\n }\n\n .backdrop-enter-from,\n .backdrop-leave-to {\n opacity: 0;\n }\n\n .aside-enter-active,\n .aside-leave-active {\n transition: opacity 200ms ease-in-out, transform 200ms ease-in-out;\n }\n\n .aside-enter-from,\n .aside-leave-to {\n opacity: 0;\n transform: translateX(-20%);\n }\n</style>\n"],"names":["slots","useSlots","isExtraLargeScreen","useMediaQuery","isBackdropVisible","computed","props","initialPageScrollingElementStyle","ref","isSidebarOpen","onBackdropClick","emit","getPageScrollingElement","watchEffect"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;iBAkBQA,IAAQC,KAWRC,IAAqBC,EAAc,gCAAgC,GACnEC,IAAoBC,EAAS,MAAMC,EAAM,UAAU,CAACJ,EAAmB,KAAK,GAC5EK,IAAmCC,EAAI,EAAE,QAAQ,IAAI,UAAU,IAAI,GACnEC,IAAgBJ,EAAS,MAAMC,EAAM,UAAUJ,EAAmB,KAAK;AAE7E,aAASQ,IAAkB;AACzB,MAAAC,EAAK,SAAS,GACdA,EAAK,kBAAkB,EAAK;AAAA,IAC9B;AAEA,aAASC,IAA0B;AACzB,aAAA,SAAS,oBAAoB,SAAS;AAAA,IAChD;AAEA,WAAAC,EAAY,MAAM;AAChB,MAAIX,EAAmB,UAInBE,EAAkB,SACb,OAAA,OAAOG,EAAiC,OAAO;AAAA,QACpD,UAAUK,IAA0B,MAAM;AAAA,QAC1C,QAAQA,IAA0B,MAAM;AAAA,MAAA,CACzC,GAGI,OAAA,OAAOA,EAAwB,EAAE,OAAO;AAAA,QAC7C,UAAUR,EAAkB,QAAQ,WAAWG,EAAiC,MAAM;AAAA;AAAA,QACtF,QAAQH,EAAkB,QAAQ,SAASG,EAAiC,MAAM;AAAA;AAAA,MAAA,CACnF;AAAA,IAAA,CACF;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
@@ -108,12 +108,12 @@ declare const _default: __VLS_WithTemplateSlots<DefineComponent<__VLS_WithDefaul
108
108
  }>>>, {
109
109
  color: "blue" | "red";
110
110
  animate: boolean;
111
+ max: string | number;
111
112
  offset: {
112
113
  top?: number | undefined;
113
114
  right?: number | undefined;
114
115
  };
115
116
  content: string | number;
116
- max: string | number;
117
117
  position: "inline" | "top-right";
118
118
  variant: "standard" | "dot";
119
119
  isDisabled: boolean;
package/dist/Button.js CHANGED
@@ -1,5 +1,5 @@
1
1
  import { defineComponent as f, computed as c, openBlock as a, createElementBlock as n, normalizeClass as r, renderSlot as s } from "vue";
2
- import { s as i } from "./Button.vue_used_vue_type_style_index_0_lang.module-b2ee90e6.js";
2
+ import { s as i } from "./Button.vue_used_vue_type_style_index_0_lang.module-63d31dc0.js";
3
3
  import { _ as d } from "./_plugin-vue_export-helper-dad06003.js";
4
4
  const y = ["href"];
5
5
  var u = /* @__PURE__ */ ((t) => (t.Primary = "primary", t.Secondary = "secondary", t.Tertiary = "tertiary", t.Icon = "icon", t.IconLabel = "iconLabel", t.Inline = "inline", t))(u || {});
@@ -1 +1 @@
1
- {"version":3,"file":"Button.js","sources":["../src/components/Button/Button.vue"],"sourcesContent":["<script lang=\"ts\" setup>\n import { computed } from 'vue';\n\n defineOptions({\n name: 'll-button',\n });\n\n export interface ButtonProps {\n /**\n * Renders the secondary variant\n */\n secondary?: boolean;\n /**\n * Renders the button as a container for an Icon\n */\n icon?: boolean;\n /**\n * Renders the button as a container for an IconLabel\n */\n iconLabel?: boolean;\n /**\n * Renders the tertiary variant\n */\n tertiary?: boolean;\n /**\n * Renders the component inline\n */\n inline?: boolean;\n /**\n * Renders a color variant\n */\n color?: 'blue' | 'red';\n /**\n * Button link. If defined, the button will render as an `<a />` tag.\n */\n href?: string;\n }\n\n const props = withDefaults(defineProps<ButtonProps>(), {\n secondary: false,\n icon: false,\n iconLabel: false,\n tertiary: false,\n inline: false,\n color: undefined,\n href: '',\n });\n\n enum ButtonTypes {\n Primary = 'primary',\n Secondary = 'secondary',\n Tertiary = 'tertiary',\n Icon = 'icon',\n IconLabel = 'iconLabel',\n Inline = 'inline',\n }\n\n type ButtonType = `${ButtonTypes}`;\n\n const buttonType = computed<ButtonType>(() => {\n for (const type of Object.values(ButtonTypes)) {\n if (props[type]) {\n return type;\n }\n }\n\n return ButtonTypes.Primary;\n });\n</script>\n\n<template>\n <a\n v-if=\"props.href\"\n data-test=\"ll-button\"\n class=\"stash-button\"\n :class=\"[$style.button, $style[`button--${buttonType}`], { [$style[`button--${props.color}`]]: props.color }]\"\n :href=\"props.href\"\n >\n <!-- @slot default -->\n <slot></slot>\n </a>\n <button\n v-else\n data-test=\"ll-button\"\n class=\"stash-button\"\n :class=\"[$style.button, $style[`button--${buttonType}`], { [$style[`button--${props.color}`]]: props.color }]\"\n >\n <!-- @slot default -->\n <slot></slot>\n </button>\n</template>\n\n<style module>\n .button {\n border-radius: var(--border-radius);\n border-width: 1px;\n display: inline-block;\n font-size: 0.875rem;\n font-weight: var(--font-weight-semibold);\n line-height: 2.125rem;\n margin: 0;\n min-width: 144px;\n padding: 0 var(--ll-space-2);\n text-align: center;\n text-decoration: none;\n vertical-align: middle;\n white-space: nowrap;\n }\n\n @media screen(lg) {\n /* `focus` and `hover` should be added only for large screens */\n .button:focus {\n box-shadow: 0 0 0 3px rgb(0 123 255 / 14%);\n outline: none;\n }\n\n .button:hover {\n text-decoration: none;\n }\n }\n\n .button[disabled] {\n cursor: default;\n pointer-events: none;\n }\n\n /* Solid treatment */\n .button--solid {\n background-color: var(--button-color);\n border-color: transparent;\n color: var(--text-color);\n }\n\n @media screen(lg) {\n /* `hover` should be added only for large screens */\n .button--solid:hover {\n background-color: var(--button-hover-color);\n }\n }\n\n .button--solid:active {\n background-color: var(--button-hover-color);\n }\n\n .button--solid[disabled] {\n --button-color: var(--color-ice-500) !important;\n }\n\n /* Ghost treatment */\n .button--ghost {\n background-color: rgb(0 0 0 / 0%);\n border-color: var(--button-color);\n color: var(--text-color);\n }\n\n @media screen(lg) {\n /* `hover` should be added only for large screens */\n .button--ghost:hover {\n background-color: var(--button-hover-color);\n }\n }\n\n .button--ghost:active {\n background-color: var(--button-hover-color);\n }\n\n .button--ghost[disabled] {\n --button-color: var(--color-ice-500) !important;\n --text-color: var(--color-ice-500) !important;\n }\n\n /* Types */\n .button--primary {\n composes: button--solid;\n --button-color: var(--color-blue-500);\n --button-hover-color: var(--color-blue-hover);\n --text-color: var(--color-white);\n }\n\n .button--secondary {\n composes: button--ghost;\n --button-color: var(--color-ice-500);\n --button-hover-color: var(--color-ice-700-hover);\n --text-color: var(--color-ice-700);\n }\n\n .button--tertiary {\n composes: button--ghost;\n --button-color: var(--color-white);\n --button-hover-color: var(--color-white-hover);\n --text-color: var(--color-white);\n }\n\n .button--icon,\n .button--iconLabel {\n /* https://developers.google.com/web/fundamentals/accessibility/accessible-styles */\n border: 0;\n border-radius: var(--border-radius);\n height: var(--ll-space-5);\n min-width: var(--ll-space-5);\n text-decoration: none;\n }\n\n .button--icon {\n padding: var(--ll-space-2);\n width: var(--ll-space-5);\n }\n\n .button--iconLabel {\n padding: 0;\n width: unset;\n }\n\n @media screen(lg) {\n /* `hover` should be added only for large screens */\n .button--icon:hover,\n .button--iconLabel:hover {\n text-decoration: none;\n }\n }\n\n .button--icon svg,\n .button--iconLabel svg {\n display: block;\n margin-left: auto;\n margin-right: auto;\n }\n\n .button--icon[disabled] svg,\n .button--iconLabel[disabled],\n .button--iconLabel[disabled] svg {\n color: var(--color-ice-500);\n }\n\n .button--inline {\n border: 0;\n color: var(--color-blue-500);\n font-weight: var(--font-weight-medium);\n line-height: 1.5;\n min-width: 0;\n padding: 0;\n }\n\n .button--inline:hover {\n text-decoration: underline;\n }\n\n .button--inline[disabled] {\n color: var(--color-ice-900);\n }\n\n /* Colors */\n .button--blue.button--primary,\n .button--blue.button--secondary {\n --button-color: var(--color-blue-500);\n }\n\n .button--blue.button--primary {\n --button-hover-color: var(--color-blue-hover);\n }\n\n .button--blue.button--secondary {\n --text-color: var(--color-blue-500);\n --button-hover-color: var(--button-secondary-blue-hover);\n }\n\n .button--red.button--primary,\n .button--red.button--secondary {\n --button-color: var(--color-red-500);\n }\n\n .button--red.button--primary {\n --button-hover-color: var(--color-red-hover);\n }\n\n .button--red.button--secondary {\n --text-color: var(--color-red-500);\n --button-hover-color: var(--button-secondary-red-hover);\n }\n\n /**\n * Button Grid\n * TODO: Move into separate component\n * https://leaflink.atlassian.net/browse/STASH-230\n * See `styles/elements/_buttons.scss` for button-grid (parent element) specific styles.\n */\n :global(.button-grid) > .button,\n :global(.header-button-grid) > .button {\n width: 50%;\n }\n\n :global(.button-grid) > .button + .button {\n margin-left: var(--ll-space-3);\n }\n\n @media screen(md) {\n :global(.button-grid) > .button {\n width: auto;\n }\n }\n\n :global(.header-button-grid) > .button + .button {\n margin-left: var(--ll-space-3);\n }\n\n @media screen(lg) {\n :global(.header-button-grid) > .button {\n width: auto;\n }\n }\n</style>\n"],"names":["ButtonTypes","buttonType","computed","type","props"],"mappings":";;;;AAgDE,IAAKA,sBAAAA,OACHA,EAAA,UAAU,WACVA,EAAA,YAAY,aACZA,EAAA,WAAW,YACXA,EAAA,OAAO,QACPA,EAAA,YAAY,aACZA,EAAA,SAAS,UANNA,IAAAA,KAAA,CAAA,CAAA;;;;;;;;;;;;;;iBAWCC,IAAaC,EAAqB,MAAM;AAC5C,iBAAWC,KAAQ,OAAO,OAAOH,CAAW;AACtC,YAAAI,EAAMD,CAAI;AACL,iBAAAA;AAIJ,aAAA;AAAA,IAAA,CACR;;;;;;;;;;;;;;;;;;;"}
1
+ {"version":3,"file":"Button.js","sources":["../src/components/Button/Button.vue"],"sourcesContent":["<script lang=\"ts\" setup>\n import { computed } from 'vue';\n\n defineOptions({\n name: 'll-button',\n });\n\n export interface ButtonProps {\n /**\n * Renders the secondary variant\n */\n secondary?: boolean;\n\n /**\n * Renders the button as a container for an Icon\n */\n icon?: boolean;\n\n /**\n * Renders the button as a container for an IconLabel\n */\n iconLabel?: boolean;\n\n /**\n * Renders the tertiary variant\n */\n tertiary?: boolean;\n\n /**\n * Renders the component inline\n */\n inline?: boolean;\n\n /**\n * Renders a color variant\n */\n color?: 'blue' | 'red';\n\n /**\n * Button link. If defined, the button will render as an `<a />` tag.\n */\n href?: string;\n }\n\n const props = withDefaults(defineProps<ButtonProps>(), {\n secondary: false,\n icon: false,\n iconLabel: false,\n tertiary: false,\n inline: false,\n color: undefined,\n href: '',\n });\n\n enum ButtonTypes {\n Primary = 'primary',\n Secondary = 'secondary',\n Tertiary = 'tertiary',\n Icon = 'icon',\n IconLabel = 'iconLabel',\n Inline = 'inline',\n }\n\n type ButtonType = `${ButtonTypes}`;\n\n const buttonType = computed<ButtonType>(() => {\n for (const type of Object.values(ButtonTypes)) {\n if (props[type]) {\n return type;\n }\n }\n\n return ButtonTypes.Primary;\n });\n</script>\n\n<template>\n <a\n v-if=\"props.href\"\n data-test=\"ll-button\"\n class=\"stash-button\"\n :class=\"[$style.button, $style[`button--${buttonType}`], { [$style[`button--${props.color}`]]: props.color }]\"\n :href=\"props.href\"\n >\n <!-- @slot default -->\n <slot></slot>\n </a>\n <button\n v-else\n data-test=\"ll-button\"\n class=\"stash-button\"\n :class=\"[$style.button, $style[`button--${buttonType}`], { [$style[`button--${props.color}`]]: props.color }]\"\n >\n <!-- @slot default -->\n <slot></slot>\n </button>\n</template>\n\n<style module>\n .button {\n border-radius: theme('borderRadius.DEFAULT');\n border-width: 1px;\n display: inline-block;\n font-size: 0.875rem;\n font-weight: theme('fontWeight.semibold');\n line-height: 2.125rem;\n margin: 0;\n min-width: 144px;\n padding: 0 theme('spacing.3');\n text-align: center;\n text-decoration: none;\n vertical-align: middle;\n white-space: nowrap;\n }\n\n @media screen('lg') {\n /* `focus` and `hover` should be added only for large screens */\n .button:focus {\n box-shadow: 0 0 0 3px rgb(0 123 255 / 14%);\n outline: none;\n }\n\n .button:hover {\n text-decoration: none;\n }\n }\n\n .button[disabled] {\n cursor: default;\n pointer-events: none;\n }\n\n /* Solid treatment */\n .button--solid {\n background-color: var(--button-color);\n border-color: transparent;\n color: var(--text-color);\n }\n\n @media screen('lg') {\n /* `hover` should be added only for large screens */\n .button--solid:hover {\n background-color: var(--button-hover-color);\n }\n }\n\n .button--solid:active {\n background-color: var(--button-hover-color);\n }\n\n .button--solid[disabled] {\n --button-color: var(--color-ice-500) !important;\n }\n\n /* Ghost treatment */\n .button--ghost {\n background-color: rgb(0 0 0 / 0%);\n border-color: var(--button-color);\n color: var(--text-color);\n }\n\n @media screen('lg') {\n /* `hover` should be added only for large screens */\n .button--ghost:hover {\n background-color: var(--button-hover-color);\n }\n }\n\n .button--ghost:active {\n background-color: var(--button-hover-color);\n }\n\n .button--ghost[disabled] {\n --button-color: var(--color-ice-500) !important;\n --text-color: var(--color-ice-500) !important;\n }\n\n /* Types */\n .button--primary {\n composes: button--solid;\n --button-color: var(--color-blue-500);\n --button-hover-color: var(--color-blue-hover);\n --text-color: var(--color-white);\n }\n\n .button--secondary {\n composes: button--ghost;\n --button-color: var(--color-ice-500);\n --button-hover-color: var(--color-ice-700-hover);\n --text-color: var(--color-ice-700);\n }\n\n .button--tertiary {\n composes: button--ghost;\n --button-color: var(--color-white);\n --button-hover-color: var(--color-white-hover);\n --text-color: var(--color-white);\n }\n\n .button--icon,\n .button--iconLabel {\n /* https://developers.google.com/web/fundamentals/accessibility/accessible-styles */\n border: 0;\n border-radius: theme('borderRadius.DEFAULT');\n height: theme('spacing.12');\n min-width: theme('spacing.12');\n text-decoration: none;\n }\n\n .button--icon {\n padding: theme('spacing.3');\n width: theme('spacing.12');\n }\n\n .button--iconLabel {\n padding: 0;\n width: unset;\n }\n\n @media screen('lg') {\n /* `hover` should be added only for large screens */\n .button--icon:hover,\n .button--iconLabel:hover {\n text-decoration: none;\n }\n }\n\n .button--icon svg,\n .button--iconLabel svg {\n display: block;\n margin-left: auto;\n margin-right: auto;\n }\n\n .button--icon[disabled] svg,\n .button--iconLabel[disabled],\n .button--iconLabel[disabled] svg {\n color: var(--color-ice-500);\n }\n\n .button--inline {\n border: 0;\n color: var(--color-blue-500);\n font-weight: theme('fontWeight.medium');\n line-height: 1.5;\n min-width: 0;\n padding: 0;\n }\n\n .button--inline:hover {\n text-decoration: underline;\n }\n\n .button--inline[disabled] {\n color: var(--color-ice-900);\n }\n\n /* Colors */\n .button--blue.button--primary,\n .button--blue.button--secondary {\n --button-color: var(--color-blue-500);\n }\n\n .button--blue.button--primary {\n --button-hover-color: var(--color-blue-hover);\n }\n\n .button--blue.button--secondary {\n --text-color: var(--color-blue-500);\n --button-hover-color: var(--button-secondary-blue-hover);\n }\n\n .button--red.button--primary,\n .button--red.button--secondary {\n --button-color: var(--color-red-500);\n }\n\n .button--red.button--primary {\n --button-hover-color: var(--color-red-hover);\n }\n\n .button--red.button--secondary {\n --text-color: var(--color-red-500);\n --button-hover-color: var(--button-secondary-red-hover);\n }\n\n /**\n * Button Grid\n * TODO: Move into separate component\n * https://leaflink.atlassian.net/browse/STASH-230\n * See `styles/elements/_buttons.scss` for button-grid (parent element) specific styles.\n */\n :global(.button-grid) > .button,\n :global(.header-button-grid) > .button {\n width: 50%;\n }\n\n :global(.button-grid) > .button + .button {\n margin-left: theme('spacing.6');\n }\n\n @media screen('md') {\n :global(.button-grid) > .button {\n width: auto;\n }\n }\n\n :global(.header-button-grid) > .button + .button {\n margin-left: theme('spacing.6');\n }\n\n @media screen('lg') {\n :global(.header-button-grid) > .button {\n width: auto;\n }\n }\n</style>\n"],"names":["ButtonTypes","buttonType","computed","type","props"],"mappings":";;;;AAsDE,IAAKA,sBAAAA,OACHA,EAAA,UAAU,WACVA,EAAA,YAAY,aACZA,EAAA,WAAW,YACXA,EAAA,OAAO,QACPA,EAAA,YAAY,aACZA,EAAA,SAAS,UANNA,IAAAA,KAAA,CAAA,CAAA;;;;;;;;;;;;;;iBAWCC,IAAaC,EAAqB,MAAM;AAC5C,iBAAWC,KAAQ,OAAO,OAAOH,CAAW;AACtC,YAAAI,EAAMD,CAAI;AACL,iBAAAA;AAIJ,aAAA;AAAA,IAAA,CACR;;;;;;;;;;;;;;;;;;;"}
@@ -0,0 +1,17 @@
1
+ const t = "_button_mair8_2", o = {
2
+ button: t,
3
+ "button--solid": "_button--solid_mair8_36",
4
+ "button--ghost": "_button--ghost_mair8_58",
5
+ "button--primary": "_button--primary_mair8_81 _button--solid_mair8_36",
6
+ "button--secondary": "_button--secondary_mair8_88 _button--ghost_mair8_58",
7
+ "button--tertiary": "_button--tertiary_mair8_95 _button--ghost_mair8_58",
8
+ "button--icon": "_button--icon_mair8_102",
9
+ "button--iconLabel": "_button--iconLabel_mair8_103",
10
+ "button--inline": "_button--inline_mair8_143",
11
+ "button--blue": "_button--blue_mair8_161",
12
+ "button--red": "_button--red_mair8_175"
13
+ };
14
+ export {
15
+ o as s
16
+ };
17
+ //# sourceMappingURL=Button.vue_used_vue_type_style_index_0_lang.module-63d31dc0.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Button.vue_used_vue_type_style_index_0_lang.module-63d31dc0.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;"}
@@ -1,12 +1,12 @@
1
- import { defineComponent as m, computed as r, ref as b, openBlock as l, createElementBlock as s, normalizeClass as p, Fragment as g, renderList as $, withModifiers as y, toDisplayString as w } from "vue";
2
- import B from "lodash-es/uniqueId";
3
- import { _ as h } from "./_plugin-vue_export-helper-dad06003.js";
4
- const k = ["data-test"], x = ["data-test", "disabled", "onClick"], C = {
1
+ import { defineComponent as b, computed as r, ref as m, openBlock as o, createElementBlock as s, normalizeClass as p, Fragment as g, renderList as $, withModifiers as y, toDisplayString as B } from "vue";
2
+ import h from "lodash-es/uniqueId";
3
+ import { _ as w } from "./_plugin-vue_export-helper-dad06003.js";
4
+ const z = ["data-test"], k = ["data-test", "disabled", "onClick"], C = {
5
5
  name: "ll-button-group"
6
- }, G = /* @__PURE__ */ m({
6
+ }, G = /* @__PURE__ */ b({
7
7
  ...C,
8
8
  props: {
9
- groupName: { default: B() },
9
+ groupName: { default: h() },
10
10
  options: {},
11
11
  fullWidth: { type: Boolean, default: !1 },
12
12
  disabled: { type: Boolean, default: !1 },
@@ -14,12 +14,12 @@ const k = ["data-test"], x = ["data-test", "disabled", "onClick"], C = {
14
14
  },
15
15
  emits: ["input"],
16
16
  setup(v, { emit: _ }) {
17
- const e = v, u = r(() => e.options.length === 1), i = r(() => e.allowDeactivate || u.value), a = b(e.options.find((t) => t.active) || null);
17
+ const e = v, u = r(() => e.options.length === 1), i = r(() => e.allowDeactivate || u.value), a = m(e.options.find((t) => t.active) || null);
18
18
  function f(t) {
19
- var o;
20
- i.value && ((o = a.value) == null ? void 0 : o.id) === t.id ? a.value = null : a.value = t, _("input", a.value);
19
+ var l;
20
+ i.value && ((l = a.value) == null ? void 0 : l.id) === t.id ? a.value = null : a.value = t, _("input", a.value);
21
21
  }
22
- return (t, o) => (l(), s("div", {
22
+ return (t, l) => (o(), s("div", {
23
23
  class: p([
24
24
  "tw-flex",
25
25
  t.$style.buttonGroup,
@@ -29,29 +29,29 @@ const k = ["data-test"], x = ["data-test", "disabled", "onClick"], C = {
29
29
  ]),
30
30
  "data-test": `button-group-${t.$props.groupName}`
31
31
  }, [
32
- (l(!0), s(g, null, $(e.options, (n) => {
32
+ (o(!0), s(g, null, $(e.options, (n) => {
33
33
  var c, d;
34
- return l(), s("button", {
34
+ return o(), s("button", {
35
35
  key: `${e.groupName}-${n.id}`,
36
36
  class: p([t.$style.button, { [t.$style.active]: ((c = a.value) == null ? void 0 : c.id) === n.id }]),
37
37
  "data-test": `${e.groupName}-button-${((d = a.value) == null ? void 0 : d.id) === n.id ? "active" : "inactive"}`,
38
38
  tabindex: 0,
39
39
  disabled: e.disabled,
40
- onClick: y((z) => f(n), ["prevent"])
41
- }, w(n.text), 11, x);
40
+ onClick: y((E) => f(n), ["prevent"])
41
+ }, B(n.text), 11, k);
42
42
  }), 128))
43
- ], 10, k));
43
+ ], 10, z));
44
44
  }
45
- }), D = "_buttonGroup_1cnwx_176", N = "_button_1cnwx_176", M = "_single_1cnwx_190", S = "_active_1cnwx_202", W = {
45
+ }), D = "_buttonGroup_1bnlz_3", N = "_button_1bnlz_3", M = "_single_1bnlz_17", S = "_active_1bnlz_29", W = {
46
46
  buttonGroup: D,
47
47
  button: N,
48
48
  single: M,
49
49
  active: S,
50
- "can-deactivate": "_can-deactivate_1cnwx_215"
50
+ "can-deactivate": "_can-deactivate_1bnlz_42"
51
51
  }, q = {
52
52
  $style: W
53
- }, L = /* @__PURE__ */ h(G, [["__cssModules", q]]);
53
+ }, j = /* @__PURE__ */ w(G, [["__cssModules", q]]);
54
54
  export {
55
- L as default
55
+ j as default
56
56
  };
57
57
  //# sourceMappingURL=ButtonGroup.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"ButtonGroup.js","sources":["../src/components/ButtonGroup/ButtonGroup.vue"],"sourcesContent":["<script lang=\"ts\">\n /**\n * @deprecated use RadioGroup instead with `variant=\"button\"`.\n * RadioGroup uses pretty much the same API as the ButtonGroup,\n * but every button is a radio element which makes more sense semantically.\n */\n export default {\n name: 'll-button-group',\n };\n</script>\n\n<script lang=\"ts\" setup>\n import uniqueId from 'lodash-es/uniqueId';\n import { computed, ref } from 'vue';\n\n export interface ButtonGroupOption {\n id: string;\n active?: boolean;\n text: string;\n }\n\n export interface ButtonGroupProps {\n /**\n * A name for the group, useful when multiple ButtonGroups exist on the page\n */\n groupName?: string;\n\n /**\n * The list of buttons to render\n */\n options: ButtonGroupOption[];\n\n /**\n * Whether the group should expand to the parent's width\n */\n fullWidth?: boolean;\n\n /**\n * Whether the entire group should be disabled\n */\n disabled?: boolean;\n\n /**\n * Whether the active button can be deactivated\n */\n allowDeactivate?: boolean;\n }\n\n const props = withDefaults(defineProps<ButtonGroupProps>(), {\n groupName: uniqueId(),\n fullWidth: false,\n disabled: false,\n allowDeactivate: false,\n });\n\n const emit =\n defineEmits<{\n (e: 'input', activeButton: ButtonGroupOption | null): void;\n }>();\n\n const isSingleButton = computed(() => props.options.length === 1);\n\n const canDeactivate = computed(() => props.allowDeactivate || isSingleButton.value);\n\n const activeButton = ref(props.options.find((o) => o.active) || null);\n\n function onClick(clickedOption: ButtonGroupOption) {\n if (canDeactivate.value && activeButton.value?.id === clickedOption.id) {\n activeButton.value = null;\n } else {\n activeButton.value = clickedOption;\n }\n\n emit('input', activeButton.value);\n }\n</script>\n\n<template>\n <div\n :class=\"[\n 'tw-flex',\n $style.buttonGroup,\n { 'tw-w-full': props.fullWidth },\n { [$style.single]: isSingleButton },\n { [$style['can-deactivate']]: canDeactivate },\n ]\"\n :data-test=\"`button-group-${$props.groupName}`\"\n >\n <button\n v-for=\"option in props.options\"\n :key=\"`${props.groupName}-${option.id}`\"\n :class=\"[$style.button, { [$style.active]: activeButton?.id === option.id }]\"\n :data-test=\"`${props.groupName}-button-${activeButton?.id === option.id ? 'active' : 'inactive'}`\"\n :tabindex=\"0\"\n :disabled=\"props.disabled\"\n @click.prevent=\"onClick(option)\"\n >\n {{ option.text }}\n </button>\n </div>\n</template>\n\n<style lang=\"scss\" module>\n // full width buttons\n .buttonGroup:global(.w-full) > button {\n flex: 1 1 50%;\n max-width: 100%;\n }\n\n .button {\n border: 1px solid var(--color-ice-500);\n border-radius: 0;\n font-weight: var(--font-weight-semibold);\n line-height: var(--line-height-body);\n min-width: 100px;\n padding: 7px 8px;\n }\n\n .single .button {\n border: 1px solid var(--color-ice-700);\n color: var(--color-ice-700);\n }\n\n .button:focus,\n .button:hover {\n border: 1px solid var(--color-blue-500) !important;\n color: var(--color-blue-500);\n z-index: 1;\n }\n\n .button.active {\n background-color: var(--color-blue-100);\n border: 1px solid var(--color-blue-500) !important;\n color: var(--color-blue-500);\n cursor: default;\n z-index: 1;\n }\n\n .button.active + button {\n border-left: 1px solid transparent;\n }\n\n .single .button.active,\n .can-deactivate .button.active {\n cursor: pointer;\n }\n\n .button[disabled] {\n color: var(--color-ice-500);\n cursor: default;\n pointer-events: none;\n }\n\n .button:focus {\n box-shadow: none;\n outline: 0;\n }\n\n .button:not(:first-child) {\n margin-left: -1px;\n }\n\n .button:not(:last-child) {\n border-right: 1px solid transparent;\n }\n\n .button:first-child {\n border-bottom-left-radius: var(--border-radius);\n border-top-left-radius: var(--border-radius);\n }\n\n .button:last-child {\n border-bottom-right-radius: var(--border-radius);\n border-top-right-radius: var(--border-radius);\n }\n</style>\n"],"names":["isSingleButton","computed","props","canDeactivate","activeButton","ref","o","onClick","clickedOption","_a","emit"],"mappings":";;;uEAMiB;AAAA,EACb,MAAM;AACR;;;;;;;;;;;iBAoDMA,IAAiBC,EAAS,MAAMC,EAAM,QAAQ,WAAW,CAAC,GAE1DC,IAAgBF,EAAS,MAAMC,EAAM,mBAAmBF,EAAe,KAAK,GAE5EI,IAAeC,EAAIH,EAAM,QAAQ,KAAK,CAACI,MAAMA,EAAE,MAAM,KAAK,IAAI;AAEpE,aAASC,EAAQC,GAAkC;;AACjD,MAAIL,EAAc,WAASM,IAAAL,EAAa,UAAb,gBAAAK,EAAoB,QAAOD,EAAc,KAClEJ,EAAa,QAAQ,OAErBA,EAAa,QAAQI,GAGlBE,EAAA,SAASN,EAAa,KAAK;AAAA,IAClC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
1
+ {"version":3,"file":"ButtonGroup.js","sources":["../src/components/ButtonGroup/ButtonGroup.vue"],"sourcesContent":["<script lang=\"ts\">\n /**\n * @deprecated use RadioGroup instead with `variant=\"button\"`.\n * RadioGroup uses pretty much the same API as the ButtonGroup,\n * but every button is a radio element which makes more sense semantically.\n */\n export default {\n name: 'll-button-group',\n };\n</script>\n\n<script lang=\"ts\" setup>\n import uniqueId from 'lodash-es/uniqueId';\n import { computed, ref } from 'vue';\n\n export interface ButtonGroupOption {\n id: string;\n active?: boolean;\n text: string;\n }\n\n export interface ButtonGroupProps {\n /**\n * A name for the group, useful when multiple ButtonGroups exist on the page\n */\n groupName?: string;\n\n /**\n * The list of buttons to render\n */\n options: ButtonGroupOption[];\n\n /**\n * Whether the group should expand to the parent's width\n */\n fullWidth?: boolean;\n\n /**\n * Whether the entire group should be disabled\n */\n disabled?: boolean;\n\n /**\n * Whether the active button can be deactivated\n */\n allowDeactivate?: boolean;\n }\n\n const props = withDefaults(defineProps<ButtonGroupProps>(), {\n groupName: uniqueId(),\n fullWidth: false,\n disabled: false,\n allowDeactivate: false,\n });\n\n const emit =\n defineEmits<{\n (e: 'input', activeButton: ButtonGroupOption | null): void;\n }>();\n\n const isSingleButton = computed(() => props.options.length === 1);\n\n const canDeactivate = computed(() => props.allowDeactivate || isSingleButton.value);\n\n const activeButton = ref(props.options.find((o) => o.active) || null);\n\n function onClick(clickedOption: ButtonGroupOption) {\n if (canDeactivate.value && activeButton.value?.id === clickedOption.id) {\n activeButton.value = null;\n } else {\n activeButton.value = clickedOption;\n }\n\n emit('input', activeButton.value);\n }\n</script>\n\n<template>\n <div\n :class=\"[\n 'tw-flex',\n $style.buttonGroup,\n { 'tw-w-full': props.fullWidth },\n { [$style.single]: isSingleButton },\n { [$style['can-deactivate']]: canDeactivate },\n ]\"\n :data-test=\"`button-group-${$props.groupName}`\"\n >\n <button\n v-for=\"option in props.options\"\n :key=\"`${props.groupName}-${option.id}`\"\n :class=\"[$style.button, { [$style.active]: activeButton?.id === option.id }]\"\n :data-test=\"`${props.groupName}-button-${activeButton?.id === option.id ? 'active' : 'inactive'}`\"\n :tabindex=\"0\"\n :disabled=\"props.disabled\"\n @click.prevent=\"onClick(option)\"\n >\n {{ option.text }}\n </button>\n </div>\n</template>\n\n<style module>\n /* full width buttons */\n .buttonGroup:global(.w-full) > button {\n flex: 1 1 50%;\n max-width: 100%;\n }\n\n .button {\n border: 1px solid var(--color-ice-500);\n border-radius: 0;\n font-weight: theme('fontWeight.semibold');\n line-height: theme('lineHeight.body');\n min-width: 100px;\n padding: 7px 8px;\n }\n\n .single .button {\n border: 1px solid var(--color-ice-700);\n color: var(--color-ice-700);\n }\n\n .button:focus,\n .button:hover {\n border: 1px solid var(--color-blue-500) !important;\n color: var(--color-blue-500);\n z-index: 1;\n }\n\n .button.active {\n background-color: var(--color-blue-100);\n border: 1px solid var(--color-blue-500) !important;\n color: var(--color-blue-500);\n cursor: default;\n z-index: 1;\n }\n\n .button.active + button {\n border-left: 1px solid transparent;\n }\n\n .single .button.active,\n .can-deactivate .button.active {\n cursor: pointer;\n }\n\n .button[disabled] {\n color: var(--color-ice-500);\n cursor: default;\n pointer-events: none;\n }\n\n .button:focus {\n box-shadow: none;\n outline: 0;\n }\n\n .button:not(:first-child) {\n margin-left: -1px;\n }\n\n .button:not(:last-child) {\n border-right: 1px solid transparent;\n }\n\n .button:first-child {\n border-bottom-left-radius: theme('borderRadius.DEFAULT');\n border-top-left-radius: theme('borderRadius.DEFAULT');\n }\n\n .button:last-child {\n border-bottom-right-radius: theme('borderRadius.DEFAULT');\n border-top-right-radius: theme('borderRadius.DEFAULT');\n }\n</style>\n"],"names":["isSingleButton","computed","props","canDeactivate","activeButton","ref","o","onClick","clickedOption","_a","emit"],"mappings":";;;uEAMiB;AAAA,EACb,MAAM;AACR;;;;;;;;;;;iBAoDMA,IAAiBC,EAAS,MAAMC,EAAM,QAAQ,WAAW,CAAC,GAE1DC,IAAgBF,EAAS,MAAMC,EAAM,mBAAmBF,EAAe,KAAK,GAE5EI,IAAeC,EAAIH,EAAM,QAAQ,KAAK,CAACI,MAAMA,EAAE,MAAM,KAAK,IAAI;AAEpE,aAASC,EAAQC,GAAkC;;AACjD,MAAIL,EAAc,WAASM,IAAAL,EAAa,UAAb,gBAAAK,EAAoB,QAAOD,EAAc,KAClEJ,EAAa,QAAQ,OAErBA,EAAa,QAAQI,GAGlBE,EAAA,SAASN,EAAa,KAAK;AAAA,IAClC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}