@veritree/ui 0.39.2 → 0.40.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.
package/index.js CHANGED
@@ -1,71 +1,76 @@
1
- import VTAlert from "./src/components/Alert/VTAlert.vue";
2
- import VTAvatar from "./src/components/Avatar/VTAvatar.vue";
3
- import VTAvatarImage from "./src/components/Avatar/VTAvatarImage.vue";
4
- import VTAvatarText from "./src/components/Avatar/VTAvatarText.vue";
5
- import VTButton from "./src/components/Button/VTButton.vue";
6
- import VTImage from "./src/components/Image/VTImage.vue";
7
- import VTImageCounter from "./src/components/Image/VTImageCounter.vue";
8
- import VTImageHover from "./src/components/Image/VTImageHover.vue";
9
- import VTDropdownMenu from "./src/components/DropdownMenu/VTDropdownMenu.vue";
10
- import VTDropdownMenuContent from "./src/components/DropdownMenu/VTDropdownMenuContent.vue";
11
- import VTDropdownMenuDivider from "./src/components/DropdownMenu/VTDropdownMenuDivider.vue";
12
- import VTDropdownMenuGroup from "./src/components/DropdownMenu/VTDropdownMenuGroup.vue";
13
- import VTDropdownMenuItem from "./src/components/DropdownMenu/VTDropdownMenuItem.vue";
14
- import VTDropdownMenuLabel from "./src/components/DropdownMenu/VTDropdownMenuLabel.vue";
15
- import VTDropdownMenuTrigger from "./src/components/DropdownMenu/VTDropdownMenuTrigger.vue";
16
- import VTPopover from "./src/components/Popover/VTPopover.vue";
17
- import VTPopoverContent from "./src/components/Popover/VTPopoverContent.vue";
18
- import VTPopoverDivider from "./src/components/Popover/VTPopoverDivider.vue";
19
- import VTPopoverGroup from "./src/components/Popover/VTPopoverGroup.vue";
20
- import VTPopoverItem from "./src/components/Popover/VTPopoverItem.vue";
21
- import VTPopoverTrigger from "./src/components/Popover/VTPopoverTrigger.vue";
22
- import VTFormFeedback from "./src/components/Form/VTFormFeedback.vue";
23
- import VTFormGroup from "./src/components/Form/VTFormGroup.vue";
24
- import VTInput from "./src/components/Form/VTInput.vue";
25
- import VTInputIcon from "./src/components/Form/VTInputIcon.vue";
26
- import VTInputPassword from "./src/components/Form/VTInputPassword.vue";
27
- import VTListbox from "./src/components/Listbox/VTListbox.vue";
28
- import VTListboxContent from "./src/components/Listbox/VTListboxContent.vue";
29
- import VTListboxItem from "./src/components/Listbox/VTListboxItem.vue";
30
- import VTListboxLabel from "./src/components/Listbox/VTListboxLabel.vue";
31
- import VTListboxList from "./src/components/Listbox/VTListboxList.vue";
32
- import VTListboxSearch from "./src/components/Listbox/VTListboxSearch.vue";
33
- import VTListboxTrigger from "./src/components/Listbox/VTListboxTrigger.vue";
34
- import VTSpinner from "./src/components/Spinner/VTSpinner.vue";
35
- import VTInputDate from "./src/components/Input/VTInputDate.vue";
36
- import VTInputFile from "./src/components/Input/VTInputFile.vue";
37
- import VTInputUpload from "./src/components/Input/VTInputUpload.vue";
38
- import VTProgressBar from "./src/components/ProgressBar/VTProgressBar.vue";
39
- import VTTextarea from "./src/components/Textarea/VTTextarea.vue";
40
- import VTModal from "./src/components/Modal/VTModal.vue";
41
- import VTTab from "./src/components/Tabs/VTTab.vue";
42
- import VTTabGroup from "./src/components/Tabs/VTTabGroup.vue";
43
- import VTTabList from "./src/components/Tabs/VTTabList.vue";
44
- import VTTabPanel from "./src/components/Tabs/VTTabPanel.vue";
45
- import VTTabPanels from "./src/components/Tabs/VTTabPanels.vue";
46
- import VTDialog from "./src/components/Dialog/VTDialog.vue";
47
- import VTDialogClose from "./src/components/Dialog/VTDialogClose.vue";
48
- import VTDialogContent from "./src/components/Dialog/VTDialogContent.vue";
49
- import VTDialogFooter from "./src/components/Dialog/VTDialogFooter.vue";
50
- import VTDialogHeader from "./src/components/Dialog/VTDialogHeader.vue";
51
- import VTDialogMain from "./src/components/Dialog/VTDialogMain.vue";
52
- import VTDialogOverlay from "./src/components/Dialog/VTDialogOverlay.vue";
53
- import VTDialogTitle from "./src/components/Dialog/VTDialogTitle.vue";
54
- import VTDrawer from "./src/components/Drawer/VTDrawer.vue";
55
- import VTDrawerClose from "./src/components/Drawer/VTDrawerClose.vue";
56
- import VTDrawerContent from "./src/components/Drawer/VTDrawerContent.vue";
57
- import VTDrawerFooter from "./src/components/Drawer/VTDrawerFooter.vue";
58
- import VTDrawerHeader from "./src/components/Drawer/VTDrawerHeader.vue";
59
- import VTDrawerTitle from "./src/components/Drawer/VTDrawerTitle.vue";
60
- import VTDrawerMain from "./src/components/Drawer/VTDrawerMain.vue";
61
- import VTDrawerOverlay from "./src/components/Drawer/VTDrawerOverlay.vue";
62
- import VTDisclosure from "./src/components/Disclosure/VTDisclosure.vue";
63
- import VTDisclosureDetails from "./src/components/Disclosure/VTDisclosureDetails.vue";
64
- import VTDisclosureHeader from "./src/components/Disclosure/VTDisclosureHeader.vue";
65
- import VTDisclosureIcon from "./src/components/Disclosure/VTDisclosureIcon.vue";
66
- import VTDisclosureContent from "./src/components/Disclosure/VTDisclosureContent.vue";
67
- import VTSkeleton from "./src/components/Skeleton/VTSkeleton.vue";
68
- import VTSkeletonItem from "./src/components/Skeleton/VTSkeletonItem.vue";
1
+ import VTAlert from './src/components/Alert/VTAlert.vue';
2
+ import VTAvatar from './src/components/Avatar/VTAvatar.vue';
3
+ import VTAvatarImage from './src/components/Avatar/VTAvatarImage.vue';
4
+ import VTAvatarText from './src/components/Avatar/VTAvatarText.vue';
5
+ import VTButton from './src/components/Button/VTButton.vue';
6
+ import VTImage from './src/components/Image/VTImage.vue';
7
+ import VTImageCounter from './src/components/Image/VTImageCounter.vue';
8
+ import VTImageHover from './src/components/Image/VTImageHover.vue';
9
+ import VTDropdownMenu from './src/components/DropdownMenu/VTDropdownMenu.vue';
10
+ import VTDropdownMenuContent from './src/components/DropdownMenu/VTDropdownMenuContent.vue';
11
+ import VTDropdownMenuDivider from './src/components/DropdownMenu/VTDropdownMenuDivider.vue';
12
+ import VTDropdownMenuGroup from './src/components/DropdownMenu/VTDropdownMenuGroup.vue';
13
+ import VTDropdownMenuItem from './src/components/DropdownMenu/VTDropdownMenuItem.vue';
14
+ import VTDropdownMenuLabel from './src/components/DropdownMenu/VTDropdownMenuLabel.vue';
15
+ import VTDropdownMenuTrigger from './src/components/DropdownMenu/VTDropdownMenuTrigger.vue';
16
+ import VTPopover from './src/components/Popover/VTPopover.vue';
17
+ import VTPopoverContent from './src/components/Popover/VTPopoverContent.vue';
18
+ import VTPopoverDivider from './src/components/Popover/VTPopoverDivider.vue';
19
+ import VTPopoverGroup from './src/components/Popover/VTPopoverGroup.vue';
20
+ import VTPopoverItem from './src/components/Popover/VTPopoverItem.vue';
21
+ import VTPopoverTrigger from './src/components/Popover/VTPopoverTrigger.vue';
22
+ import VTForm from './src/components/Form/VTForm.vue';
23
+ import VTFormRow from './src/components/Form/VTFormRow.vue';
24
+ import VTFormCol from './src/components/Form/VTFormCol.vue';
25
+ import VTFieldset from './src/components/Form/VTFieldset.vue';
26
+ import VTLegend from './src/components/Form/VTLegend.vue';
27
+ import VTFormFeedback from './src/components/Form/VTFormFeedback.vue';
28
+ import VTFormGroup from './src/components/Form/VTFormGroup.vue';
29
+ import VTInput from './src/components/Form/VTInput.vue';
30
+ import VTInputIcon from './src/components/Form/VTInputIcon.vue';
31
+ import VTInputPassword from './src/components/Form/VTInputPassword.vue';
32
+ import VTListbox from './src/components/Listbox/VTListbox.vue';
33
+ import VTListboxContent from './src/components/Listbox/VTListboxContent.vue';
34
+ import VTListboxItem from './src/components/Listbox/VTListboxItem.vue';
35
+ import VTListboxLabel from './src/components/Listbox/VTListboxLabel.vue';
36
+ import VTListboxList from './src/components/Listbox/VTListboxList.vue';
37
+ import VTListboxSearch from './src/components/Listbox/VTListboxSearch.vue';
38
+ import VTListboxTrigger from './src/components/Listbox/VTListboxTrigger.vue';
39
+ import VTSpinner from './src/components/Spinner/VTSpinner.vue';
40
+ import VTInputDate from './src/components/Input/VTInputDate.vue';
41
+ import VTInputFile from './src/components/Input/VTInputFile.vue';
42
+ import VTInputUpload from './src/components/Input/VTInputUpload.vue';
43
+ import VTProgressBar from './src/components/ProgressBar/VTProgressBar.vue';
44
+ import VTTextarea from './src/components/Textarea/VTTextarea.vue';
45
+ import VTModal from './src/components/Modal/VTModal.vue';
46
+ import VTTab from './src/components/Tabs/VTTab.vue';
47
+ import VTTabGroup from './src/components/Tabs/VTTabGroup.vue';
48
+ import VTTabList from './src/components/Tabs/VTTabList.vue';
49
+ import VTTabPanel from './src/components/Tabs/VTTabPanel.vue';
50
+ import VTTabPanels from './src/components/Tabs/VTTabPanels.vue';
51
+ import VTDialog from './src/components/Dialog/VTDialog.vue';
52
+ import VTDialogClose from './src/components/Dialog/VTDialogClose.vue';
53
+ import VTDialogContent from './src/components/Dialog/VTDialogContent.vue';
54
+ import VTDialogFooter from './src/components/Dialog/VTDialogFooter.vue';
55
+ import VTDialogHeader from './src/components/Dialog/VTDialogHeader.vue';
56
+ import VTDialogMain from './src/components/Dialog/VTDialogMain.vue';
57
+ import VTDialogOverlay from './src/components/Dialog/VTDialogOverlay.vue';
58
+ import VTDialogTitle from './src/components/Dialog/VTDialogTitle.vue';
59
+ import VTDrawer from './src/components/Drawer/VTDrawer.vue';
60
+ import VTDrawerClose from './src/components/Drawer/VTDrawerClose.vue';
61
+ import VTDrawerContent from './src/components/Drawer/VTDrawerContent.vue';
62
+ import VTDrawerFooter from './src/components/Drawer/VTDrawerFooter.vue';
63
+ import VTDrawerHeader from './src/components/Drawer/VTDrawerHeader.vue';
64
+ import VTDrawerTitle from './src/components/Drawer/VTDrawerTitle.vue';
65
+ import VTDrawerMain from './src/components/Drawer/VTDrawerMain.vue';
66
+ import VTDrawerOverlay from './src/components/Drawer/VTDrawerOverlay.vue';
67
+ import VTDisclosure from './src/components/Disclosure/VTDisclosure.vue';
68
+ import VTDisclosureDetails from './src/components/Disclosure/VTDisclosureDetails.vue';
69
+ import VTDisclosureHeader from './src/components/Disclosure/VTDisclosureHeader.vue';
70
+ import VTDisclosureIcon from './src/components/Disclosure/VTDisclosureIcon.vue';
71
+ import VTDisclosureContent from './src/components/Disclosure/VTDisclosureContent.vue';
72
+ import VTSkeleton from './src/components/Skeleton/VTSkeleton.vue';
73
+ import VTSkeletonItem from './src/components/Skeleton/VTSkeletonItem.vue';
69
74
 
