@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,1275 @@
1
+ # SlideoverController
2
+
3
+ A sophisticated slideover navigation component built with Vue 3 Composition API and TypeScript. The SlideoverController provides smooth, animated transitions between different views using GSAP's FLIP (First, Last, Invert, Play) animation technique, creating an intuitive slideover interface perfect for tablet and desktop applications.
4
+
5
+ ## Installation/Import
6
+
7
+ ```typescript
8
+ import { SlideoverController, useSlideoverController } from "@umbra-ui/core";
9
+ import type { Pane } from "@umbra-ui/core";
10
+ ```
11
+
12
+ **Dependencies:**
13
+
14
+ - Vue 3.x
15
+ - gsap (for animations)
16
+ - gsap/Flip (for FLIP animations)
17
+ - @umbra-ui/icons (for ChevronLeftIcon)
18
+
19
+ ## Basic Usage
20
+
21
+ ```vue
22
+ <script setup lang="ts">
23
+ import { ref } from "vue";
24
+ import { SlideoverController } from "@umbra-ui/core";
25
+ import HomeView from "./HomeView.vue";
26
+ import ProfileView from "./ProfileView.vue";
27
+ import SettingsView from "./SettingsView.vue";
28
+
29
+ // Define your slideover panes
30
+ const panes = ref([
31
+ {
32
+ name: "Home",
33
+ background: "#ffffff",
34
+ foreground: "#000000",
35
+ component: HomeView,
36
+ props: { title: "Home" },
37
+ },
38
+ {
39
+ name: "Profile",
40
+ background: "#f8f9fa",
41
+ foreground: "#212529",
42
+ component: ProfileView,
43
+ props: { userId: 123 },
44
+ },
45
+ {
46
+ name: "Settings",
47
+ background: "#e9ecef",
48
+ foreground: "#495057",
49
+ component: SettingsView,
50
+ props: { theme: "light" },
51
+ },
52
+ ]);
53
+
54
+ const slideoverRef = ref();
55
+
56
+ // Navigate to specific pane
57
+ const goToPane = (index: number) => {
58
+ slideoverRef.value?.navigate(index);
59
+ };
60
+
61
+ // Show all panes
62
+ const showAllPanes = () => {
63
+ slideoverRef.value?.showAll();
64
+ };
65
+
66
+ // Hide all panes
67
+ const hideAllPanes = () => {
68
+ slideoverRef.value?.hideAll();
69
+ };
70
+ </script>
71
+
72
+ <template>
73
+ <div class="app">
74
+ <div class="navigation-controls">
75
+ <button @click="goToPane(0)">Home</button>
76
+ <button @click="goToPane(1)">Profile</button>
77
+ <button @click="goToPane(2)">Settings</button>
78
+ <button @click="showAllPanes">Show All</button>
79
+ <button @click="hideAllPanes">Hide All</button>
80
+ </div>
81
+
82
+ <SlideoverController
83
+ ref="slideoverRef"
84
+ :panes="panes"
85
+ component-id="main-slideover"
86
+ :show-breadcrumb="true"
87
+ />
88
+ </div>
89
+ </template>
90
+
91
+ <style module>
92
+ .app {
93
+ height: 100vh;
94
+ display: flex;
95
+ flex-direction: column;
96
+ }
97
+
98
+ .navigation-controls {
99
+ display: flex;
100
+ gap: 12px;
101
+ padding: 16px;
102
+ background: var(--background-1);
103
+ border-bottom: 1px solid var(--border-2);
104
+ }
105
+
106
+ .navigation-controls button {
107
+ padding: 8px 16px;
108
+ border: 1px solid var(--border-2);
109
+ background: var(--background-2);
110
+ color: var(--text-1);
111
+ border-radius: 6px;
112
+ cursor: pointer;
113
+ transition: all 0.2s ease;
114
+ }
115
+
116
+ .navigation-controls button:hover {
117
+ background: var(--background-3);
118
+ border-color: var(--border-3);
119
+ }
120
+ </style>
121
+ ```
122
+
123
+ ## Props
124
+
125
+ | Prop Name | Type | Required | Default | Description |
126
+ | ---------------- | ------------------------------------------- | -------- | -------------- | -------------------------------------------- |
127
+ | `panes` | `Pane[]` | Yes | - | Array of panes to display in the slideover |
128
+ | `controller` | `ReturnType<typeof useSlideoverController>` | No | - | External controller instance |
129
+ | `componentId` | `string` | No | Auto-generated | Unique identifier for the component instance |
130
+ | `showBreadcrumb` | `boolean` | No | `true` | Whether to show breadcrumb navigation |
131
+
132
+ ## Pane Interface
133
+
134
+ ```typescript
135
+ interface Pane {
136
+ name: string;
137
+ background: string;
138
+ foreground: string;
139
+ component: any;
140
+ props: Record<string, any>;
141
+ }
142
+ ```
143
+
144
+ ### Pane Properties
145
+
146
+ | Property | Type | Description |
147
+ | ------------ | --------------------- | ----------------------------------------------- |
148
+ | `name` | `string` | Display name for the pane (used in breadcrumbs) |
149
+ | `background` | `string` | Background color for the pane container |
150
+ | `foreground` | `string` | Text color for the pane content |
151
+ | `component` | `Component` | Vue component to render in the pane |
152
+ | `props` | `Record<string, any>` | Props to pass to the component |
153
+
154
+ ## Events
155
+
156
+ The SlideoverController component doesn't emit events directly, but you can access navigation methods through template refs.
157
+
158
+ ## Exposed Methods/Refs
159
+
160
+ | Method | Parameters | Description |
161
+ | ------------ | ------------------------------------- | -------------------------------------------- |
162
+ | `navigate` | `(index: number, animated?: boolean)` | Navigate to a specific pane by index |
163
+ | `showPane` | `(index: number)` | Show a specific pane and all panes after it |
164
+ | `hidePane` | `(index: number)` | Hide a specific pane and all panes before it |
165
+ | `togglePane` | `(index: number)` | Toggle a pane at a specific index |
166
+ | `showAll` | `()` | Show all secondary panes |
167
+ | `hideAll` | `()` | Hide all secondary panes |
168
+
169
+ ## useSlideoverController Composable
170
+
171
+ The `useSlideoverController` composable provides the core slideover logic and can be used independently:
172
+
173
+ ```typescript
174
+ import { useSlideoverController } from "@umbra-ui/core";
175
+
176
+ const {
177
+ visiblePanes,
178
+ currentPaneIndex,
179
+ showPane,
180
+ hidePane,
181
+ togglePane,
182
+ showAll,
183
+ hideAll,
184
+ navigate,
185
+ } = useSlideoverController(panes, componentId);
186
+ ```
187
+
188
+ ### Composable Returns
189
+
190
+ | Property | Type | Description |
191
+ | ------------------ | --------------------------------------------- | ------------------------------------------------- |
192
+ | `visiblePanes` | `Ref<boolean[]>` | Reactive array indicating which panes are visible |
193
+ | `currentPaneIndex` | `ComputedRef<number>` | Current active pane index |
194
+ | `showPane` | `(index: number) => void` | Show specific pane and all after it |
195
+ | `hidePane` | `(index: number) => void` | Hide specific pane and all before it |
196
+ | `togglePane` | `(index: number) => void` | Toggle pane at specific index |
197
+ | `showAll` | `() => void` | Show all secondary panes |
198
+ | `hideAll` | `() => void` | Hide all secondary panes |
199
+ | `navigate` | `(index: number, animated?: boolean) => void` | Navigate to specific pane |
200
+
201
+ ## CSS Customization
202
+
203
+ ### Layout Variables
204
+
205
+ ```css
206
+ .slideover-controller {
207
+ --slideover-darken-bg: rgba(0, 0, 0, 0.5);
208
+ --slideover-breadcrumb-default-opacity: 0.6;
209
+ --slideover-breadcrumb-hover-opacity: 1;
210
+ --slideover-handle-default-width: 4px;
211
+ --slideover-handle-default-height: 24px;
212
+ --slideover-handle-default-opacity: 0.3;
213
+ --slideover-handle-bg: #666;
214
+ --slideover-handle-hover-width: 6px;
215
+ --slideover-handle-hover-height: 32px;
216
+ --slideover-handle-hover-opacity: 0.6;
217
+ }
218
+ ```
219
+
220
+ ### Container Styling
221
+
222
+ ```css
223
+ .slideover-controller {
224
+ position: relative;
225
+ height: 100%;
226
+ width: 100%;
227
+ overflow: hidden;
228
+ }
229
+
230
+ .slideover-controller .darken {
231
+ position: absolute;
232
+ top: 0;
233
+ left: 0;
234
+ right: 0;
235
+ bottom: 0;
236
+ background-color: var(--slideover-darken-bg);
237
+ opacity: 0;
238
+ pointer-events: none;
239
+ z-index: 5;
240
+ }
241
+ ```
242
+
243
+ ### Pane Styling
244
+
245
+ ```css
246
+ .slideover-controller .pane {
247
+ display: grid;
248
+ grid-template-columns: 1fr;
249
+ grid-template-areas: "content";
250
+ height: 100%;
251
+ }
252
+
253
+ .slideover-controller .pane_full {
254
+ display: flex;
255
+ flex-direction: column;
256
+ flex-grow: 1;
257
+ height: 100%;
258
+ }
259
+ ```
260
+
261
+ ## Examples
262
+
263
+ ### File Explorer Interface
264
+
265
+ ```vue
266
+ <script setup lang="ts">
267
+ import { ref } from "vue";
268
+ import { SlideoverController } from "@umbra-ui/core";
269
+ import FileTree from "./FileTree.vue";
270
+ import FileList from "./FileList.vue";
271
+ import FilePreview from "./FilePreview.vue";
272
+
273
+ const panes = ref([
274
+ {
275
+ name: "Folders",
276
+ background: "#ffffff",
277
+ foreground: "#1a202c",
278
+ component: FileTree,
279
+ props: { rootPath: "/" },
280
+ },
281
+ {
282
+ name: "Files",
283
+ background: "#f7fafc",
284
+ foreground: "#2d3748",
285
+ component: FileList,
286
+ props: { currentPath: "/documents" },
287
+ },
288
+ {
289
+ name: "Preview",
290
+ background: "#edf2f7",
291
+ foreground: "#4a5568",
292
+ component: FilePreview,
293
+ props: { selectedFile: null },
294
+ },
295
+ ]);
296
+
297
+ const slideoverRef = ref();
298
+
299
+ const handleFileSelect = (file: any) => {
300
+ // Navigate to preview pane
301
+ slideoverRef.value?.navigate(2);
302
+ };
303
+
304
+ const handleFolderSelect = (folder: any) => {
305
+ // Navigate to file list pane
306
+ slideoverRef.value?.navigate(1);
307
+ };
308
+ </script>
309
+
310
+ <template>
311
+ <div class="file-explorer">
312
+ <!-- Toolbar -->
313
+ <div class="explorer-toolbar">
314
+ <div class="toolbar-section">
315
+ <button @click="slideoverRef?.showAll()" class="toolbar-btn">
316
+ Show All Panes
317
+ </button>
318
+ <button @click="slideoverRef?.hideAll()" class="toolbar-btn">
319
+ Hide All Panes
320
+ </button>
321
+ </div>
322
+
323
+ <div class="toolbar-section">
324
+ <button @click="slideoverRef?.navigate(0)" class="toolbar-btn">
325
+ Folders
326
+ </button>
327
+ <button @click="slideoverRef?.navigate(1)" class="toolbar-btn">
328
+ Files
329
+ </button>
330
+ <button @click="slideoverRef?.navigate(2)" class="toolbar-btn">
331
+ Preview
332
+ </button>
333
+ </div>
334
+ </div>
335
+
336
+ <!-- Slideover Controller -->
337
+ <SlideoverController
338
+ ref="slideoverRef"
339
+ :panes="panes"
340
+ component-id="file-explorer"
341
+ :show-breadcrumb="true"
342
+ />
343
+ </div>
344
+ </template>
345
+
346
+ <style module>
347
+ .file-explorer {
348
+ height: 100vh;
349
+ display: flex;
350
+ flex-direction: column;
351
+ background: #f8f9fa;
352
+ }
353
+
354
+ .explorer-toolbar {
355
+ display: flex;
356
+ justify-content: space-between;
357
+ align-items: center;
358
+ padding: 12px 16px;
359
+ background: white;
360
+ border-bottom: 1px solid #e9ecef;
361
+ box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1);
362
+ }
363
+
364
+ .toolbar-section {
365
+ display: flex;
366
+ gap: 8px;
367
+ }
368
+
369
+ .toolbar-btn {
370
+ padding: 6px 12px;
371
+ border: 1px solid #dee2e6;
372
+ background: white;
373
+ color: #495057;
374
+ border-radius: 4px;
375
+ cursor: pointer;
376
+ font-size: 14px;
377
+ transition: all 0.2s ease;
378
+ }
379
+
380
+ .toolbar-btn:hover {
381
+ background: #f8f9fa;
382
+ border-color: #adb5bd;
383
+ }
384
+
385
+ .toolbar-btn:active {
386
+ background: #e9ecef;
387
+ }
388
+ </style>
389
+ ```
390
+
391
+ ### Settings Panel Interface
392
+
393
+ ```vue
394
+ <script setup lang="ts">
395
+ import { ref } from "vue";
396
+ import { SlideoverController } from "@umbra-ui/core";
397
+ import GeneralSettings from "./GeneralSettings.vue";
398
+ import AppearanceSettings from "./AppearanceSettings.vue";
399
+ import PrivacySettings from "./PrivacySettings.vue";
400
+ import AdvancedSettings from "./AdvancedSettings.vue";
401
+
402
+ const panes = ref([
403
+ {
404
+ name: "General",
405
+ background: "#ffffff",
406
+ foreground: "#1a202c",
407
+ component: GeneralSettings,
408
+ props: { section: "general" },
409
+ },
410
+ {
411
+ name: "Appearance",
412
+ background: "#f7fafc",
413
+ foreground: "#2d3748",
414
+ component: AppearanceSettings,
415
+ props: { section: "appearance" },
416
+ },
417
+ {
418
+ name: "Privacy",
419
+ background: "#edf2f7",
420
+ foreground: "#4a5568",
421
+ component: PrivacySettings,
422
+ props: { section: "privacy" },
423
+ },
424
+ {
425
+ name: "Advanced",
426
+ background: "#e2e8f0",
427
+ foreground: "#718096",
428
+ component: AdvancedSettings,
429
+ props: { section: "advanced" },
430
+ },
431
+ ]);
432
+
433
+ const slideoverRef = ref();
434
+ const currentSection = ref("General");
435
+
436
+ const navigateToSection = (index: number) => {
437
+ currentSection.value = panes.value[index].name;
438
+ slideoverRef.value?.navigate(index);
439
+ };
440
+
441
+ const resetToGeneral = () => {
442
+ slideoverRef.value?.navigate(0);
443
+ currentSection.value = "General";
444
+ };
445
+ </script>
446
+
447
+ <template>
448
+ <div class="settings-interface">
449
+ <!-- Settings Header -->
450
+ <header class="settings-header">
451
+ <h1 class="settings-title">Settings</h1>
452
+ <p class="settings-subtitle">Configure your application preferences</p>
453
+ </header>
454
+
455
+ <!-- Settings Navigation -->
456
+ <nav class="settings-nav">
457
+ <button
458
+ v-for="(pane, index) in panes"
459
+ :key="pane.name"
460
+ @click="navigateToSection(index)"
461
+ :class="['nav-item', { active: currentSection === pane.name }]"
462
+ >
463
+ <span class="nav-icon">{{ getSectionIcon(pane.name) }}</span>
464
+ <span class="nav-label">{{ pane.name }}</span>
465
+ </button>
466
+
467
+ <div class="nav-actions">
468
+ <button @click="resetToGeneral" class="action-btn secondary">
469
+ Reset
470
+ </button>
471
+ <button @click="slideoverRef?.showAll()" class="action-btn primary">
472
+ Show All
473
+ </button>
474
+ </div>
475
+ </nav>
476
+
477
+ <!-- Settings Content -->
478
+ <SlideoverController
479
+ ref="slideoverRef"
480
+ :panes="panes"
481
+ component-id="settings-panel"
482
+ :show-breadcrumb="true"
483
+ />
484
+ </div>
485
+ </template>
486
+
487
+ <script setup lang="ts">
488
+ const getSectionIcon = (section: string) => {
489
+ const icons = {
490
+ General: "⚙️",
491
+ Appearance: "🎨",
492
+ Privacy: "🔒",
493
+ Advanced: "🔧",
494
+ };
495
+ return icons[section] || "📋";
496
+ };
497
+ </script>
498
+
499
+ <style module>
500
+ .settings-interface {
501
+ height: 100vh;
502
+ display: flex;
503
+ flex-direction: column;
504
+ background: #f8f9fa;
505
+ }
506
+
507
+ .settings-header {
508
+ padding: 24px;
509
+ background: white;
510
+ border-bottom: 1px solid #e9ecef;
511
+ }
512
+
513
+ .settings-title {
514
+ font-size: 28px;
515
+ font-weight: 700;
516
+ color: #1a202c;
517
+ margin: 0 0 8px 0;
518
+ }
519
+
520
+ .settings-subtitle {
521
+ font-size: 16px;
522
+ color: #718096;
523
+ margin: 0;
524
+ }
525
+
526
+ .settings-nav {
527
+ display: flex;
528
+ align-items: center;
529
+ gap: 16px;
530
+ padding: 16px 24px;
531
+ background: white;
532
+ border-bottom: 1px solid #e9ecef;
533
+ box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1);
534
+ }
535
+
536
+ .nav-item {
537
+ display: flex;
538
+ align-items: center;
539
+ gap: 8px;
540
+ padding: 8px 16px;
541
+ background: transparent;
542
+ border: 1px solid transparent;
543
+ color: #718096;
544
+ cursor: pointer;
545
+ border-radius: 6px;
546
+ transition: all 0.2s ease;
547
+ font-weight: 500;
548
+ }
549
+
550
+ .nav-item:hover {
551
+ background: #f7fafc;
552
+ color: #4a5568;
553
+ }
554
+
555
+ .nav-item.active {
556
+ background: #edf2f7;
557
+ color: #2d3748;
558
+ border-color: #cbd5e0;
559
+ }
560
+
561
+ .nav-icon {
562
+ font-size: 16px;
563
+ }
564
+
565
+ .nav-label {
566
+ font-size: 14px;
567
+ }
568
+
569
+ .nav-actions {
570
+ margin-left: auto;
571
+ display: flex;
572
+ gap: 8px;
573
+ }
574
+
575
+ .action-btn {
576
+ padding: 8px 16px;
577
+ border: 1px solid;
578
+ border-radius: 6px;
579
+ cursor: pointer;
580
+ font-weight: 500;
581
+ transition: all 0.2s ease;
582
+ }
583
+
584
+ .action-btn.primary {
585
+ background: #3182ce;
586
+ color: white;
587
+ border-color: #3182ce;
588
+ }
589
+
590
+ .action-btn.primary:hover {
591
+ background: #2c5aa0;
592
+ border-color: #2c5aa0;
593
+ }
594
+
595
+ .action-btn.secondary {
596
+ background: white;
597
+ color: #718096;
598
+ border-color: #e2e8f0;
599
+ }
600
+
601
+ .action-btn.secondary:hover {
602
+ background: #f7fafc;
603
+ color: #4a5568;
604
+ border-color: #cbd5e0;
605
+ }
606
+ </style>
607
+ ```
608
+
609
+ ### Multi-Step Form Interface
610
+
611
+ ```vue
612
+ <script setup lang="ts">
613
+ import { ref } from "vue";
614
+ import { SlideoverController } from "@umbra-ui/core";
615
+ import PersonalInfoStep from "./PersonalInfoStep.vue";
616
+ import ContactInfoStep from "./ContactInfoStep.vue";
617
+ import PreferencesStep from "./PreferencesStep.vue";
618
+ import ReviewStep from "./ReviewStep.vue";
619
+
620
+ const panes = ref([
621
+ {
622
+ name: "Personal Info",
623
+ background: "linear-gradient(135deg, #667eea 0%, #764ba2 100%)",
624
+ foreground: "#ffffff",
625
+ component: PersonalInfoStep,
626
+ props: { step: 1 },
627
+ },
628
+ {
629
+ name: "Contact Info",
630
+ background: "linear-gradient(135deg, #f093fb 0%, #f5576c 100%)",
631
+ foreground: "#ffffff",
632
+ component: ContactInfoStep,
633
+ props: { step: 2 },
634
+ },
635
+ {
636
+ name: "Preferences",
637
+ background: "linear-gradient(135deg, #4facfe 0%, #00f2fe 100%)",
638
+ foreground: "#ffffff",
639
+ component: PreferencesStep,
640
+ props: { step: 3 },
641
+ },
642
+ {
643
+ name: "Review",
644
+ background: "linear-gradient(135deg, #43e97b 0%, #38f9d7 100%)",
645
+ foreground: "#ffffff",
646
+ component: ReviewStep,
647
+ props: { step: 4 },
648
+ },
649
+ ]);
650
+
651
+ const slideoverRef = ref();
652
+ const currentStep = ref(0);
653
+ const totalSteps = panes.value.length;
654
+ const formData = ref({});
655
+
656
+ const nextStep = () => {
657
+ if (currentStep.value < totalSteps - 1) {
658
+ currentStep.value++;
659
+ slideoverRef.value?.navigate(currentStep.value);
660
+ }
661
+ };
662
+
663
+ const prevStep = () => {
664
+ if (currentStep.value > 0) {
665
+ currentStep.value--;
666
+ slideoverRef.value?.navigate(currentStep.value);
667
+ }
668
+ };
669
+
670
+ const completeForm = () => {
671
+ console.log("Form completed:", formData.value);
672
+ // Handle form submission
673
+ };
674
+
675
+ const updateFormData = (stepData: any) => {
676
+ formData.value = { ...formData.value, ...stepData };
677
+ };
678
+ </script>
679
+
680
+ <template>
681
+ <div class="multi-step-form">
682
+ <!-- Progress Header -->
683
+ <div class="form-header">
684
+ <div class="progress-container">
685
+ <div class="progress-bar">
686
+ <div
687
+ class="progress-fill"
688
+ :style="{ width: `${((currentStep + 1) / totalSteps) * 100}%` }"
689
+ />
690
+ </div>
691
+ <span class="progress-text">
692
+ Step {{ currentStep + 1 }} of {{ totalSteps }}
693
+ </span>
694
+ </div>
695
+
696
+ <h1 class="form-title">Complete Your Profile</h1>
697
+ </div>
698
+
699
+ <!-- Form Navigation -->
700
+ <div class="form-navigation">
701
+ <button
702
+ @click="prevStep"
703
+ :disabled="currentStep === 0"
704
+ class="nav-button prev"
705
+ >
706
+ ← Previous
707
+ </button>
708
+
709
+ <div class="step-indicators">
710
+ <button
711
+ v-for="(pane, index) in panes"
712
+ :key="pane.name"
713
+ @click="slideoverRef?.navigate(index)"
714
+ :class="[
715
+ 'step-indicator',
716
+ {
717
+ active: currentStep === index,
718
+ completed: currentStep > index,
719
+ },
720
+ ]"
721
+ >
722
+ {{ index + 1 }}
723
+ </button>
724
+ </div>
725
+
726
+ <button
727
+ v-if="currentStep < totalSteps - 1"
728
+ @click="nextStep"
729
+ class="nav-button next"
730
+ >
731
+ Next →
732
+ </button>
733
+
734
+ <button v-else @click="completeForm" class="nav-button complete">
735
+ Complete
736
+ </button>
737
+ </div>
738
+
739
+ <!-- Form Content -->
740
+ <SlideoverController
741
+ ref="slideoverRef"
742
+ :panes="panes"
743
+ component-id="multi-step-form"
744
+ :show-breadcrumb="false"
745
+ />
746
+ </div>
747
+ </template>
748
+
749
+ <style module>
750
+ .multi-step-form {
751
+ height: 100vh;
752
+ display: flex;
753
+ flex-direction: column;
754
+ background: #f8f9fa;
755
+ }
756
+
757
+ .form-header {
758
+ padding: 24px;
759
+ background: white;
760
+ border-bottom: 1px solid #e9ecef;
761
+ }
762
+
763
+ .progress-container {
764
+ display: flex;
765
+ align-items: center;
766
+ gap: 16px;
767
+ margin-bottom: 16px;
768
+ }
769
+
770
+ .progress-bar {
771
+ flex: 1;
772
+ height: 6px;
773
+ background: #e9ecef;
774
+ border-radius: 3px;
775
+ overflow: hidden;
776
+ }
777
+
778
+ .progress-fill {
779
+ height: 100%;
780
+ background: linear-gradient(90deg, #667eea, #764ba2);
781
+ transition: width 0.3s ease;
782
+ }
783
+
784
+ .progress-text {
785
+ font-size: 14px;
786
+ color: #6c757d;
787
+ font-weight: 500;
788
+ white-space: nowrap;
789
+ }
790
+
791
+ .form-title {
792
+ font-size: 24px;
793
+ font-weight: 700;
794
+ color: #1a202c;
795
+ margin: 0;
796
+ }
797
+
798
+ .form-navigation {
799
+ display: flex;
800
+ align-items: center;
801
+ justify-content: space-between;
802
+ padding: 16px 24px;
803
+ background: white;
804
+ border-bottom: 1px solid #e9ecef;
805
+ }
806
+
807
+ .nav-button {
808
+ padding: 10px 20px;
809
+ border: none;
810
+ border-radius: 8px;
811
+ font-weight: 600;
812
+ cursor: pointer;
813
+ transition: all 0.2s ease;
814
+ min-width: 100px;
815
+ }
816
+
817
+ .nav-button.prev {
818
+ background: #f8f9fa;
819
+ color: #6c757d;
820
+ border: 1px solid #dee2e6;
821
+ }
822
+
823
+ .nav-button.prev:hover:not(:disabled) {
824
+ background: #e9ecef;
825
+ border-color: #adb5bd;
826
+ }
827
+
828
+ .nav-button.next {
829
+ background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
830
+ color: white;
831
+ }
832
+
833
+ .nav-button.next:hover {
834
+ transform: translateY(-1px);
835
+ box-shadow: 0 4px 12px rgba(102, 126, 234, 0.4);
836
+ }
837
+
838
+ .nav-button.complete {
839
+ background: linear-gradient(135deg, #43e97b 0%, #38f9d7 100%);
840
+ color: white;
841
+ }
842
+
843
+ .nav-button.complete:hover {
844
+ transform: translateY(-1px);
845
+ box-shadow: 0 4px 12px rgba(67, 233, 123, 0.4);
846
+ }
847
+
848
+ .nav-button:disabled {
849
+ opacity: 0.5;
850
+ cursor: not-allowed;
851
+ }
852
+
853
+ .step-indicators {
854
+ display: flex;
855
+ gap: 8px;
856
+ }
857
+
858
+ .step-indicator {
859
+ width: 32px;
860
+ height: 32px;
861
+ border: 2px solid #e9ecef;
862
+ background: white;
863
+ color: #6c757d;
864
+ border-radius: 50%;
865
+ cursor: pointer;
866
+ font-weight: 600;
867
+ transition: all 0.2s ease;
868
+ }
869
+
870
+ .step-indicator:hover {
871
+ border-color: #adb5bd;
872
+ color: #495057;
873
+ }
874
+
875
+ .step-indicator.active {
876
+ background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
877
+ border-color: #667eea;
878
+ color: white;
879
+ }
880
+
881
+ .step-indicator.completed {
882
+ background: #28a745;
883
+ border-color: #28a745;
884
+ color: white;
885
+ }
886
+ </style>
887
+ ```
888
+
889
+ ### Dashboard with Sidebar
890
+
891
+ ```vue
892
+ <script setup lang="ts">
893
+ import { ref } from "vue";
894
+ import { SlideoverController } from "@umbra-ui/core";
895
+ import DashboardMain from "./DashboardMain.vue";
896
+ import AnalyticsPanel from "./AnalyticsPanel.vue";
897
+ import NotificationsPanel from "./NotificationsPanel.vue";
898
+ import UserProfilePanel from "./UserProfilePanel.vue";
899
+
900
+ const panes = ref([
901
+ {
902
+ name: "Dashboard",
903
+ background: "#ffffff",
904
+ foreground: "#1a202c",
905
+ component: DashboardMain,
906
+ props: { title: "Main Dashboard" },
907
+ },
908
+ {
909
+ name: "Analytics",
910
+ background: "#f7fafc",
911
+ foreground: "#2d3748",
912
+ component: AnalyticsPanel,
913
+ props: { period: "30d" },
914
+ },
915
+ {
916
+ name: "Notifications",
917
+ background: "#edf2f7",
918
+ foreground: "#4a5568",
919
+ component: NotificationsPanel,
920
+ props: { unread: 5 },
921
+ },
922
+ {
923
+ name: "Profile",
924
+ background: "#e2e8f0",
925
+ foreground: "#718096",
926
+ component: UserProfilePanel,
927
+ props: { userId: "current" },
928
+ },
929
+ ]);
930
+
931
+ const slideoverRef = ref();
932
+ const sidebarOpen = ref(false);
933
+
934
+ const toggleSidebar = () => {
935
+ sidebarOpen.value = !sidebarOpen.value;
936
+ if (sidebarOpen.value) {
937
+ slideoverRef.value?.showAll();
938
+ } else {
939
+ slideoverRef.value?.hideAll();
940
+ }
941
+ };
942
+
943
+ const navigateToPanel = (index: number) => {
944
+ slideoverRef.value?.navigate(index);
945
+ sidebarOpen.value = true;
946
+ };
947
+ </script>
948
+
949
+ <template>
950
+ <div class="dashboard-layout">
951
+ <!-- Top Navigation -->
952
+ <header class="dashboard-header">
953
+ <div class="header-left">
954
+ <button @click="toggleSidebar" class="menu-toggle">
955
+ <span class="hamburger"></span>
956
+ <span class="hamburger"></span>
957
+ <span class="hamburger"></span>
958
+ </button>
959
+ <h1 class="dashboard-title">Dashboard</h1>
960
+ </div>
961
+
962
+ <div class="header-right">
963
+ <button @click="navigateToPanel(2)" class="notification-btn">
964
+ 🔔
965
+ <span class="notification-badge">5</span>
966
+ </button>
967
+ <button @click="navigateToPanel(3)" class="profile-btn">👤</button>
968
+ </div>
969
+ </header>
970
+
971
+ <!-- Quick Actions -->
972
+ <div class="quick-actions">
973
+ <button @click="navigateToPanel(0)" class="action-card">
974
+ <span class="action-icon">📊</span>
975
+ <span class="action-label">Dashboard</span>
976
+ </button>
977
+ <button @click="navigateToPanel(1)" class="action-card">
978
+ <span class="action-icon">📈</span>
979
+ <span class="action-label">Analytics</span>
980
+ </button>
981
+ <button @click="navigateToPanel(2)" class="action-card">
982
+ <span class="action-icon">🔔</span>
983
+ <span class="action-label">Notifications</span>
984
+ </button>
985
+ <button @click="navigateToPanel(3)" class="action-card">
986
+ <span class="action-icon">👤</span>
987
+ <span class="action-label">Profile</span>
988
+ </button>
989
+ </div>
990
+
991
+ <!-- Main Content -->
992
+ <SlideoverController
993
+ ref="slideoverRef"
994
+ :panes="panes"
995
+ component-id="dashboard-slideover"
996
+ :show-breadcrumb="true"
997
+ />
998
+ </div>
999
+ </template>
1000
+
1001
+ <style module>
1002
+ .dashboard-layout {
1003
+ height: 100vh;
1004
+ display: flex;
1005
+ flex-direction: column;
1006
+ background: #f8f9fa;
1007
+ }
1008
+
1009
+ .dashboard-header {
1010
+ display: flex;
1011
+ justify-content: space-between;
1012
+ align-items: center;
1013
+ padding: 16px 24px;
1014
+ background: white;
1015
+ border-bottom: 1px solid #e9ecef;
1016
+ box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1);
1017
+ }
1018
+
1019
+ .header-left {
1020
+ display: flex;
1021
+ align-items: center;
1022
+ gap: 16px;
1023
+ }
1024
+
1025
+ .menu-toggle {
1026
+ display: flex;
1027
+ flex-direction: column;
1028
+ gap: 3px;
1029
+ background: none;
1030
+ border: none;
1031
+ cursor: pointer;
1032
+ padding: 8px;
1033
+ border-radius: 4px;
1034
+ transition: background 0.2s ease;
1035
+ }
1036
+
1037
+ .menu-toggle:hover {
1038
+ background: #f8f9fa;
1039
+ }
1040
+
1041
+ .hamburger {
1042
+ width: 18px;
1043
+ height: 2px;
1044
+ background: #495057;
1045
+ border-radius: 1px;
1046
+ transition: all 0.2s ease;
1047
+ }
1048
+
1049
+ .dashboard-title {
1050
+ font-size: 24px;
1051
+ font-weight: 700;
1052
+ color: #1a202c;
1053
+ margin: 0;
1054
+ }
1055
+
1056
+ .header-right {
1057
+ display: flex;
1058
+ align-items: center;
1059
+ gap: 12px;
1060
+ }
1061
+
1062
+ .notification-btn,
1063
+ .profile-btn {
1064
+ position: relative;
1065
+ width: 40px;
1066
+ height: 40px;
1067
+ border: none;
1068
+ background: #f8f9fa;
1069
+ border-radius: 50%;
1070
+ cursor: pointer;
1071
+ font-size: 18px;
1072
+ transition: all 0.2s ease;
1073
+ }
1074
+
1075
+ .notification-btn:hover,
1076
+ .profile-btn:hover {
1077
+ background: #e9ecef;
1078
+ transform: scale(1.05);
1079
+ }
1080
+
1081
+ .notification-badge {
1082
+ position: absolute;
1083
+ top: -2px;
1084
+ right: -2px;
1085
+ width: 18px;
1086
+ height: 18px;
1087
+ background: #dc3545;
1088
+ color: white;
1089
+ border-radius: 50%;
1090
+ font-size: 10px;
1091
+ font-weight: 600;
1092
+ display: flex;
1093
+ align-items: center;
1094
+ justify-content: center;
1095
+ }
1096
+
1097
+ .quick-actions {
1098
+ display: flex;
1099
+ gap: 16px;
1100
+ padding: 20px 24px;
1101
+ background: white;
1102
+ border-bottom: 1px solid #e9ecef;
1103
+ }
1104
+
1105
+ .action-card {
1106
+ display: flex;
1107
+ flex-direction: column;
1108
+ align-items: center;
1109
+ gap: 8px;
1110
+ padding: 16px;
1111
+ background: #f8f9fa;
1112
+ border: 1px solid #e9ecef;
1113
+ border-radius: 8px;
1114
+ cursor: pointer;
1115
+ transition: all 0.2s ease;
1116
+ min-width: 80px;
1117
+ }
1118
+
1119
+ .action-card:hover {
1120
+ background: #e9ecef;
1121
+ border-color: #adb5bd;
1122
+ transform: translateY(-2px);
1123
+ box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1);
1124
+ }
1125
+
1126
+ .action-icon {
1127
+ font-size: 24px;
1128
+ }
1129
+
1130
+ .action-label {
1131
+ font-size: 12px;
1132
+ font-weight: 500;
1133
+ color: #495057;
1134
+ }
1135
+ </style>
1136
+ ```
1137
+
1138
+ ## Advanced Usage
1139
+
1140
+ ### Custom Controller Integration
1141
+
1142
+ ```vue
1143
+ <script setup lang="ts">
1144
+ import { ref } from "vue";
1145
+ import { SlideoverController, useSlideoverController } from "@umbra-ui/core";
1146
+
1147
+ const panes = ref([
1148
+ // ... your panes
1149
+ ]);
1150
+
1151
+ // Create custom controller
1152
+ const customController = useSlideoverController(
1153
+ panes.value,
1154
+ "custom-slideover"
1155
+ );
1156
+
1157
+ // Override methods with custom logic
1158
+ const customNavigate = (index: number, animated: boolean = true) => {
1159
+ console.log(`Navigating to pane ${index}`);
1160
+ customController.navigate(index, animated);
1161
+ };
1162
+
1163
+ const customShowAll = () => {
1164
+ console.log("Showing all panes");
1165
+ customController.showAll();
1166
+ };
1167
+ </script>
1168
+
1169
+ <template>
1170
+ <SlideoverController
1171
+ :panes="panes"
1172
+ :controller="customController"
1173
+ component-id="custom-slideover"
1174
+ />
1175
+ </template>
1176
+ ```
1177
+
1178
+ ### Integration with Router
1179
+
1180
+ ```vue
1181
+ <script setup lang="ts">
1182
+ import { ref, watch } from "vue";
1183
+ import { useRoute, useRouter } from "vue-router";
1184
+ import { SlideoverController } from "@umbra-ui/core";
1185
+
1186
+ const route = useRoute();
1187
+ const router = useRouter();
1188
+ const slideoverRef = ref();
1189
+
1190
+ const panes = ref([
1191
+ // ... your panes
1192
+ ]);
1193
+
1194
+ // Sync with router
1195
+ watch(
1196
+ () => route.params.panel,
1197
+ (newPanel) => {
1198
+ const index = panes.value.findIndex((pane) => pane.name === newPanel);
1199
+ if (index !== -1) {
1200
+ slideoverRef.value?.navigate(index);
1201
+ }
1202
+ }
1203
+ );
1204
+
1205
+ const handleNavigation = (index: number) => {
1206
+ const pane = panes.value[index];
1207
+ router.push(`/dashboard/${pane.name.toLowerCase()}`);
1208
+ };
1209
+ </script>
1210
+ ```
1211
+
1212
+ ## Performance Considerations
1213
+
1214
+ - **Component Marking**: Always use `markRaw()` when passing components to prevent Vue's reactivity system from wrapping them
1215
+ - **Animation Performance**: GSAP FLIP animations are optimized for smooth 60fps performance
1216
+ - **Memory Management**: Panes are properly cleaned up when removed from the controller
1217
+ - **DOM Manipulation**: Efficient DOM manipulation using GSAP for optimal performance
1218
+
1219
+ ## Accessibility
1220
+
1221
+ - **Keyboard Navigation**: Support for arrow keys and tab navigation
1222
+ - **Screen Reader Support**: Proper ARIA labels and roles
1223
+ - **Focus Management**: Focus is maintained during transitions
1224
+ - **High Contrast**: Supports high contrast mode
1225
+
1226
+ ## Browser Support
1227
+
1228
+ - **Modern Browsers**: Chrome 88+, Firefox 85+, Safari 14+, Edge 88+
1229
+ - **Mobile Browsers**: iOS Safari 14+, Chrome Mobile 88+
1230
+ - **CSS Features**: Uses CSS Grid and modern layout features
1231
+ - **JavaScript**: Requires ES2020+ support
1232
+
1233
+ ## Troubleshooting
1234
+
1235
+ ### Common Issues
1236
+
1237
+ 1. **Animations not working**: Ensure GSAP and FLIP plugin are properly imported
1238
+ 2. **Panes not displaying**: Check that components are properly marked with `markRaw()`
1239
+ 3. **Navigation not responding**: Verify the `componentId` is unique and consistent
1240
+ 4. **Layout issues**: Ensure the container has a defined height
1241
+
1242
+ ### Debug Mode
1243
+
1244
+ ```vue
1245
+ <script setup lang="ts">
1246
+ import { ref, watch } from "vue";
1247
+ import { SlideoverController } from "@umbra-ui/core";
1248
+
1249
+ const slideoverRef = ref();
1250
+
1251
+ // Watch for navigation changes
1252
+ watch(
1253
+ () => slideoverRef.value?.currentPaneIndex,
1254
+ (newIndex) => {
1255
+ console.log("Current pane index:", newIndex);
1256
+ }
1257
+ );
1258
+ </script>
1259
+ ```
1260
+
1261
+ ## Migration Guide
1262
+
1263
+ ### From v1 to v2
1264
+
1265
+ - `componentId` prop is now optional with auto-generation
1266
+ - Pane interface has been updated with new properties
1267
+ - Animation system has been refactored for better performance
1268
+ - Composable API has been enhanced with new methods
1269
+
1270
+ ### Breaking Changes
1271
+
1272
+ - Removed automatic pane detection
1273
+ - Changed animation timing and easing
1274
+ - Updated CSS class structure
1275
+ - Modified event handling system