@cfasim-ui/components 0.7.8 → 0.8.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (89) hide show
  1. package/dist/Box/Box.d.ts +7 -11
  2. package/dist/Button/Button.d.ts +7 -11
  3. package/dist/ButtonGroup/ButtonGroup.d.ts +8 -12
  4. package/dist/Container/Container.d.ts +7 -11
  5. package/dist/Expander/Expander.d.ts +12 -14
  6. package/dist/Grid/Grid.d.ts +6 -5
  7. package/dist/Hint/Hint.d.ts +2 -1
  8. package/dist/Icon/Icon.d.ts +3 -2
  9. package/dist/LightDarkToggle/LightDarkToggle.d.ts +2 -1
  10. package/dist/MultiSelect/MultiSelect.d.ts +6 -6
  11. package/dist/NumberInput/NumberInput.d.ts +13 -11
  12. package/dist/ParamEditor/ParamEditor.d.ts +3 -2
  13. package/dist/ParamEditor/ParamEditorImpl.d.ts +3 -5
  14. package/dist/{ParamEditorImpl-D0xZTyAN.js → ParamEditorImpl-CkElC6PI.js} +3075 -3041
  15. package/dist/SelectBox/SelectBox.d.ts +8 -6
  16. package/dist/{SelectBox-CByXZfaC.js → SelectBox-Df8dE2r-.js} +6 -6
  17. package/dist/SidebarLayout/SidebarLayout.d.ts +21 -20
  18. package/dist/Spinner/Spinner.d.ts +3 -2
  19. package/dist/TextInput/TextInput.d.ts +7 -5
  20. package/dist/Toggle/Toggle.d.ts +8 -6
  21. package/dist/ToggleGroup/ToggleGroup.d.ts +8 -6
  22. package/dist/_internal/FieldLabel.d.ts +2 -1
  23. package/dist/index.js +20 -20
  24. package/docs/Box.md +49 -0
  25. package/docs/Button.md +67 -0
  26. package/docs/ButtonGroup.md +64 -0
  27. package/docs/Container.md +103 -0
  28. package/docs/Expander.md +34 -0
  29. package/docs/Grid.md +170 -0
  30. package/docs/Hint.md +29 -0
  31. package/docs/Icon.md +188 -0
  32. package/docs/MultiSelect.md +143 -0
  33. package/docs/NumberInput.md +485 -0
  34. package/docs/ParamEditor.md +97 -0
  35. package/docs/SelectBox.md +182 -0
  36. package/docs/SidebarLayout.md +106 -0
  37. package/docs/Spinner.md +51 -0
  38. package/docs/TextInput.md +83 -0
  39. package/docs/Toggle.md +81 -0
  40. package/docs/ToggleGroup.md +163 -0
  41. package/docs/index.json +194 -0
  42. package/package.json +24 -20
  43. package/src/Box/Box.md +41 -0
  44. package/src/Box/Box.vue +52 -0
  45. package/src/Button/Button.md +59 -0
  46. package/src/Button/Button.vue +81 -0
  47. package/src/ButtonGroup/ButtonGroup.md +62 -0
  48. package/src/ButtonGroup/ButtonGroup.vue +91 -0
  49. package/src/Container/Container.md +99 -0
  50. package/src/Container/Container.vue +62 -0
  51. package/src/Expander/Expander.md +23 -0
  52. package/src/Expander/Expander.vue +95 -0
  53. package/src/Grid/Grid.md +175 -0
  54. package/src/Grid/Grid.vue +145 -0
  55. package/src/Hint/Hint.md +24 -0
  56. package/src/Hint/Hint.vue +83 -0
  57. package/src/Icon/Icon.md +176 -0
  58. package/src/Icon/Icon.vue +104 -0
  59. package/src/Icon/defaultIcons.ts +92 -0
  60. package/src/Icon/github.svg +1 -0
  61. package/src/Icon/registry.ts +68 -0
  62. package/src/LightDarkToggle/LightDarkToggle.vue +49 -0
  63. package/src/MultiSelect/MultiSelect.md +142 -0
  64. package/src/MultiSelect/MultiSelect.vue +279 -0
  65. package/src/NumberInput/NumberInput.md +455 -0
  66. package/src/NumberInput/NumberInput.vue +575 -0
  67. package/src/ParamEditor/ParamEditor.md +87 -0
  68. package/src/ParamEditor/ParamEditor.vue +43 -0
  69. package/src/ParamEditor/ParamEditorImpl.vue +358 -0
  70. package/src/SelectBox/SelectBox.md +169 -0
  71. package/src/SelectBox/SelectBox.vue +260 -0
  72. package/src/SidebarLayout/SidebarLayout.md +106 -0
  73. package/src/SidebarLayout/SidebarLayout.vue +468 -0
  74. package/src/Spinner/Spinner.md +45 -0
  75. package/src/Spinner/Spinner.vue +55 -0
  76. package/src/TextInput/TextInput.md +68 -0
  77. package/src/TextInput/TextInput.vue +54 -0
  78. package/src/Toggle/Toggle.md +68 -0
  79. package/src/Toggle/Toggle.vue +81 -0
  80. package/src/ToggleGroup/ToggleGroup.md +158 -0
  81. package/src/ToggleGroup/ToggleGroup.vue +138 -0
  82. package/src/_internal/FieldLabel.vue +27 -0
  83. package/src/_internal/field.ts +27 -0
  84. package/src/_internal/gap.ts +17 -0
  85. package/src/_internal/input.css +54 -0
  86. package/src/_internal/listbox.css +53 -0
  87. package/src/env.d.ts +4 -0
  88. package/src/index.ts +33 -0
  89. package/src/svg.d.ts +5 -0
