@umbra.ui/core 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (272) hide show
  1. package/dist/components/controls/Dropdown/types.d.ts +5 -0
  2. package/dist/components/controls/Dropdown/types.d.ts.map +1 -0
  3. package/dist/components/controls/Dropdown/types.js +1 -0
  4. package/dist/components/controls/SegmentedControl/types.d.ts +6 -0
  5. package/dist/components/controls/SegmentedControl/types.d.ts.map +1 -0
  6. package/dist/components/controls/SegmentedControl/types.js +1 -0
  7. package/dist/components/dialogs/Alert/types.d.ts +7 -0
  8. package/dist/components/dialogs/Alert/types.d.ts.map +1 -0
  9. package/dist/components/dialogs/Alert/types.js +1 -0
  10. package/dist/components/dialogs/Toast/types.d.ts +34 -0
  11. package/dist/components/dialogs/Toast/types.d.ts.map +1 -0
  12. package/dist/components/dialogs/Toast/types.js +10 -0
  13. package/dist/components/dialogs/Toast/useToast.d.ts +36 -0
  14. package/dist/components/dialogs/Toast/useToast.d.ts.map +1 -0
  15. package/dist/components/dialogs/Toast/useToast.js +90 -0
  16. package/dist/components/indicators/Tooltip/tooltip.d.ts +3 -0
  17. package/dist/components/indicators/Tooltip/tooltip.d.ts.map +1 -0
  18. package/dist/components/indicators/Tooltip/tooltip.js +33 -0
  19. package/dist/components/indicators/Tooltip/types.d.ts +14 -0
  20. package/dist/components/indicators/Tooltip/types.d.ts.map +1 -0
  21. package/dist/components/indicators/Tooltip/types.js +1 -0
  22. package/dist/components/indicators/Tooltip/useTooltip.d.ts +18 -0
  23. package/dist/components/indicators/Tooltip/useTooltip.d.ts.map +1 -0
  24. package/dist/components/indicators/Tooltip/useTooltip.js +57 -0
  25. package/dist/components/inputs/Tags/tag-bar-styles.d.ts +14 -0
  26. package/dist/components/inputs/Tags/tag-bar-styles.d.ts.map +1 -0
  27. package/dist/components/inputs/Tags/tag-bar-styles.js +313 -0
  28. package/dist/components/inputs/Tags/types.d.ts +93 -0
  29. package/dist/components/inputs/Tags/types.d.ts.map +1 -0
  30. package/dist/components/inputs/Tags/types.js +216 -0
  31. package/dist/components/inputs/search/types.d.ts +9 -0
  32. package/dist/components/inputs/search/types.d.ts.map +1 -0
  33. package/dist/components/inputs/search/types.js +1 -0
  34. package/dist/components/navigation/adaptive/types.d.ts +16 -0
  35. package/dist/components/navigation/adaptive/types.d.ts.map +1 -0
  36. package/dist/components/navigation/adaptive/types.js +1 -0
  37. package/dist/components/navigation/adaptive/useAdaptiveLayout.d.ts +27 -0
  38. package/dist/components/navigation/adaptive/useAdaptiveLayout.d.ts.map +1 -0
  39. package/dist/components/navigation/adaptive/useAdaptiveLayout.js +40 -0
  40. package/dist/components/navigation/adaptive/useBreakpoints.d.ts +6 -0
  41. package/dist/components/navigation/adaptive/useBreakpoints.d.ts.map +1 -0
  42. package/dist/components/navigation/adaptive/useBreakpoints.js +37 -0
  43. package/dist/components/navigation/adaptive/useContainerMonitor.d.ts +93 -0
  44. package/dist/components/navigation/adaptive/useContainerMonitor.d.ts.map +1 -0
  45. package/dist/components/navigation/adaptive/useContainerMonitor.js +145 -0
  46. package/dist/components/navigation/adaptive/useViewAnimation.d.ts +31 -0
  47. package/dist/components/navigation/adaptive/useViewAnimation.d.ts.map +1 -0
  48. package/dist/components/navigation/adaptive/useViewAnimation.js +591 -0
  49. package/dist/components/navigation/adaptive/useViewResize.d.ts +52 -0
  50. package/dist/components/navigation/adaptive/useViewResize.d.ts.map +1 -0
  51. package/dist/components/navigation/adaptive/useViewResize.js +146 -0
  52. package/dist/components/navigation/navstack/useNavigationStack.d.ts +25 -0
  53. package/dist/components/navigation/navstack/useNavigationStack.d.ts.map +1 -0
  54. package/dist/components/navigation/navstack/useNavigationStack.js +133 -0
  55. package/dist/components/navigation/slideover/useSlideoverController.d.ts +20 -0
  56. package/dist/components/navigation/slideover/useSlideoverController.d.ts.map +1 -0
  57. package/dist/components/navigation/slideover/useSlideoverController.js +267 -0
  58. package/dist/components/navigation/splitview/useSplitViewController.d.ts +20 -0
  59. package/dist/components/navigation/splitview/useSplitViewController.d.ts.map +1 -0
  60. package/dist/components/navigation/splitview/useSplitViewController.js +325 -0
  61. package/dist/components/navigation/tabcontroller/types.d.ts +21 -0
  62. package/dist/components/navigation/tabcontroller/types.d.ts.map +1 -0
  63. package/dist/components/navigation/tabcontroller/types.js +1 -0
  64. package/dist/components/navigation/tabcontroller/useTabController.d.ts +5 -0
  65. package/dist/components/navigation/tabcontroller/useTabController.d.ts.map +1 -0
  66. package/dist/components/navigation/tabcontroller/useTabController.js +10 -0
  67. package/dist/components/navigation/types.d.ts +8 -0
  68. package/dist/components/navigation/types.d.ts.map +1 -0
  69. package/dist/components/navigation/types.js +1 -0
  70. package/dist/components/pickers/CollectionPicker/types.d.ts +11 -0
  71. package/dist/components/pickers/CollectionPicker/types.d.ts.map +1 -0
  72. package/dist/components/pickers/CollectionPicker/types.js +1 -0
  73. package/dist/components/pickers/ColorPicker/colors.d.ts +13 -0
  74. package/dist/components/pickers/ColorPicker/colors.d.ts.map +1 -0
  75. package/dist/components/pickers/ColorPicker/colors.js +266 -0
  76. package/dist/components/pickers/FilePicker/types.d.ts +10 -0
  77. package/dist/components/pickers/FilePicker/types.d.ts.map +1 -0
  78. package/dist/components/pickers/FilePicker/types.js +1 -0
  79. package/dist/index.d.ts +91 -0
  80. package/dist/index.d.ts.map +1 -0
  81. package/dist/index.js +196 -0
  82. package/dist/theme.d.ts +73 -0
  83. package/dist/theme.d.ts.map +1 -0
  84. package/dist/theme.js +279 -0
  85. package/dist/themes/blank.d.ts +7 -0
  86. package/dist/themes/blank.d.ts.map +1 -0
  87. package/dist/themes/blank.js +543 -0
  88. package/dist/themes/crimson-dark.d.ts +4 -0
  89. package/dist/themes/crimson-dark.d.ts.map +1 -0
  90. package/dist/themes/crimson-dark.js +552 -0
  91. package/dist/themes/cyan-light.d.ts +4 -0
  92. package/dist/themes/cyan-light.d.ts.map +1 -0
  93. package/dist/themes/cyan-light.js +552 -0
  94. package/dist/themes/dark.d.ts +4 -0
  95. package/dist/themes/dark.d.ts.map +1 -0
  96. package/dist/themes/dark.js +551 -0
  97. package/dist/themes/gold-dark.d.ts +4 -0
  98. package/dist/themes/gold-dark.d.ts.map +1 -0
  99. package/dist/themes/gold-dark.js +552 -0
  100. package/dist/themes/grass-dark.d.ts +4 -0
  101. package/dist/themes/grass-dark.d.ts.map +1 -0
  102. package/dist/themes/grass-dark.js +552 -0
  103. package/dist/themes/indigo.d.ts +4 -0
  104. package/dist/themes/indigo.d.ts.map +1 -0
  105. package/dist/themes/indigo.js +552 -0
  106. package/dist/themes/light.d.ts +4 -0
  107. package/dist/themes/light.d.ts.map +1 -0
  108. package/dist/themes/light.js +551 -0
  109. package/dist/themes/orange-dark.d.ts +4 -0
  110. package/dist/themes/orange-dark.d.ts.map +1 -0
  111. package/dist/themes/orange-dark.js +551 -0
  112. package/dist/themes/orange-light.d.ts +4 -0
  113. package/dist/themes/orange-light.d.ts.map +1 -0
  114. package/dist/themes/orange-light.js +551 -0
  115. package/package.json +62 -0
  116. package/src/components/controls/Button/Button.vue +417 -0
  117. package/src/components/controls/Button/README.md +348 -0
  118. package/src/components/controls/Button/theme.css +200 -0
  119. package/src/components/controls/Checkbox/Checkbox.vue +164 -0
  120. package/src/components/controls/Checkbox/README.md +441 -0
  121. package/src/components/controls/Checkbox/theme.css +36 -0
  122. package/src/components/controls/Dropdown/Dropdown.vue +476 -0
  123. package/src/components/controls/Dropdown/README.md +370 -0
  124. package/src/components/controls/Dropdown/theme.css +50 -0
  125. package/src/components/controls/Dropdown/types.ts +6 -0
  126. package/src/components/controls/IconButton/IconButton.vue +267 -0
  127. package/src/components/controls/IconButton/README.md +502 -0
  128. package/src/components/controls/IconButton/theme.css +89 -0
  129. package/src/components/controls/Radio/README.md +591 -0
  130. package/src/components/controls/Radio/Radio.vue +89 -0
  131. package/src/components/controls/Radio/theme.css +14 -0
  132. package/src/components/controls/RangeSlider/README.md +608 -0
  133. package/src/components/controls/RangeSlider/RangeSlider.vue +535 -0
  134. package/src/components/controls/RangeSlider/theme.css +80 -0
  135. package/src/components/controls/SegmentedControl/README.md +587 -0
  136. package/src/components/controls/SegmentedControl/SegmentedControl.vue +284 -0
  137. package/src/components/controls/SegmentedControl/theme.css +60 -0
  138. package/src/components/controls/SegmentedControl/types.ts +5 -0
  139. package/src/components/controls/Slider/README.md +627 -0
  140. package/src/components/controls/Slider/Slider.vue +260 -0
  141. package/src/components/controls/Slider/theme.css +74 -0
  142. package/src/components/controls/Stepper/README.md +601 -0
  143. package/src/components/controls/Stepper/Stepper.vue +103 -0
  144. package/src/components/controls/Stepper/theme.css +53 -0
  145. package/src/components/controls/Switch/README.md +667 -0
  146. package/src/components/controls/Switch/Switch.vue +127 -0
  147. package/src/components/controls/Switch/theme.css +42 -0
  148. package/src/components/dialogs/Alert/Alert.vue +218 -0
  149. package/src/components/dialogs/Alert/README.md +450 -0
  150. package/src/components/dialogs/Alert/theme.css +44 -0
  151. package/src/components/dialogs/Alert/types.ts +11 -0
  152. package/src/components/dialogs/Toast/README.md +522 -0
  153. package/src/components/dialogs/Toast/Toast.vue +296 -0
  154. package/src/components/dialogs/Toast/ToastContainer.vue +330 -0
  155. package/src/components/dialogs/Toast/theme.css +44 -0
  156. package/src/components/dialogs/Toast/types.ts +46 -0
  157. package/src/components/dialogs/Toast/useToast.ts +127 -0
  158. package/src/components/indicators/ProgressBar/ProgressBar.vue +98 -0
  159. package/src/components/indicators/ProgressBar/README.md +744 -0
  160. package/src/components/indicators/ProgressBar/theme.css +36 -0
  161. package/src/components/indicators/Tooltip/README.md +723 -0
  162. package/src/components/indicators/Tooltip/TooltipProvider.vue +142 -0
  163. package/src/components/indicators/Tooltip/theme.css +18 -0
  164. package/src/components/indicators/Tooltip/tooltip.ts +48 -0
  165. package/src/components/indicators/Tooltip/types.ts +15 -0
  166. package/src/components/indicators/Tooltip/useTooltip.ts +71 -0
  167. package/src/components/inputs/AutogrowTextView/AutogrowTextView.vue +110 -0
  168. package/src/components/inputs/AutogrowTextView/README.md +643 -0
  169. package/src/components/inputs/AutogrowTextView/theme.css +28 -0
  170. package/src/components/inputs/InputCard/InputCard.vue +600 -0
  171. package/src/components/inputs/InputCard/README.md +636 -0
  172. package/src/components/inputs/InputEmail/InputEmail.vue +698 -0
  173. package/src/components/inputs/InputEmail/README.md +764 -0
  174. package/src/components/inputs/InputNumber/InputNumber.vue +300 -0
  175. package/src/components/inputs/InputNumber/README.md +749 -0
  176. package/src/components/inputs/InputPhone/InputPhone.vue +645 -0
  177. package/src/components/inputs/InputPhone/README.md +636 -0
  178. package/src/components/inputs/InputSecure/InputSecure.vue +646 -0
  179. package/src/components/inputs/InputSecure/README.md +771 -0
  180. package/src/components/inputs/InputText/InputText.vue +225 -0
  181. package/src/components/inputs/InputText/README.md +844 -0
  182. package/src/components/inputs/OTP/OTP.vue +349 -0
  183. package/src/components/inputs/OTP/README.md +736 -0
  184. package/src/components/inputs/OTP/theme.css +50 -0
  185. package/src/components/inputs/StringCapture/README.md +718 -0
  186. package/src/components/inputs/StringCapture/StringCapture.vue +315 -0
  187. package/src/components/inputs/StringCapture/theme.css +86 -0
  188. package/src/components/inputs/Tags/README.md +897 -0
  189. package/src/components/inputs/Tags/TagBar.vue +793 -0
  190. package/src/components/inputs/Tags/TagCreation.vue +219 -0
  191. package/src/components/inputs/Tags/TagPicker.vue +380 -0
  192. package/src/components/inputs/Tags/tag-bar-styles.ts +354 -0
  193. package/src/components/inputs/Tags/theme.css +121 -0
  194. package/src/components/inputs/Tags/types.ts +346 -0
  195. package/src/components/inputs/search/README.md +759 -0
  196. package/src/components/inputs/search/SearchBar.vue +394 -0
  197. package/src/components/inputs/search/SearchResults.vue +310 -0
  198. package/src/components/inputs/search/theme.css +187 -0
  199. package/src/components/inputs/search/types.ts +8 -0
  200. package/src/components/inputs/theme.css +102 -0
  201. package/src/components/menus/ActionMenu/ActionMenu.vue +383 -0
  202. package/src/components/menus/ActionMenu/README.md +825 -0
  203. package/src/components/menus/ActionMenu/theme.css +93 -0
  204. package/src/components/models/Popover/Popover.vue +551 -0
  205. package/src/components/models/Popover/README.md +885 -0
  206. package/src/components/models/Popover/theme.css +52 -0
  207. package/src/components/models/Sheet/README.md +1159 -0
  208. package/src/components/models/Sheet/Sheet.vue +465 -0
  209. package/src/components/models/Sheet/theme.css +72 -0
  210. package/src/components/models/Sidebar/README.md +1228 -0
  211. package/src/components/models/Sidebar/Sidebar.vue +480 -0
  212. package/src/components/models/Sidebar/theme.css +90 -0
  213. package/src/components/navigation/adaptive/AdaptiveLayout.vue +779 -0
  214. package/src/components/navigation/adaptive/AdaptiveLayoutBreadcrumbs.vue +192 -0
  215. package/src/components/navigation/adaptive/AdaptiveLayoutMenuButton.vue +149 -0
  216. package/src/components/navigation/adaptive/README.md +768 -0
  217. package/src/components/navigation/adaptive/types.ts +19 -0
  218. package/src/components/navigation/adaptive/useAdaptiveLayout.ts +89 -0
  219. package/src/components/navigation/adaptive/useBreakpoints.ts +41 -0
  220. package/src/components/navigation/adaptive/useContainerMonitor.ts +214 -0
  221. package/src/components/navigation/adaptive/useViewAnimation.ts +721 -0
  222. package/src/components/navigation/adaptive/useViewResize.ts +211 -0
  223. package/src/components/navigation/navstack/NavigationStack.vue +180 -0
  224. package/src/components/navigation/navstack/README.md +994 -0
  225. package/src/components/navigation/navstack/useNavigationStack.ts +164 -0
  226. package/src/components/navigation/slideover/README.md +1275 -0
  227. package/src/components/navigation/slideover/SlideoverController.vue +287 -0
  228. package/src/components/navigation/slideover/useSlideoverController.ts +320 -0
  229. package/src/components/navigation/splitview/README.md +1115 -0
  230. package/src/components/navigation/splitview/SplitViewController.vue +176 -0
  231. package/src/components/navigation/splitview/useSplitViewController.ts +388 -0
  232. package/src/components/navigation/tabcontroller/README.md +919 -0
  233. package/src/components/navigation/tabcontroller/TabController.vue +307 -0
  234. package/src/components/navigation/tabcontroller/TabItem.vue +57 -0
  235. package/src/components/navigation/tabcontroller/types.ts +24 -0
  236. package/src/components/navigation/tabcontroller/useTabController.ts +18 -0
  237. package/src/components/navigation/theme.css +91 -0
  238. package/src/components/navigation/types.ts +7 -0
  239. package/src/components/pickers/CollectionPicker/CollectionPicker.vue +398 -0
  240. package/src/components/pickers/CollectionPicker/README.md +1115 -0
  241. package/src/components/pickers/CollectionPicker/theme.css +14 -0
  242. package/src/components/pickers/CollectionPicker/types.ts +11 -0
  243. package/src/components/pickers/ColorPicker/ColorPicker.vue +376 -0
  244. package/src/components/pickers/ColorPicker/README.md +1439 -0
  245. package/src/components/pickers/ColorPicker/colors.ts +299 -0
  246. package/src/components/pickers/ColorPicker/theme.css +32 -0
  247. package/src/components/pickers/DatePicker/DatePicker.vue +660 -0
  248. package/src/components/pickers/DatePicker/README.md +1195 -0
  249. package/src/components/pickers/DatePicker/theme.css +22 -0
  250. package/src/components/pickers/FilePicker/FilePicker.vue +534 -0
  251. package/src/components/pickers/FilePicker/README.md +1542 -0
  252. package/src/components/pickers/FilePicker/theme.css +48 -0
  253. package/src/components/pickers/FilePicker/types.ts +10 -0
  254. package/src/components/pickers/IconPicker/IconPicker.vue +327 -0
  255. package/src/components/pickers/IconPicker/README.md +1161 -0
  256. package/src/components/pickers/IconPicker/theme.css +28 -0
  257. package/src/components/pickers/theme.css +82 -0
  258. package/src/components/views/MarkdownViewer/MarkdownViewer.vue +442 -0
  259. package/src/components/views/MarkdownViewer/README.md +833 -0
  260. package/src/components/views/MarkdownViewer/theme.css +130 -0
  261. package/src/index.ts +263 -0
  262. package/src/theme.ts +378 -0
  263. package/src/themes/crimson-dark.ts +556 -0
  264. package/src/themes/cyan-light.ts +556 -0
  265. package/src/themes/dark.ts +557 -0
  266. package/src/themes/gold-dark.ts +556 -0
  267. package/src/themes/grass-dark.ts +556 -0
  268. package/src/themes/indigo.ts +556 -0
  269. package/src/themes/light.ts +557 -0
  270. package/src/themes/orange-dark.ts +557 -0
  271. package/src/themes/orange-light.ts +557 -0
  272. package/src/vue.d.ts +45 -0
