@skewedaspect/sleekspace-ui 0.2.0-beta.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 (266) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +111 -0
  3. package/dist/sleekspace-ui.css +12844 -0
  4. package/dist/sleekspace-ui.es.js +19021 -0
  5. package/dist/sleekspace-ui.umd.js +19040 -0
  6. package/docs/components/accordion.md +92 -0
  7. package/docs/components/alert.md +72 -0
  8. package/docs/components/avatar.md +69 -0
  9. package/docs/components/breadcrumbs.md +65 -0
  10. package/docs/components/button/_meta.yaml +12 -0
  11. package/docs/components/button/accessibility.md +16 -0
  12. package/docs/components/button/custom-colors.md +18 -0
  13. package/docs/components/button/icons.md +31 -0
  14. package/docs/components/button/intro.md +8 -0
  15. package/docs/components/button/kinds.md +25 -0
  16. package/docs/components/button/sizes.md +14 -0
  17. package/docs/components/button/states.md +12 -0
  18. package/docs/components/button/usage.md +23 -0
  19. package/docs/components/button/variants.md +14 -0
  20. package/docs/components/button.md +110 -0
  21. package/docs/components/card.md +87 -0
  22. package/docs/components/checkbox.md +77 -0
  23. package/docs/components/collapsible.md +71 -0
  24. package/docs/components/divider.md +62 -0
  25. package/docs/components/dropdown.md +88 -0
  26. package/docs/components/field.md +80 -0
  27. package/docs/components/group.md +41 -0
  28. package/docs/components/input.md +84 -0
  29. package/docs/components/listbox.md +82 -0
  30. package/docs/components/modal.md +101 -0
  31. package/docs/components/navbar.md +64 -0
  32. package/docs/components/number-input.md +78 -0
  33. package/docs/components/page.md +77 -0
  34. package/docs/components/pagination.md +88 -0
  35. package/docs/components/panel.md +74 -0
  36. package/docs/components/popover.md +93 -0
  37. package/docs/components/progress.md +76 -0
  38. package/docs/components/radio.md +86 -0
  39. package/docs/components/sidebar.md +74 -0
  40. package/docs/components/skeleton.md +76 -0
  41. package/docs/components/slider.md +94 -0
  42. package/docs/components/spinner.md +59 -0
  43. package/docs/components/switch.md +97 -0
  44. package/docs/components/table.md +91 -0
  45. package/docs/components/tabs.md +108 -0
  46. package/docs/components/tag.md +75 -0
  47. package/docs/components/tags-input.md +88 -0
  48. package/docs/components/textarea.md +80 -0
  49. package/docs/components/theme.md +65 -0
  50. package/docs/components/toast.md +95 -0
  51. package/docs/components/tooltip.md +90 -0
  52. package/docs/guides/custom-colors.md +84 -0
  53. package/docs/guides/design-tokens.md +105 -0
  54. package/docs/guides/getting-started.md +144 -0
  55. package/docs/guides/installation.md +62 -0
  56. package/docs/guides/theming.md +101 -0
  57. package/package.json +76 -0
  58. package/src/components/Accordion/SkAccordion.vue +133 -0
  59. package/src/components/Accordion/SkAccordionItem.vue +131 -0
  60. package/src/components/Accordion/index.ts +3 -0
  61. package/src/components/Accordion/types.ts +9 -0
  62. package/src/components/Alert/SkAlert.vue +137 -0
  63. package/src/components/Alert/types.ts +10 -0
  64. package/src/components/Avatar/SkAvatar.vue +141 -0
  65. package/src/components/Avatar/index.ts +8 -0
  66. package/src/components/Avatar/types.ts +31 -0
  67. package/src/components/Breadcrumbs/SkBreadcrumbItem.vue +76 -0
  68. package/src/components/Breadcrumbs/SkBreadcrumbSeparator.vue +38 -0
  69. package/src/components/Breadcrumbs/SkBreadcrumbs.vue +93 -0
  70. package/src/components/Breadcrumbs/index.ts +10 -0
  71. package/src/components/Breadcrumbs/types.ts +36 -0
  72. package/src/components/Button/SkButton.vue +148 -0
  73. package/src/components/Button/types.ts +21 -0
  74. package/src/components/Card/SkCard.vue +144 -0
  75. package/src/components/Card/types.ts +12 -0
  76. package/src/components/Checkbox/SkCheckbox.vue +136 -0
  77. package/src/components/Checkbox/index.ts +8 -0
  78. package/src/components/Checkbox/types.ts +10 -0
  79. package/src/components/Collapsible/SkCollapsible.vue +159 -0
  80. package/src/components/Collapsible/index.ts +2 -0
  81. package/src/components/Collapsible/types.ts +8 -0
  82. package/src/components/Divider/SkDivider.vue +63 -0
  83. package/src/components/Divider/types.ts +15 -0
  84. package/src/components/Dropdown/SkDropdown.vue +150 -0
  85. package/src/components/Dropdown/SkDropdownMenuItem.vue +58 -0
  86. package/src/components/Dropdown/SkDropdownMenuSeparator.vue +26 -0
  87. package/src/components/Dropdown/SkDropdownSubmenu.vue +107 -0
  88. package/src/components/Dropdown/index.ts +11 -0
  89. package/src/components/Dropdown/types.ts +11 -0
  90. package/src/components/Field/SkField.vue +152 -0
  91. package/src/components/Field/index.ts +8 -0
  92. package/src/components/Field/types.ts +7 -0
  93. package/src/components/Group/SkGroup.vue +52 -0
  94. package/src/components/Group/types.ts +10 -0
  95. package/src/components/Input/SkInput.vue +117 -0
  96. package/src/components/Input/index.ts +8 -0
  97. package/src/components/Input/types.ts +11 -0
  98. package/src/components/Listbox/SkListbox.vue +164 -0
  99. package/src/components/Listbox/SkListboxItem.vue +68 -0
  100. package/src/components/Listbox/SkListboxSeparator.vue +26 -0
  101. package/src/components/Listbox/index.ts +10 -0
  102. package/src/components/Listbox/types.ts +10 -0
  103. package/src/components/Modal/SkModal.vue +231 -0
  104. package/src/components/Modal/index.ts +8 -0
  105. package/src/components/Modal/types.ts +12 -0
  106. package/src/components/NavBar/SkNavBar.vue +83 -0
  107. package/src/components/NavBar/index.ts +8 -0
  108. package/src/components/NavBar/types.ts +15 -0
  109. package/src/components/NumberInput/SkNumberInput.vue +168 -0
  110. package/src/components/NumberInput/index.ts +8 -0
  111. package/src/components/NumberInput/types.ts +10 -0
  112. package/src/components/Page/SkPage.vue +94 -0
  113. package/src/components/Page/index.ts +8 -0
  114. package/src/components/Page/types.ts +21 -0
  115. package/src/components/Pagination/SkPagination.vue +185 -0
  116. package/src/components/Pagination/SkPaginationItem.vue +107 -0
  117. package/src/components/Pagination/index.ts +9 -0
  118. package/src/components/Pagination/types.ts +40 -0
  119. package/src/components/Panel/SkPanel.vue +96 -0
  120. package/src/components/Panel/types.ts +15 -0
  121. package/src/components/Popover/SkPopover.vue +185 -0
  122. package/src/components/Popover/index.ts +8 -0
  123. package/src/components/Popover/types.ts +11 -0
  124. package/src/components/Progress/SkProgress.vue +144 -0
  125. package/src/components/Progress/index.ts +8 -0
  126. package/src/components/Progress/types.ts +34 -0
  127. package/src/components/Radio/SkRadio.vue +110 -0
  128. package/src/components/Radio/SkRadioGroup.vue +92 -0
  129. package/src/components/Radio/index.ts +9 -0
  130. package/src/components/Radio/types.ts +11 -0
  131. package/src/components/Sidebar/README.md +405 -0
  132. package/src/components/Sidebar/SkSidebar.vue +88 -0
  133. package/src/components/Sidebar/SkSidebarItem.vue +58 -0
  134. package/src/components/Sidebar/SkSidebarSection.vue +40 -0
  135. package/src/components/Sidebar/types.ts +3 -0
  136. package/src/components/Skeleton/SkSkeleton.vue +171 -0
  137. package/src/components/Skeleton/index.ts +8 -0
  138. package/src/components/Skeleton/types.ts +31 -0
  139. package/src/components/Slider/SkSlider.vue +165 -0
  140. package/src/components/Slider/index.ts +8 -0
  141. package/src/components/Slider/types.ts +44 -0
  142. package/src/components/Spinner/SkSpinner.vue +105 -0
  143. package/src/components/Spinner/index.ts +8 -0
  144. package/src/components/Spinner/types.ts +28 -0
  145. package/src/components/Switch/SkSwitch.vue +215 -0
  146. package/src/components/Switch/index.ts +8 -0
  147. package/src/components/Switch/types.ts +12 -0
  148. package/src/components/Table/SkTable.vue +109 -0
  149. package/src/components/Table/index.ts +2 -0
  150. package/src/components/Table/types.ts +15 -0
  151. package/src/components/Tabs/README.md +331 -0
  152. package/src/components/Tabs/SkTab.vue +84 -0
  153. package/src/components/Tabs/SkTabList.vue +62 -0
  154. package/src/components/Tabs/SkTabPanel.vue +47 -0
  155. package/src/components/Tabs/SkTabPanels.vue +23 -0
  156. package/src/components/Tabs/SkTabs.vue +124 -0
  157. package/src/components/Tabs/types.ts +21 -0
  158. package/src/components/Tag/SkTag.vue +129 -0
  159. package/src/components/Tag/types.ts +15 -0
  160. package/src/components/TagsInput/SkTagsInput.vue +184 -0
  161. package/src/components/TagsInput/index.ts +8 -0
  162. package/src/components/TagsInput/types.ts +10 -0
  163. package/src/components/Textarea/SkTextarea.vue +117 -0
  164. package/src/components/Textarea/index.ts +8 -0
  165. package/src/components/Textarea/types.ts +10 -0
  166. package/src/components/Theme/SkTheme.vue +47 -0
  167. package/src/components/Theme/types.ts +17 -0
  168. package/src/components/Theme/useTheme.ts +131 -0
  169. package/src/components/Toast/SkToast.vue +156 -0
  170. package/src/components/Toast/SkToastProvider.vue +180 -0
  171. package/src/components/Toast/index.ts +15 -0
  172. package/src/components/Toast/types.ts +63 -0
  173. package/src/components/Toast/useToast.ts +78 -0
  174. package/src/components/Tooltip/SkTooltip.vue +162 -0
  175. package/src/components/Tooltip/SkTooltipProvider.vue +114 -0
  176. package/src/components/Tooltip/index.ts +9 -0
  177. package/src/components/Tooltip/types.ts +13 -0
  178. package/src/composables/useCustomColors.test.ts +505 -0
  179. package/src/composables/useCustomColors.ts +124 -0
  180. package/src/composables/usePortalContext.test.ts +402 -0
  181. package/src/composables/usePortalContext.ts +95 -0
  182. package/src/global.d.ts +76 -0
  183. package/src/index.ts +259 -0
  184. package/src/styles/_scrollbar.scss +100 -0
  185. package/src/styles/base/_fonts.scss +105 -0
  186. package/src/styles/base/_global.scss +47 -0
  187. package/src/styles/base/_index.scss +24 -0
  188. package/src/styles/base/_reset.scss +11 -0
  189. package/src/styles/base/_typography.scss +178 -0
  190. package/src/styles/components/_accordion.scss +250 -0
  191. package/src/styles/components/_alert.scss +239 -0
  192. package/src/styles/components/_avatar.scss +133 -0
  193. package/src/styles/components/_breadcrumbs.scss +137 -0
  194. package/src/styles/components/_button.scss +731 -0
  195. package/src/styles/components/_card.scss +141 -0
  196. package/src/styles/components/_checkbox.scss +232 -0
  197. package/src/styles/components/_collapsible.scss +158 -0
  198. package/src/styles/components/_divider.scss +121 -0
  199. package/src/styles/components/_field.scss +87 -0
  200. package/src/styles/components/_group.scss +138 -0
  201. package/src/styles/components/_index.scss +46 -0
  202. package/src/styles/components/_input.scss +205 -0
  203. package/src/styles/components/_listbox.scss +453 -0
  204. package/src/styles/components/_menu.scss +216 -0
  205. package/src/styles/components/_modal.scss +329 -0
  206. package/src/styles/components/_navbar.scss +258 -0
  207. package/src/styles/components/_number-input.scss +352 -0
  208. package/src/styles/components/_page.scss +98 -0
  209. package/src/styles/components/_pagination.scss +411 -0
  210. package/src/styles/components/_panel.scss +281 -0
  211. package/src/styles/components/_popover.scss +258 -0
  212. package/src/styles/components/_progress.scss +280 -0
  213. package/src/styles/components/_radio.scss +255 -0
  214. package/src/styles/components/_sidebar.scss +92 -0
  215. package/src/styles/components/_skeleton.scss +138 -0
  216. package/src/styles/components/_slider.scss +262 -0
  217. package/src/styles/components/_spinner.scss +331 -0
  218. package/src/styles/components/_switch.scss +370 -0
  219. package/src/styles/components/_table.scss +405 -0
  220. package/src/styles/components/_tabs.scss +486 -0
  221. package/src/styles/components/_tag.scss +425 -0
  222. package/src/styles/components/_tags-input.scss +279 -0
  223. package/src/styles/components/_textarea.scss +208 -0
  224. package/src/styles/components/_toast.scss +331 -0
  225. package/src/styles/components/_tooltip.scss +206 -0
  226. package/src/styles/fonts/Titillium_Web/OFL.txt +93 -0
  227. package/src/styles/fonts/Titillium_Web/TitilliumWeb-Black.ttf +0 -0
  228. package/src/styles/fonts/Titillium_Web/TitilliumWeb-Bold.ttf +0 -0
  229. package/src/styles/fonts/Titillium_Web/TitilliumWeb-BoldItalic.ttf +0 -0
  230. package/src/styles/fonts/Titillium_Web/TitilliumWeb-ExtraLight.ttf +0 -0
  231. package/src/styles/fonts/Titillium_Web/TitilliumWeb-ExtraLightItalic.ttf +0 -0
  232. package/src/styles/fonts/Titillium_Web/TitilliumWeb-Italic.ttf +0 -0
  233. package/src/styles/fonts/Titillium_Web/TitilliumWeb-Light.ttf +0 -0
  234. package/src/styles/fonts/Titillium_Web/TitilliumWeb-LightItalic.ttf +0 -0
  235. package/src/styles/fonts/Titillium_Web/TitilliumWeb-Regular.ttf +0 -0
  236. package/src/styles/fonts/Titillium_Web/TitilliumWeb-SemiBold.ttf +0 -0
  237. package/src/styles/fonts/Titillium_Web/TitilliumWeb-SemiBoldItalic.ttf +0 -0
  238. package/src/styles/index.scss +17 -0
  239. package/src/styles/mixins/_cut-border.scss +254 -0
  240. package/src/styles/mixins/_index.scss +7 -0
  241. package/src/styles/theme/_variables.scss +42 -0
  242. package/src/styles/themes/README.md +127 -0
  243. package/src/styles/themes/_colorful.scss +58 -0
  244. package/src/styles/themes/_greyscale.scss +58 -0
  245. package/src/styles/themes/index.scss +9 -0
  246. package/src/styles/tokens/README.md +268 -0
  247. package/src/styles/tokens/_foundation-borders.scss +26 -0
  248. package/src/styles/tokens/_foundation-colors.scss +169 -0
  249. package/src/styles/tokens/_foundation-glow.scss +36 -0
  250. package/src/styles/tokens/_foundation-radius.scss +53 -0
  251. package/src/styles/tokens/_foundation-scrollbar.scss +31 -0
  252. package/src/styles/tokens/_foundation-shadows.scss +37 -0
  253. package/src/styles/tokens/_foundation-space.scss +36 -0
  254. package/src/styles/tokens/_foundation-transitions.scss +37 -0
  255. package/src/styles/tokens/_foundation-typography.scss +58 -0
  256. package/src/styles/tokens/_semantic-color-kinds.scss +112 -0
  257. package/src/styles/tokens/_semantic-colors.scss +10 -0
  258. package/src/styles/tokens/_semantic-interactive.scss +29 -0
  259. package/src/styles/tokens/_semantic-scrollbar.scss +48 -0
  260. package/src/styles/tokens/_semantic-surfaces.scss +36 -0
  261. package/src/styles/tokens/index.scss +38 -0
  262. package/src/styles/tokens.scss +268 -0
  263. package/src/styles/utilities/_index.scss +9 -0
  264. package/src/styles/utilities/_typography.scss +121 -0
  265. package/src/types.ts +50 -0
  266. package/web-types.json +3524 -0