@@ -0,0 +1,182 @@
1
+ # SelectBox
2
+
3
+ A single-select dropdown built on reka-ui. Set `autocomplete` to turn it into a
4
+ filterable single-select combobox: type to narrow the options, just like
5
+ [MultiSelect](./multi-select) but bound to a single `string`.
6
+
7
+ ## Examples
8
+
9
+ <script setup>
10
+ import { ref } from 'vue'
11
+ const interval = ref('weekly')
12
+ const state = ref('')
13
+ </script>
14
+
15
+ <ComponentDemo>
16
+ <div style="width: 200px">
17
+ <SelectBox
18
+ v-model="interval"
19
+ label="Interval"
20
+ :options="[
21
+ { value: 'daily', label: 'Daily' },
22
+ { value: 'weekly', label: 'Weekly' },
23
+ { value: 'monthly', label: 'Monthly' },
24
+ ]"
25
+ />
26
+ </div>
27
+
28
+ <template #code>
29
+
30
+ ```vue
31
+ <script setup>
32
+ import { ref } from "vue";
33
+ const interval = ref("weekly");
34
+ </script>
35
+
36
+ <SelectBox
37
+ v-model="interval"
38
+ label="Interval"
39
+ :options="[
40
+ { value: 'daily', label: 'Daily' },
41
+ { value: 'weekly', label: 'Weekly' },
42
+ { value: 'monthly', label: 'Monthly' },
43
+ ]"
44
+ />
45
+ ```
46
+
47
+ </template>
48
+ </ComponentDemo>
49
+
50
+ ### Hidden label
51
+
52
+ Use `hide-label` to visually hide the label while keeping it available to
53
+ screen readers. Prefer this over `aria-label` whenever you have label text,
54
+ since a real `<label>` is translated by browsers and keeps the naming in the
55
+ DOM.
56
+
57
+ <ComponentDemo>
58
+ <div style="width: 200px">
59
+ <SelectBox
60
+ v-model="interval"
61
+ label="Interval"
62
+ hide-label
63
+ :options="[
64
+ { value: 'daily', label: 'Daily' },
65
+ { value: 'weekly', label: 'Weekly' },
66
+ { value: 'monthly', label: 'Monthly' },
67
+ ]"
68
+ />
69
+ </div>
70
+
71
+ <template #code>
72
+
73
+ ```vue
74
+ <SelectBox
75
+ v-model="interval"
76
+ label="Interval"
77
+ hide-label
78
+ :options="[
79
+ { value: 'daily', label: 'Daily' },
80
+ { value: 'weekly', label: 'Weekly' },
81
+ { value: 'monthly', label: 'Monthly' },
82
+ ]"
83
+ />
84
+ ```
85
+
86
+ </template>
87
+ </ComponentDemo>
88
+
89
+ ### Autocomplete
90
+
91
+ Add `autocomplete` to make the field filterable. Type to narrow the list; the
92
+ selected option's label fills the input. `v-model` is still a single `string`.
93
+
94
+ <ComponentDemo>
95
+ <div style="width: 240px">
96
+ <SelectBox
97
+ v-model="state"
98
+ autocomplete
99
+ label="State"
100
+ placeholder="Search states…"
101
+ :options="[
102
+ { value: 'ca', label: 'California' },
103
+ { value: 'ny', label: 'New York' },
104
+ { value: 'tx', label: 'Texas' },
105
+ { value: 'wa', label: 'Washington' },
106
+ { value: 'fl', label: 'Florida' },
107
+ ]"
108
+ />
109
+ </div>
110
+
111
+ <template #code>
112
+
113
+ ```vue
114
+ <script setup>
115
+ import { ref } from "vue";
116
+ const state = ref("");
117
+ </script>
118
+
119
+ <SelectBox
120
+ v-model="state"
121
+ autocomplete
122
+ label="State"
123
+ placeholder="Search states…"
124
+ :options="[
125
+ { value: 'ca', label: 'California' },
126
+ { value: 'ny', label: 'New York' },
127
+ { value: 'tx', label: 'Texas' },
128
+ { value: 'wa', label: 'Washington' },
129
+ { value: 'fl', label: 'Florida' },
130
+ ]"
131
+ />
132
+ ```
133
+
134
+ </template>
135
+ </ComponentDemo>
136
+
137
+ ## Accessibility
138
+
139
+ In the default mode the field is a reka-ui Select; with `autocomplete` it's a
140
+ reka-ui Combobox following the
141
+ [ARIA combobox pattern](https://www.w3.org/WAI/ARIA/apg/patterns/combobox/):
142
+
143
+ - The input has `role="combobox"` with `aria-expanded`, `aria-controls`, and
144
+ `aria-autocomplete="list"`; the popup is a `role="listbox"` and each option a
145
+ `role="option"` that reflects its state via `aria-selected`.
146
+ - Keyboard support is handled for you: type to filter, ↑/↓ to move through the
147
+ list, Enter to select the highlighted option, and Escape to close.
148
+ - Pass `label` so the field is named by a real `<label>`. In autocomplete mode
149
+ the label is also wired to the input via `for`/`id`, so clicking it focuses
150
+ the field; use `hide-label` to keep the label for screen readers while hiding
151
+ it visually, or `aria-label` when there's no visible label text.
152
+ - The chevron is a labelled toggle (`aria-label="Toggle options"`) kept out of
153
+ the tab order, and native browser autofill is disabled so it can't cover the
154
+ option list.
155
+
156
+ ## Model
157
+
158
+ | Name | Type |
159
+ |------|------|
160
+ | `v-model` | `string` |
161
+
162
+ ## Props
163
+
164
+ | Prop | Type | Required | Default |
165
+ |------|------|----------|---------|
166
+ | `label` | `string` | No | — |
167
+ | `hideLabel` | `boolean` | No | — |
168
+ | `ariaLabel` | `string` | No | — |
169
+ | `hint` | `string` | No | — |
170
+ | `options` | `SelectOption[]` | Yes | — |
171
+ | `placeholder` | `string` | No | — |
172
+ | `autocomplete` | `boolean` | No | — |
173
+
174
+
175
+ ### SelectOption
176
+
177
+ ```ts
178
+ interface SelectOption {
179
+ value: string;
180
+ label: string;
181
+ }
182
+ ```
@@ -0,0 +1,106 @@
1
+ # SidebarLayout
2
+
3
+ A responsive two-panel layout with a collapsible sidebar and main content area. On mobile, the sidebar becomes an overlay.
4
+
5
+ When the sidebar is collapsed it is marked [`inert`](https://developer.mozilla.org/en-US/docs/Web/HTML/Global_attributes/inert), so its contents (including the collapse button) are removed from the tab order and the accessibility tree while visually hidden. The expand button is likewise `inert` while the sidebar is open. This keeps keyboard and screen-reader focus on whichever control is actually visible.
6
+
7
+ ## Demo
8
+
9
+ <a href="/cfa-simulator/docs/demos/sidebar-layout/index.html" target="_blank">Open in full window ↗</a>
10
+
11
+ <div style="border: 1px solid var(--vp-c-border); border-radius: 8px; overflow: hidden; height: 500px;">
12
+ <iframe src="/cfa-simulator/docs/demos/sidebar-layout/index.html" style="width: 100%; height: 100%; border: none;" />
13
+ </div>
14
+
15
+ ## Tabs Demo (Router Mode)
16
+
17
+ <a href="/cfa-simulator/docs/demos/sidebar-tabs/index.html" target="_blank">Open in full window ↗</a>
18
+
19
+ <div style="border: 1px solid var(--vp-c-border); border-radius: 8px; overflow: hidden; height: 500px;">
20
+ <iframe src="/cfa-simulator/docs/demos/sidebar-tabs/index.html" style="width: 100%; height: 100%; border: none;" />
21
+ </div>
22
+
23
+ ## Usage
24
+
25
+ ```vue
26
+ <SidebarLayout>
27
+ <template #sidebar>
28
+ <h2>Controls</h2>
29
+ <NumberInput v-model="value" label="Parameter" slider live />
30
+ </template>
31
+ <h1>Main Content</h1>
32
+ <p>Your charts and data go here.</p>
33
+ </SidebarLayout>
34
+ ```
35
+
36
+ ## Slots
37
+
38
+ | Slot | Description |
39
+ | --------- | ------------------------------------------ |
40
+ | `sidebar` | Content rendered in the left sidebar panel |
41
+ | `default` | Main content area |
42
+
43
+ ## Props
44
+
45
+ | Prop | Type | Default | Description |
46
+ | ------------- | --------- | ----------- | ---------------------------------------------------- |
47
+ | `hideTopbar` | `boolean` | `false` | Hides the topbar that contains the light/dark toggle |
48
+ | `tabs` | `Tab[]` | `undefined` | Array of tab definitions to render in the main area |
49
+ | `v-model:tab` | `string` | `undefined` | The active tab value (two-way binding) |
50
+
51
+ ### Tab type
52
+
53
+ ```ts
54
+ interface Tab {
55
+ value: string; // unique identifier
56
+ label: string; // display text
57
+ to?: string; // optional route path for vue-router integration
58
+ }
59
+ ```
60
+
61
+ ## Tabs
62
+
63
+ When the `tabs` prop is provided, a tab bar renders at the top of the main content area. Tabs support two modes:
64
+
65
+ ### Local mode
66
+
67
+ Use `v-model:tab` to control which tab is active. Render content conditionally in the default slot.
68
+
69
+ ```vue
70
+ <script setup>
71
+ import { ref } from "vue";
72
+ const activeTab = ref("chart");
73
+ </script>
74
+
75
+ <SidebarLayout
76
+ v-model:tab="activeTab"
77
+ :tabs="[
78
+ { value: 'chart', label: 'Chart' },
79
+ { value: 'data', label: 'Data' },
80
+ ]"
81
+ >
82
+ <template #sidebar>
83
+ <h2>Controls</h2>
84
+ </template>
85
+ <div v-if="activeTab === 'chart'">Chart content</div>
86
+ <div v-if="activeTab === 'data'">Data table</div>
87
+ </SidebarLayout>
88
+ ```
89
+
90
+ ### Router mode
91
+
92
+ When tabs include a `to` property and vue-router is installed, clicking a tab navigates to that route. The active tab is automatically determined from the current route.
93
+
94
+ ```vue
95
+ <SidebarLayout
96
+ :tabs="[
97
+ { value: 'chart', label: 'Chart', to: '/model/chart' },
98
+ { value: 'data', label: 'Data', to: '/model/data' },
99
+ ]"
100
+ >
101
+ <template #sidebar>
102
+ <h2>Controls</h2>
103
+ </template>
104
+ <RouterView />
105
+ </SidebarLayout>
106
+ ```
@@ -0,0 +1,51 @@
1
+ # Spinner
2
+
3
+ A loading indicator with accessible labeling.
4
+
5
+ ## Examples
6
+
7
+ ### Sizes
8
+
9
+ <ComponentDemo>
10
+ <Spinner size="sm" label="Loading" />
11
+ <Spinner size="md" label="Loading" />
12
+ <Spinner size="lg" label="Loading" />
13
+
14
+ <template #code>
15
+
16
+ ```vue
17
+ <Spinner size="sm" label="Loading" />
18
+ <Spinner size="md" label="Loading" />
19
+ <Spinner size="lg" label="Loading" />
20
+ ```
21
+
22
+ </template>
23
+ </ComponentDemo>
24
+
25
+ ### In context
26
+
27
+ <ComponentDemo>
28
+ <div style="display: flex; align-items: center; gap: 8px;">
29
+ <Spinner size="sm" label="Running model" />
30
+ <span>Running model...</span>
31
+ </div>
32
+
33
+ <template #code>
34
+
35
+ ```vue
36
+ <div style="display: flex; align-items: center; gap: 8px;">
37
+ <Spinner size="sm" label="Running model" />
38
+ <span>Running model...</span>
39
+ </div>
40
+ ```
41
+
42
+ </template>
43
+ </ComponentDemo>
44
+
45
+ ## Props
46
+
47
+ | Prop | Type | Required | Default |
48
+ |------|------|----------|---------|
49
+ | `size` | `SpinnerSize` | No | `"sm"` |
50
+ | `label` | `string` | No | — |
51
+
@@ -0,0 +1,83 @@
1
+ # TextInput
2
+
3
+ A text input field with optional label and hint.
4
+
5
+ ## Examples
6
+
7
+ <script setup>
8
+ import { ref } from 'vue'
9
+ const name = ref('')
10
+ </script>
11
+
12
+ <ComponentDemo>
13
+ <div style="width: 300px">
14
+ <TextInput
15
+ v-model="name"
16
+ label="Model name"
17
+ placeholder="e.g. my-model"
18
+ hint="A short identifier used in URLs"
19
+ />
20
+ </div>
21
+
22
+ <template #code>
23
+
24
+ ```vue
25
+ <script setup>
26
+ import { ref } from "vue";
27
+ const name = ref("");
28
+ </script>
29
+
30
+ <TextInput
31
+ v-model="name"
32
+ label="Model name"
33
+ placeholder="e.g. my-model"
34
+ hint="A short identifier used in URLs"
35
+ />
36
+ ```
37
+
38
+ </template>
39
+ </ComponentDemo>
40
+
41
+ ### Hidden label
42
+
43
+ Use `hide-label` to visually hide the label while keeping it available to screen
44
+ readers. The label is still a real `<label>` in the DOM, so clicking the input
45
+ area still works and the control is properly named for assistive tech. Prefer
46
+ this over omitting the label whenever the input has no visible text describing
47
+ it.
48
+
49
+ <ComponentDemo>
50
+ <div style="width: 300px">
51
+ <TextInput
52
+ v-model="name"
53
+ label="Search"
54
+ placeholder="Search…"
55
+ hide-label
56
+ />
57
+ </div>
58
+
59
+ <template #code>
60
+
61
+ ```vue
62
+ <TextInput v-model="name" label="Search" placeholder="Search…" hide-label />
63
+ ```
64
+
65
+ </template>
66
+ </ComponentDemo>
67
+
68
+ ## Model
69
+
70
+ | Name | Type |
71
+ |------|------|
72
+ | `v-model` | `string` |
73
+
74
+ ## Props
75
+
76
+ | Prop | Type | Required | Default |
77
+ |------|------|----------|---------|
78
+ | `label` | `string` | No | — |
79
+ | `hideLabel` | `boolean` | No | — |
80
+ | `ariaLabel` | `string` | No | — |
81
+ | `hint` | `string` | No | — |
82
+ | `placeholder` | `string` | No | — |
83
+
package/docs/Toggle.md ADDED
@@ -0,0 +1,81 @@
1
+ # Toggle
2
+
3
+ A boolean switch built on reka-ui.
4
+
5
+ ## Examples
6
+
7
+ <script setup>
8
+ import { ref } from 'vue'
9
+ const enabled = ref(false)
10
+ const disabled = ref(true)
11
+ </script>
12
+
13
+ ### Basic
14
+
15
+ <ComponentDemo>
16
+ <Toggle v-model="enabled" label="Enable vaccination" />
17
+
18
+ <template #code>
19
+
20
+ ```vue
21
+ <script setup>
22
+ import { ref } from "vue";
23
+ const enabled = ref(false);
24
+ </script>
25
+
26
+ <Toggle v-model="enabled" label="Enable vaccination" />
27
+ ```
28
+
29
+ </template>
30
+ </ComponentDemo>
31
+
32
+ ### With hint
33
+
34
+ <ComponentDemo>
35
+ <Toggle
36
+ v-model="enabled"
37
+ label="Enable isolation"
38
+ hint="Whether symptomatic individuals are isolated"
39
+ />
40
+
41
+ <template #code>
42
+
43
+ ```vue
44
+ <Toggle
45
+ v-model="enabled"
46
+ label="Enable isolation"
47
+ hint="Whether symptomatic individuals are isolated"
48
+ />
49
+ ```
50
+
51
+ </template>
52
+ </ComponentDemo>
53
+
54
+ ### Disabled
55
+
56
+ <ComponentDemo>
57
+ <Toggle v-model="disabled" label="Locked setting" :disabled="true" />
58
+
59
+ <template #code>
60
+
61
+ ```vue
62
+ <Toggle v-model="value" label="Locked setting" :disabled="true" />
63
+ ```
64
+
65
+ </template>
66
+ </ComponentDemo>
67
+
68
+ ## Model
69
+
70
+ | Name | Type |
71
+ |------|------|
72
+ | `v-model` | `boolean` |
73
+
74
+ ## Props
75
+
76
+ | Prop | Type | Required | Default |
77
+ |------|------|----------|---------|
78
+ | `label` | `string` | Yes | — |
79
+ | `hint` | `string` | No | — |
80
+ | `disabled` | `boolean` | No | — |
81
+
@@ -0,0 +1,163 @@
1
+ # ToggleGroup
2
+
3
+ A segmented control that looks like a [`ButtonGroup`](./button-group) but tracks
4
+ which item(s) are pressed. By default it is single-select (like a radio group);
5
+ add `multiple` to let several items be pressed at once. Built on
6
+ [reka-ui's ToggleGroup](https://reka-ui.com/docs/components/toggle-group).
7
+
8
+ ## Examples
9
+
10
+ ### Single select
11
+
12
+ `v-model` holds the pressed value (a `string`). Clicking the active item again
13
+ clears the selection.
14
+
15
+ <script setup>
16
+ import { ref } from 'vue'
17
+ const interval = ref('weekly')
18
+ const days = ref(['mon', 'wed'])
19
+ </script>
20
+
21
+ <ComponentDemo>
22
+ <ToggleGroup
23
+ v-model="interval"
24
+ label="Interval"
25
+ :options="[
26
+ { value: 'daily', label: 'Daily' },
27
+ { value: 'weekly', label: 'Weekly' },
28
+ { value: 'monthly', label: 'Monthly' },
29
+ ]"
30
+ />
31
+ <p>Selected: {{ interval }}</p>
32
+
33
+ <template #code>
34
+
35
+ ```vue
36
+ <script setup>
37
+ import { ref } from "vue";
38
+ const interval = ref("weekly");
39
+ </script>
40
+
41
+ <ToggleGroup
42
+ v-model="interval"
43
+ label="Interval"
44
+ :options="[
45
+ { value: 'daily', label: 'Daily' },
46
+ { value: 'weekly', label: 'Weekly' },
47
+ { value: 'monthly', label: 'Monthly' },
48
+ ]"
49
+ />
50
+ ```
51
+
52
+ </template>
53
+ </ComponentDemo>
54
+
55
+ ### Multiple select
56
+
57
+ With `multiple`, `v-model` is a `string[]` and any number of items can be
58
+ pressed at once.
59
+
60
+ <ComponentDemo>
61
+ <ToggleGroup
62
+ v-model="days"
63
+ multiple
64
+ label="Active days"
65
+ :options="[
66
+ { value: 'mon', label: 'Mon' },
67
+ { value: 'tue', label: 'Tue' },
68
+ { value: 'wed', label: 'Wed' },
69
+ { value: 'thu', label: 'Thu' },
70
+ { value: 'fri', label: 'Fri' },
71
+ ]"
72
+ />
73
+ <p>Selected: {{ days.join(', ') || 'none' }}</p>
74
+
75
+ <template #code>
76
+
77
+ ```vue
78
+ <script setup>
79
+ import { ref } from "vue";
80
+ const days = ref(["mon", "wed"]);
81
+ </script>
82
+
83
+ <ToggleGroup
84
+ v-model="days"
85
+ multiple
86
+ label="Active days"
87
+ :options="[
88
+ { value: 'mon', label: 'Mon' },
89
+ { value: 'tue', label: 'Tue' },
90
+ { value: 'wed', label: 'Wed' },
91
+ { value: 'thu', label: 'Thu' },
92
+ { value: 'fri', label: 'Fri' },
93
+ ]"
94
+ />
95
+ ```
96
+
97
+ </template>
98
+ </ComponentDemo>
99
+
100
+ ### Vertical and disabled options
101
+
102
+ Set `orientation="vertical"` to stack the items, and mark individual options
103
+ `disabled`.
104
+
105
+ <ComponentDemo>
106
+ <ToggleGroup
107
+ model-value="map"
108
+ orientation="vertical"
109
+ aria-label="View"
110
+ :options="[
111
+ { value: 'map', label: 'Map' },
112
+ { value: 'chart', label: 'Chart' },
113
+ { value: 'table', label: 'Table', disabled: true },
114
+ ]"
115
+ />
116
+
117
+ <template #code>
118
+
119
+ ```vue
120
+ <ToggleGroup
121
+ v-model="view"
122
+ orientation="vertical"
123
+ aria-label="View"
124
+ :options="[
125
+ { value: 'map', label: 'Map' },
126
+ { value: 'chart', label: 'Chart' },
127
+ { value: 'table', label: 'Table', disabled: true },
128
+ ]"
129
+ />
130
+ ```
131
+
132
+ </template>
133
+ </ComponentDemo>
134
+
135
+ ## Model
136
+
137
+ | Name | Type |
138
+ |------|------|
139
+ | `v-model` | `string \| string[]` |
140
+
141
+ ## Props
142
+
143
+ | Prop | Type | Required | Default |
144
+ |------|------|----------|---------|
145
+ | `label` | `string` | No | — |
146
+ | `hideLabel` | `boolean` | No | — |
147
+ | `ariaLabel` | `string` | No | — |
148
+ | `hint` | `string` | No | — |
149
+ | `options` | `ToggleGroupOption[]` | Yes | — |
150
+ | `multiple` | `boolean` | No | — |
151
+ | `disabled` | `boolean` | No | — |
152
+ | `orientation` | `"horizontal" \| "vertical"` | No | `"horizontal"` |
153
+
154
+
155
+ ### ToggleGroupOption
156
+
157
+ ```ts
158
+ interface ToggleGroupOption {
159
+ value: string;
160
+ label: string;
161
+ disabled?: boolean;
162
+ }
163
+ ```