70
75
  export {
71
76
  VTAvatar,
@@ -89,8 +94,13 @@ export {
89
94
  VTPopoverGroup,
90
95
  VTPopoverItem,
91
96
  VTPopoverTrigger,
97
+ VTForm,
98
+ VTFormCol,
92
99
  VTFormFeedback,
93
100
  VTFormGroup,
101
+ VTFormRow,
102
+ VTFieldset,
103
+ VTLegend,
94
104
  VTListbox,
95
105
  VTListboxContent,
96
106
  VTListboxItem,
@@ -135,5 +145,5 @@ export {
135
145
  VTDisclosureIcon,
136
146
  VTDisclosureContent,
137
147
  VTSkeleton,
138
- VTSkeletonItem
148
+ VTSkeletonItem,
139
149
  };
@@ -245,8 +245,10 @@ export const floatingUiItemMixin = {
245
245
  return;
246
246
  }
247
247
 
248
- // unselect all items before selecting new item
249
- this.items.forEach((item) => item.unselect());
248
+ // unselect all items before selecting new one
249
+ for (const item of this.items) {
250
+ item.unselect();
251
+ }
250
252
 
251
253
  /**
252
254
  * Select item passing the event type to decide if
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@veritree/ui",
3
- "version": "0.39.2",
3
+ "version": "0.40.0",
4
4
  "description": "veritree ui library",
5
5
  "type": "module",
6
6
  "main": "index.js",
@@ -47,6 +47,7 @@
47
47
  headless && busy ? 'button--busy' : busy ? 'invisible' : null,
48
48
  ]"
49
49
  >
50
+ <!-- @slot Use this slot for the button content -->
50
51
  <slot></slot>
51
52
  </span>
52
53
  </component>
@@ -55,36 +56,98 @@
55
56
  <script>
56
57
  import VTSpinner from '../Spinner/VTSpinner.vue';
57
58
 
59
+ /**
60
+ * The veritree button.
61
+ * @displayName VTButton
62
+ */
58
63
  export default {
59
64
  name: 'VTButton',
60
65
 
61
66
  components: { VTSpinner },
62
67
 
63
68
  props: {
69
+ /**
70
+ * Specifies the visual style variant of the button
71
+ *
72
+ * @values
73
+ * - 'primary': The default primary style for the button
74
+ * - 'secondary': A secondary style for the button
75
+ * - 'tertiary': A tertiary style for the button
76
+ */
64
77
  variant: {
65
78
  type: String,
66
79
  default: 'primary',
67
80
  },
81
+
82
+ /**
83
+ * Specifies the size of the button
84
+ *
85
+ * @values
86
+ * - 'small': A smaller size for the button
87
+ * - 'large': A larger size for the button
88
+ */
68
89
  size: {
69
90
  type: String,
70
91
  default: 'large',
71
92
  },
93
+
94
+ /**
95
+ * Specifies the target URL of the button when clicked, using Vue Router's syntax for dynamic routes.
96
+ * @values
97
+ *
98
+ * - String: A static URL string
99
+ * - Object: A Vue Router route object
100
+ * - null: The button will not be clickable
101
+ */
102
+
72
103
  to: {
73
104
  type: [String, Object],
74
105
  default: null,
75
106
  },
107
+
108
+ /**
109
+ * Specifies the target URL of the button when clicked, using standard URL syntax.
110
+ * @values
111
+ *
112
+ * - String: A static URL string
113
+ * - Object: An object to be serialized into URL parameters
114
+ * - null: The button will not be clickable
115
+ */
76
116
  href: {
77
117
  type: [String, Object],
78
118
  default: null,
79
119
  },
120
+
121
+ /**
122
+ * Determines whether the button will use its default atomic style (tailwind) or its default class
123
+ *
124
+ * @values
125
+ * - true: The button will have no default style and can be fully customized with a custom class
126
+ * - false: The button will use its default atomic style (tailwind) and can be further customized with additional classes
127
+ */
80
128
  headless: {
81
129
  type: Boolean,
82
130
  default: false,
83
131
  },
132
+
133
+ /**
134
+ * Determines whether the button is currently in a loading or processing state
135
+ *
136
+ * @values
137
+ * - true: The button is in a loading or processing state and should not be interacted with until the processing is complete
138
+ * - false: The button is not in a loading or processing state and can be interacted with as usual
139
+ */
140
+
84
141
  busy: {
85
142
  type: Boolean,
86
143
  default: false,
87
144
  },
145
+
146
+ /**
147
+ * Determines whether the button is disabled or not
148
+ *
149
+ * @values true, false
150
+ */
88
151
  disabled: {
89
152
  type: Boolean,
90
153
  default: false,
@@ -46,15 +46,14 @@ export default {
46
46
 
47
47
  const emit = () => this.emit();
48
48
 
49
- const full = this.full;
50
-
51
49
  return {
52
50
  componentId,
53
51
  hide,
54
52
  emit,
55
53
  registerContent,
56
54
  registerOverlay,
57
- full,
55
+ full: this.full,
56
+ type: this.type,
58
57
  };
59
58
  },
60
59
  };
@@ -65,14 +64,18 @@ export default {
65
64
  },
66
65
 
67
66
  props: {
68
- visible: {
67
+ headless: {
69
68
  type: Boolean,
70
69
  default: false,
71
70
  },
72
- headless: {
71
+ visible: {
73
72
  type: Boolean,
74
73
  default: false,
75
74
  },
75
+ type: {
76
+ type: String,
77
+ default: null, // null or static: when set to static, the dialog will not close when clicking outside it or on esc.
78
+ },
76
79
  full: {
77
80
  type: Boolean,
78
81
  default: false,
@@ -136,7 +139,7 @@ export default {
136
139
  */
137
140
  onClick(ev) {
138
141
  if (!ev || ev.target.id !== this.overlay?.id) return;
139
- this.hide();
142
+ if (this.type !== 'static') this.hide();
140
143
  },
141
144
  },
142
145
  };
@@ -17,7 +17,7 @@
17
17
  : `relative m-auto flex flex-col overflow-auto rounded bg-white p-4 focus:outline-none lg:p-6 ${classes}`
18
18
  "
19
19
  tabindex="-1"
20
- @keydown.esc.stop="hide"
20
+ @keydown.esc.stop="onEsc"
21
21
  >
22
22
  <slot></slot>
23
23
  </div>
@@ -55,6 +55,10 @@ export default {
55
55
  full() {
56
56
  return this.apiDialog().full;
57
57
  },
58
+
59
+ type() {
60
+ return this.apiDialog().type;
61
+ },
58
62
  },
59
63
 
60
64
  mounted() {
@@ -65,6 +69,11 @@ export default {
65
69
  },
66
70
 
67
71
  methods: {
72
+ onEsc() {
73
+ if (this.type === 'static') return;
74
+ this.hide();
75
+ },
76
+
68
77
  show() {
69
78
  this.visible = true;
70
79
  },
@@ -7,6 +7,7 @@
7
7
  ? 'dialog-header'
8
8
  : '-mx-4 -mt-4 flex items-center justify-between gap-x-3 p-4 md:-mx-6 md:-mt-6 md:p-6',
9
9
  ]"
10
+ @click.stop
10
11
  >
11
12
  <slot></slot>
12
13
  </component>
@@ -0,0 +1,5 @@
1
+ <template>
2
+ <fieldset class="grid gap-3">
3
+ <slot />
4
+ </fieldset>
5
+ </template>
@@ -1,3 +1,11 @@
1
1
  <template>
2
- <form class="grid gap-3"><slot /></form>
2
+ <form class="grid gap-3" @submit.prevent="$emit('submit')">
3
+ <slot />
4
+ </form>
3
5
  </template>
6
+
7
+ <script>
8
+ export default {
9
+ name: 'VTForm',
10
+ };
11
+ </script>
@@ -0,0 +1,5 @@
1
+ <template>
2
+ <legend class="text-body mb-1 block w-full font-normal text-gray-500">
3
+ <slot />
4
+ </legend>
5
+ </template>
@@ -16,16 +16,39 @@ export default {
16
16
  provide() {
17
17
  return {
18
18
  apiListbox: () => {
19
+ const $mutable = {};
20
+
21
+ // Used to get and update the value computed
22
+ // that will then emit the value up to the
23
+ // parent component
24
+ Object.defineProperty($mutable, 'valueComputed', {
25
+ enumerable: true,
26
+ get: () => this.valueComputed,
27
+ set: (value) => (this.valueComputed = value),
28
+ });
29
+
30
+ /**
31
+ * This function registers a trigger by setting its value to the componentTrigger property of the current object.
32
+ * @param {VueComponent} trigger - The trigger to be registered.
33
+ */
19
34
  const registerTrigger = (trigger) => {
20
35
  if (!trigger) return;
21
36
  this.componentTrigger = trigger;
22
37
  };
23
38
 
39
+ /**
40
+ * Registers content to be used in the children components by setting its value to the componentContent property of the current object.
41
+ * @param {any} content - The content to be registered.
42
+ */
24
43
  const registerContent = (content) => {
25
44
  if (!content) return;
26
45
  this.componentContent = content;
27
46
  };
28
47
 
48
+ /**
49
+ * Registers search to be used in the children components by setting its value to the componentSearch property of the current object.
50
+ * @param {any} search - The search to be registered.
51
+ */
29
52
  const registerSearch = (search) => {
30
53
  if (!search) return;
31
54
  this.componentSearch = search;
@@ -52,8 +75,7 @@ export default {
52
75
  };
53
76
 
54
77
  const emit = (value) => {
55
- this.$emit('input', value);
56
- this.$emit('change', value);
78
+ this.valueComputed = value;
57
79
  };
58
80
 
59
81
  return {
@@ -63,8 +85,9 @@ export default {
63
85
  componentContent: this.componentContent,
64
86
  componentSearch: this.componentSearch,
65
87
  items: this.items,
88
+ multiple: this.multiple,
66
89
  search: this.search,
67
- selectedValue: this.value,
90
+ $mutable,
68
91
  registerTrigger,
69
92
  registerContent,
70
93
  registerSearch,
@@ -79,22 +102,55 @@ export default {
79
102
  },
80
103
 
81
104
  props: {
105
+ /**
106
+ * The value of the component. Can be a string, number, object, or array.
107
+ * @type {string|number|object|array}
108
+ * @default null
109
+ */
82
110
  value: {
83
- type: [String, Number, Object],
111
+ type: [String, Number, Object, Array],
84
112
  default: null,
85
113
  },
114
+ /**
115
+ * Determines whether the button will use its default atomic style (tailwind) or its default class
116
+ * @type {boolean}
117
+ * @values
118
+ * - true: The button will have no default style and can be fully customized with a custom class
119
+ * - false: The button will use its default atomic style (tailwind) and can be further customized with additional classes
120
+ * @default null
121
+ */
86
122
  headless: {
87
123
  type: Boolean,
88
124
  default: false,
89
125
  },
126
+ /**
127
+ * The placement of the component relative to its trigger element.
128
+ * @type {string}
129
+ * @values 'top', 'top-start', 'top-end', 'bottom', 'bottom-start', 'bottom-end', 'left', 'left-start', 'left-end', 'right', 'right-start', 'right-end'
130
+ * @default 'bottom-start'
131
+ */
90
132
  placement: {
91
133
  type: String,
92
134
  default: 'bottom-start',
93
135
  },
136
+ /**
137
+ * Determines whether the component should be aligned to the right of its trigger element.
138
+ * @type {boolean}
139
+ * @default false
140
+ */
94
141
  right: {
95
142
  type: Boolean,
96
143
  default: false,
97
144
  },
145
+ /**
146
+ * Determines whether the component should allow multiple selections.
147
+ * @type {boolean}
148
+ * @default false
149
+ */
150
+ multiple: {
151
+ type: Boolean,
152
+ default: false,
153
+ },
98
154
  },
99
155
 
100
156
  data() {
@@ -103,6 +159,7 @@ export default {
103
159
  componentSearch: null,
104
160
  search: '',
105
161
  items: [],
162
+ itemsChecked: [],
106
163
  /**
107
164
  * Explaining the need for the floatingUiMinWidth data
108
165
  *
@@ -125,6 +182,16 @@ export default {
125
182
  id() {
126
183
  return `listbox-${this.componentId}`;
127
184
  },
185
+
186
+ valueComputed: {
187
+ get() {
188
+ return this.value;
189
+ },
190
+ set(newValue) {
191
+ this.$emit('input', newValue);
192
+ this.$emit('change', newValue);
193
+ },
194
+ },
128
195
  },
129
196
  };
130
197
  </script>
@@ -16,9 +16,16 @@
16
16
  @keydown.enter.prevent="onClick"
17
17
  @keydown.tab.prevent
18
18
  >
19
- <!-- <span v-if="multiple">
20
- <input type="radio" v-model="options" :value="value" />
21
- </span> -->
19
+ <span v-if="apiListbox().multiple">
20
+ <input
21
+ v-model="apiListbox().$mutable.valueComputed"
22
+ :id="`${id}-checkbox`"
23
+ :value="value"
24
+ type="checkbox"
25
+ @click.stop
26
+ @change="onChange"
27
+ />
28
+ </span>
22
29
  <slot></slot>
23
30
  <span v-if="wasSelected" class="ml-auto">
24
31
  <IconCheckOutline class="text-secondary-200 h-5 w-5" />
@@ -53,7 +60,6 @@ export default {
53
60
  // apiInjected is used in the mixin floating-ui-item
54
61
  apiInjected: this.apiListbox,
55
62
  componentName: 'listbox-item',
56
- options: [],
57
63
  };
58
64
  },
59
65
 
@@ -79,7 +85,7 @@ export default {
79
85
  wasSelected() {
80
86
  return (
81
87
  JSON.stringify(this.value) ===
82
- JSON.stringify(this.apiListbox().selectedValue)
88
+ JSON.stringify(this.apiListbox().$mutable.valueComputed)
83
89
  );
84
90
  },
85
91
  },
@@ -1,10 +1,9 @@
1
1
  <template>
2
2
  <component
3
3
  :is="as"
4
- :class="{
5
- ListboxLabel: headless,
6
- 'mb-2 block text-xs font-normal uppercase': !headless,
7
- }"
4
+ :class="[
5
+ headless ? 'listbox-label' : 'mb-2 block text-xs font-normal uppercase',
6
+ ]"
8
7
  >
9
8
  <slot></slot>
10
9
  </component>
@@ -123,6 +123,7 @@ export default {
123
123
 
124
124
  onClick(e) {
125
125
  this.init(e);
126
+ this.$emit('click');
126
127
  },
127
128
 
128
129
  onKeyDownOrUp(e) {