@@ -0,0 +1,144 @@
1
+ ---
2
+ title: Getting Started
3
+ ---
4
+
5
+ # Getting Started
6
+
7
+ SleekSpace UI is a Vue 3 component library with a cyberpunk aesthetic. It provides themed components built on OKLCH colors, beveled corners, and runtime theming through CSS custom properties.
8
+
9
+ ## Quick Start
10
+
11
+ ### Minimal Example
12
+
13
+ The only requirement is wrapping your app in `SkTheme`. Here is the simplest setup:
14
+
15
+ ```vue
16
+ <template>
17
+ <SkTheme theme="colorful">
18
+ <SkPanel kind="neutral">
19
+ <h2>Welcome to SleekSpace UI</h2>
20
+ <p>You're ready to build something cool.</p>
21
+ <SkButton kind="accent" variant="solid">
22
+ Get Started
23
+ </SkButton>
24
+ </SkPanel>
25
+ </SkTheme>
26
+ </template>
27
+ ```
28
+
29
+ That's it. You can start using any SleekSpace component inside `SkTheme`.
30
+
31
+ ### Recommended Setup with SkPage
32
+
33
+ For most applications, you will want a proper page layout with a header, sidebar, and content area. `SkPage` provides this structure:
34
+
35
+ ```vue
36
+ <template>
37
+ <SkTheme theme="colorful">
38
+ <SkPage fixed-header>
39
+ <template #header>
40
+ <SkNavBar kind="primary">
41
+ <template #brand>My App</template>
42
+ </SkNavBar>
43
+ </template>
44
+
45
+ <template #sidebar>
46
+ <SkSidebar>
47
+ <SkSidebarItem href="/">Home</SkSidebarItem>
48
+ <SkSidebarItem href="/settings">Settings</SkSidebarItem>
49
+ </SkSidebar>
50
+ </template>
51
+
52
+ <SkPanel kind="neutral">
53
+ <h2>Welcome to SleekSpace UI</h2>
54
+ <SkButton kind="accent" variant="solid">
55
+ Get Started
56
+ </SkButton>
57
+ </SkPanel>
58
+
59
+ <template #footer>
60
+ <p>Footer content goes here</p>
61
+ </template>
62
+ </SkPage>
63
+ </SkTheme>
64
+ </template>
65
+ ```
66
+
67
+ ### Why Use SkPage?
68
+
69
+ `SkPage` is optional, but most applications will benefit from it:
70
+
71
+ - **Full page layout structure** -- Provides header, sidebar, content, and footer regions in a single component.
72
+ - **Semantic HTML** -- Uses `<main>`, `<header>`, `<footer>`, and `<aside>` elements for better accessibility and SEO.
73
+ - **Fixed headers and footers** -- Keep navigation visible while the content area scrolls independently.
74
+ - **Flexible slots** -- All slots are optional. Use just a header, just a sidebar, or any combination. The layout adapts automatically.
75
+ - **Sidebar positioning** -- Place the sidebar on the left or right with a single prop.
76
+
77
+ If you are building a single-page app, dashboard, or documentation site, `SkPage` gives you a solid foundation. For simpler use cases like embedded widgets or single components, you can skip it entirely.
78
+
79
+ ## Global vs Cherry-Pick Imports
80
+
81
+ ### Global Registration (Plugin)
82
+
83
+ The plugin registers all components globally. No per-file imports are needed:
84
+
85
+ ```js
86
+ import SleekSpaceUI from '@skewedaspect/sleekspace-ui';
87
+ app.use(SleekSpaceUI);
88
+ ```
89
+
90
+ ### Cherry-Pick Imports
91
+
92
+ Import only what you need per component file:
93
+
94
+ ```vue
95
+ <script setup>
96
+ import { SkButton, SkPanel } from '@skewedaspect/sleekspace-ui';
97
+ </script>
98
+
99
+ <template>
100
+ <SkPanel kind="neutral">
101
+ <SkButton kind="primary">Click Me</SkButton>
102
+ </SkPanel>
103
+ </template>
104
+ ```
105
+
106
+ ### Auto-Import with unplugin-vue-components
107
+
108
+ Set up automatic imports with a custom resolver:
109
+
110
+ ```ts
111
+ // vite.config.ts
112
+ import Components from 'unplugin-vue-components/vite';
113
+
114
+ export default defineConfig({
115
+ plugins: [
116
+ vue(),
117
+ Components({
118
+ dts: true,
119
+ resolvers: [
120
+ (componentName) => {
121
+ if (componentName.startsWith('Sk')) {
122
+ return { name: componentName, from: '@skewedaspect/sleekspace-ui' };
123
+ }
124
+ }
125
+ ]
126
+ })
127
+ ]
128
+ });
129
+ ```
130
+
131
+ ## Common Props
132
+
133
+ Most SleekSpace components share these props:
134
+
135
+ - **kind** -- Semantic color: `neutral`, `primary`, `accent`, `info`, `success`, `warning`, `danger`. Many also accept color kinds like `neon-blue`, `neon-purple`, etc.
136
+ - **size** -- Dimensions: `xs`, `sm`, `md`, `lg`, `xl` (component-dependent).
137
+ - **variant** -- Visual style: `solid`, `outline`, `subtle`, `ghost`, `link` (component-dependent).
138
+ - **baseColor / textColor** -- Override colors with any CSS value (hex, OKLCH, RGB, CSS variable).
139
+
140
+ ## Next Steps
141
+
142
+ - [Theming](./theming.md) -- Runtime theme switching and custom themes
143
+ - [Design Tokens](./design-tokens.md) -- Token architecture and usage
144
+ - [Custom Colors](./custom-colors.md) -- Per-component color overrides
@@ -0,0 +1,62 @@
1
+ ---
2
+ title: Installation
3
+ ---
4
+
5
+ # Installation
6
+
7
+ ## Install the package
8
+
9
+ ```bash
10
+ npm install @skewedaspect/sleekspace-ui
11
+ ```
12
+
13
+ ## Vue Plugin Registration
14
+
15
+ Register all components globally using the Vue plugin:
16
+
17
+ ```js
18
+ import { createApp } from 'vue';
19
+ import App from './App.vue';
20
+ import SleekSpaceUI from '@skewedaspect/sleekspace-ui';
21
+ import '@skewedaspect/sleekspace-ui/style';
22
+
23
+ const app = createApp(App);
24
+ app.use(SleekSpaceUI);
25
+ app.mount('#app');
26
+ ```
27
+
28
+ ## CSS Import
29
+
30
+ The style import is required regardless of how you register components:
31
+
32
+ ```js
33
+ import '@skewedaspect/sleekspace-ui/style';
34
+ ```
35
+
36
+ This provides all component styles and design tokens needed for theming.
37
+
38
+ ## Tailwind CSS v4 Integration
39
+
40
+ To use SleekSpace design tokens as Tailwind utilities, import the tokens file in your CSS entry point:
41
+
42
+ ```css
43
+ @import "tailwindcss";
44
+ @import "@skewedaspect/sleekspace-ui/tokens.css";
45
+ ```
46
+
47
+ This registers all SleekSpace CSS custom properties with Tailwind's `@theme` system, enabling utility classes like `bg-sk-primary`, `text-sk-accent-text`, and `border-sk-danger`.
48
+
49
+ ## TypeScript Support
50
+
51
+ For VS Code with Volar, add the global types to your `tsconfig.json`:
52
+
53
+ ```json
54
+ {
55
+ "include": [
56
+ "src/**/*",
57
+ "node_modules/@skewedaspect/sleekspace-ui/src/global.d.ts"
58
+ ]
59
+ }
60
+ ```
61
+
62
+ WebStorm and IntelliJ IDEA work automatically via the included `web-types.json`.
@@ -0,0 +1,101 @@
1
+ ---
2
+ title: Theming
3
+ ---
4
+
5
+ # Theming
6
+
7
+ SleekSpace UI uses a runtime theming system powered by CSS custom properties and the `data-scheme` attribute. Themes change semantic token values so all components update automatically.
8
+
9
+ ## SkTheme Component
10
+
11
+ Wrap your application or any section in SkTheme to apply a theme:
12
+
13
+ ```vue
14
+ <template>
15
+ <SkTheme theme="colorful">
16
+ <SkButton kind="primary">Colorful Primary</SkButton>
17
+ <SkPanel kind="accent">Colorful Accent</SkPanel>
18
+ </SkTheme>
19
+ </template>
20
+ ```
21
+
22
+ ## Available Themes
23
+
24
+ - **greyscale** (default) -- Monochromatic color scheme where semantic colors map to neutral grays.
25
+ - **colorful** -- Vibrant cyberpunk palette with distinct hues for each semantic kind.
26
+
27
+ ## Runtime Theme Switching
28
+
29
+ Use the `useTheme` composable for programmatic control:
30
+
31
+ ```vue
32
+ <script setup>
33
+ import { useTheme } from '@skewedaspect/sleekspace-ui';
34
+
35
+ const { currentTheme, setTheme } = useTheme();
36
+ </script>
37
+
38
+ <template>
39
+ <p>Current: {{ currentTheme }}</p>
40
+ <SkButton @click="setTheme('colorful')">Colorful</SkButton>
41
+ <SkButton @click="setTheme('greyscale')">Greyscale</SkButton>
42
+ </template>
43
+ ```
44
+
45
+ ## How It Works
46
+
47
+ SkTheme sets a `data-scheme` attribute on its wrapper element. CSS rules scoped to each scheme override semantic token values:
48
+
49
+ ```css
50
+ [data-scheme="greyscale"] {
51
+ --sk-primary-base: oklch(0.5 0 0);
52
+ }
53
+
54
+ [data-scheme="colorful"] {
55
+ --sk-primary-base: oklch(0.65 0.2 260);
56
+ }
57
+ ```
58
+
59
+ All components reference these semantic tokens, so switching the scheme instantly updates every component in the subtree.
60
+
61
+ ## Creating Custom Themes
62
+
63
+ Define a custom theme by providing CSS custom property overrides on a new `data-scheme` value:
64
+
65
+ ```css
66
+ [data-scheme="ocean"] {
67
+ --sk-primary-base: oklch(0.55 0.15 230);
68
+ --sk-primary-text: oklch(1 0 0);
69
+ --sk-primary-hover: oklch(0.45 0.15 230);
70
+
71
+ --sk-accent-base: oklch(0.6 0.2 180);
72
+ --sk-accent-text: oklch(1 0 0);
73
+ --sk-accent-hover: oklch(0.5 0.2 180);
74
+
75
+ /* Define all 7 semantic kinds: neutral, primary, accent, info, success, warning, danger */
76
+ }
77
+ ```
78
+
79
+ Then use it with the theme component:
80
+
81
+ ```vue
82
+ <SkTheme theme="ocean">
83
+ <YourContent />
84
+ </SkTheme>
85
+ ```
86
+
87
+ ## Semantic Kinds
88
+
89
+ All themed components accept a `kind` prop with these values:
90
+
91
+ | Kind | Purpose |
92
+ |------|---------|
93
+ | `neutral` | Default, neutral styling |
94
+ | `primary` | Primary brand color |
95
+ | `accent` | Secondary brand color |
96
+ | `info` | Informational messages |
97
+ | `success` | Success states |
98
+ | `warning` | Warning states |
99
+ | `danger` | Error or destructive actions |
100
+
101
+ Components also support 10 direct color kinds (`boulder`, `neon-blue`, `light-blue`, `neon-orange`, `neon-purple`, `neon-green`, `neon-mint`, `neon-pink`, `yellow`, `red`) that are not affected by theme switching.
package/package.json ADDED
@@ -0,0 +1,76 @@
1
+ {
2
+ "name": "@skewedaspect/sleekspace-ui",
3
+ "version": "0.2.0-beta.1",
4
+ "description": "A Vue 3 component library with a cyberpunk aesthetic, featuring OKLCH colors, beveled corners, and a powerful design token system",
5
+ "type": "module",
6
+ "main": "dist/sleekspace-ui.umd.js",
7
+ "module": "dist/sleekspace-ui.es.js",
8
+ "types": "dist/index.d.ts",
9
+ "web-types": "./web-types.json",
10
+ "exports": {
11
+ ".": {
12
+ "types": "./dist/index.d.ts",
13
+ "import": "./dist/sleekspace-ui.es.js",
14
+ "require": "./dist/sleekspace-ui.umd.js"
15
+ },
16
+ "./style": "./dist/sleekspace-ui.css",
17
+ "./styles/source": "./src/styles/index.scss",
18
+ "./tokens.css": "./dist/tokens.css"
19
+ },
20
+ "files": [
21
+ "dist",
22
+ "src",
23
+ "docs",
24
+ "web-types.json",
25
+ "README.md",
26
+ "LICENSE"
27
+ ],
28
+ "scripts": {
29
+ "dev": "vite build --watch",
30
+ "build": "npm run generate:types && vue-docgen-web-types && npm run generate:api-docs && vite build && npm run build:tokens && npm run copy:docs",
31
+ "generate:api-docs": "tsx scripts/generate-api-docs.ts",
32
+ "build:tokens": "sass src/styles/tokens.scss dist/tokens.css --no-source-map",
33
+ "copy:docs": "cp ../../Readme.md README.md && cp ../../LICENSE LICENSE",
34
+ "generate:types": "tsx scripts/generate-global-types.ts",
35
+ "generate:web-types": "vue-docgen-web-types",
36
+ "lint": "eslint src"
37
+ },
38
+ "keywords": [
39
+ "vue",
40
+ "vue3",
41
+ "component",
42
+ "ui",
43
+ "design-system",
44
+ "oklch",
45
+ "cyberpunk",
46
+ "tailwind",
47
+ "typescript"
48
+ ],
49
+ "author": "Christopher S. Case",
50
+ "license": "MIT",
51
+ "repository": {
52
+ "type": "git",
53
+ "url": "https://gitlab.com/skewedaspect/sleekspace-ui.git",
54
+ "directory": "packages/sleekspace-ui"
55
+ },
56
+ "bugs": "https://gitlab.com/skewedaspect/sleekspace-ui/-/issues",
57
+ "homepage": "https://gitlab.com/skewedaspect/sleekspace-ui",
58
+ "peerDependencies": {
59
+ "vue": "^3.3.0"
60
+ },
61
+ "devDependencies": {
62
+ "@types/node": "^24.8.1",
63
+ "@vitejs/plugin-vue": "^6.0.1",
64
+ "sass": "^1.83.2",
65
+ "ts-morph": "^27.0.2",
66
+ "typescript": "^5.8.3",
67
+ "vite": "^7.1.10",
68
+ "vite-plugin-dts": "^4.5.3",
69
+ "vue": "^3.5.13",
70
+ "vue-docgen-web-types": "^0.1.8"
71
+ },
72
+ "dependencies": {
73
+ "modern-normalize": "^3.0.1",
74
+ "reka-ui": "^2.6.0"
75
+ }
76
+ }
@@ -0,0 +1,133 @@
1
+ <!----------------------------------------------------------------------------------------------------------------------
2
+ - Accordion Root Component
3
+ --------------------------------------------------------------------------------------------------------------------->
4
+
5
+ <template>
6
+ <AccordionRoot
7
+ v-model="modelValue"
8
+ :type="type"
9
+ :collapsible="collapsible"
10
+ :disabled="disabled"
11
+ :class="classes"
12
+ :style="customColorStyles"
13
+ >
14
+ <slot />
15
+ </AccordionRoot>
16
+ </template>
17
+
18
+ <!--------------------------------------------------------------------------------------------------------------------->
19
+
20
+ <style lang="scss" scoped>
21
+ // Accordion styles are implemented in /src/styles/components/_accordion.scss
22
+ </style>
23
+
24
+ <!--------------------------------------------------------------------------------------------------------------------->
25
+
26
+ <script setup lang="ts">
27
+ /**
28
+ * @component
29
+ * Accordion root container for collapsible sections.
30
+ * Use with SkAccordionItem components.
31
+ */
32
+
33
+ import { computed, provide, toRef } from 'vue';
34
+ import { AccordionRoot } from 'reka-ui';
35
+
36
+ // Types
37
+ import type { ComponentCustomColors } from '@/types';
38
+ import type { SkAccordionKind, SkAccordionType } from './types';
39
+
40
+ // Composables
41
+ import { useCustomColors } from '@/composables/useCustomColors';
42
+
43
+ //------------------------------------------------------------------------------------------------------------------
44
+
45
+ /**
46
+ * Accordion root container for collapsible sections.
47
+ *
48
+ * Supports single or multiple open items with smooth animations.
49
+ *
50
+ * @example Single mode (default)
51
+ * ```vue
52
+ * <SkAccordion v-model="openItem">
53
+ * <SkAccordionItem value="item-1" title="Section 1">
54
+ * Content 1
55
+ * </SkAccordionItem>
56
+ * <SkAccordionItem value="item-2" title="Section 2">
57
+ * Content 2
58
+ * </SkAccordionItem>
59
+ * </SkAccordion>
60
+ * ```
61
+ *
62
+ * @example Multiple mode
63
+ * ```vue
64
+ * <SkAccordion type="multiple" v-model="openItems">
65
+ * <SkAccordionItem value="item-1" title="Section 1">
66
+ * Content 1
67
+ * </SkAccordionItem>
68
+ * <SkAccordionItem value="item-2" title="Section 2">
69
+ * Content 2
70
+ * </SkAccordionItem>
71
+ * </SkAccordion>
72
+ * ```
73
+ */
74
+ export interface SkAccordionComponentProps extends ComponentCustomColors
75
+ {
76
+ /** Single or multiple open items */
77
+ type ?: SkAccordionType;
78
+ /** Controlled state (v-model) */
79
+ modelValue ?: string | string[];
80
+ /** Allow closing all items (single mode only) */
81
+ collapsible ?: boolean;
82
+ /** Semantic color kind */
83
+ kind ?: SkAccordionKind;
84
+ /** Disable all items */
85
+ disabled ?: boolean;
86
+ }
87
+
88
+ //------------------------------------------------------------------------------------------------------------------
89
+
90
+ const props = withDefaults(defineProps<SkAccordionComponentProps>(), {
91
+ type: 'single',
92
+ modelValue: undefined,
93
+ collapsible: false,
94
+ kind: 'neutral',
95
+ disabled: false,
96
+ });
97
+
98
+ const emit = defineEmits<{
99
+ 'update:modelValue' : [ value : string | string[] | undefined ];
100
+ }>();
101
+
102
+ //------------------------------------------------------------------------------------------------------------------
103
+
104
+ // Two-way binding for accordion state
105
+ const modelValue = computed({
106
+ get: () => props.modelValue,
107
+ set: (value) => emit('update:modelValue', value),
108
+ });
109
+
110
+ //------------------------------------------------------------------------------------------------------------------
111
+
112
+ const customColorStyles = useCustomColors(
113
+ 'accordion',
114
+ toRef(() => props.baseColor),
115
+ toRef(() => props.textColor)
116
+ );
117
+
118
+ // Provide kind for child items (reactive computed so changes propagate)
119
+ provide('accordion-kind', computed(() => props.kind));
120
+
121
+ // Provide modelValue for child items to check if they are open
122
+ provide('accordion-modelValue', modelValue);
123
+
124
+ //------------------------------------------------------------------------------------------------------------------
125
+
126
+ const classes = computed(() => ({
127
+ 'sk-accordion': true,
128
+ // Only apply kind class if custom colors are NOT provided
129
+ [`sk-${ props.kind }`]: !props.baseColor,
130
+ }));
131
+ </script>
132
+
133
+ <!--------------------------------------------------------------------------------------------------------------------->
@@ -0,0 +1,131 @@
1
+ <!----------------------------------------------------------------------------------------------------------------------
2
+ - Accordion Item Component
3
+ --------------------------------------------------------------------------------------------------------------------->
4
+
5
+ <template>
6
+ <AccordionItem
7
+ :value="value"
8
+ :disabled="disabled"
9
+ :class="itemClasses"
10
+ >
11
+ <AccordionHeader class="sk-accordion-header">
12
+ <AccordionTrigger class="sk-accordion-trigger">
13
+ <slot name="title" :open="isOpen">
14
+ {{ title }}
15
+ </slot>
16
+ <svg
17
+ xmlns="http://www.w3.org/2000/svg"
18
+ viewBox="0 0 24 24"
19
+ fill="none"
20
+ stroke="currentColor"
21
+ stroke-width="2"
22
+ stroke-linecap="square"
23
+ stroke-linejoin="miter"
24
+ :class="chevronClasses"
25
+ >
26
+ <polyline points="6 9 12 15 18 9" />
27
+ </svg>
28
+ </AccordionTrigger>
29
+ </AccordionHeader>
30
+ <AccordionContent class="sk-accordion-content">
31
+ <div class="sk-accordion-content-inner">
32
+ <slot />
33
+ </div>
34
+ </AccordionContent>
35
+ </AccordionItem>
36
+ </template>
37
+
38
+ <!--------------------------------------------------------------------------------------------------------------------->
39
+
40
+ <style lang="scss" scoped>
41
+ // Accordion item styles are implemented in /src/styles/components/_accordion.scss
42
+ </style>
43
+
44
+ <!--------------------------------------------------------------------------------------------------------------------->
45
+
46
+ <script setup lang="ts">
47
+ /**
48
+ * @component
49
+ * Individual accordion item with collapsible content.
50
+ */
51
+
52
+ import { type ComputedRef, type Ref, computed, inject, ref } from 'vue';
53
+ import {
54
+ AccordionContent,
55
+ AccordionHeader,
56
+ AccordionItem,
57
+ AccordionTrigger,
58
+ } from 'reka-ui';
59
+
60
+ // Types
61
+ import type { SkAccordionKind } from './types';
62
+
63
+ //------------------------------------------------------------------------------------------------------------------
64
+
65
+ /**
66
+ * Individual accordion item with collapsible content.
67
+ *
68
+ * @example With custom title slot
69
+ * ```vue
70
+ * <SkAccordionItem value="item-1">
71
+ * <template #title="{ open }">
72
+ * <span>Custom Title</span>
73
+ * <SkBadge v-if="open" kind="primary">Open</SkBadge>
74
+ * </template>
75
+ * Content here
76
+ * </SkAccordionItem>
77
+ * ```
78
+ */
79
+ export interface SkAccordionItemComponentProps
80
+ {
81
+ /** Required unique identifier */
82
+ value : string;
83
+ /** Title text (overridden by title slot) */
84
+ title ?: string;
85
+ /** Disable this item */
86
+ disabled ?: boolean;
87
+ /** Override parent kind */
88
+ kind ?: SkAccordionKind;
89
+ }
90
+
91
+ //------------------------------------------------------------------------------------------------------------------
92
+
93
+ const props = withDefaults(defineProps<SkAccordionItemComponentProps>(), {
94
+ title: undefined,
95
+ disabled: false,
96
+ kind: undefined,
97
+ });
98
+
99
+ //------------------------------------------------------------------------------------------------------------------
100
+
101
+ // Inject parent kind and compute effective kind
102
+ const parentKind = inject<ComputedRef<SkAccordionKind>>('accordion-kind', computed(() => 'neutral'));
103
+ const effectiveKind = computed(() => props.kind ?? parentKind.value);
104
+
105
+ // Inject parent modelValue to check if this item is open
106
+ const parentModelValue = inject<Ref<string | string[] | undefined>>('accordion-modelValue', ref(undefined));
107
+ const isOpen = computed(() =>
108
+ {
109
+ const modelValue = parentModelValue.value;
110
+ if(Array.isArray(modelValue))
111
+ {
112
+ return modelValue.includes(props.value);
113
+ }
114
+ return modelValue === props.value;
115
+ });
116
+
117
+ //------------------------------------------------------------------------------------------------------------------
118
+
119
+ const itemClasses = computed(() => ({
120
+ 'sk-accordion-item': true,
121
+ [`sk-${ effectiveKind.value }`]: true,
122
+ 'sk-open': isOpen.value,
123
+ }));
124
+
125
+ const chevronClasses = computed(() => ({
126
+ 'sk-accordion-chevron': true,
127
+ 'sk-open': isOpen.value,
128
+ }));
129
+ </script>
130
+
131
+ <!--------------------------------------------------------------------------------------------------------------------->
@@ -0,0 +1,3 @@
1
+ export { default as SkAccordion } from './SkAccordion.vue';
2
+ export { default as SkAccordionItem } from './SkAccordionItem.vue';
3
+ export * from './types';
@@ -0,0 +1,9 @@
1
+ // Types
2
+ import type { ComponentKind } from '@/types';
3
+
4
+ //----------------------------------------------------------------------------------------------------------------------
5
+
6
+ export type SkAccordionKind = ComponentKind;
7
+ export type SkAccordionType = 'single' | 'multiple';
8
+
9
+ //----------------------------------------------------------------------------------------------------------------------