@@ -0,0 +1,591 @@
1
+ # Radio
2
+
3
+ A radio button group component built with Vue 3 Composition API and TypeScript. The Radio component provides a set of mutually exclusive options with customizable layouts and visual styles.
4
+
5
+ ## Installation/Import
6
+
7
+ ```typescript
8
+ import { Radio } from "@umbra-ui/core";
9
+ import type { ControlItem } from "@umbra-ui/core";
10
+ ```
11
+
12
+ **Dependencies:**
13
+
14
+ - Vue 3.x
15
+ - @umbra-ui/core (Checkbox component)
16
+
17
+ ## Basic Usage
18
+
19
+ ```vue
20
+ <script setup lang="ts">
21
+ import { ref } from "vue";
22
+ import { Radio } from "@umbra-ui/core";
23
+ import type { ControlItem } from "@umbra-ui/core";
24
+
25
+ const selectedIndex = ref(0);
26
+
27
+ const radioItems: ControlItem[] = [
28
+ { title: "Option 1" },
29
+ { title: "Option 2" },
30
+ { title: "Option 3" },
31
+ ];
32
+
33
+ const handleRadioClick = (index: number, item: ControlItem) => {
34
+ console.log("Selected:", item.title, "at index:", index);
35
+ selectedIndex.value = index;
36
+ };
37
+ </script>
38
+
39
+ <template>
40
+ <Radio
41
+ :items="radioItems"
42
+ :selected-index="selectedIndex"
43
+ @click="handleRadioClick"
44
+ />
45
+ </template>
46
+ ```
47
+
48
+ ## Props
49
+
50
+ | Prop Name | Type | Required | Default | Description |
51
+ | --------------- | --------------------------------- | -------- | ---------------------------------------------------------- | -------------------------------------- |
52
+ | `items` | `ControlItem[]` | Yes | `[{ title: "One" }, { title: "Two" }, { title: "Three" }]` | Array of radio options to display |
53
+ | `selectedIndex` | `number` | Yes | `0` | Index of the currently selected option |
54
+ | `checkboxType` | `"circle" \| "square" \| "plain"` | No | `"circle"` | Visual style of the radio buttons |
55
+ | `layout` | `"horizontal" \| "vertical"` | No | `"horizontal"` | Layout direction of the radio group |
56
+
57
+ ### ControlItem Interface
58
+
59
+ ```typescript
60
+ interface ControlItem {
61
+ title: string;
62
+ subtitle?: string;
63
+ disabled?: boolean;
64
+ }
65
+ ```
66
+
67
+ ### Checkbox Types
68
+
69
+ - **`circle`**: Circular radio buttons (default)
70
+ - **`square`**: Square radio buttons with rounded corners
71
+ - **`plain`**: Minimal radio buttons with no background
72
+
73
+ ### Layout Options
74
+
75
+ - **`horizontal`**: Radio buttons arranged in a row
76
+ - **`vertical`**: Radio buttons arranged in a column
77
+
78
+ ## Events
79
+
80
+ | Event Name | Payload Type | Description |
81
+ | ---------- | ------------------------------------ | --------------------------------------- |
82
+ | `click` | `[index: number, item: ControlItem]` | Emitted when a radio option is selected |
83
+
84
+ ### Event Examples
85
+
86
+ ```vue
87
+ <script setup lang="ts">
88
+ import { ref } from "vue";
89
+ import { Radio } from "@umbra-ui/core";
90
+ import type { ControlItem } from "@umbra-ui/core";
91
+
92
+ const selectedIndex = ref(0);
93
+
94
+ const handleRadioClick = (index: number, item: ControlItem) => {
95
+ console.log("Selected option:", item.title);
96
+ console.log("Selected index:", index);
97
+ selectedIndex.value = index;
98
+ };
99
+ </script>
100
+
101
+ <template>
102
+ <Radio
103
+ :items="radioItems"
104
+ :selected-index="selectedIndex"
105
+ @click="handleRadioClick"
106
+ />
107
+ </template>
108
+ ```
109
+
110
+ ## Slots
111
+
112
+ This component does not use slots. All content is controlled via props.
113
+
114
+ ## Exposed Methods/Refs
115
+
116
+ This component does not expose any methods or refs via `defineExpose`.
117
+
118
+ ## CSS Customization
119
+
120
+ The Radio component uses CSS custom properties that can be overridden to customize the appearance:
121
+
122
+ ### Color Variables
123
+
124
+ ```css
125
+ /* Radio item colors */
126
+ --radio-item-color: #8b8d98;
127
+ --radio-item-selected-color: #1a1d23;
128
+ ```
129
+
130
+ ### Custom Styling Example
131
+
132
+ ```vue
133
+ <template>
134
+ <Radio :items="items" :selected-index="selectedIndex" class="custom-radio" />
135
+ </template>
136
+
137
+ <style>
138
+ .custom-radio {
139
+ --radio-item-color: #666;
140
+ --radio-item-selected-color: #ff6b6b;
141
+ }
142
+ </style>
143
+ ```
144
+
145
+ ## Examples
146
+
147
+ ### Basic Radio Group
148
+
149
+ ```vue
150
+ <script setup lang="ts">
151
+ import { ref } from "vue";
152
+ import { Radio } from "@umbra-ui/core";
153
+ import type { ControlItem } from "@umbra-ui/core";
154
+
155
+ const selectedIndex = ref(0);
156
+
157
+ const options: ControlItem[] = [
158
+ { title: "Small" },
159
+ { title: "Medium" },
160
+ { title: "Large" },
161
+ ];
162
+ </script>
163
+
164
+ <template>
165
+ <Radio
166
+ :items="options"
167
+ :selected-index="selectedIndex"
168
+ @click="(index) => (selectedIndex = index)"
169
+ />
170
+ </template>
171
+ ```
172
+
173
+ ### Different Layouts
174
+
175
+ ```vue
176
+ <script setup lang="ts">
177
+ import { ref } from "vue";
178
+ import { Radio } from "@umbra-ui/core";
179
+ import type { ControlItem } from "@umbra-ui/core";
180
+
181
+ const horizontalSelected = ref(0);
182
+ const verticalSelected = ref(0);
183
+
184
+ const options: ControlItem[] = [
185
+ { title: "Option 1" },
186
+ { title: "Option 2" },
187
+ { title: "Option 3" },
188
+ ];
189
+ </script>
190
+
191
+ <template>
192
+ <div class="layout-examples">
193
+ <div class="example">
194
+ <h3>Horizontal Layout</h3>
195
+ <Radio
196
+ :items="options"
197
+ :selected-index="horizontalSelected"
198
+ layout="horizontal"
199
+ @click="(index) => (horizontalSelected = index)"
200
+ />
201
+ </div>
202
+
203
+ <div class="example">
204
+ <h3>Vertical Layout</h3>
205
+ <Radio
206
+ :items="options"
207
+ :selected-index="verticalSelected"
208
+ layout="vertical"
209
+ @click="(index) => (verticalSelected = index)"
210
+ />
211
+ </div>
212
+ </div>
213
+ </template>
214
+
215
+ <style module>
216
+ .layout-examples {
217
+ display: flex;
218
+ flex-direction: column;
219
+ gap: 2rem;
220
+ }
221
+
222
+ .example {
223
+ display: flex;
224
+ flex-direction: column;
225
+ gap: 1rem;
226
+ }
227
+ </style>
228
+ ```
229
+
230
+ ### Different Checkbox Types
231
+
232
+ ```vue
233
+ <script setup lang="ts">
234
+ import { ref } from "vue";
235
+ import { Radio } from "@umbra-ui/core";
236
+ import type { ControlItem } from "@umbra-ui/core";
237
+
238
+ const circleSelected = ref(0);
239
+ const squareSelected = ref(0);
240
+ const plainSelected = ref(0);
241
+
242
+ const options: ControlItem[] = [
243
+ { title: "Circle" },
244
+ { title: "Square" },
245
+ { title: "Plain" },
246
+ ];
247
+ </script>
248
+
249
+ <template>
250
+ <div class="type-examples">
251
+ <div class="example">
252
+ <h3>Circle Type</h3>
253
+ <Radio
254
+ :items="options"
255
+ :selected-index="circleSelected"
256
+ checkbox-type="circle"
257
+ @click="(index) => (circleSelected = index)"
258
+ />
259
+ </div>
260
+
261
+ <div class="example">
262
+ <h3>Square Type</h3>
263
+ <Radio
264
+ :items="options"
265
+ :selected-index="squareSelected"
266
+ checkbox-type="square"
267
+ @click="(index) => (squareSelected = index)"
268
+ />
269
+ </div>
270
+
271
+ <div class="example">
272
+ <h3>Plain Type</h3>
273
+ <Radio
274
+ :items="options"
275
+ :selected-index="plainSelected"
276
+ checkbox-type="plain"
277
+ @click="(index) => (plainSelected = index)"
278
+ />
279
+ </div>
280
+ </div>
281
+ </template>
282
+
283
+ <style module>
284
+ .type-examples {
285
+ display: flex;
286
+ flex-direction: column;
287
+ gap: 2rem;
288
+ }
289
+
290
+ .example {
291
+ display: flex;
292
+ flex-direction: column;
293
+ gap: 1rem;
294
+ }
295
+ </style>
296
+ ```
297
+
298
+ ### Form Integration
299
+
300
+ ```vue
301
+ <script setup lang="ts">
302
+ import { ref } from "vue";
303
+ import { Radio } from "@umbra-ui/core";
304
+ import type { ControlItem } from "@umbra-ui/core";
305
+
306
+ interface FormData {
307
+ size: number;
308
+ color: number;
309
+ material: number;
310
+ }
311
+
312
+ const formData = ref<FormData>({
313
+ size: 0,
314
+ color: 0,
315
+ material: 0,
316
+ });
317
+
318
+ const sizes: ControlItem[] = [
319
+ { title: "Small" },
320
+ { title: "Medium" },
321
+ { title: "Large" },
322
+ { title: "Extra Large" },
323
+ ];
324
+
325
+ const colors: ControlItem[] = [
326
+ { title: "Red" },
327
+ { title: "Blue" },
328
+ { title: "Green" },
329
+ { title: "Yellow" },
330
+ ];
331
+
332
+ const materials: ControlItem[] = [
333
+ { title: "Cotton" },
334
+ { title: "Polyester" },
335
+ { title: "Wool" },
336
+ { title: "Silk" },
337
+ ];
338
+
339
+ const submitForm = () => {
340
+ console.log("Form submitted:", formData.value);
341
+ };
342
+ </script>
343
+
344
+ <template>
345
+ <form class="form-example" @submit.prevent="submitForm">
346
+ <div class="form-group">
347
+ <label>Size</label>
348
+ <Radio
349
+ :items="sizes"
350
+ :selected-index="formData.size"
351
+ @click="(index) => (formData.size = index)"
352
+ />
353
+ </div>
354
+
355
+ <div class="form-group">
356
+ <label>Color</label>
357
+ <Radio
358
+ :items="colors"
359
+ :selected-index="formData.color"
360
+ @click="(index) => (formData.color = index)"
361
+ />
362
+ </div>
363
+
364
+ <div class="form-group">
365
+ <label>Material</label>
366
+ <Radio
367
+ :items="materials"
368
+ :selected-index="formData.material"
369
+ @click="(index) => (formData.material = index)"
370
+ />
371
+ </div>
372
+
373
+ <button type="submit">Submit</button>
374
+ </form>
375
+ </template>
376
+
377
+ <style module>
378
+ .form-example {
379
+ display: flex;
380
+ flex-direction: column;
381
+ gap: 2rem;
382
+ max-width: 400px;
383
+ }
384
+
385
+ .form-group {
386
+ display: flex;
387
+ flex-direction: column;
388
+ gap: 1rem;
389
+ }
390
+ </style>
391
+ ```
392
+
393
+ ### Settings Panel
394
+
395
+ ```vue
396
+ <script setup lang="ts">
397
+ import { ref } from "vue";
398
+ import { Radio } from "@umbra-ui/core";
399
+ import type { ControlItem } from "@umbra-ui/core";
400
+
401
+ const themeSelected = ref(0);
402
+ const languageSelected = ref(0);
403
+ const notificationsSelected = ref(0);
404
+
405
+ const themes: ControlItem[] = [
406
+ { title: "Light" },
407
+ { title: "Dark" },
408
+ { title: "Auto" },
409
+ ];
410
+
411
+ const languages: ControlItem[] = [
412
+ { title: "English" },
413
+ { title: "Spanish" },
414
+ { title: "French" },
415
+ { title: "German" },
416
+ ];
417
+
418
+ const notifications: ControlItem[] = [
419
+ { title: "All" },
420
+ { title: "Important only" },
421
+ { title: "None" },
422
+ ];
423
+
424
+ const saveSettings = () => {
425
+ const settings = {
426
+ theme: themes[themeSelected.value].title,
427
+ language: languages[languageSelected.value].title,
428
+ notifications: notifications[notificationsSelected.value].title,
429
+ };
430
+ console.log("Settings saved:", settings);
431
+ };
432
+ </script>
433
+
434
+ <template>
435
+ <div class="settings-panel">
436
+ <h2>Settings</h2>
437
+
438
+ <div class="setting-group">
439
+ <h3>Theme</h3>
440
+ <Radio
441
+ :items="themes"
442
+ :selected-index="themeSelected"
443
+ @click="(index) => (themeSelected = index)"
444
+ />
445
+ </div>
446
+
447
+ <div class="setting-group">
448
+ <h3>Language</h3>
449
+ <Radio
450
+ :items="languages"
451
+ :selected-index="languageSelected"
452
+ @click="(index) => (languageSelected = index)"
453
+ />
454
+ </div>
455
+
456
+ <div class="setting-group">
457
+ <h3>Notifications</h3>
458
+ <Radio
459
+ :items="notifications"
460
+ :selected-index="notificationsSelected"
461
+ @click="(index) => (notificationsSelected = index)"
462
+ />
463
+ </div>
464
+
465
+ <button @click="saveSettings">Save Settings</button>
466
+ </div>
467
+ </template>
468
+
469
+ <style module>
470
+ .settings-panel {
471
+ display: flex;
472
+ flex-direction: column;
473
+ gap: 2rem;
474
+ max-width: 400px;
475
+ padding: 2rem;
476
+ background-color: #f5f5f5;
477
+ border-radius: 0.5rem;
478
+ }
479
+
480
+ .setting-group {
481
+ display: flex;
482
+ flex-direction: column;
483
+ gap: 1rem;
484
+ }
485
+ </style>
486
+ ```
487
+
488
+ ### Dynamic Radio Groups
489
+
490
+ ```vue
491
+ <script setup lang="ts">
492
+ import { ref, computed } from "vue";
493
+ import { Radio } from "@umbra-ui/core";
494
+ import type { ControlItem } from "@umbra-ui/core";
495
+
496
+ const selectedCategory = ref(0);
497
+ const selectedSubcategory = ref(0);
498
+
499
+ const categories: ControlItem[] = [
500
+ { title: "Electronics" },
501
+ { title: "Clothing" },
502
+ { title: "Books" },
503
+ { title: "Home & Garden" },
504
+ ];
505
+
506
+ const subcategories = computed(() => {
507
+ const categoryMap: Record<number, ControlItem[]> = {
508
+ 0: [
509
+ { title: "Smartphones" },
510
+ { title: "Laptops" },
511
+ { title: "Tablets" },
512
+ { title: "Accessories" },
513
+ ],
514
+ 1: [
515
+ { title: "Men's Clothing" },
516
+ { title: "Women's Clothing" },
517
+ { title: "Kids' Clothing" },
518
+ { title: "Shoes" },
519
+ ],
520
+ 2: [
521
+ { title: "Fiction" },
522
+ { title: "Non-fiction" },
523
+ { title: "Textbooks" },
524
+ { title: "Children's Books" },
525
+ ],
526
+ 3: [
527
+ { title: "Furniture" },
528
+ { title: "Decor" },
529
+ { title: "Garden Tools" },
530
+ { title: "Kitchen" },
531
+ ],
532
+ };
533
+
534
+ return categoryMap[selectedCategory.value] || [];
535
+ });
536
+
537
+ const handleCategoryChange = (index: number) => {
538
+ selectedCategory.value = index;
539
+ selectedSubcategory.value = 0; // Reset subcategory selection
540
+ };
541
+ </script>
542
+
543
+ <template>
544
+ <div class="dynamic-radio">
545
+ <div class="radio-group">
546
+ <h3>Category</h3>
547
+ <Radio
548
+ :items="categories"
549
+ :selected-index="selectedCategory"
550
+ @click="handleCategoryChange"
551
+ />
552
+ </div>
553
+
554
+ <div class="radio-group" v-if="subcategories.length > 0">
555
+ <h3>Subcategory</h3>
556
+ <Radio
557
+ :items="subcategories"
558
+ :selected-index="selectedSubcategory"
559
+ @click="(index) => (selectedSubcategory = index)"
560
+ />
561
+ </div>
562
+ </div>
563
+ </template>
564
+
565
+ <style module>
566
+ .dynamic-radio {
567
+ display: flex;
568
+ flex-direction: column;
569
+ gap: 2rem;
570
+ max-width: 500px;
571
+ }
572
+
573
+ .radio-group {
574
+ display: flex;
575
+ flex-direction: column;
576
+ gap: 1rem;
577
+ }
578
+ </style>
579
+ ```
580
+
581
+ ## Notes
582
+
583
+ - The component uses the Checkbox component internally for the radio button appearance
584
+ - Only one option can be selected at a time (mutually exclusive)
585
+ - The component supports both light and dark themes
586
+ - Hover effects include a subtle scale transform for better user feedback
587
+ - Selected items have different text color styling
588
+ - The component automatically handles prop changes and updates the internal state
589
+ - Layout spacing is optimized for both horizontal and vertical arrangements
590
+ - The component is fully accessible with proper click handling
591
+ - Radio groups are commonly used in forms for single-choice selections
@@ -0,0 +1,89 @@
1
+ <script setup lang="ts">
2
+ import { ref, watch } from "vue";
3
+ import type { ControlItem } from "../SegmentedControl/types";
4
+ import Checkbox from "../Checkbox/Checkbox.vue";
5
+ import "./theme.css";
6
+ export interface Props {
7
+ items: ControlItem[];
8
+ selectedIndex: number;
9
+ checkboxType?: "circle" | "square" | "plain";
10
+ layout?: "horizontal" | "vertical";
11
+ }
12
+ const props = withDefaults(defineProps<Props>(), {
13
+ items: () => [{ title: "One" }, { title: "Two" }, { title: "Three" }],
14
+ selectedIndex: 0,
15
+ checkboxType: "circle",
16
+ layout: "horizontal",
17
+ });
18
+ const emit = defineEmits<{
19
+ click: [index: number, item: ControlItem];
20
+ }>();
21
+
22
+ const handleClick = (index: number, item: ControlItem) => {
23
+ selectedIndex.value = index;
24
+ emit("click", index, item);
25
+ };
26
+
27
+ const selectedIndex = ref(props.selectedIndex);
28
+
29
+ // Watch for changes to selectedIndex prop
30
+ watch(
31
+ () => props.selectedIndex,
32
+ (newSelectedIndex) => {
33
+ selectedIndex.value = newSelectedIndex;
34
+ }
35
+ );
36
+ </script>
37
+
38
+ <template>
39
+ <div :class="[$style.container, $style[`container_${layout}`]]">
40
+ <div
41
+ :class="$style.item"
42
+ v-for="(item, index) in items"
43
+ :key="index"
44
+ @click="handleClick(index, item)"
45
+ >
46
+ <Checkbox
47
+ :isChecked="selectedIndex === index"
48
+ @update:isChecked="selectedIndex = index"
49
+ :checkboxType="checkboxType"
50
+ />
51
+ <p :class="['callout', selectedIndex === index && $style.selected]">
52
+ {{ item.title }}
53
+ </p>
54
+ </div>
55
+ </div>
56
+ </template>
57
+
58
+ <style module>
59
+ .container {
60
+ display: flex;
61
+ flex-direction: column;
62
+ cursor: default;
63
+ }
64
+ .container_horizontal {
65
+ flex-direction: row;
66
+ gap: 22px;
67
+ }
68
+ .container_vertical {
69
+ flex-direction: column;
70
+ gap: 15px;
71
+ }
72
+
73
+ .item {
74
+ display: flex;
75
+ align-items: center;
76
+ gap: 12px;
77
+ color: var(--radio-item-color);
78
+ transition: transform 0.2s ease-in-out;
79
+ }
80
+ .item:hover {
81
+ transform: scale(1.03);
82
+ }
83
+ .item p {
84
+ transition: color 0.2s ease-in-out;
85
+ }
86
+ .selected {
87
+ color: var(--radio-item-selected-color);
88
+ }
89
+ </style>
@@ -0,0 +1,14 @@
1
+ /* Light theme using Colors */
2
+ :root {
3
+ /* Radio item colors */
4
+ --radio-item-color: #8b8d98; /* gray9 - muted text for light mode */
5
+ --radio-item-selected-color: #1a1d23; /* gray12 - dark text for selected state in light mode */
6
+ }
7
+
8
+ /* Dark theme */
9
+ .dark,
10
+ .dark-theme {
11
+ /* Radio item colors */
12
+ --radio-item-color: #b4b4b4; /* Original dark mode value */
13
+ --radio-item-selected-color: #eeeeee; /* Original dark mode value */
14
+ }