@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.
- package/LICENSE +21 -0
- package/README.md +111 -0
- package/dist/sleekspace-ui.css +12844 -0
- package/dist/sleekspace-ui.es.js +19021 -0
- package/dist/sleekspace-ui.umd.js +19040 -0
- package/docs/components/accordion.md +92 -0
- package/docs/components/alert.md +72 -0
- package/docs/components/avatar.md +69 -0
- package/docs/components/breadcrumbs.md +65 -0
- package/docs/components/button/_meta.yaml +12 -0
- package/docs/components/button/accessibility.md +16 -0
- package/docs/components/button/custom-colors.md +18 -0
- package/docs/components/button/icons.md +31 -0
- package/docs/components/button/intro.md +8 -0
- package/docs/components/button/kinds.md +25 -0
- package/docs/components/button/sizes.md +14 -0
- package/docs/components/button/states.md +12 -0
- package/docs/components/button/usage.md +23 -0
- package/docs/components/button/variants.md +14 -0
- package/docs/components/button.md +110 -0
- package/docs/components/card.md +87 -0
- package/docs/components/checkbox.md +77 -0
- package/docs/components/collapsible.md +71 -0
- package/docs/components/divider.md +62 -0
- package/docs/components/dropdown.md +88 -0
- package/docs/components/field.md +80 -0
- package/docs/components/group.md +41 -0
- package/docs/components/input.md +84 -0
- package/docs/components/listbox.md +82 -0
- package/docs/components/modal.md +101 -0
- package/docs/components/navbar.md +64 -0
- package/docs/components/number-input.md +78 -0
- package/docs/components/page.md +77 -0
- package/docs/components/pagination.md +88 -0
- package/docs/components/panel.md +74 -0
- package/docs/components/popover.md +93 -0
- package/docs/components/progress.md +76 -0
- package/docs/components/radio.md +86 -0
- package/docs/components/sidebar.md +74 -0
- package/docs/components/skeleton.md +76 -0
- package/docs/components/slider.md +94 -0
- package/docs/components/spinner.md +59 -0
- package/docs/components/switch.md +97 -0
- package/docs/components/table.md +91 -0
- package/docs/components/tabs.md +108 -0
- package/docs/components/tag.md +75 -0
- package/docs/components/tags-input.md +88 -0
- package/docs/components/textarea.md +80 -0
- package/docs/components/theme.md +65 -0
- package/docs/components/toast.md +95 -0
- package/docs/components/tooltip.md +90 -0
- package/docs/guides/custom-colors.md +84 -0
- package/docs/guides/design-tokens.md +105 -0
- package/docs/guides/getting-started.md +144 -0
- package/docs/guides/installation.md +62 -0
- package/docs/guides/theming.md +101 -0
- package/package.json +76 -0
- package/src/components/Accordion/SkAccordion.vue +133 -0
- package/src/components/Accordion/SkAccordionItem.vue +131 -0
- package/src/components/Accordion/index.ts +3 -0
- package/src/components/Accordion/types.ts +9 -0
- package/src/components/Alert/SkAlert.vue +137 -0
- package/src/components/Alert/types.ts +10 -0
- package/src/components/Avatar/SkAvatar.vue +141 -0
- package/src/components/Avatar/index.ts +8 -0
- package/src/components/Avatar/types.ts +31 -0
- package/src/components/Breadcrumbs/SkBreadcrumbItem.vue +76 -0
- package/src/components/Breadcrumbs/SkBreadcrumbSeparator.vue +38 -0
- package/src/components/Breadcrumbs/SkBreadcrumbs.vue +93 -0
- package/src/components/Breadcrumbs/index.ts +10 -0
- package/src/components/Breadcrumbs/types.ts +36 -0
- package/src/components/Button/SkButton.vue +148 -0
- package/src/components/Button/types.ts +21 -0
- package/src/components/Card/SkCard.vue +144 -0
- package/src/components/Card/types.ts +12 -0
- package/src/components/Checkbox/SkCheckbox.vue +136 -0
- package/src/components/Checkbox/index.ts +8 -0
- package/src/components/Checkbox/types.ts +10 -0
- package/src/components/Collapsible/SkCollapsible.vue +159 -0
- package/src/components/Collapsible/index.ts +2 -0
- package/src/components/Collapsible/types.ts +8 -0
- package/src/components/Divider/SkDivider.vue +63 -0
- package/src/components/Divider/types.ts +15 -0
- package/src/components/Dropdown/SkDropdown.vue +150 -0
- package/src/components/Dropdown/SkDropdownMenuItem.vue +58 -0
- package/src/components/Dropdown/SkDropdownMenuSeparator.vue +26 -0
- package/src/components/Dropdown/SkDropdownSubmenu.vue +107 -0
- package/src/components/Dropdown/index.ts +11 -0
- package/src/components/Dropdown/types.ts +11 -0
- package/src/components/Field/SkField.vue +152 -0
- package/src/components/Field/index.ts +8 -0
- package/src/components/Field/types.ts +7 -0
- package/src/components/Group/SkGroup.vue +52 -0
- package/src/components/Group/types.ts +10 -0
- package/src/components/Input/SkInput.vue +117 -0
- package/src/components/Input/index.ts +8 -0
- package/src/components/Input/types.ts +11 -0
- package/src/components/Listbox/SkListbox.vue +164 -0
- package/src/components/Listbox/SkListboxItem.vue +68 -0
- package/src/components/Listbox/SkListboxSeparator.vue +26 -0
- package/src/components/Listbox/index.ts +10 -0
- package/src/components/Listbox/types.ts +10 -0
- package/src/components/Modal/SkModal.vue +231 -0
- package/src/components/Modal/index.ts +8 -0
- package/src/components/Modal/types.ts +12 -0
- package/src/components/NavBar/SkNavBar.vue +83 -0
- package/src/components/NavBar/index.ts +8 -0
- package/src/components/NavBar/types.ts +15 -0
- package/src/components/NumberInput/SkNumberInput.vue +168 -0
- package/src/components/NumberInput/index.ts +8 -0
- package/src/components/NumberInput/types.ts +10 -0
- package/src/components/Page/SkPage.vue +94 -0
- package/src/components/Page/index.ts +8 -0
- package/src/components/Page/types.ts +21 -0
- package/src/components/Pagination/SkPagination.vue +185 -0
- package/src/components/Pagination/SkPaginationItem.vue +107 -0
- package/src/components/Pagination/index.ts +9 -0
- package/src/components/Pagination/types.ts +40 -0
- package/src/components/Panel/SkPanel.vue +96 -0
- package/src/components/Panel/types.ts +15 -0
- package/src/components/Popover/SkPopover.vue +185 -0
- package/src/components/Popover/index.ts +8 -0
- package/src/components/Popover/types.ts +11 -0
- package/src/components/Progress/SkProgress.vue +144 -0
- package/src/components/Progress/index.ts +8 -0
- package/src/components/Progress/types.ts +34 -0
- package/src/components/Radio/SkRadio.vue +110 -0
- package/src/components/Radio/SkRadioGroup.vue +92 -0
- package/src/components/Radio/index.ts +9 -0
- package/src/components/Radio/types.ts +11 -0
- package/src/components/Sidebar/README.md +405 -0
- package/src/components/Sidebar/SkSidebar.vue +88 -0
- package/src/components/Sidebar/SkSidebarItem.vue +58 -0
- package/src/components/Sidebar/SkSidebarSection.vue +40 -0
- package/src/components/Sidebar/types.ts +3 -0
- package/src/components/Skeleton/SkSkeleton.vue +171 -0
- package/src/components/Skeleton/index.ts +8 -0
- package/src/components/Skeleton/types.ts +31 -0
- package/src/components/Slider/SkSlider.vue +165 -0
- package/src/components/Slider/index.ts +8 -0
- package/src/components/Slider/types.ts +44 -0
- package/src/components/Spinner/SkSpinner.vue +105 -0
- package/src/components/Spinner/index.ts +8 -0
- package/src/components/Spinner/types.ts +28 -0
- package/src/components/Switch/SkSwitch.vue +215 -0
- package/src/components/Switch/index.ts +8 -0
- package/src/components/Switch/types.ts +12 -0
- package/src/components/Table/SkTable.vue +109 -0
- package/src/components/Table/index.ts +2 -0
- package/src/components/Table/types.ts +15 -0
- package/src/components/Tabs/README.md +331 -0
- package/src/components/Tabs/SkTab.vue +84 -0
- package/src/components/Tabs/SkTabList.vue +62 -0
- package/src/components/Tabs/SkTabPanel.vue +47 -0
- package/src/components/Tabs/SkTabPanels.vue +23 -0
- package/src/components/Tabs/SkTabs.vue +124 -0
- package/src/components/Tabs/types.ts +21 -0
- package/src/components/Tag/SkTag.vue +129 -0
- package/src/components/Tag/types.ts +15 -0
- package/src/components/TagsInput/SkTagsInput.vue +184 -0
- package/src/components/TagsInput/index.ts +8 -0
- package/src/components/TagsInput/types.ts +10 -0
- package/src/components/Textarea/SkTextarea.vue +117 -0
- package/src/components/Textarea/index.ts +8 -0
- package/src/components/Textarea/types.ts +10 -0
- package/src/components/Theme/SkTheme.vue +47 -0
- package/src/components/Theme/types.ts +17 -0
- package/src/components/Theme/useTheme.ts +131 -0
- package/src/components/Toast/SkToast.vue +156 -0
- package/src/components/Toast/SkToastProvider.vue +180 -0
- package/src/components/Toast/index.ts +15 -0
- package/src/components/Toast/types.ts +63 -0
- package/src/components/Toast/useToast.ts +78 -0
- package/src/components/Tooltip/SkTooltip.vue +162 -0
- package/src/components/Tooltip/SkTooltipProvider.vue +114 -0
- package/src/components/Tooltip/index.ts +9 -0
- package/src/components/Tooltip/types.ts +13 -0
- package/src/composables/useCustomColors.test.ts +505 -0
- package/src/composables/useCustomColors.ts +124 -0
- package/src/composables/usePortalContext.test.ts +402 -0
- package/src/composables/usePortalContext.ts +95 -0
- package/src/global.d.ts +76 -0
- package/src/index.ts +259 -0
- package/src/styles/_scrollbar.scss +100 -0
- package/src/styles/base/_fonts.scss +105 -0
- package/src/styles/base/_global.scss +47 -0
- package/src/styles/base/_index.scss +24 -0
- package/src/styles/base/_reset.scss +11 -0
- package/src/styles/base/_typography.scss +178 -0
- package/src/styles/components/_accordion.scss +250 -0
- package/src/styles/components/_alert.scss +239 -0
- package/src/styles/components/_avatar.scss +133 -0
- package/src/styles/components/_breadcrumbs.scss +137 -0
- package/src/styles/components/_button.scss +731 -0
- package/src/styles/components/_card.scss +141 -0
- package/src/styles/components/_checkbox.scss +232 -0
- package/src/styles/components/_collapsible.scss +158 -0
- package/src/styles/components/_divider.scss +121 -0
- package/src/styles/components/_field.scss +87 -0
- package/src/styles/components/_group.scss +138 -0
- package/src/styles/components/_index.scss +46 -0
- package/src/styles/components/_input.scss +205 -0
- package/src/styles/components/_listbox.scss +453 -0
- package/src/styles/components/_menu.scss +216 -0
- package/src/styles/components/_modal.scss +329 -0
- package/src/styles/components/_navbar.scss +258 -0
- package/src/styles/components/_number-input.scss +352 -0
- package/src/styles/components/_page.scss +98 -0
- package/src/styles/components/_pagination.scss +411 -0
- package/src/styles/components/_panel.scss +281 -0
- package/src/styles/components/_popover.scss +258 -0
- package/src/styles/components/_progress.scss +280 -0
- package/src/styles/components/_radio.scss +255 -0
- package/src/styles/components/_sidebar.scss +92 -0
- package/src/styles/components/_skeleton.scss +138 -0
- package/src/styles/components/_slider.scss +262 -0
- package/src/styles/components/_spinner.scss +331 -0
- package/src/styles/components/_switch.scss +370 -0
- package/src/styles/components/_table.scss +405 -0
- package/src/styles/components/_tabs.scss +486 -0
- package/src/styles/components/_tag.scss +425 -0
- package/src/styles/components/_tags-input.scss +279 -0
- package/src/styles/components/_textarea.scss +208 -0
- package/src/styles/components/_toast.scss +331 -0
- package/src/styles/components/_tooltip.scss +206 -0
- package/src/styles/fonts/Titillium_Web/OFL.txt +93 -0
- package/src/styles/fonts/Titillium_Web/TitilliumWeb-Black.ttf +0 -0
- package/src/styles/fonts/Titillium_Web/TitilliumWeb-Bold.ttf +0 -0
- package/src/styles/fonts/Titillium_Web/TitilliumWeb-BoldItalic.ttf +0 -0
- package/src/styles/fonts/Titillium_Web/TitilliumWeb-ExtraLight.ttf +0 -0
- package/src/styles/fonts/Titillium_Web/TitilliumWeb-ExtraLightItalic.ttf +0 -0
- package/src/styles/fonts/Titillium_Web/TitilliumWeb-Italic.ttf +0 -0
- package/src/styles/fonts/Titillium_Web/TitilliumWeb-Light.ttf +0 -0
- package/src/styles/fonts/Titillium_Web/TitilliumWeb-LightItalic.ttf +0 -0
- package/src/styles/fonts/Titillium_Web/TitilliumWeb-Regular.ttf +0 -0
- package/src/styles/fonts/Titillium_Web/TitilliumWeb-SemiBold.ttf +0 -0
- package/src/styles/fonts/Titillium_Web/TitilliumWeb-SemiBoldItalic.ttf +0 -0
- package/src/styles/index.scss +17 -0
- package/src/styles/mixins/_cut-border.scss +254 -0
- package/src/styles/mixins/_index.scss +7 -0
- package/src/styles/theme/_variables.scss +42 -0
- package/src/styles/themes/README.md +127 -0
- package/src/styles/themes/_colorful.scss +58 -0
- package/src/styles/themes/_greyscale.scss +58 -0
- package/src/styles/themes/index.scss +9 -0
- package/src/styles/tokens/README.md +268 -0
- package/src/styles/tokens/_foundation-borders.scss +26 -0
- package/src/styles/tokens/_foundation-colors.scss +169 -0
- package/src/styles/tokens/_foundation-glow.scss +36 -0
- package/src/styles/tokens/_foundation-radius.scss +53 -0
- package/src/styles/tokens/_foundation-scrollbar.scss +31 -0
- package/src/styles/tokens/_foundation-shadows.scss +37 -0
- package/src/styles/tokens/_foundation-space.scss +36 -0
- package/src/styles/tokens/_foundation-transitions.scss +37 -0
- package/src/styles/tokens/_foundation-typography.scss +58 -0
- package/src/styles/tokens/_semantic-color-kinds.scss +112 -0
- package/src/styles/tokens/_semantic-colors.scss +10 -0
- package/src/styles/tokens/_semantic-interactive.scss +29 -0
- package/src/styles/tokens/_semantic-scrollbar.scss +48 -0
- package/src/styles/tokens/_semantic-surfaces.scss +36 -0
- package/src/styles/tokens/index.scss +38 -0
- package/src/styles/tokens.scss +268 -0
- package/src/styles/utilities/_index.scss +9 -0
- package/src/styles/utilities/_typography.scss +121 -0
- package/src/types.ts +50 -0
- 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,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
|
+
//----------------------------------------------------------------------------------------------------------------------
|