@skewedaspect/sleekspace-ui 0.8.1 → 0.9.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 (191) hide show
  1. package/dist/components/Dropdown/SkDropdown.vue.d.ts +9 -1
  2. package/dist/components/Dropdown/types.d.ts +2 -1
  3. package/dist/components/NavBar/SkNavBar.vue.d.ts +9 -1
  4. package/dist/components/NavBar/context.d.ts +2 -0
  5. package/dist/components/NavBar/types.d.ts +5 -1
  6. package/dist/components/NumberInput/SkNumberInput.vue.d.ts +8 -0
  7. package/dist/components/Page/SkPage.vue.d.ts +9 -0
  8. package/dist/components/ScrollArea/SkScrollArea.vue.d.ts +105 -4
  9. package/dist/composables/useCustomColors.d.ts +18 -56
  10. package/{src → dist}/global.d.ts +6 -2
  11. package/dist/sleekspace-ui.css +4257 -1253
  12. package/dist/sleekspace-ui.es.js +300 -170
  13. package/dist/sleekspace-ui.umd.js +299 -169
  14. package/dist/static/classes.d.ts +18 -0
  15. package/dist/static/components/alert.d.ts +12 -0
  16. package/dist/static/components/avatar.d.ts +9 -0
  17. package/dist/static/components/breadcrumbs.d.ts +6 -0
  18. package/dist/static/components/button.d.ts +13 -0
  19. package/dist/static/components/card.d.ts +5 -0
  20. package/dist/static/components/checkbox.d.ts +10 -0
  21. package/dist/static/components/colorPicker.d.ts +8 -0
  22. package/dist/static/components/divider.d.ts +8 -0
  23. package/dist/static/components/dropdown.d.ts +8 -0
  24. package/dist/static/components/field.d.ts +15 -0
  25. package/dist/static/components/group.d.ts +5 -0
  26. package/dist/static/components/input.d.ts +14 -0
  27. package/dist/static/components/navBar.d.ts +16 -0
  28. package/dist/static/components/numberInput.d.ts +15 -0
  29. package/dist/static/components/page.d.ts +9 -0
  30. package/dist/static/components/pagination.d.ts +5 -0
  31. package/dist/static/components/panel.d.ts +11 -0
  32. package/dist/static/components/progress.d.ts +9 -0
  33. package/dist/static/components/radio.d.ts +11 -0
  34. package/dist/static/components/select.d.ts +10 -0
  35. package/dist/static/components/sidebar.d.ts +9 -0
  36. package/dist/static/components/skeleton.d.ts +11 -0
  37. package/dist/static/components/slider.d.ts +12 -0
  38. package/dist/static/components/spinner.d.ts +12 -0
  39. package/dist/static/components/switchInput.d.ts +10 -0
  40. package/dist/static/components/table.d.ts +12 -0
  41. package/dist/static/components/tag.d.ts +8 -0
  42. package/dist/static/components/tagsInput.d.ts +7 -0
  43. package/dist/static/components/textarea.d.ts +12 -0
  44. package/dist/static/components/toolbar.d.ts +12 -0
  45. package/dist/static/components/tooltip.d.ts +7 -0
  46. package/dist/static/escape.d.ts +2 -0
  47. package/dist/static/index.cjs.js +1 -0
  48. package/dist/static/index.d.ts +68 -0
  49. package/dist/static/index.es.js +732 -0
  50. package/dist/static/render.d.ts +12 -0
  51. package/dist/static/specs.d.ts +2 -0
  52. package/dist/static/types.d.ts +43 -0
  53. package/dist/tokens.css +322 -0
  54. package/dist/types/index.d.ts +36 -0
  55. package/dist/utils/slots.d.ts +6 -0
  56. package/docs/guides/installation.md +8 -2
  57. package/docs/guides/pure-css/_meta.yaml +8 -0
  58. package/docs/guides/pure-css/class-api.md +1070 -0
  59. package/docs/guides/pure-css/custom-elements.md +574 -0
  60. package/docs/guides/pure-css/index.md +86 -0
  61. package/docs/guides/pure-css/limitations.md +152 -0
  62. package/docs/guides/pure-css/static-helpers.md +1203 -0
  63. package/llms-full.txt +3739 -261
  64. package/package.json +19 -5
  65. package/src/components/Alert/SkAlert.vue +4 -2
  66. package/src/components/Breadcrumbs/SkBreadcrumbs.vue +6 -12
  67. package/src/components/Button/SkButton.vue +8 -5
  68. package/src/components/Card/SkCard.vue +13 -5
  69. package/src/components/Checkbox/SkCheckbox.vue +9 -2
  70. package/src/components/ContextMenu/SkContextMenuRadioGroup.vue +4 -1
  71. package/src/components/Dropdown/SkDropdown.vue +20 -3
  72. package/src/components/Dropdown/SkDropdownRadioGroup.vue +4 -1
  73. package/src/components/Dropdown/types.ts +2 -1
  74. package/src/components/Modal/SkModal.vue +11 -4
  75. package/src/components/NavBar/SkNavBar.vue +19 -8
  76. package/src/components/NavBar/context.ts +4 -2
  77. package/src/components/NavBar/types.ts +6 -1
  78. package/src/components/NumberInput/SkNumberInput.vue +10 -1
  79. package/src/components/Page/SkPage.vue +29 -15
  80. package/src/components/Panel/SkPanel.vue +2 -1
  81. package/src/components/Popover/SkPopover.vue +11 -4
  82. package/src/components/Radio/SkRadio.vue +9 -2
  83. package/src/components/ScrollArea/SkScrollArea.vue +78 -5
  84. package/src/components/Switch/SkSwitch.vue +14 -13
  85. package/src/components/Tabs/SkTab.vue +7 -2
  86. package/src/components/TreeView/SkTreeItem.vue +10 -2
  87. package/src/components/TreeView/SkTreeView.vue +7 -2
  88. package/src/composables/useCustomColors.ts +86 -77
  89. package/src/composables/usePortalContext.test.ts +0 -2
  90. package/src/shims.d.ts +10 -0
  91. package/src/static/__tests__/parity.test.ts +717 -0
  92. package/src/static/__tests__/parityHarness.test.ts +98 -0
  93. package/src/static/__tests__/parityHarness.ts +260 -0
  94. package/src/static/classes.test.ts +82 -0
  95. package/src/static/classes.ts +111 -0
  96. package/src/static/components/__tests__/helpers.test.ts +837 -0
  97. package/src/static/components/alert.ts +117 -0
  98. package/src/static/components/avatar.ts +86 -0
  99. package/src/static/components/breadcrumbs.ts +28 -0
  100. package/src/static/components/button.ts +75 -0
  101. package/src/static/components/card.ts +27 -0
  102. package/src/static/components/checkbox.ts +48 -0
  103. package/src/static/components/colorPicker.ts +45 -0
  104. package/src/static/components/divider.ts +39 -0
  105. package/src/static/components/dropdown.ts +36 -0
  106. package/src/static/components/field.ts +86 -0
  107. package/src/static/components/group.ts +27 -0
  108. package/src/static/components/input.ts +55 -0
  109. package/src/static/components/navBar.ts +94 -0
  110. package/src/static/components/numberInput.ts +64 -0
  111. package/src/static/components/page.ts +31 -0
  112. package/src/static/components/pagination.ts +27 -0
  113. package/src/static/components/panel.ts +33 -0
  114. package/src/static/components/progress.ts +31 -0
  115. package/src/static/components/radio.ts +53 -0
  116. package/src/static/components/select.ts +51 -0
  117. package/src/static/components/sidebar.ts +85 -0
  118. package/src/static/components/skeleton.ts +66 -0
  119. package/src/static/components/slider.ts +50 -0
  120. package/src/static/components/spinner.ts +94 -0
  121. package/src/static/components/switchInput.ts +49 -0
  122. package/src/static/components/table.ts +88 -0
  123. package/src/static/components/tag.ts +76 -0
  124. package/src/static/components/tagsInput.ts +35 -0
  125. package/src/static/components/textarea.ts +53 -0
  126. package/src/static/components/toolbar.ts +74 -0
  127. package/src/static/components/tooltip.ts +29 -0
  128. package/src/static/escape.test.ts +53 -0
  129. package/src/static/escape.ts +28 -0
  130. package/src/static/generated/defaults.ts +379 -0
  131. package/src/static/generated/propTypes.ts +426 -0
  132. package/src/static/index.ts +116 -0
  133. package/src/static/render.test.ts +83 -0
  134. package/src/static/render.ts +76 -0
  135. package/src/static/specs.test.ts +58 -0
  136. package/src/static/specs.ts +230 -0
  137. package/src/static/types.ts +176 -0
  138. package/src/styles/__tests__/testHelpers.ts +97 -0
  139. package/src/styles/base/_custom-elements.scss +51 -0
  140. package/src/styles/base/_index.scss +4 -0
  141. package/src/styles/components/__tests__/componentSelectors.test.ts +2575 -0
  142. package/src/styles/components/_alert.scss +82 -39
  143. package/src/styles/components/_avatar.scss +102 -47
  144. package/src/styles/components/_breadcrumbs.scss +39 -37
  145. package/src/styles/components/_button.scss +58 -5
  146. package/src/styles/components/_card.scss +64 -2
  147. package/src/styles/components/_checkbox.scss +35 -5
  148. package/src/styles/components/_color-picker.scss +48 -13
  149. package/src/styles/components/_divider.scss +86 -52
  150. package/src/styles/components/_dropdown.scss +214 -0
  151. package/src/styles/components/_field.scss +76 -23
  152. package/src/styles/components/_group.scss +190 -79
  153. package/src/styles/components/_index.scss +1 -0
  154. package/src/styles/components/_input.scss +81 -5
  155. package/src/styles/components/_menu.scss +1 -1
  156. package/src/styles/components/_navbar.scss +76 -45
  157. package/src/styles/components/_number-input.scss +98 -85
  158. package/src/styles/components/_page.scss +82 -23
  159. package/src/styles/components/_pagination.scss +240 -212
  160. package/src/styles/components/_panel.scss +268 -122
  161. package/src/styles/components/_progress.scss +120 -70
  162. package/src/styles/components/_radio.scss +35 -5
  163. package/src/styles/components/_scroll-area.scss +50 -22
  164. package/src/styles/components/_select.scss +40 -9
  165. package/src/styles/components/_sidebar.scss +59 -34
  166. package/src/styles/components/_skeleton.scss +111 -65
  167. package/src/styles/components/_slider.scss +34 -10
  168. package/src/styles/components/_spinner.scss +107 -56
  169. package/src/styles/components/_switch.scss +36 -5
  170. package/src/styles/components/_table.scss +150 -166
  171. package/src/styles/components/_tag.scss +244 -154
  172. package/src/styles/components/_tags-input.scss +46 -12
  173. package/src/styles/components/_textarea.scss +36 -5
  174. package/src/styles/components/_toolbar.scss +85 -31
  175. package/src/styles/components/_tooltip.scss +172 -3
  176. package/src/styles/mixins/_cut-border.scss +18 -4
  177. package/src/styles/mixins/_dual-selector.scss +192 -0
  178. package/src/styles/mixins/_index.scss +1 -0
  179. package/src/styles/mixins/dualSelector.test.ts +151 -0
  180. package/src/styles/themes/_colorful.scss +25 -0
  181. package/src/styles/themes/_greyscale.scss +25 -0
  182. package/src/styles/themes/_shade-scale.scss +39 -0
  183. package/src/styles/tokens/_semantic-color-kinds.scss +66 -0
  184. package/src/{types.ts → types/index.ts} +19 -11
  185. package/src/utils/slots.ts +75 -0
  186. package/web-types.json +980 -137
  187. package/dist/composables/useCustomColors.test.d.ts +0 -1
  188. package/dist/composables/useFocusTrap.test.d.ts +0 -1
  189. package/dist/composables/usePortalContext.test.d.ts +0 -1
  190. package/dist/styles/mixins/fluidSize.test.d.ts +0 -1
  191. package/dist/types.d.ts +0 -29
package/llms-full.txt CHANGED
@@ -55,13 +55,19 @@ This registers all SleekSpace CSS custom properties with Tailwind's `@theme` sys
55
55
 
56
56
  ## TypeScript Support
57
57
 
58
- For VS Code with Volar, add the global types to your `tsconfig.json`:
58
+ For VS Code with Volar, wire up the global component type augmentation. The recommended approach is a one-line triple-slash reference in one of your own `.d.ts` files (for example `src/shims.d.ts` or `env.d.ts`):
59
+
60
+ ```typescript
61
+ /// <reference types="@skewedaspect/sleekspace-ui/global" />
62
+ ```
63
+
64
+ Alternatively, include the declaration file directly in your `tsconfig.json`:
59
65
 
60
66
  ```json
61
67
  {
62
68
  "include": [
63
69
  "src/**/*",
64
- "node_modules/@skewedaspect/sleekspace-ui/src/global.d.ts"
70
+ "node_modules/@skewedaspect/sleekspace-ui/dist/global.d.ts"
65
71
  ]
66
72
  }
67
73
  ```
@@ -1062,326 +1068,3410 @@ Some components use specialized color props instead (SkProgress uses `trackColor
1062
1068
 
1063
1069
  ---
1064
1070
 
1065
- # AI & LLMs
1071
+ # Sleekspace Without Vue
1066
1072
 
1067
- SleekSpace UI ships with LLM-friendly documentation files that make it easy for AI assistants like Claude, ChatGPT, GitHub Copilot, and Cursor to understand and help with the library.
1073
+ Sleekspace is a Vue 3 component library, but the design system itself is framework-agnostic.
1074
+ If you're building a static site — VitePress output, Astro, 11ty, a build-time script — you
1075
+ can use Sleekspace's visual language without shipping Vue or paying for hydration.
1068
1076
 
1069
- ## Available Files
1077
+ ## Quick lookup
1070
1078
 
1071
- Two documentation files are available, optimized for different use cases:
1079
+ Common tasks and where to find them:
1072
1080
 
1073
- | File | Size | Best For |
1074
- |------|------|----------|
1075
- | `llms.txt` | ~7 KB | Quick context, token-efficient prompts |
1076
- | `llms-full.txt` | ~196 KB | Complete reference, in-depth help |
1081
+ | I want to… | Go here |
1082
+ |-----------|---------|
1083
+ | Build an alert box | [`alert()`](./static-helpers.md#alert) or [class form](./class-api.md#alert) |
1084
+ | Add a spinner | [`spinner()`](./static-helpers.md#spinner) or [class form](./class-api.md#spinner) |
1085
+ | Render a nav bar | [`navBar()`](./static-helpers.md#navbar) or [class form](./class-api.md#navbar) |
1086
+ | Lay out a page shell | [`page()`](./static-helpers.md#page) or [class form](./class-api.md#page) |
1087
+ | Show an avatar | [`avatar()`](./static-helpers.md#avatar) or [class form](./class-api.md#avatar) |
1088
+ | Wrap a form field | [`field()`](./static-helpers.md#field) or [class form](./class-api.md#field) |
1089
+ | Display a data table | [`table()`](./static-helpers.md#table) or [class form](./class-api.md#table) |
1090
+ | Add a tag / badge | [`tag()`](./static-helpers.md#tag) or [class form](./class-api.md#tag) |
1077
1091
 
1078
- **llms.txt** is a concise index with component summaries. It gives AI assistants enough context to understand what the library offers and how components work together.
1092
+ ## Three ways to use Sleekspace without Vue
1079
1093
 
1080
- **llms-full.txt** is the complete reference. It includes all guide documentation, every component's usage examples, and full API reference tables with all props, slots, and events.
1094
+ ### 1. Class API Bootstrap-style HTML classes
1081
1095
 
1082
- ## How to Use
1096
+ Ship the compiled CSS and write HTML directly.
1083
1097
 
1084
- ### AI-Powered IDEs (Claude Code, Cursor, Windsurf)
1098
+ ```html
1099
+ <link rel="stylesheet" href="/path/to/sleekspace-ui.css" />
1085
1100
 
1086
- Point your AI assistant to fetch the documentation from our docs site:
1101
+ <div class="sk-panel sk-primary sk-lg">
1102
+ <p>Primary panel, large cut size.</p>
1103
+ </div>
1104
+ ```
1087
1105
 
1088
- - https://sleekspace.skewedaspect.com/llms.txt
1089
- - https://sleekspace.skewedaspect.com/llms-full.txt
1106
+ Works in any SSG, any language, any framework. Zero JS.
1090
1107
 
1091
- Example: "Fetch https://sleekspace.skewedaspect.com/llms.txt and help me create a form with validation."
1108
+ [See the full class reference →](./class-api.md)
1092
1109
 
1093
- ### Web-Based AI (ChatGPT, Claude.ai)
1110
+ ### 2. Custom-element API attribute-driven
1094
1111
 
1095
- Direct the AI to read the documentation URLs:
1112
+ Author containers as light-DOM custom elements with attributes.
1096
1113
 
1097
- Example prompt:
1114
+ ```html
1115
+ <sk-panel kind="primary" size="lg">
1116
+ <p>Same panel, attribute-driven.</p>
1117
+ </sk-panel>
1118
+ ```
1098
1119
 
1099
- > "Read https://sleekspace.skewedaspect.com/llms.txt and then help me create a themed dashboard layout."
1120
+ Zero JS required Sleekspace targets custom elements via attribute selectors, no registration
1121
+ needed. Form controls remain on native elements via the class API.
1100
1122
 
1101
- ### Paste Into Context
1123
+ [See the custom-element reference →](./custom-elements.md)
1102
1124
 
1103
- For quick questions, copy the content of `llms.txt` and paste it into your conversation. For in-depth help with complex implementations, use `llms-full.txt`.
1125
+ ### 3. Static helpers Node SSG ergonomics
1104
1126
 
1105
- ## What's Included
1127
+ Import typed helper functions from the `/static` subpath.
1106
1128
 
1107
- The documentation files contain:
1129
+ ```typescript
1130
+ import { panel, button } from '@skewedaspect/sleekspace-ui/static';
1108
1131
 
1109
- - **All guides** -- Installation, theming, design tokens, custom colors
1110
- - **Every component** -- Usage examples and documentation for all 46 components
1111
- - **Complete API reference** -- Props, slots, and events in structured tables
1112
- - **Best practices** -- Common patterns and recommended approaches
1132
+ const html = panel({ kind: 'primary', size: 'lg' }, `<p>Content</p>`);
1133
+ ```
1113
1134
 
1114
- The files are auto-generated from the source documentation, so they stay in sync with the library.
1135
+ Strongly typed, zero runtime dependencies, works in any Node-based SSG.
1115
1136
 
1116
- ## Why This Matters
1137
+ [See the static helpers reference →](./static-helpers.md)
1117
1138
 
1118
- AI assistants work best when they have accurate, up-to-date context about the tools you are using. With these files:
1139
+ ## What you don't get
1119
1140
 
1120
- - **Accurate help** -- AI responses are based on real documentation, not training data that may be outdated
1121
- - **No hallucinations** -- Props, events, and usage patterns match what the library actually provides
1122
- - **Better suggestions** -- AI can recommend appropriate components, theming approaches, and composition patterns
1123
- - **Faster development** -- Get library-specific help without searching through documentation manually
1141
+ The pure-CSS layer covers presentational components only. Interactive components that need JS
1142
+ state management (Modal, Toast, Accordion, Dropdown menu, TreeView, Tabs, etc.) remain Vue-only.
1124
1143
 
1144
+ [See the full limitations page →](./limitations.md)
1125
1145
 
1126
- ---
1146
+ ## Path chooser
1127
1147
 
1148
+ - **I just want to write HTML that looks like Sleekspace.** → [Class API](./class-api.md)
1149
+ - **I want attribute-driven ergonomics for containers.** → [Custom elements](./custom-elements.md)
1150
+ - **I'm building SSG output from Node.** → [Static helpers](./static-helpers.md)
1151
+ - **I want to know what's missing vs. the Vue version.** → [Limitations](./limitations.md)
1128
1152
 
1129
- # Components
1153
+ # Class API Reference
1130
1154
 
1131
- # SkAccordion
1155
+ The class API is Sleekspace's lowest-level styling surface. Grab the compiled CSS,
1156
+ add the right `sk-*` classes to your HTML, and you're done. No Vue, no JS, no build tool required.
1132
1157
 
1133
- A collapsible sections container for organizing content into expandable panels. Supports single or multiple open items with smooth animations. Built on RekaUI's Accordion primitive with full WAI-ARIA support.
1158
+ ## Concepts
1134
1159
 
1160
+ Every component has one **base class** (`sk-panel`, `sk-button`, etc.) plus **modifier classes**
1161
+ that toggle kinds, sizes, states, and other boolean options. Modifiers stack on the same element.
1135
1162
 
1136
- Use `v-model` to control which item is open. In single mode (default), only one item can be open at a time. Each `SkAccordionItem` requires a unique `value` prop.
1163
+ ```html
1164
+ <!-- base only -->
1165
+ <div class="sk-panel">…</div>
1137
1166
 
1138
- ```vue
1139
- <script setup>
1140
- import { ref } from 'vue';
1167
+ <!-- base + kind + size -->
1168
+ <div class="sk-panel sk-primary sk-lg">…</div>
1169
+ ```
1141
1170
 
1142
- const openItem = ref('item-1');
1143
- </script>
1171
+ **You do not need to specify modifiers to get defaults.** If you omit `kind`, components render
1172
+ in their default kind (usually `sk-neutral`). If you omit `size`, they render at `sk-md`.
1173
+ Explicit classes override defaults; omitting them triggers the built-in default via
1174
+ zero-specificity `:where()` selectors.
1144
1175
 
1145
- <template>
1146
- <SkAccordion v-model="openItem" kind="primary">
1147
- <SkAccordionItem value="item-1" title="What is SleekSpace UI?">
1148
- SleekSpace UI is a Vue 3 component library...
1149
- </SkAccordionItem>
1150
- <SkAccordionItem value="item-2" title="How do I install it?">
1151
- Install via npm...
1152
- </SkAccordionItem>
1153
- <SkAccordionItem value="item-3" title="Is it customizable?">
1154
- Yes! Every component supports custom colors...
1155
- </SkAccordionItem>
1156
- </SkAccordion>
1157
- </template>
1158
- ```
1176
+ **Kind classes** are shared across most components: `sk-neutral`, `sk-primary`, `sk-accent`,
1177
+ `sk-info`, `sk-success`, `sk-warning`, `sk-danger`, plus the extended palette
1178
+ `sk-boulder`, `sk-neon-blue`, `sk-neon-green`, `sk-neon-red`, `sk-neon-yellow`.
1159
1179
 
1180
+ **Size classes** are also shared: `sk-xs`, `sk-sm`, `sk-md` (default), `sk-lg`, `sk-xl`.
1160
1181
 
1161
- Set `type="multiple"` to allow multiple items open simultaneously. The `v-model` becomes an array of open item values.
1182
+ **Custom colors** can override the kind via inline CSS variables see the per-component
1183
+ note for the relevant variable name.
1162
1184
 
1163
- ```vue
1164
- <script setup>
1165
- import { ref } from 'vue';
1185
+ For container components you can also use the
1186
+ [custom-element form](./custom-elements.md) as an alternative to class-based markup.
1166
1187
 
1167
- const openItems = ref(['feature-1', 'feature-2']);
1168
- </script>
1188
+ ---
1169
1189
 
1170
- <template>
1171
- <SkAccordion v-model="openItems" type="multiple" kind="accent">
1172
- <SkAccordionItem value="feature-1" title="Theming">
1173
- Full theme support...
1174
- </SkAccordionItem>
1175
- <SkAccordionItem value="feature-2" title="Accessibility">
1176
- ARIA compliant...
1177
- </SkAccordionItem>
1178
- <SkAccordionItem value="feature-3" title="Performance">
1179
- Optimized animations...
1180
- </SkAccordionItem>
1181
- </SkAccordion>
1182
- </template>
1183
- ```
1190
+ ## Component Reference
1184
1191
 
1192
+ ### Panel
1185
1193
 
1186
- All seven semantic kinds adapt to your theme colors. The `kind` prop on SkAccordion is inherited by all child items, but individual items can override with their own `kind` prop.
1194
+ **Base class:** `sk-panel`
1187
1195
 
1188
- ```vue
1189
- <SkAccordion kind="neutral">
1190
- <SkAccordionItem value="n1" title="Neutral">Content</SkAccordionItem>
1191
- </SkAccordion>
1192
- <SkAccordion kind="primary">
1193
- <SkAccordionItem value="p1" title="Primary">Content</SkAccordionItem>
1194
- </SkAccordion>
1195
- <SkAccordion kind="accent">
1196
- <SkAccordionItem value="a1" title="Accent">Content</SkAccordionItem>
1197
- </SkAccordion>
1198
- <SkAccordion kind="success">
1199
- <SkAccordionItem value="s1" title="Success">Content</SkAccordionItem>
1200
- </SkAccordion>
1201
- <SkAccordion kind="warning">
1202
- <SkAccordionItem value="w1" title="Warning">Content</SkAccordionItem>
1203
- </SkAccordion>
1204
- <SkAccordion kind="danger">
1205
- <SkAccordionItem value="d1" title="Danger">Content</SkAccordionItem>
1206
- </SkAccordion>
1207
- <SkAccordion kind="info">
1208
- <SkAccordionItem value="i1" title="Info">Content</SkAccordionItem>
1209
- </SkAccordion>
1210
- ```
1196
+ **Modifiers:**
1211
1197
 
1198
+ | Class | Effect | Default |
1199
+ |-------|--------|---------|
1200
+ | `sk-neutral` / `sk-primary` / … | Kind color | `sk-neutral` |
1201
+ | `sk-xs` … `sk-xl` | Corner decoration size | `sk-md` |
1202
+ | `sk-cut-top-left`, `sk-cut-top-right`, `sk-cut-bottom-right`, `sk-cut-bottom-left` | Which corners are beveled | `sk-cut-bottom-right` |
1203
+ | `sk-decoration-top-left` / … | Which corner shows the accent stripe | `sk-decoration-bottom-right` |
1204
+ | `sk-no-border` | Remove border | off |
1205
+ | `sk-no-decoration` | Hide accent stripe | off |
1212
1206
 
1213
- Override the kind with custom `baseColor` and `textColor` props. Supports hex, OKLCH, or any valid CSS color value.
1207
+ **Custom color var:** `--sk-panel-color-base`
1214
1208
 
1215
- ```vue
1216
- <SkAccordion base-color="#8B5CF6" collapsible>
1217
- <SkAccordionItem value="c1" title="Custom Purple">
1218
- Using hex color #8B5CF6
1219
- </SkAccordionItem>
1220
- </SkAccordion>
1209
+ **Rendered HTML:**
1221
1210
 
1222
- <SkAccordion base-color="oklch(0.75 0.2 180)" collapsible>
1223
- <SkAccordionItem value="c2" title="Custom Teal">
1224
- Using OKLCH color
1225
- </SkAccordionItem>
1226
- </SkAccordion>
1211
+ ```html
1212
+ <div class="sk-panel sk-primary sk-lg sk-cut-top-left sk-cut-bottom-right sk-decoration-top-left">
1213
+ <p>Primary panel with diagonal cuts.</p>
1214
+ </div>
1227
1215
  ```
1228
1216
 
1217
+ [See Vue docs →](/components/panel)
1229
1218
 
1230
- Classic use case for accordions - frequently asked questions. Set `collapsible` in single mode to allow closing all items.
1219
+ ---
1231
1220
 
1232
- ```vue
1233
- <script setup>
1234
- import { ref } from 'vue';
1221
+ ### Card
1235
1222
 
1236
- const faqOpen = ref('faq-1');
1237
- </script>
1223
+ **Base class:** `sk-card`
1238
1224
 
1239
- <template>
1240
- <SkAccordion v-model="faqOpen" kind="info" collapsible>
1241
- <SkAccordionItem value="faq-1" title="Do you offer a free trial?">
1242
- Yes! We offer a 14-day free trial...
1243
- </SkAccordionItem>
1244
- <SkAccordionItem value="faq-2" title="Can I cancel anytime?">
1245
- Absolutely. You can cancel your subscription...
1246
- </SkAccordionItem>
1247
- <SkAccordionItem value="faq-3" title="What payment methods do you accept?">
1248
- We accept all major credit cards...
1249
- </SkAccordionItem>
1250
- <SkAccordionItem value="faq-4" title="Is my data secure?">
1251
- Yes. We use bank-level encryption...
1252
- </SkAccordionItem>
1253
- </SkAccordion>
1254
- </template>
1255
- ```
1225
+ **Modifiers:**
1256
1226
 
1227
+ | Class | Effect | Default |
1228
+ |-------|--------|---------|
1229
+ | `sk-neutral` / `sk-primary` / … | Kind color | `sk-neutral` |
1257
1230
 
1258
- ### Props
1231
+ The card shell is the outer container. Inner structure (header, media, footer) is composed
1232
+ with child elements — the static helper leaves slotting to you.
1259
1233
 
1260
- | Prop | Type | Default | Required | Description |
1261
- |------|------|---------|----------|-------------|
1262
- | type | "single" \| "multiple" | 'single' | false | Controls whether one or multiple accordion items can be open simultaneously.
1263
- In 'single' mode, opening a new item automatically closes the previously open item.
1264
- In 'multiple' mode, users can expand any number of items independently. |
1265
- | modelValue | string \| string[] | undefined | false | The value(s) of currently open accordion item(s). Use with `v-model` for two-way binding.
1266
- In 'single' mode, this is a string matching one item's `value` prop.
1267
- In 'multiple' mode, this is an array of strings matching multiple items' `value` props. |
1268
- | collapsible | boolean | false | false | When true and in 'single' mode, allows all items to be collapsed by clicking the open item again.
1269
- When false, one item must always remain open (the first click selects, subsequent clicks don't collapse).
1270
- This prop has no effect in 'multiple' mode where items are always independently collapsible. |
1271
- | kind | "neutral" \| "primary" \| "accent" \| "danger" \| "info" \| "success" \| "warning" \| "boulder" \| "neon-blue" \| "light-blue" \| "neon-orange" \| "neon-purple" \| "neon-green" \| "neon-mint" \| "neon-pink" \| "yellow" \| "red" | 'neutral' | false | Semantic color kind that controls the accordion's header and border colors. The kind is automatically
1272
- inherited by all child SkAccordionItem components unless they specify their own kind.
1273
- Semantic kinds (neutral, primary, accent, etc.) adapt to your theme. |
1274
- | disabled | boolean | false | false | When true, disables all accordion items. Items cannot be expanded or collapsed, and
1275
- the accordion appears with reduced opacity. Individual items can also be disabled
1276
- independently via their own `disabled` prop. |
1234
+ **Custom color var:** `--sk-panel-color-base`
1277
1235
 
1278
- ### Slots
1236
+ **Rendered HTML:**
1279
1237
 
1280
- | Slot | Description |
1281
- |------|-------------|
1282
- | default | Container for SkAccordionItem components. Each item becomes a collapsible section. |
1238
+ ```html
1239
+ <div class="sk-card sk-accent">
1240
+ <div class="sk-card-header"><h3>Card Title</h3></div>
1241
+ <div class="sk-card-body"><p>Content here.</p></div>
1242
+ </div>
1243
+ ```
1283
1244
 
1284
- ### Events
1245
+ [See Vue docs →](/components/card)
1285
1246
 
1286
- | Event | Description |
1287
- |-------|-------------|
1288
- | update:modelValue | |
1247
+ ---
1289
1248
 
1249
+ ### Alert
1290
1250
 
1291
- ---
1251
+ **Base class:** `sk-alert`
1292
1252
 
1293
- # SkAlert
1253
+ **Modifiers:**
1294
1254
 
1295
- A feedback component for displaying informational messages. Each kind renders a corresponding icon (info circle, checkmark, warning triangle, or error cross) alongside the message content. Renders with `role="alert"` for screen reader announcements.
1255
+ | Class | Effect | Default |
1256
+ |-------|--------|---------|
1257
+ | `sk-neutral` / `sk-primary` / … | Kind color | `sk-info` |
1258
+ | `sk-subtle` | Lower-contrast background variant | off |
1296
1259
 
1260
+ The element should carry `role="alert"` for accessibility.
1297
1261
 
1298
- Use alerts to provide feedback, display status, or draw attention to important information. Each kind includes an appropriate default icon.
1262
+ The static helper emits a two-wrapper structure: an optional icon div followed by a content
1263
+ wrapper. When building the class API form by hand, mirror this structure so CSS spacing rules
1264
+ apply correctly:
1299
1265
 
1300
- ```vue
1301
- <SkAlert kind="info">
1302
- This is an informational alert message. Use it to provide helpful information to users.
1303
- </SkAlert>
1266
+ **Rendered HTML (info kind, default — with icon):**
1267
+
1268
+ ```html
1269
+ <div class="sk-alert sk-info" role="alert">
1270
+ <div class="sk-alert-icon">
1271
+ <!-- info SVG icon -->
1272
+ <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
1273
+ <circle cx="12" cy="12" r="10"></circle>
1274
+ <line x1="12" y1="16" x2="12" y2="12"></line>
1275
+ <circle cx="12" cy="8" r="0.5" fill="currentColor"></circle>
1276
+ </svg>
1277
+ </div>
1278
+ <div class="sk-alert-content">
1279
+ <p>Something to note.</p>
1280
+ </div>
1281
+ </div>
1304
1282
  ```
1305
1283
 
1284
+ **Rendered HTML (neutral kind — no icon):**
1306
1285
 
1307
- Four semantic kinds with built-in icons: `info` for information, `success` for positive feedback, `warning` for caution, and `danger` for errors or critical messages.
1286
+ ```html
1287
+ <div class="sk-alert sk-neutral" role="alert">
1288
+ <div class="sk-alert-content">
1289
+ <p>Deployment paused — review the diff before continuing.</p>
1290
+ </div>
1291
+ </div>
1292
+ ```
1308
1293
 
1309
- ```vue
1310
- <SkAlert kind="info">
1311
- <strong>Info:</strong> Your changes will be saved automatically.
1312
- </SkAlert>
1294
+ Icons are auto-selected for the four feedback kinds (info, success, warning, danger).
1295
+ Non-feedback kinds (neutral, primary, accent) render without an icon container.
1313
1296
 
1314
- <SkAlert kind="success">
1315
- <strong>Success:</strong> Your profile has been updated successfully.
1316
- </SkAlert>
1297
+ **Custom color var:** `--sk-alert-color-base`
1317
1298
 
1318
- <SkAlert kind="warning">
1319
- <strong>Warning:</strong> This action cannot be undone.
1320
- </SkAlert>
1299
+ [See Vue docs →](/components/alert)
1321
1300
 
1322
- <SkAlert kind="danger">
1323
- <strong>Error:</strong> Failed to save changes. Please try again.
1324
- </SkAlert>
1325
- ```
1301
+ ---
1326
1302
 
1303
+ ### Divider
1327
1304
 
1328
- Use `prominent` for critical messages that require immediate attention. Prominent alerts have stronger colors and increased visual weight.
1305
+ **Base class:** `sk-divider`
1329
1306
 
1330
- ```vue
1331
- <SkAlert kind="info" :prominent="true">
1332
- <strong>System Maintenance:</strong> The system will undergo scheduled maintenance on Sunday at 2 AM UTC.
1333
- </SkAlert>
1307
+ **Modifiers:**
1334
1308
 
1335
- <SkAlert kind="warning" :prominent="true">
1336
- <strong>Storage Limit:</strong> You're using 95% of your storage space.
1337
- </SkAlert>
1338
- ```
1309
+ | Class | Effect | Default |
1310
+ |-------|--------|---------|
1311
+ | `sk-neutral` / `sk-primary` / … | Kind color | `sk-neutral` |
1312
+ | `sk-horizontal` / `sk-vertical` | Layout axis | `sk-horizontal` |
1313
+ | `sk-md` / `sk-xs` … `sk-xl` | Line thickness | `sk-md` |
1314
+ | `sk-subtle` | Lower-contrast line | off |
1339
1315
 
1316
+ Note: the divider emits an `<hr>` element (not a `<div>`), and uses `sk-horizontal` / `sk-vertical`
1317
+ directly (not `sk-orientation-*`). The element carries `role="separator"` automatically.
1340
1318
 
1341
- Alerts can contain any content including headings, paragraphs, lists, buttons, and links for comprehensive messaging.
1319
+ **Rendered HTML:**
1342
1320
 
1343
- ```vue
1344
- <SkAlert kind="info">
1345
- <h4 class="font-semibold mb-2">New Features Available</h4>
1346
- <p class="mb-2">We've added several new features to improve your experience:</p>
1347
- <ul class="list-disc list-inside mb-3 space-y-1">
1348
- <li>Dark mode support</li>
1349
- <li>Keyboard shortcuts</li>
1350
- <li>Export to PDF</li>
1351
- </ul>
1352
- <SkButton size="sm" kind="info">Learn More</SkButton>
1353
- </SkAlert>
1321
+ ```html
1322
+ <hr class="sk-divider sk-horizontal sk-neutral sk-md" role="separator">
1354
1323
  ```
1355
1324
 
1325
+ [See Vue docs →](/components/divider)
1356
1326
 
1357
- Override the default icon using the `icon` slot for custom branding or specific message types.
1327
+ ---
1358
1328
 
1359
- ```vue
1360
- <SkAlert kind="info">
1361
- <template #icon>
1362
- <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
1363
- <path d="M12 2l3.09 6.26L22 9.27l-5 4.87 1.18 6.88L12 17.77l-6.18 3.25L7 14.14 2 9.27l6.91-1.01L12 2z" />
1364
- </svg>
1365
- </template>
1366
- <strong>Pro Tip:</strong> Use keyboard shortcut Ctrl+S to save your work quickly.
1367
- </SkAlert>
1368
- ```
1329
+ ### Page
1369
1330
 
1331
+ **Base class:** `sk-page`
1370
1332
 
1371
- Use `base-color` for any CSS color value. Provide `text-color` for optimal contrast, or it will default to the theme's neutral text color.
1333
+ **Modifiers:**
1372
1334
 
1373
- ```vue
1374
- <SkAlert
1375
- base-color="oklch(0.65 0.25 280)"
1376
- text-color="white"
1377
- >
1378
- <strong>Custom Purple:</strong> This alert uses a custom purple base color with white text.
1379
- </SkAlert>
1335
+ | Class | Effect | Default |
1336
+ |-------|--------|---------|
1337
+ | `sk-fixed-header` | Stick header to viewport top | off |
1338
+ | `sk-fixed-footer` | Stick footer to viewport bottom | off |
1339
+ | `sk-flush` | Remove outer padding | off |
1380
1340
 
1381
- <SkAlert
1382
- base-color="oklch(0.75 0.2 150)"
1383
- text-color="oklch(0.2 0.05 150)"
1384
- >
1341
+ `sk-page` is a layout shell. Inner regions use `sk-page-header`, `sk-page-main`,
1342
+ `sk-page-sidebar`, `sk-page-aside`, and `sk-page-footer` as child elements.
1343
+
1344
+ **Rendered HTML:**
1345
+
1346
+ ```html
1347
+ <div class="sk-page sk-fixed-header">
1348
+ <header class="sk-page-header">…</header>
1349
+ <main class="sk-page-main">…</main>
1350
+ </div>
1351
+ ```
1352
+
1353
+ [See Vue docs →](/components/page)
1354
+
1355
+ ---
1356
+
1357
+ ### Group
1358
+
1359
+ **Base class:** `sk-group`
1360
+
1361
+ **Modifiers:**
1362
+
1363
+ | Class | Effect | Default |
1364
+ |-------|--------|---------|
1365
+ | `sk-horizontal` / `sk-vertical` | Flex direction | `sk-horizontal` |
1366
+
1367
+ Groups child elements with joined borders, removing intermediate gaps and rounding only
1368
+ outer corners.
1369
+
1370
+ **Rendered HTML:**
1371
+
1372
+ ```html
1373
+ <div class="sk-group sk-horizontal">
1374
+ <button class="sk-button sk-neutral" type="button">
1375
+ <span class="sk-button-chrome">A</span>
1376
+ </button>
1377
+ <button class="sk-button sk-neutral" type="button">
1378
+ <span class="sk-button-chrome">B</span>
1379
+ </button>
1380
+ </div>
1381
+ ```
1382
+
1383
+ [See Vue docs →](/components/group)
1384
+
1385
+ ---
1386
+
1387
+ ### Skeleton
1388
+
1389
+ **Base class:** `sk-skeleton`
1390
+
1391
+ **Modifiers:**
1392
+
1393
+ | Class | Effect | Default |
1394
+ |-------|--------|---------|
1395
+ | `sk-text` / `sk-circular` / `sk-rectangular` / `sk-square` | Shape variant | `sk-text` |
1396
+ | `sk-shimmer` | Shimmer animation | `sk-shimmer` (default on) |
1397
+ | `sk-pulse` | Pulse animation | off |
1398
+
1399
+ Note: the variant class names are `sk-text`, `sk-circular`, `sk-rectangular`, `sk-square`
1400
+ (not `sk-shape-*`). The static helper defaults animation to `sk-shimmer`; omit both
1401
+ `sk-shimmer` and `sk-pulse` for a static (no-animation) skeleton.
1402
+
1403
+ Width and height are set via inline style — they have no CSS class equivalent.
1404
+
1405
+ **Rendered HTML:**
1406
+
1407
+ ```html
1408
+ <!-- text skeleton with shimmer (defaults) -->
1409
+ <div class="sk-skeleton sk-text sk-shimmer"></div>
1410
+
1411
+ <!-- rect skeleton with explicit dimensions -->
1412
+ <div class="sk-skeleton sk-rectangular sk-shimmer" style="width: 200px; height: 40px;"></div>
1413
+
1414
+ <!-- circular avatar placeholder -->
1415
+ <div class="sk-skeleton sk-circular sk-pulse" style="width: 48px; height: 48px;"></div>
1416
+ ```
1417
+
1418
+ [See Vue docs →](/components/skeleton)
1419
+
1420
+ ---
1421
+
1422
+ ### Progress
1423
+
1424
+ **Base class:** `sk-progress`
1425
+
1426
+ **Modifiers:**
1427
+
1428
+ | Class | Effect | Default |
1429
+ |-------|--------|---------|
1430
+ | `sk-neutral` / `sk-primary` / … | Kind color | `sk-neutral` |
1431
+ | `sk-xs` … `sk-xl` | Bar height | `sk-md` |
1432
+ | `sk-indeterminate` | Animated indeterminate state | off |
1433
+
1434
+ Uses the `<progress>` element natively. Pass `value` and `max` attributes.
1435
+
1436
+ **Rendered HTML:**
1437
+
1438
+ ```html
1439
+ <progress class="sk-progress sk-primary sk-sm" value="40" max="100"></progress>
1440
+ ```
1441
+
1442
+ [See Vue docs →](/components/progress)
1443
+
1444
+ ---
1445
+
1446
+ ### Spinner
1447
+
1448
+ **Base class:** `sk-spinner`
1449
+
1450
+ **Modifiers:**
1451
+
1452
+ | Class | Effect | Default |
1453
+ |-------|--------|---------|
1454
+ | `sk-neutral` / `sk-primary` / … | Kind color | `sk-primary` |
1455
+ | `sk-xs` … `sk-xl` | Spinner diameter | `sk-md` |
1456
+ | `sk-variant-circular` / `sk-variant-dots` / `sk-variant-crosshair` | Visual style | `sk-variant-circular` |
1457
+
1458
+ The spinner emits ARIA attributes (`role="status"`, `aria-live="polite"`, `aria-label="Loading"`)
1459
+ and a variant-specific inner DOM. Mirror this structure when using the class API directly:
1460
+
1461
+ **Rendered HTML (circular — default):**
1462
+
1463
+ ```html
1464
+ <div class="sk-spinner sk-primary sk-md sk-variant-circular"
1465
+ role="status" aria-live="polite" aria-label="Loading">
1466
+ <div class="sk-spinner-circular">
1467
+ <div class="sk-arc sk-arc-large"></div>
1468
+ <div class="sk-arc sk-arc-small"></div>
1469
+ </div>
1470
+ </div>
1471
+ ```
1472
+
1473
+ **Rendered HTML (dots):**
1474
+
1475
+ ```html
1476
+ <div class="sk-spinner sk-accent sk-lg sk-variant-dots"
1477
+ role="status" aria-live="polite" aria-label="Loading">
1478
+ <div class="sk-spinner-dots">
1479
+ <div class="sk-dot"></div>
1480
+ <div class="sk-dot"></div>
1481
+ <div class="sk-dot"></div>
1482
+ </div>
1483
+ </div>
1484
+ ```
1485
+
1486
+ **Rendered HTML (crosshair):**
1487
+
1488
+ ```html
1489
+ <div class="sk-spinner sk-neutral sk-md sk-variant-crosshair"
1490
+ role="status" aria-live="polite" aria-label="Loading">
1491
+ <div class="sk-crosshair-loader"></div>
1492
+ </div>
1493
+ ```
1494
+
1495
+ [See Vue docs →](/components/spinner)
1496
+
1497
+ ---
1498
+
1499
+ ### NavBar
1500
+
1501
+ **Base class:** `sk-navbar`
1502
+
1503
+ **Modifiers:**
1504
+
1505
+ | Class | Effect | Default |
1506
+ |-------|--------|---------|
1507
+ | `sk-neutral` / `sk-primary` / … | Kind color | `sk-neutral` |
1508
+ | `sk-sticky` | Position sticky at viewport top | on (default) |
1509
+
1510
+ The navbar emits a content wrapper with optional slot regions inside. Each slot region is
1511
+ only emitted when it has content:
1512
+
1513
+ **Rendered HTML (with leading, brand, nav, and actions):**
1514
+
1515
+ ```html
1516
+ <nav class="sk-navbar sk-neutral sk-sticky">
1517
+ <div class="sk-navbar-content">
1518
+ <div class="sk-navbar-leading"><!-- sidebar toggle --></div>
1519
+ <div class="sk-navbar-brand">MySite</div>
1520
+ <div class="sk-navbar-nav">
1521
+ <a href="/docs">Docs</a>
1522
+ </div>
1523
+ <div class="sk-navbar-actions"><!-- user menu --></div>
1524
+ </div>
1525
+ </nav>
1526
+ ```
1527
+
1528
+ **Rendered HTML (brand + nav only):**
1529
+
1530
+ ```html
1531
+ <nav class="sk-navbar sk-neutral sk-sticky">
1532
+ <div class="sk-navbar-content">
1533
+ <div class="sk-navbar-brand">MySite</div>
1534
+ <div class="sk-navbar-nav">…</div>
1535
+ </div>
1536
+ </nav>
1537
+ ```
1538
+
1539
+ **Custom color vars:** `--sk-navbar-color-base`, `--sk-navbar-fg`
1540
+
1541
+ [See Vue docs →](/components/navbar)
1542
+
1543
+ ---
1544
+
1545
+ ### Toolbar
1546
+
1547
+ **Base class:** `sk-toolbar`
1548
+
1549
+ **Modifiers:**
1550
+
1551
+ | Class | Effect | Default |
1552
+ |-------|--------|---------|
1553
+ | `sk-neutral` / `sk-primary` / … | Kind color | `sk-neutral` |
1554
+ | `sk-horizontal` / `sk-vertical` | Layout axis | `sk-horizontal` |
1555
+ | `sk-cut-top-left`, `sk-cut-top-right`, `sk-cut-bottom-right`, `sk-cut-bottom-left` | Beveled corners | all four (default) |
1556
+
1557
+ The element should carry `role="toolbar"`. Orientation uses `sk-horizontal` / `sk-vertical`
1558
+ directly (not `sk-orientation-*`). By default all four corners are cut.
1559
+
1560
+ **Rendered HTML:**
1561
+
1562
+ ```html
1563
+ <div class="sk-toolbar sk-neutral sk-horizontal sk-cut-top-left sk-cut-top-right sk-cut-bottom-right sk-cut-bottom-left"
1564
+ role="toolbar">
1565
+ <button class="sk-button sk-neutral" type="button">
1566
+ <span class="sk-button-chrome">Cut</span>
1567
+ </button>
1568
+ <button class="sk-button sk-neutral" type="button">
1569
+ <span class="sk-button-chrome">Copy</span>
1570
+ </button>
1571
+ </div>
1572
+ ```
1573
+
1574
+ **Custom color vars:** `--sk-toolbar-color-base`, `--sk-toolbar-fg`
1575
+
1576
+ [See Vue docs →](/components/toolbar)
1577
+
1578
+ ---
1579
+
1580
+ ### Sidebar
1581
+
1582
+ **Base class:** `sk-sidebar`
1583
+
1584
+ **Modifiers (on `<aside>`):**
1585
+
1586
+ | Class | Effect | Default |
1587
+ |-------|--------|---------|
1588
+ | `sk-neutral` / `sk-primary` / … | Kind color | `sk-neutral` |
1589
+ | `sk-sidebar-right` | Mount on the right side | off (left) |
1590
+ | `sk-dense` | Compact item padding | off |
1591
+
1592
+ The sidebar emits a rich inner structure. Drawer open/close behavior is Vue-only; the class
1593
+ API form is always visible. Inner panel corner is `sk-cut-bottom-right` (left side) or
1594
+ `sk-cut-bottom-left` (right side).
1595
+
1596
+ **Rendered HTML (left sidebar, neutral):**
1597
+
1598
+ ```html
1599
+ <aside class="sk-sidebar sk-neutral">
1600
+ <div class="sk-panel sk-neutral sk-md sk-cut-bottom-right sk-decoration-bottom-right sk-sidebar-panel">
1601
+ <div class="sk-panel-scroll-content">
1602
+ <nav class="sk-sidebar-nav">
1603
+ <!-- navigation links -->
1604
+ </nav>
1605
+ </div>
1606
+ </div>
1607
+ </aside>
1608
+ ```
1609
+
1610
+ [See Vue docs →](/components/sidebar)
1611
+
1612
+ ---
1613
+
1614
+ ### Breadcrumbs
1615
+
1616
+ **Base class:** `sk-breadcrumbs`
1617
+
1618
+ **Modifiers:**
1619
+
1620
+ | Class | Effect | Default |
1621
+ |-------|--------|---------|
1622
+ | `sk-neutral` / `sk-primary` / … | Kind color | `sk-neutral` |
1623
+
1624
+ Uses a `<nav>` element. Add `aria-label="Breadcrumbs"` for accessibility.
1625
+
1626
+ **Rendered HTML:**
1627
+
1628
+ ```html
1629
+ <nav class="sk-breadcrumbs sk-neutral" aria-label="Breadcrumbs">
1630
+ <ol>
1631
+ <li><a href="/">Home</a></li>
1632
+ <li><a href="/docs">Docs</a></li>
1633
+ <li aria-current="page">Installation</li>
1634
+ </ol>
1635
+ </nav>
1636
+ ```
1637
+
1638
+ [See Vue docs →](/components/breadcrumbs)
1639
+
1640
+ ---
1641
+
1642
+ ### Pagination
1643
+
1644
+ **Base class:** `sk-pagination`
1645
+
1646
+ **Modifiers:**
1647
+
1648
+ | Class | Effect | Default |
1649
+ |-------|--------|---------|
1650
+ | `sk-neutral` / `sk-primary` / … | Kind color | `sk-neutral` |
1651
+
1652
+ Uses a `<nav>` element. Add `aria-label="Pagination"`.
1653
+
1654
+ **Rendered HTML:**
1655
+
1656
+ ```html
1657
+ <nav class="sk-pagination sk-neutral" aria-label="Pagination">
1658
+ <button class="sk-button sk-neutral" type="button" aria-label="Previous">
1659
+ <span class="sk-button-chrome">‹</span>
1660
+ </button>
1661
+ <button class="sk-button sk-primary" type="button" aria-current="page">
1662
+ <span class="sk-button-chrome">1</span>
1663
+ </button>
1664
+ <button class="sk-button sk-neutral" type="button">
1665
+ <span class="sk-button-chrome">2</span>
1666
+ </button>
1667
+ <button class="sk-button sk-neutral" type="button" aria-label="Next">
1668
+ <span class="sk-button-chrome">›</span>
1669
+ </button>
1670
+ </nav>
1671
+ ```
1672
+
1673
+ [See Vue docs →](/components/pagination)
1674
+
1675
+ ---
1676
+
1677
+ ### Tag
1678
+
1679
+ **Base class:** `sk-tag`
1680
+
1681
+ **Modifiers:**
1682
+
1683
+ | Class | Effect | Default |
1684
+ |-------|--------|---------|
1685
+ | `sk-neutral` / `sk-primary` / … | Kind color | `sk-neutral` |
1686
+ | `sk-xs` … `sk-xl` | Tag size | `sk-md` |
1687
+ | `sk-solid` / `sk-outline` / `sk-ghost` | Visual variant | `sk-solid` |
1688
+ | `sk-removable` | Show remove affordance | off |
1689
+
1690
+ Uses a `<span>` element. Content must be wrapped in `<span class="sk-tag-content">`. When
1691
+ `sk-removable` is present, include the remove button after the content span.
1692
+
1693
+ **Rendered HTML (simple):**
1694
+
1695
+ ```html
1696
+ <span class="sk-tag sk-accent sk-solid sk-sm">
1697
+ <span class="sk-tag-content">Beta</span>
1698
+ </span>
1699
+ ```
1700
+
1701
+ **Rendered HTML (removable):**
1702
+
1703
+ ```html
1704
+ <span class="sk-tag sk-neutral sk-solid sk-md sk-removable">
1705
+ <span class="sk-tag-content">design-system</span>
1706
+ <button type="button" class="sk-tag-remove" aria-label="Remove">
1707
+ <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24"
1708
+ viewBox="0 0 24 24" fill="none" stroke="currentColor"
1709
+ stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
1710
+ <line x1="18" y1="6" x2="6" y2="18"></line>
1711
+ <line x1="6" y1="6" x2="18" y2="18"></line>
1712
+ </svg>
1713
+ </button>
1714
+ </span>
1715
+ ```
1716
+
1717
+ **Custom color vars:** `--sk-tag-color-base`, `--sk-tag-fg`
1718
+
1719
+ [See Vue docs →](/components/tag)
1720
+
1721
+ ---
1722
+
1723
+ ### Avatar
1724
+
1725
+ **Base class:** `sk-avatar`
1726
+
1727
+ **Modifiers:**
1728
+
1729
+ | Class | Effect | Default |
1730
+ |-------|--------|---------|
1731
+ | `sk-neutral` / `sk-primary` / … | Kind color | `sk-neutral` |
1732
+ | `sk-xs` … `sk-xl` | Avatar size | `sk-md` |
1733
+
1734
+ Note: there is no `shape` modifier — the Vue component does not expose a shape prop; avatars
1735
+ are always circular.
1736
+
1737
+ The inner content follows a priority chain: image (`src`) → initials text → default person icon SVG.
1738
+
1739
+ **Rendered HTML (with image):**
1740
+
1741
+ ```html
1742
+ <div class="sk-avatar sk-neutral sk-md">
1743
+ <img src="/avatar.jpg" alt="User name" class="sk-avatar-image">
1744
+ </div>
1745
+ ```
1746
+
1747
+ **Rendered HTML (with initials):**
1748
+
1749
+ ```html
1750
+ <div class="sk-avatar sk-primary sk-lg">
1751
+ <span class="sk-avatar-initials">AB</span>
1752
+ </div>
1753
+ ```
1754
+
1755
+ **Rendered HTML (fallback icon, no src or initials):**
1756
+
1757
+ ```html
1758
+ <div class="sk-avatar sk-neutral sk-md">
1759
+ <svg class="sk-avatar-icon" viewBox="0 0 24 24" fill="currentColor">
1760
+ <path d="M12 12c2.21 0 4-1.79 4-4s-1.79-4-4-4-4 1.79-4 4 1.79 4 4 4zm0 2c-2.67 0-8 1.34-8 4v2h16v-2c0-2.66-5.33-4-8-4z"></path>
1761
+ </svg>
1762
+ </div>
1763
+ ```
1764
+
1765
+ **Custom color vars:** `--sk-avatar-color-base`, `--sk-avatar-fg`
1766
+
1767
+ [See Vue docs →](/components/avatar)
1768
+
1769
+ ---
1770
+
1771
+ ### Field
1772
+
1773
+ **Base class:** `sk-field`
1774
+
1775
+ **Modifiers:**
1776
+
1777
+ | Class | Effect | Default |
1778
+ |-------|--------|---------|
1779
+ | `sk-label-top` / `sk-label-left` / `sk-label-right` | Label placement | `sk-label-top` |
1780
+ | `sk-has-error` | Error state styling | off |
1781
+
1782
+ Wrap a label + input in a field for consistent layout and error messaging. The input wrapper
1783
+ div is always emitted. Label, description, and error paragraphs are optional.
1784
+
1785
+ **Rendered HTML (with label):**
1786
+
1787
+ ```html
1788
+ <div class="sk-field sk-label-top">
1789
+ <label for="email" class="sk-field-label">Email</label>
1790
+ <div class="sk-field-input-wrapper">
1791
+ <input class="sk-input sk-neutral" id="email" type="email" />
1792
+ </div>
1793
+ </div>
1794
+ ```
1795
+
1796
+ **Rendered HTML (with error):**
1797
+
1798
+ ```html
1799
+ <div class="sk-field sk-label-top sk-has-error">
1800
+ <label for="email" class="sk-field-label">Email</label>
1801
+ <div class="sk-field-input-wrapper">
1802
+ <input class="sk-input sk-neutral" id="email" type="email" />
1803
+ </div>
1804
+ <p id="email-error" class="sk-field-error">Please enter a valid email address.</p>
1805
+ </div>
1806
+ ```
1807
+
1808
+ **Rendered HTML (required field):**
1809
+
1810
+ ```html
1811
+ <div class="sk-field sk-label-top">
1812
+ <label for="name" class="sk-field-label">
1813
+ Name<span class="sk-field-required">*</span>
1814
+ </label>
1815
+ <div class="sk-field-input-wrapper">
1816
+ <input class="sk-input sk-neutral" id="name" type="text" required />
1817
+ </div>
1818
+ </div>
1819
+ ```
1820
+
1821
+ [See Vue docs →](/components/field)
1822
+
1823
+ ---
1824
+
1825
+ ### Table
1826
+
1827
+ **Base class:** `sk-table`
1828
+
1829
+ **Modifiers:**
1830
+
1831
+ | Class | Effect | Default |
1832
+ |-------|--------|---------|
1833
+ | `sk-neutral` / `sk-primary` / … | Kind color | `sk-neutral` |
1834
+ | `sk-default` / other variants | Visual variant | `sk-default` |
1835
+ | `sk-striped` | Alternating row backgrounds | off |
1836
+ | `sk-hoverable` | Row hover highlight | on (default) |
1837
+ | `sk-bordered` | Outer border | on (default) |
1838
+ | `sk-no-inner-borders` | Suppress inner cell borders | on (default — inner borders off) |
1839
+ | `sk-subtle` | Reduced contrast | off |
1840
+
1841
+ The table is wrapped in a `sk-table-wrapper` div. Both elements receive modifier classes.
1842
+
1843
+ **Rendered HTML (defaults):**
1844
+
1845
+ ```html
1846
+ <div class="sk-table-wrapper sk-table-wrapper-neutral">
1847
+ <table class="sk-table sk-neutral sk-default sk-hoverable sk-bordered sk-no-inner-borders">
1848
+ <thead>
1849
+ <tr><th>Name</th><th>Role</th></tr>
1850
+ </thead>
1851
+ <tbody>
1852
+ <tr><td>Alice</td><td>Engineer</td></tr>
1853
+ </tbody>
1854
+ </table>
1855
+ </div>
1856
+ ```
1857
+
1858
+ **Rendered HTML (striped, dark background, subtle):**
1859
+
1860
+ ```html
1861
+ <div class="sk-table-wrapper sk-table-wrapper-neutral sk-dark-background sk-subtle">
1862
+ <table class="sk-table sk-neutral sk-default sk-striped sk-hoverable sk-bordered sk-no-inner-borders sk-subtle">
1863
+ <thead><tr><th>Name</th></tr></thead>
1864
+ <tbody><tr><td>Alice</td></tr></tbody>
1865
+ </table>
1866
+ </div>
1867
+ ```
1868
+
1869
+ **Custom color vars:** `--sk-table-color-base`, `--sk-table-fg`
1870
+
1871
+ [See Vue docs →](/components/table)
1872
+
1873
+ ---
1874
+
1875
+ ### Tooltip
1876
+
1877
+ **Base class:** `sk-tooltip`
1878
+
1879
+ **Modifiers:**
1880
+
1881
+ | Class | Effect | Default |
1882
+ |-------|--------|---------|
1883
+ | `sk-neutral` / `sk-primary` / … | Kind color | `sk-neutral` |
1884
+ | `sk-solid` / `sk-outline` | Visual variant | `sk-solid` |
1885
+ | `sk-placement-top` / `sk-placement-right` / `sk-placement-bottom` / `sk-placement-left` | Tooltip position | `sk-placement-top` |
1886
+
1887
+ The element should carry `role="tooltip"`. The Vue version includes a JS-managed trigger
1888
+ and positioning engine — the class API is for static rendering of pre-positioned tooltips.
1889
+
1890
+ **Rendered HTML:**
1891
+
1892
+ ```html
1893
+ <div class="sk-tooltip sk-neutral sk-solid sk-placement-top" role="tooltip">
1894
+ Click to expand
1895
+ </div>
1896
+ ```
1897
+
1898
+ [See Vue docs →](/components/tooltip)
1899
+
1900
+ ---
1901
+
1902
+ ### Button
1903
+
1904
+ **Base class:** `sk-button`
1905
+
1906
+ **Modifiers:**
1907
+
1908
+ | Class | Effect | Default |
1909
+ |-------|--------|---------|
1910
+ | `sk-neutral` / `sk-primary` / … | Kind color | `sk-neutral` |
1911
+ | `sk-xs` … `sk-xl` | Button size | `sk-md` |
1912
+ | `sk-solid` / `sk-outline` / `sk-ghost` | Visual variant | `sk-solid` |
1913
+ | `sk-loading` | Spinner + aria-busy | off |
1914
+ | `sk-pressed` | aria-pressed state | off |
1915
+ | `sk-dense` | Compact padding | off |
1916
+
1917
+ Button children must be wrapped in `<span class="sk-button-chrome">`.
1918
+
1919
+ **Rendered HTML (button element):**
1920
+
1921
+ ```html
1922
+ <button class="sk-button sk-primary sk-lg sk-solid" type="button">
1923
+ <span class="sk-button-chrome">Launch</span>
1924
+ </button>
1925
+ ```
1926
+
1927
+ **Rendered HTML (anchor variant):**
1928
+
1929
+ ```html
1930
+ <a class="sk-button sk-accent sk-outline" href="/docs">
1931
+ <span class="sk-button-chrome">Read the docs</span>
1932
+ </a>
1933
+ ```
1934
+
1935
+ [See Vue docs →](/components/button)
1936
+
1937
+ ---
1938
+
1939
+ ### Input
1940
+
1941
+ **Base class:** `sk-input`
1942
+
1943
+ **Modifiers:**
1944
+
1945
+ | Class | Effect | Default |
1946
+ |-------|--------|---------|
1947
+ | `sk-neutral` / `sk-primary` / … | Kind color | `sk-neutral` |
1948
+ | `sk-xs` … `sk-xl` | Input size | `sk-md` |
1949
+
1950
+ Apply directly to the `<input>` element.
1951
+
1952
+ **Rendered HTML:**
1953
+
1954
+ ```html
1955
+ <input class="sk-input sk-neutral" type="text" placeholder="Search…" />
1956
+ ```
1957
+
1958
+ [See Vue docs →](/components/input)
1959
+
1960
+ ---
1961
+
1962
+ ### Textarea
1963
+
1964
+ **Base class:** `sk-textarea`
1965
+
1966
+ **Modifiers:**
1967
+
1968
+ | Class | Effect | Default |
1969
+ |-------|--------|---------|
1970
+ | `sk-neutral` / `sk-primary` / … | Kind color | `sk-neutral` |
1971
+ | `sk-xs` … `sk-xl` | Textarea size | `sk-md` |
1972
+
1973
+ **Rendered HTML:**
1974
+
1975
+ ```html
1976
+ <textarea class="sk-textarea sk-neutral" rows="4" placeholder="Enter description…"></textarea>
1977
+ ```
1978
+
1979
+ [See Vue docs →](/components/textarea)
1980
+
1981
+ ---
1982
+
1983
+ ### Select
1984
+
1985
+ **Base class:** `sk-select`
1986
+
1987
+ **Modifiers:**
1988
+
1989
+ | Class | Effect | Default |
1990
+ |-------|--------|---------|
1991
+ | `sk-neutral` / `sk-primary` / … | Kind color | `sk-neutral` |
1992
+ | `sk-xs` … `sk-xl` | Select size | `sk-md` |
1993
+
1994
+ Apply to the native `<select>` element. The popup uses native browser styling; appearance
1995
+ can be overridden with `appearance: base-select` in Chromium.
1996
+
1997
+ **Rendered HTML:**
1998
+
1999
+ ```html
2000
+ <select class="sk-select sk-neutral">
2001
+ <option value="">Choose…</option>
2002
+ <option value="a">Option A</option>
2003
+ </select>
2004
+ ```
2005
+
2006
+ [See Vue docs →](/components/select)
2007
+
2008
+ ---
2009
+
2010
+ ### Slider
2011
+
2012
+ **Base class:** `sk-slider`
2013
+
2014
+ **Modifiers:**
2015
+
2016
+ | Class | Effect | Default |
2017
+ |-------|--------|---------|
2018
+ | `sk-neutral` / `sk-primary` / … | Kind color | `sk-neutral` |
2019
+ | `sk-xs` … `sk-xl` | Slider size | `sk-md` |
2020
+
2021
+ Apply to `<input type="range">`. Single-thumb only — Vue's dual-thumb variant requires JS.
2022
+
2023
+ **Rendered HTML:**
2024
+
2025
+ ```html
2026
+ <input class="sk-slider sk-primary" type="range" min="0" max="100" value="40" />
2027
+ ```
2028
+
2029
+ [See Vue docs →](/components/slider)
2030
+
2031
+ ---
2032
+
2033
+ ### ColorPicker
2034
+
2035
+ **Base class:** `sk-color-picker`
2036
+
2037
+ **Modifiers:**
2038
+
2039
+ | Class | Effect | Default |
2040
+ |-------|--------|---------|
2041
+ | `sk-xs` … `sk-xl` | Swatch size | `sk-md` |
2042
+
2043
+ Apply to `<input type="color">`. The palette UI is Vue-only.
2044
+
2045
+ **Rendered HTML:**
2046
+
2047
+ ```html
2048
+ <input class="sk-color-picker sk-md" type="color" value="#c4842d" />
2049
+ ```
2050
+
2051
+ [See Vue docs →](/components/color-picker)
2052
+
2053
+ ---
2054
+
2055
+ ### Checkbox
2056
+
2057
+ **Base class:** `sk-checkbox` (on the `<label>` wrapper)
2058
+
2059
+ The checkbox is a compound element. Use this exact structure:
2060
+
2061
+ **Rendered HTML:**
2062
+
2063
+ ```html
2064
+ <label class="sk-checkbox sk-neutral sk-md">
2065
+ <input type="checkbox" name="agree" />
2066
+ <span class="sk-checkbox-box"></span>
2067
+ <span class="sk-checkbox-label">I agree to the terms</span>
2068
+ </label>
2069
+ ```
2070
+
2071
+ **Modifiers on `sk-checkbox`:**
2072
+
2073
+ | Class | Effect | Default |
2074
+ |-------|--------|---------|
2075
+ | `sk-neutral` / `sk-primary` / … | Kind color | `sk-neutral` |
2076
+ | `sk-xs` … `sk-xl` | Checkbox size | `sk-md` |
2077
+
2078
+ [See Vue docs →](/components/checkbox)
2079
+
2080
+ ---
2081
+
2082
+ ### Radio
2083
+
2084
+ **Base class:** `sk-radio` (on the `<label>` wrapper)
2085
+
2086
+ Compound structure:
2087
+
2088
+ **Rendered HTML:**
2089
+
2090
+ ```html
2091
+ <label class="sk-radio sk-neutral sk-md">
2092
+ <input type="radio" name="color" value="red" />
2093
+ <span class="sk-radio-dot"></span>
2094
+ <span class="sk-radio-label">Red</span>
2095
+ </label>
2096
+ ```
2097
+
2098
+ **Modifiers on `sk-radio`:**
2099
+
2100
+ | Class | Effect | Default |
2101
+ |-------|--------|---------|
2102
+ | `sk-neutral` / `sk-primary` / … | Kind color | `sk-neutral` |
2103
+ | `sk-xs` … `sk-xl` | Radio size | `sk-md` |
2104
+
2105
+ [See Vue docs →](/components/radio)
2106
+
2107
+ ---
2108
+
2109
+ ### Switch
2110
+
2111
+ **Base class:** `sk-switch` (on the `<label>` wrapper)
2112
+
2113
+ Compound structure:
2114
+
2115
+ **Rendered HTML:**
2116
+
2117
+ ```html
2118
+ <label class="sk-switch sk-primary sk-md">
2119
+ <input type="checkbox" name="notifications" />
2120
+ <span class="sk-switch-track">
2121
+ <span class="sk-switch-thumb"></span>
2122
+ </span>
2123
+ <span class="sk-switch-label">Enable notifications</span>
2124
+ </label>
2125
+ ```
2126
+
2127
+ **Modifiers on `sk-switch`:**
2128
+
2129
+ | Class | Effect | Default |
2130
+ |-------|--------|---------|
2131
+ | `sk-neutral` / `sk-primary` / … | Kind color | `sk-neutral` |
2132
+ | `sk-xs` … `sk-xl` | Switch size | `sk-md` |
2133
+
2134
+ [See Vue docs →](/components/switch)
2135
+
2136
+ ---
2137
+
2138
+ ### NumberInput
2139
+
2140
+ **Base class:** `sk-number-input-wrapper` (on the outer `<div>`)
2141
+
2142
+ Compound structure. Stepper buttons are intentionally omitted — they need JS.
2143
+
2144
+ **Rendered HTML:**
2145
+
2146
+ ```html
2147
+ <div class="sk-number-input-wrapper sk-neutral sk-md">
2148
+ <input class="sk-number-input-field" type="number" min="0" max="100" value="42" />
2149
+ </div>
2150
+ ```
2151
+
2152
+ **Modifiers on `sk-number-input-wrapper`:**
2153
+
2154
+ | Class | Effect | Default |
2155
+ |-------|--------|---------|
2156
+ | `sk-neutral` / `sk-primary` / … | Kind color | `sk-neutral` |
2157
+ | `sk-xs` … `sk-xl` | Input size | `sk-md` |
2158
+
2159
+ [See Vue docs →](/components/number-input)
2160
+
2161
+ ---
2162
+
2163
+ ### TagsInput
2164
+
2165
+ **Base class:** `sk-tags-input`
2166
+
2167
+ A styled container for tag chip elements. The add/remove behavior requires Vue.
2168
+
2169
+ **Rendered HTML:**
2170
+
2171
+ ```html
2172
+ <div class="sk-tags-input sk-neutral sk-md">
2173
+ <span class="sk-tag sk-neutral sk-solid sk-sm">
2174
+ <span class="sk-tag-content">design-system</span>
2175
+ </span>
2176
+ <span class="sk-tag sk-neutral sk-solid sk-sm">
2177
+ <span class="sk-tag-content">css</span>
2178
+ </span>
2179
+ </div>
2180
+ ```
2181
+
2182
+ **Modifiers:**
2183
+
2184
+ | Class | Effect | Default |
2185
+ |-------|--------|---------|
2186
+ | `sk-neutral` / `sk-primary` / … | Kind color | `sk-neutral` |
2187
+ | `sk-xs` … `sk-xl` | Container size | `sk-md` |
2188
+
2189
+ [See Vue docs →](/components/tags-input)
2190
+
2191
+ ---
2192
+
2193
+ ### Dropdown
2194
+
2195
+ **Base class:** `sk-dropdown`
2196
+
2197
+ Rendered as a `<details>` disclosure element — no JS required. This is a reduced form;
2198
+ the Vue version uses a managed menu with focus trap and keyboard navigation.
2199
+
2200
+ **Modifiers:**
2201
+
2202
+ | Class | Effect | Default |
2203
+ |-------|--------|---------|
2204
+ | `sk-neutral` / `sk-primary` / … | Kind color | `sk-neutral` |
2205
+ | `sk-xs` … `sk-xl` | Size | `sk-md` |
2206
+
2207
+ **Rendered HTML:**
2208
+
2209
+ ```html
2210
+ <details class="sk-dropdown sk-neutral sk-md">
2211
+ <summary>Options ▾</summary>
2212
+ <a class="sk-dropdown-item" href="/settings">Settings</a>
2213
+ <a class="sk-dropdown-item" href="/logout">Log out</a>
2214
+ </details>
2215
+ ```
2216
+
2217
+ [See Vue docs →](/components/dropdown)
2218
+
2219
+ # Custom-Element API Reference
2220
+
2221
+ Sleekspace's CSS includes attribute selectors for all 19 in-scope container components, so
2222
+ you can author them as custom elements (`<sk-panel kind="primary">`) and get the exact same
2223
+ styling as the class API (`<div class="sk-panel sk-primary">`) — no JavaScript required, no
2224
+ custom-element registration, no `customElements.define()`.
2225
+
2226
+ Browsers parse unknown tags as `HTMLUnknownElement` with `display: inline` by default.
2227
+ Sleekspace's CSS resets those to `display: block` (or `inline-flex` for badge-like components)
2228
+ so the layout behaves the same as the class-API `<div>` counterparts.
2229
+
2230
+ ## How it works
2231
+
2232
+ The SCSS uses a dual-selector mixin that emits class and attribute selectors in the same rule:
2233
+
2234
+ ```scss
2235
+ /* Generated output — kind="primary" triggers the same rule as .sk-primary */
2236
+ .sk-panel.sk-primary,
2237
+ sk-panel[kind="primary"] { … }
2238
+ ```
2239
+
2240
+ Boolean attributes work the same way:
2241
+
2242
+ ```scss
2243
+ .sk-panel.sk-no-border,
2244
+ sk-panel[no-border] { … }
2245
+ ```
2246
+
2247
+ No JS. No polyfill. Just CSS.
2248
+
2249
+ ## Which components have a custom-element form?
2250
+
2251
+ The 19 container components listed below all support the `<sk-*>` tag form.
2252
+
2253
+ The following 12 components **do not** have a custom-element form and are class-API only:
2254
+ Button, Input, Textarea, Select, Slider, ColorPicker, Checkbox, Radio, Switch, NumberInput,
2255
+ TagsInput, Dropdown.
2256
+
2257
+ **Why?** Form controls are native semantic elements with mandatory tag names (`<input>`,
2258
+ `<select>`, etc.). Replacing them with `<sk-input>` would lose native form behavior,
2259
+ accessibility, and browser autofill. Compound controls (Checkbox, Radio, Switch, NumberInput)
2260
+ require a hidden native `<input>` child that can't be expressed in a single custom tag without
2261
+ JS registration. For these 12, use the [class API](./class-api.md).
2262
+
2263
+ ---
2264
+
2265
+ ## Component Reference
2266
+
2267
+ ### sk-panel
2268
+
2269
+ **Tag:** `<sk-panel>`
2270
+
2271
+ **Attributes:**
2272
+
2273
+ | Attribute | Values | Default |
2274
+ |-----------|--------|---------|
2275
+ | `kind` | neutral, primary, accent, info, success, warning, danger, boulder, neon-blue, neon-green, neon-red, neon-yellow | neutral |
2276
+ | `size` | xs, sm, md, lg, xl | md |
2277
+ | `corners` | Space-separated: top-left, top-right, bottom-right, bottom-left | bottom-right |
2278
+ | `decoration-corner` | top-left, top-right, bottom-right, bottom-left | bottom-right |
2279
+ | `no-border` | Boolean presence | off |
2280
+ | `no-decoration` | Boolean presence | off |
2281
+
2282
+ **Example:**
2283
+
2284
+ ```html
2285
+ <sk-panel kind="primary" size="lg" corners="top-left bottom-right" decoration-corner="top-left">
2286
+ <p>Content here.</p>
2287
+ </sk-panel>
2288
+ ```
2289
+
2290
+ [See Vue docs →](/components/panel)
2291
+
2292
+ ---
2293
+
2294
+ ### sk-card
2295
+
2296
+ **Tag:** `<sk-card>`
2297
+
2298
+ **Attributes:**
2299
+
2300
+ | Attribute | Values | Default |
2301
+ |-----------|--------|---------|
2302
+ | `kind` | neutral, primary, accent, info, success, warning, danger | neutral |
2303
+
2304
+ **Example:**
2305
+
2306
+ ```html
2307
+ <sk-card kind="accent">
2308
+ <div class="sk-card-header"><h3>Card Title</h3></div>
2309
+ <div class="sk-card-body"><p>Content.</p></div>
2310
+ </sk-card>
2311
+ ```
2312
+
2313
+ [See Vue docs →](/components/card)
2314
+
2315
+ ---
2316
+
2317
+ ### sk-alert
2318
+
2319
+ **Tag:** `<sk-alert>`
2320
+
2321
+ **Attributes:**
2322
+
2323
+ | Attribute | Values | Default |
2324
+ |-----------|--------|---------|
2325
+ | `kind` | neutral, primary, accent, info, success, warning, danger | info |
2326
+ | `subtle` | Boolean presence | off |
2327
+
2328
+ Add `role="alert"` for accessibility. Note: the custom-element form does not auto-inject
2329
+ icon or content wrapper divs — the static helper and Vue component do that. For the full
2330
+ icon + content structure, use the static helper `alert()` or the class API form with manual
2331
+ wrapper divs (see [class API → Alert](./class-api.md#alert)).
2332
+
2333
+ **Example:**
2334
+
2335
+ ```html
2336
+ <sk-alert kind="warning" role="alert">
2337
+ <div class="sk-alert-content">
2338
+ <p>Unsaved changes will be lost.</p>
2339
+ </div>
2340
+ </sk-alert>
2341
+ ```
2342
+
2343
+ [See Vue docs →](/components/alert)
2344
+
2345
+ ---
2346
+
2347
+ ### sk-divider
2348
+
2349
+ **Tag:** `<sk-divider>`
2350
+
2351
+ **Attributes:**
2352
+
2353
+ | Attribute | Values | Default |
2354
+ |-----------|--------|---------|
2355
+ | `kind` | neutral, primary, accent, info, success, warning, danger | neutral |
2356
+ | `orientation` | horizontal, vertical | horizontal |
2357
+ | `variant` | (omit for default), subtle | — |
2358
+
2359
+ Note: in the class API the divider is an `<hr>` — in the custom-element form you can use
2360
+ `<sk-divider>` and the CSS handles display. Add `role="separator"`.
2361
+
2362
+ **Example:**
2363
+
2364
+ ```html
2365
+ <sk-divider kind="neutral" role="separator"></sk-divider>
2366
+ ```
2367
+
2368
+ [See Vue docs →](/components/divider)
2369
+
2370
+ ---
2371
+
2372
+ ### sk-page
2373
+
2374
+ **Tag:** `<sk-page>`
2375
+
2376
+ **Attributes:**
2377
+
2378
+ | Attribute | Values | Default |
2379
+ |-----------|--------|---------|
2380
+ | `fixed-header` | Boolean presence | off |
2381
+ | `fixed-footer` | Boolean presence | off |
2382
+ | `flush` | Boolean presence | off |
2383
+
2384
+ **Example:**
2385
+
2386
+ ```html
2387
+ <sk-page fixed-header>
2388
+ <header class="sk-page-header">…</header>
2389
+ <main class="sk-page-main">…</main>
2390
+ </sk-page>
2391
+ ```
2392
+
2393
+ [See Vue docs →](/components/page)
2394
+
2395
+ ---
2396
+
2397
+ ### sk-group
2398
+
2399
+ **Tag:** `<sk-group>`
2400
+
2401
+ **Attributes:**
2402
+
2403
+ | Attribute | Values | Default |
2404
+ |-----------|--------|---------|
2405
+ | `orientation` | horizontal, vertical | horizontal |
2406
+
2407
+ **Example:**
2408
+
2409
+ ```html
2410
+ <sk-group>
2411
+ <button class="sk-button sk-neutral" type="button">
2412
+ <span class="sk-button-chrome">A</span>
2413
+ </button>
2414
+ <button class="sk-button sk-neutral" type="button">
2415
+ <span class="sk-button-chrome">B</span>
2416
+ </button>
2417
+ </sk-group>
2418
+ ```
2419
+
2420
+ [See Vue docs →](/components/group)
2421
+
2422
+ ---
2423
+
2424
+ ### sk-skeleton
2425
+
2426
+ **Tag:** `<sk-skeleton>`
2427
+
2428
+ **Attributes:**
2429
+
2430
+ | Attribute | Values | Default |
2431
+ |-----------|--------|---------|
2432
+ | `variant` | text, circular, rectangular, square | text |
2433
+ | `animation` | shimmer, pulse, none | shimmer |
2434
+
2435
+ Note: width and height are set via inline `style` — there are no attribute equivalents.
2436
+
2437
+ **Example:**
2438
+
2439
+ ```html
2440
+ <sk-skeleton variant="rectangular" animation="shimmer"
2441
+ style="width: 200px; height: 40px;"></sk-skeleton>
2442
+ ```
2443
+
2444
+ [See Vue docs →](/components/skeleton)
2445
+
2446
+ ---
2447
+
2448
+ ### sk-progress
2449
+
2450
+ **Tag:** `<sk-progress>`
2451
+
2452
+ **Attributes:**
2453
+
2454
+ | Attribute | Values | Default |
2455
+ |-----------|--------|---------|
2456
+ | `kind` | neutral, primary, accent, info, success, warning, danger | neutral |
2457
+ | `size` | xs, sm, md, lg, xl | md |
2458
+ | `indeterminate` | Boolean presence | off |
2459
+
2460
+ Also set the native `value` and `max` attributes.
2461
+
2462
+ **Example:**
2463
+
2464
+ ```html
2465
+ <sk-progress kind="primary" size="sm" value="40" max="100"></sk-progress>
2466
+ ```
2467
+
2468
+ [See Vue docs →](/components/progress)
2469
+
2470
+ ---
2471
+
2472
+ ### sk-spinner
2473
+
2474
+ **Tag:** `<sk-spinner>`
2475
+
2476
+ **Attributes:**
2477
+
2478
+ | Attribute | Values | Default |
2479
+ |-----------|--------|---------|
2480
+ | `kind` | neutral, primary, accent, info, success, warning, danger | primary |
2481
+ | `size` | xs, sm, md, lg, xl | md |
2482
+ | `variant` | circular, dots, crosshair | circular |
2483
+
2484
+ Note: the custom-element form does not inject the inner arc/dot DOM that the static helper
2485
+ and Vue component emit. Add `role="status"` and `aria-label="Loading"` manually.
2486
+
2487
+ **Example:**
2488
+
2489
+ ```html
2490
+ <sk-spinner kind="accent" size="lg" variant="circular"
2491
+ role="status" aria-label="Loading"></sk-spinner>
2492
+ ```
2493
+
2494
+ [See Vue docs →](/components/spinner)
2495
+
2496
+ ---
2497
+
2498
+ ### sk-navbar
2499
+
2500
+ **Tag:** `<sk-navbar>`
2501
+
2502
+ **Attributes:**
2503
+
2504
+ | Attribute | Values | Default |
2505
+ |-----------|--------|---------|
2506
+ | `kind` | neutral, primary, accent, info, success, warning, danger | neutral |
2507
+ | `sticky` | Boolean presence | on (sticky by default in class API) |
2508
+
2509
+ Note: the `sk-sticky` class is applied by default via the static helper when `sticky !== false`.
2510
+ In the custom-element form, `sticky` is a boolean attribute — include it to enable, omit to disable.
2511
+
2512
+ **Example:**
2513
+
2514
+ ```html
2515
+ <sk-navbar kind="neutral" sticky>
2516
+ <div class="sk-navbar-content">
2517
+ <div class="sk-navbar-brand">MySite</div>
2518
+ <div class="sk-navbar-nav">…</div>
2519
+ </div>
2520
+ </sk-navbar>
2521
+ ```
2522
+
2523
+ [See Vue docs →](/components/navbar)
2524
+
2525
+ ---
2526
+
2527
+ ### sk-toolbar
2528
+
2529
+ **Tag:** `<sk-toolbar>`
2530
+
2531
+ **Attributes:**
2532
+
2533
+ | Attribute | Values | Default |
2534
+ |-----------|--------|---------|
2535
+ | `kind` | neutral, primary, accent, info, success, warning, danger | neutral |
2536
+ | `orientation` | horizontal, vertical | horizontal |
2537
+
2538
+ Add `role="toolbar"`.
2539
+
2540
+ **Example:**
2541
+
2542
+ ```html
2543
+ <sk-toolbar kind="neutral" role="toolbar">
2544
+ <button class="sk-button sk-neutral" type="button">
2545
+ <span class="sk-button-chrome">Cut</span>
2546
+ </button>
2547
+ <button class="sk-button sk-neutral" type="button">
2548
+ <span class="sk-button-chrome">Copy</span>
2549
+ </button>
2550
+ </sk-toolbar>
2551
+ ```
2552
+
2553
+ [See Vue docs →](/components/toolbar)
2554
+
2555
+ ---
2556
+
2557
+ ### sk-sidebar
2558
+
2559
+ **Tag:** `<sk-sidebar>`
2560
+
2561
+ **Attributes:**
2562
+
2563
+ | Attribute | Values | Default |
2564
+ |-----------|--------|---------|
2565
+ | `kind` | neutral, primary, accent, info, success, warning, danger | neutral |
2566
+ | `side` | left, right | left |
2567
+ | `dense` | Boolean presence | off |
2568
+
2569
+ Drawer open/close is Vue-only. The custom-element form is always visible.
2570
+
2571
+ **Example:**
2572
+
2573
+ ```html
2574
+ <sk-sidebar kind="neutral">
2575
+ <nav>…</nav>
2576
+ </sk-sidebar>
2577
+ ```
2578
+
2579
+ [See Vue docs →](/components/sidebar)
2580
+
2581
+ ---
2582
+
2583
+ ### sk-breadcrumbs
2584
+
2585
+ **Tag:** `<sk-breadcrumbs>`
2586
+
2587
+ **Attributes:**
2588
+
2589
+ | Attribute | Values | Default |
2590
+ |-----------|--------|---------|
2591
+ | `kind` | neutral, primary, accent, info, success, warning, danger | neutral |
2592
+
2593
+ Add `aria-label="Breadcrumbs"`.
2594
+
2595
+ **Example:**
2596
+
2597
+ ```html
2598
+ <sk-breadcrumbs kind="neutral" aria-label="Breadcrumbs">
2599
+ <ol>
2600
+ <li><a href="/">Home</a></li>
2601
+ <li aria-current="page">Docs</li>
2602
+ </ol>
2603
+ </sk-breadcrumbs>
2604
+ ```
2605
+
2606
+ [See Vue docs →](/components/breadcrumbs)
2607
+
2608
+ ---
2609
+
2610
+ ### sk-pagination
2611
+
2612
+ **Tag:** `<sk-pagination>`
2613
+
2614
+ **Attributes:**
2615
+
2616
+ | Attribute | Values | Default |
2617
+ |-----------|--------|---------|
2618
+ | `kind` | neutral, primary, accent, info, success, warning, danger | neutral |
2619
+
2620
+ Add `aria-label="Pagination"`.
2621
+
2622
+ **Example:**
2623
+
2624
+ ```html
2625
+ <sk-pagination kind="neutral" aria-label="Pagination">
2626
+ <button class="sk-button sk-neutral" type="button">
2627
+ <span class="sk-button-chrome">‹</span>
2628
+ </button>
2629
+ <button class="sk-button sk-primary" type="button" aria-current="page">
2630
+ <span class="sk-button-chrome">1</span>
2631
+ </button>
2632
+ <button class="sk-button sk-neutral" type="button">
2633
+ <span class="sk-button-chrome">›</span>
2634
+ </button>
2635
+ </sk-pagination>
2636
+ ```
2637
+
2638
+ [See Vue docs →](/components/pagination)
2639
+
2640
+ ---
2641
+
2642
+ ### sk-tag
2643
+
2644
+ **Tag:** `<sk-tag>`
2645
+
2646
+ **Attributes:**
2647
+
2648
+ | Attribute | Values | Default |
2649
+ |-----------|--------|---------|
2650
+ | `kind` | neutral, primary, accent, info, success, warning, danger | neutral |
2651
+ | `size` | xs, sm, md, lg, xl | md |
2652
+ | `variant` | solid, outline, ghost | solid |
2653
+ | `removable` | Boolean presence | off |
2654
+
2655
+ Note: content should be wrapped in `<span class="sk-tag-content">` for correct inner spacing.
2656
+
2657
+ **Example:**
2658
+
2659
+ ```html
2660
+ <sk-tag kind="accent" size="sm" variant="outline">
2661
+ <span class="sk-tag-content">Beta</span>
2662
+ </sk-tag>
2663
+ ```
2664
+
2665
+ [See Vue docs →](/components/tag)
2666
+
2667
+ ---
2668
+
2669
+ ### sk-avatar
2670
+
2671
+ **Tag:** `<sk-avatar>`
2672
+
2673
+ **Attributes:**
2674
+
2675
+ | Attribute | Values | Default |
2676
+ |-----------|--------|---------|
2677
+ | `kind` | neutral, primary, accent, info, success, warning, danger | neutral |
2678
+ | `size` | xs, sm, md, lg, xl | md |
2679
+
2680
+ Note: there is no `shape` attribute — the Vue component does not expose a shape prop.
2681
+ Place the inner content (img, initials span, or fallback icon) as children.
2682
+
2683
+ **Example:**
2684
+
2685
+ ```html
2686
+ <sk-avatar kind="primary" size="lg">
2687
+ <img src="/avatar.jpg" alt="User" class="sk-avatar-image" />
2688
+ </sk-avatar>
2689
+ ```
2690
+
2691
+ [See Vue docs →](/components/avatar)
2692
+
2693
+ ---
2694
+
2695
+ ### sk-field
2696
+
2697
+ **Tag:** `<sk-field>`
2698
+
2699
+ **Attributes:**
2700
+
2701
+ | Attribute | Values | Default |
2702
+ |-----------|--------|---------|
2703
+ | `label-position` | top, left, right | top |
2704
+ | `has-error` | Boolean presence | off |
2705
+
2706
+ **Example:**
2707
+
2708
+ ```html
2709
+ <sk-field label-position="top">
2710
+ <label class="sk-field-label" for="email">Email</label>
2711
+ <div class="sk-field-input-wrapper">
2712
+ <input class="sk-input sk-neutral" id="email" type="email" />
2713
+ </div>
2714
+ </sk-field>
2715
+ ```
2716
+
2717
+ [See Vue docs →](/components/field)
2718
+
2719
+ ---
2720
+
2721
+ ### sk-table
2722
+
2723
+ **Tag:** `<sk-table>`
2724
+
2725
+ **Attributes:**
2726
+
2727
+ | Attribute | Values | Default |
2728
+ |-----------|--------|---------|
2729
+ | `kind` | neutral, primary, accent, info, success, warning, danger | neutral |
2730
+ | `variant` | default, (others) | default |
2731
+ | `striped` | Boolean presence | off |
2732
+ | `hoverable` | Boolean presence | on by default (omit to disable via class: don't add `sk-hoverable`) |
2733
+ | `bordered` | Boolean presence | on by default |
2734
+ | `inner-borders` | Boolean presence | off (inner borders suppressed by default) |
2735
+ | `dark-background` | Boolean presence | off |
2736
+ | `subtle` | Boolean presence | off |
2737
+
2738
+ Note: the custom-element form targets the `<table>` directly. The `sk-table-wrapper` div
2739
+ is a class-API / static-helper construct — it's not injected automatically for custom elements.
2740
+
2741
+ **Example:**
2742
+
2743
+ ```html
2744
+ <sk-table kind="neutral" striped>
2745
+ <thead><tr><th>Name</th><th>Role</th></tr></thead>
2746
+ <tbody><tr><td>Alice</td><td>Engineer</td></tr></tbody>
2747
+ </sk-table>
2748
+ ```
2749
+
2750
+ [See Vue docs →](/components/table)
2751
+
2752
+ ---
2753
+
2754
+ ### sk-tooltip
2755
+
2756
+ **Tag:** `<sk-tooltip>`
2757
+
2758
+ **Attributes:**
2759
+
2760
+ | Attribute | Values | Default |
2761
+ |-----------|--------|---------|
2762
+ | `kind` | neutral, primary, accent, info, success, warning, danger | neutral |
2763
+ | `variant` | solid, outline | solid |
2764
+ | `placement` | top, right, bottom, left | top |
2765
+
2766
+ Add `role="tooltip"`. The Vue version includes trigger management and floating-UI positioning —
2767
+ the custom-element form is for static pre-positioned tooltip markup only.
2768
+
2769
+ **Example:**
2770
+
2771
+ ```html
2772
+ <sk-tooltip kind="neutral" placement="top" role="tooltip">
2773
+ Click to expand
2774
+ </sk-tooltip>
2775
+ ```
2776
+
2777
+ [See Vue docs →](/components/tooltip)
2778
+
2779
+ ---
2780
+
2781
+ ## Form controls: class-only {#form-controls}
2782
+
2783
+ The following 12 components **do not** have a custom-element form and require the class API:
2784
+ Button, Input, Textarea, Select, Slider, ColorPicker, Checkbox, Radio, Switch, NumberInput,
2785
+ TagsInput, Dropdown.
2786
+
2787
+ Use the [class API](./class-api.md) for all 12 of these components.
2788
+
2789
+ # Static Helpers Reference
2790
+
2791
+ The `/static` subpath exports typed helper functions that generate Sleekspace HTML strings.
2792
+ They're intended for Node-based SSGs and build scripts where you want type-safe component
2793
+ output without importing Vue or shipping a runtime dependency.
2794
+
2795
+ Each helper returns a `string` of plain HTML — zero side effects, zero global state.
2796
+
2797
+ ## Installation
2798
+
2799
+ ```bash
2800
+ npm install @skewedaspect/sleekspace-ui
2801
+ ```
2802
+
2803
+ The CSS is a separate import:
2804
+
2805
+ ```typescript
2806
+ // In your bundler entry or HTML:
2807
+ import '@skewedaspect/sleekspace-ui/style';
2808
+ // or link the compiled CSS directly in your HTML
2809
+ ```
2810
+
2811
+ ## Import
2812
+
2813
+ ```typescript
2814
+ import { panel, button, alert, text, escapeAttr } from '@skewedaspect/sleekspace-ui/static';
2815
+ ```
2816
+
2817
+ All 31 component helpers plus utilities are exported from this single entry point.
2818
+
2819
+ ## Helper signature
2820
+
2821
+ Every component helper has the same shape:
2822
+
2823
+ ```typescript
2824
+ function helperName(props?: Props, children?: string): string
2825
+ ```
2826
+
2827
+ - `props` — typed props object. All properties are optional with sensible defaults.
2828
+ - `children` — inner HTML string. Pass pre-escaped content or use the `text()` utility.
2829
+ - Returns — a complete HTML string for the component's root element.
2830
+
2831
+ Container helpers (panel, card, etc.) include children in the output. Void helpers
2832
+ (input, slider, color-picker) ignore children.
2833
+
2834
+ ---
2835
+
2836
+ ## Utilities
2837
+
2838
+ ### `text(value)`
2839
+
2840
+ Escapes a plain string for safe HTML text content. Use whenever interpolating user-controlled
2841
+ or data-driven strings into HTML.
2842
+
2843
+ ```typescript
2844
+ import { text, panel } from '@skewedaspect/sleekspace-ui/static';
2845
+
2846
+ const html = panel({}, `<p>${ text(userInput) }</p>`);
2847
+ ```
2848
+
2849
+ ### `escapeAttr(value)`
2850
+
2851
+ Escapes a string for use inside an HTML attribute value (double-quoted).
2852
+
2853
+ ```typescript
2854
+ import { escapeAttr } from '@skewedaspect/sleekspace-ui/static';
2855
+
2856
+ const safe = `data-id="${ escapeAttr(rawId) }"`;
2857
+ ```
2858
+
2859
+ ### `composeClasses(spec, props)`
2860
+
2861
+ Low-level class composition utility. Takes a `ClassSpec` describing how props map to modifier
2862
+ classes, returns the space-separated class string. Useful when you need class output without
2863
+ a full helper.
2864
+
2865
+ ```typescript
2866
+ import { composeClasses } from '@skewedaspect/sleekspace-ui/static';
2867
+
2868
+ const classes = composeClasses({ base: 'sk-panel', kind: true }, { kind: 'primary' });
2869
+ // → "sk-panel sk-primary"
2870
+ ```
2871
+
2872
+ ### `render(spec, props, children)`
2873
+
2874
+ Generic renderer used internally by the thin-wrapper helpers (panel, card, progress, etc.).
2875
+ Takes a `RenderSpec` and emits the class-API HTML string. Useful for building custom helpers
2876
+ that follow the same class composition rules.
2877
+
2878
+ ```typescript
2879
+ import { render } from '@skewedaspect/sleekspace-ui/static';
2880
+
2881
+ const html = render(
2882
+ { tag: 'div', classSpec: { base: 'sk-panel', kind: true }, extraAttrs: { role: 'region' } },
2883
+ { kind: 'accent' },
2884
+ '<p>Custom region</p>'
2885
+ );
2886
+ // → '<div class="sk-panel sk-accent" role="region"><p>Custom region</p></div>'
2887
+ ```
2888
+
2889
+ ---
2890
+
2891
+ ## Framework Examples
2892
+
2893
+ ### VitePress
2894
+
2895
+ Use inside a `transformHtml` hook or a custom markdown-it plugin to render Sleekspace
2896
+ components inside `.md` files.
2897
+
2898
+ ```typescript
2899
+ // .vitepress/config.ts
2900
+ import { defineConfig } from 'vitepress';
2901
+ import { panel } from '@skewedaspect/sleekspace-ui/static';
2902
+
2903
+ export default defineConfig({
2904
+ transformHtml(code) {
2905
+ return code.replace(/<sk-callout kind="([^"]+)">([\s\S]*?)<\/sk-callout>/g, (_, kind, content) =>
2906
+ panel({ kind }, content)
2907
+ );
2908
+ },
2909
+ });
2910
+ ```
2911
+
2912
+ Or add a custom markdown-it fence renderer:
2913
+
2914
+ ```typescript
2915
+ // .vitepress/config.ts
2916
+ import markdownItSleekspace from './plugins/markdownItSleekspace';
2917
+
2918
+ export default defineConfig({
2919
+ markdown: {
2920
+ config(md) {
2921
+ md.use(markdownItSleekspace);
2922
+ },
2923
+ },
2924
+ });
2925
+ ```
2926
+
2927
+ ---
2928
+
2929
+ ### Astro
2930
+
2931
+ Import directly in `.astro` component files. Astro renders these at build time — no Vue runtime needed.
2932
+
2933
+ ```astro
2934
+ ---
2935
+ import { panel, button } from '@skewedaspect/sleekspace-ui/static';
2936
+ import '@skewedaspect/sleekspace-ui/style';
2937
+
2938
+ const callout = panel(
2939
+ { kind: 'accent', size: 'lg' },
2940
+ `<p>Build-time rendered with no runtime cost.</p>`
2941
+ );
2942
+ ---
2943
+
2944
+ <Fragment set:html={callout} />
2945
+ ```
2946
+
2947
+ For reuse across pages, wrap in a `.astro` component:
2948
+
2949
+ ```astro
2950
+ ---
2951
+ // src/components/Callout.astro
2952
+ import { panel } from '@skewedaspect/sleekspace-ui/static';
2953
+ const { kind = 'neutral', size = 'md' } = Astro.props;
2954
+ const html = panel({ kind, size }, await Astro.slots.render('default'));
2955
+ ---
2956
+ <Fragment set:html={html} />
2957
+ ```
2958
+
2959
+ ---
2960
+
2961
+ ### 11ty
2962
+
2963
+ Register as a paired shortcode in `.eleventy.js`:
2964
+
2965
+ ```javascript
2966
+ // .eleventy.js
2967
+ const { panel, button, alert } = require('@skewedaspect/sleekspace-ui/static');
2968
+
2969
+ module.exports = function(eleventyConfig) {
2970
+ eleventyConfig.addPairedShortcode('panel', (content, kind = 'neutral', size = 'md') =>
2971
+ panel({ kind, size }, content)
2972
+ );
2973
+
2974
+ eleventyConfig.addPairedShortcode('alert', (content, kind = 'info') =>
2975
+ alert({ kind }, content)
2976
+ );
2977
+
2978
+ eleventyConfig.addShortcode('button', (label, kind = 'primary', href) =>
2979
+ button({ kind, href }, label)
2980
+ );
2981
+ };
2982
+ ```
2983
+
2984
+ Then in your Nunjucks / Liquid templates:
2985
+
2986
+ ```njk
2987
+ {% panel "primary", "lg" %}
2988
+ <p>This panel is rendered at build time.</p>
2989
+ {% endpanel %}
2990
+ ```
2991
+
2992
+ ---
2993
+
2994
+ ### Vanilla Node build script
2995
+
2996
+ ```typescript
2997
+ import { writeFileSync } from 'fs';
2998
+ import { panel, navBar, button, text } from '@skewedaspect/sleekspace-ui/static';
2999
+
3000
+ const nav = navBar(
3001
+ { kind: 'neutral', sticky: true, brand: `<span>${ text('MySite') }</span>` },
3002
+ `<a href="/docs">Docs</a>`
3003
+ );
3004
+
3005
+ const hero = panel({ kind: 'primary', size: 'xl' },
3006
+ `<h1>Hello world</h1>`
3007
+ + button({ kind: 'accent', size: 'lg' }, text('Get started'))
3008
+ );
3009
+
3010
+ const page = `<!doctype html>
3011
+ <html lang="en">
3012
+ <head>
3013
+ <meta charset="utf-8" />
3014
+ <link rel="stylesheet" href="/sleekspace-ui.css" />
3015
+ </head>
3016
+ <body>
3017
+ ${ nav }
3018
+ <main>${ hero }</main>
3019
+ </body>
3020
+ </html>`;
3021
+
3022
+ writeFileSync('dist/index.html', page);
3023
+ ```
3024
+
3025
+ ---
3026
+
3027
+ ## Component Helper Reference
3028
+
3029
+ All 31 helpers are documented below with their props and actual emitted HTML output.
3030
+
3031
+ ---
3032
+
3033
+ ### panel
3034
+
3035
+ ```typescript
3036
+ panel(props?: PanelStaticProps, children?: string): string
3037
+ ```
3038
+
3039
+ **Props:**
3040
+
3041
+ | Prop | Type | Default | Description |
3042
+ |------|------|---------|-------------|
3043
+ | `kind` | `SkPanelKind` | `'neutral'` | Kind color |
3044
+ | `size` | `SkPanelSize` | `'md'` | Corner decoration size |
3045
+ | `corners` | `SkPanelCorner[]` | `['bottom-right']` | Which corners are beveled |
3046
+ | `decorationCorner` | `SkPanelCorner` | `'bottom-right'` | Which corner shows accent stripe |
3047
+ | `noBorder` | `boolean` | `false` | Remove border |
3048
+ | `noDecoration` | `boolean` | `false` | Hide accent stripe |
3049
+ | `baseColor` | `string` | — | Override via `--sk-panel-color-base` |
3050
+
3051
+ **Output:**
3052
+
3053
+ ```html
3054
+ <div class="sk-panel sk-neutral sk-md sk-cut-bottom-right sk-decoration-bottom-right">
3055
+ <!-- children -->
3056
+ </div>
3057
+ ```
3058
+
3059
+ ---
3060
+
3061
+ ### card
3062
+
3063
+ ```typescript
3064
+ card(props?: CardStaticProps, children?: string): string
3065
+ ```
3066
+
3067
+ **Props:**
3068
+
3069
+ | Prop | Type | Default | Description |
3070
+ |------|------|---------|-------------|
3071
+ | `kind` | `SkCardKind` | `'neutral'` | Kind color |
3072
+ | `baseColor` | `string` | — | Override via `--sk-panel-color-base` |
3073
+
3074
+ **Output:**
3075
+
3076
+ ```html
3077
+ <div class="sk-card sk-neutral"><!-- children --></div>
3078
+ ```
3079
+
3080
+ ---
3081
+
3082
+ ### alert {#alert}
3083
+
3084
+ ```typescript
3085
+ alert(props?: AlertStaticProps, children?: string): string
3086
+ ```
3087
+
3088
+ **Props:**
3089
+
3090
+ | Prop | Type | Default | Description |
3091
+ |------|------|---------|-------------|
3092
+ | `kind` | `SkAlertKind` | `'info'` | Kind color |
3093
+ | `subtle` | `boolean` | `false` | Lower-contrast variant |
3094
+ | `icon` | `string \| false` | `undefined` | Custom icon HTML, `false` to suppress, or omit for auto |
3095
+ | `baseColor` | `string` | — | Override via `--sk-alert-color-base` |
3096
+ | `textColor` | `string` | — | Override via `--sk-alert-fg` |
3097
+
3098
+ When `icon` is omitted, icons are auto-selected for feedback kinds (info, success, warning, danger).
3099
+ Non-feedback kinds (neutral, primary, accent) emit no icon container. Pass `icon: false` to
3100
+ suppress the icon on a feedback kind. Pass `icon: '<svg>…</svg>'` for a custom icon.
3101
+
3102
+ **Output (info kind — default):**
3103
+
3104
+ ```html
3105
+ <div class="sk-alert sk-info" role="alert">
3106
+ <div class="sk-alert-icon">
3107
+ <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
3108
+ <circle cx="12" cy="12" r="10"></circle>
3109
+ <line x1="12" y1="16" x2="12" y2="12"></line>
3110
+ <circle cx="12" cy="8" r="0.5" fill="currentColor"></circle>
3111
+ </svg>
3112
+ </div>
3113
+ <div class="sk-alert-content"><!-- children --></div>
3114
+ </div>
3115
+ ```
3116
+
3117
+ **Output (neutral kind — no icon):**
3118
+
3119
+ ```html
3120
+ <div class="sk-alert sk-neutral" role="alert">
3121
+ <div class="sk-alert-content"><!-- children --></div>
3122
+ </div>
3123
+ ```
3124
+
3125
+ **Output (icon: false):**
3126
+
3127
+ ```html
3128
+ <div class="sk-alert sk-success" role="alert">
3129
+ <div class="sk-alert-content"><!-- children --></div>
3130
+ </div>
3131
+ ```
3132
+
3133
+ ---
3134
+
3135
+ ### divider
3136
+
3137
+ ```typescript
3138
+ divider(props?: DividerStaticProps): string
3139
+ ```
3140
+
3141
+ **Props:**
3142
+
3143
+ | Prop | Type | Default | Description |
3144
+ |------|------|---------|-------------|
3145
+ | `kind` | `ComponentKind` | `'neutral'` | Kind color |
3146
+ | `orientation` | `'horizontal' \| 'vertical'` | `'horizontal'` | Layout axis |
3147
+ | `size` | `ComponentSize` | `'md'` | Line thickness |
3148
+ | `variant` | `'subtle'` | — | Reduced-contrast variant |
3149
+
3150
+ Note: divider renders as an `<hr>` element, not a `<div>`.
3151
+
3152
+ **Output:**
3153
+
3154
+ ```html
3155
+ <hr class="sk-divider sk-horizontal sk-neutral sk-md" role="separator">
3156
+ ```
3157
+
3158
+ ---
3159
+
3160
+ ### page
3161
+
3162
+ ```typescript
3163
+ page(props?: PageStaticProps, children?: string): string
3164
+ ```
3165
+
3166
+ **Props:**
3167
+
3168
+ | Prop | Type | Default | Description |
3169
+ |------|------|---------|-------------|
3170
+ | `fixedHeader` | `boolean` | `false` | Stick header to viewport top |
3171
+ | `fixedFooter` | `boolean` | `false` | Stick footer to viewport bottom |
3172
+ | `flush` | `boolean` | `false` | Remove outer padding |
3173
+ | `sidebarMode` | `SkPagePanelMode` | — | Sidebar panel mode |
3174
+ | `asideMode` | `SkPagePanelMode` | — | Aside panel mode |
3175
+
3176
+ **Output:**
3177
+
3178
+ ```html
3179
+ <div class="sk-page"><!-- children --></div>
3180
+ ```
3181
+
3182
+ ---
3183
+
3184
+ ### group
3185
+
3186
+ ```typescript
3187
+ group(props?: GroupStaticProps, children?: string): string
3188
+ ```
3189
+
3190
+ **Props:**
3191
+
3192
+ | Prop | Type | Default | Description |
3193
+ |------|------|---------|-------------|
3194
+ | `orientation` | `'horizontal' \| 'vertical'` | `'horizontal'` | Flex direction |
3195
+
3196
+ **Output:**
3197
+
3198
+ ```html
3199
+ <div class="sk-group sk-horizontal"><!-- children --></div>
3200
+ ```
3201
+
3202
+ ---
3203
+
3204
+ ### skeleton {#skeleton}
3205
+
3206
+ ```typescript
3207
+ skeleton(props?: SkeletonStaticProps): string
3208
+ ```
3209
+
3210
+ **Props:**
3211
+
3212
+ | Prop | Type | Default | Description |
3213
+ |------|------|---------|-------------|
3214
+ | `variant` | `'text' \| 'circular' \| 'rectangular' \| 'square'` | `'text'` | Shape preset |
3215
+ | `animation` | `'shimmer' \| 'pulse' \| 'none'` | `'shimmer'` | Animation style |
3216
+ | `width` | `string` | — | CSS width (e.g. `'200px'`, `'100%'`) — emitted as inline style |
3217
+ | `height` | `string` | — | CSS height — emitted as inline style |
3218
+
3219
+ For `circular` and `square` variants, if only `width` is set, `height` is automatically
3220
+ set to the same value.
3221
+
3222
+ **Output (text, defaults):**
3223
+
3224
+ ```html
3225
+ <div class="sk-skeleton sk-text sk-shimmer"></div>
3226
+ ```
3227
+
3228
+ **Output (rect with dimensions):**
3229
+
3230
+ ```html
3231
+ <div class="sk-skeleton sk-rectangular sk-shimmer" style="width: 200px; height: 40px;"></div>
3232
+ ```
3233
+
3234
+ **Output (animation: 'none'):**
3235
+
3236
+ ```html
3237
+ <div class="sk-skeleton sk-text"></div>
3238
+ ```
3239
+
3240
+ ---
3241
+
3242
+ ### progress
3243
+
3244
+ ```typescript
3245
+ progress(props?: ProgressStaticProps): string
3246
+ ```
3247
+
3248
+ **Props:**
3249
+
3250
+ | Prop | Type | Default | Description |
3251
+ |------|------|---------|-------------|
3252
+ | `kind` | `ComponentKind` | `'neutral'` | Kind color |
3253
+ | `size` | `SkProgressSize` | `'md'` | Bar height |
3254
+ | `indeterminate` | `boolean` | `false` | Animated indeterminate state |
3255
+ | `value` | `number \| null` | — | Progress value (native attribute) |
3256
+ | `max` | `number` | — | Max value (native attribute) |
3257
+
3258
+ **Output:**
3259
+
3260
+ ```html
3261
+ <progress class="sk-progress sk-neutral sk-md" value="40" max="100"></progress>
3262
+ ```
3263
+
3264
+ ---
3265
+
3266
+ ### spinner {#spinner}
3267
+
3268
+ ```typescript
3269
+ spinner(props?: SpinnerStaticProps): string
3270
+ ```
3271
+
3272
+ **Props:**
3273
+
3274
+ | Prop | Type | Default | Description |
3275
+ |------|------|---------|-------------|
3276
+ | `kind` | `ComponentKind` | `'primary'` | Kind color |
3277
+ | `size` | `SkSpinnerSize` | `'md'` | Spinner diameter |
3278
+ | `variant` | `'circular' \| 'dots' \| 'crosshair'` | `'circular'` | Visual style |
3279
+ | `color` | `string` | — | Override via `--sk-spinner-color` inline style |
3280
+
3281
+ Always emits `role="status"`, `aria-live="polite"`, `aria-label="Loading"`. Inner DOM
3282
+ varies by variant.
3283
+
3284
+ **Output (circular — default):**
3285
+
3286
+ ```html
3287
+ <div class="sk-spinner sk-primary sk-md sk-variant-circular"
3288
+ role="status" aria-live="polite" aria-label="Loading">
3289
+ <div class="sk-spinner-circular">
3290
+ <div class="sk-arc sk-arc-large"></div>
3291
+ <div class="sk-arc sk-arc-small"></div>
3292
+ </div>
3293
+ </div>
3294
+ ```
3295
+
3296
+ **Output (dots):**
3297
+
3298
+ ```html
3299
+ <div class="sk-spinner sk-primary sk-md sk-variant-dots"
3300
+ role="status" aria-live="polite" aria-label="Loading">
3301
+ <div class="sk-spinner-dots">
3302
+ <div class="sk-dot"></div>
3303
+ <div class="sk-dot"></div>
3304
+ <div class="sk-dot"></div>
3305
+ </div>
3306
+ </div>
3307
+ ```
3308
+
3309
+ **Output (crosshair):**
3310
+
3311
+ ```html
3312
+ <div class="sk-spinner sk-primary sk-md sk-variant-crosshair"
3313
+ role="status" aria-live="polite" aria-label="Loading">
3314
+ <div class="sk-crosshair-loader"></div>
3315
+ </div>
3316
+ ```
3317
+
3318
+ ---
3319
+
3320
+ ### navBar {#navbar}
3321
+
3322
+ ```typescript
3323
+ navBar(props?: NavBarStaticProps, children?: string): string
3324
+ ```
3325
+
3326
+ **Props:**
3327
+
3328
+ | Prop | Type | Default | Description |
3329
+ |------|------|---------|-------------|
3330
+ | `kind` | `SkNavBarKind` | `'neutral'` | Kind color |
3331
+ | `sticky` | `boolean` | `true` | Apply `sk-sticky` class |
3332
+ | `leading` | `string` | — | HTML for leading slot (sidebar toggle, etc.) |
3333
+ | `brand` | `string` | — | HTML for brand slot (logo / site name) |
3334
+ | `actions` | `string` | — | HTML for actions slot (right-aligned CTAs / user menu) |
3335
+ | `baseColor` | `string` | — | Override via `--sk-navbar-color-base` |
3336
+ | `textColor` | `string` | — | Override via `--sk-navbar-fg` |
3337
+
3338
+ `children` maps to the nav links slot (`sk-navbar-nav`). Each slot region (`leading`, `brand`,
3339
+ nav links, `actions`) is only emitted when it has content.
3340
+
3341
+ **Output (brand + nav only):**
3342
+
3343
+ ```html
3344
+ <nav class="sk-navbar sk-neutral sk-sticky">
3345
+ <div class="sk-navbar-content">
3346
+ <div class="sk-navbar-brand">MySite</div>
3347
+ <div class="sk-navbar-nav">
3348
+ <a href="/docs">Docs</a>
3349
+ </div>
3350
+ </div>
3351
+ </nav>
3352
+ ```
3353
+
3354
+ **Output (all slots):**
3355
+
3356
+ ```html
3357
+ <nav class="sk-navbar sk-neutral sk-sticky">
3358
+ <div class="sk-navbar-content">
3359
+ <div class="sk-navbar-leading"><!-- sidebar toggle --></div>
3360
+ <div class="sk-navbar-brand">MySite</div>
3361
+ <div class="sk-navbar-nav"><!-- nav links --></div>
3362
+ <div class="sk-navbar-actions"><!-- user menu --></div>
3363
+ </div>
3364
+ </nav>
3365
+ ```
3366
+
3367
+ ---
3368
+
3369
+ ### toolbar {#toolbar}
3370
+
3371
+ ```typescript
3372
+ toolbar(props?: ToolbarStaticProps, children?: string): string
3373
+ ```
3374
+
3375
+ **Props:**
3376
+
3377
+ | Prop | Type | Default | Description |
3378
+ |------|------|---------|-------------|
3379
+ | `kind` | `SkToolbarKind` | — | Kind color |
3380
+ | `orientation` | `'horizontal' \| 'vertical'` | `'horizontal'` | Layout axis |
3381
+ | `corners` | `SkToolbarCorner[]` | `['top-left', 'top-right', 'bottom-right', 'bottom-left']` | Beveled corners |
3382
+ | `baseColor` | `string` | — | Override via `--sk-toolbar-color-base` |
3383
+ | `textColor` | `string` | — | Override via `--sk-toolbar-fg` |
3384
+
3385
+ Always emits `role="toolbar"`. Orientation uses `sk-horizontal` / `sk-vertical` directly.
3386
+ By default all four corners are cut.
3387
+
3388
+ **Output (defaults):**
3389
+
3390
+ ```html
3391
+ <div class="sk-toolbar sk-horizontal sk-cut-top-left sk-cut-top-right sk-cut-bottom-right sk-cut-bottom-left"
3392
+ role="toolbar">
3393
+ <!-- children -->
3394
+ </div>
3395
+ ```
3396
+
3397
+ **Output (with kind, no corners):**
3398
+
3399
+ ```html
3400
+ <div class="sk-toolbar sk-neutral sk-horizontal" role="toolbar">
3401
+ <!-- children -->
3402
+ </div>
3403
+ ```
3404
+
3405
+ ---
3406
+
3407
+ ### sidebar
3408
+
3409
+ ```typescript
3410
+ sidebar(props?: SidebarStaticProps, children?: string): string
3411
+ ```
3412
+
3413
+ **Props:**
3414
+
3415
+ | Prop | Type | Default | Description |
3416
+ |------|------|---------|-------------|
3417
+ | `kind` | `SkSidebarKind` | `'neutral'` | Kind color |
3418
+ | `side` | `'left' \| 'right'` | `'left'` | Mount side |
3419
+ | `dense` | `boolean` | `false` | Compact item padding |
3420
+ | `width` | `string` | — | CSS width (not reflected in classes) |
3421
+ | `baseColor` | `string` | — | Override via `--sk-sidebar-color-base` |
3422
+
3423
+ Children are wrapped in `sk-sidebar-nav`. The helper emits the full inner panel structure.
3424
+
3425
+ **Output (left sidebar, neutral):**
3426
+
3427
+ ```html
3428
+ <aside class="sk-sidebar sk-neutral">
3429
+ <div class="sk-panel sk-neutral sk-md sk-cut-bottom-right sk-decoration-bottom-right sk-sidebar-panel">
3430
+ <div class="sk-panel-scroll-content">
3431
+ <nav class="sk-sidebar-nav"><!-- children --></nav>
3432
+ </div>
3433
+ </div>
3434
+ </aside>
3435
+ ```
3436
+
3437
+ **Output (right sidebar):**
3438
+
3439
+ ```html
3440
+ <aside class="sk-sidebar sk-neutral sk-sidebar-right">
3441
+ <div class="sk-panel sk-neutral sk-md sk-cut-bottom-left sk-decoration-bottom-left sk-sidebar-panel">
3442
+ <div class="sk-panel-scroll-content">
3443
+ <nav class="sk-sidebar-nav"><!-- children --></nav>
3444
+ </div>
3445
+ </div>
3446
+ </aside>
3447
+ ```
3448
+
3449
+ ---
3450
+
3451
+ ### breadcrumbs
3452
+
3453
+ ```typescript
3454
+ breadcrumbs(props?: BreadcrumbsStaticProps, children?: string): string
3455
+ ```
3456
+
3457
+ **Props:**
3458
+
3459
+ | Prop | Type | Default | Description |
3460
+ |------|------|---------|-------------|
3461
+ | `kind` | `SkBreadcrumbsKind` | `'neutral'` | Kind color |
3462
+ | `separator` | `string` | — | Separator character/HTML |
3463
+ | `baseColor` | `string` | — | Custom color override |
3464
+
3465
+ **Output:**
3466
+
3467
+ ```html
3468
+ <nav class="sk-breadcrumbs sk-neutral" aria-label="Breadcrumbs"><!-- children --></nav>
3469
+ ```
3470
+
3471
+ ---
3472
+
3473
+ ### pagination
3474
+
3475
+ ```typescript
3476
+ pagination(props?: PaginationStaticProps, children?: string): string
3477
+ ```
3478
+
3479
+ **Props:**
3480
+
3481
+ | Prop | Type | Default | Description |
3482
+ |------|------|---------|-------------|
3483
+ | `kind` | `SkPaginationKind` | `'neutral'` | Kind color |
3484
+ | `baseColor` | `string` | — | Custom color override |
3485
+
3486
+ **Output:**
3487
+
3488
+ ```html
3489
+ <nav class="sk-pagination sk-neutral" aria-label="Pagination"><!-- children --></nav>
3490
+ ```
3491
+
3492
+ ---
3493
+
3494
+ ### tag {#tag}
3495
+
3496
+ ```typescript
3497
+ tag(props?: TagStaticProps, children?: string): string
3498
+ ```
3499
+
3500
+ **Props:**
3501
+
3502
+ | Prop | Type | Default | Description |
3503
+ |------|------|---------|-------------|
3504
+ | `kind` | `ComponentKind` | `'neutral'` | Kind color |
3505
+ | `variant` | `SkTagVariant` | `'solid'` | Visual style |
3506
+ | `size` | `SkTagSize` | `'md'` | Tag size |
3507
+ | `removable` | `boolean` | `false` | Show remove button |
3508
+ | `baseColor` | `string` | — | Override via `--sk-tag-color-base` |
3509
+ | `textColor` | `string` | — | Override via `--sk-tag-fg` |
3510
+
3511
+ Content is always wrapped in `sk-tag-content`. The remove button is only emitted when
3512
+ `removable: true`.
3513
+
3514
+ **Output (simple):**
3515
+
3516
+ ```html
3517
+ <span class="sk-tag sk-neutral sk-solid sk-md">
3518
+ <span class="sk-tag-content">Label</span>
3519
+ </span>
3520
+ ```
3521
+
3522
+ **Output (removable):**
3523
+
3524
+ ```html
3525
+ <span class="sk-tag sk-neutral sk-solid sk-md sk-removable">
3526
+ <span class="sk-tag-content">Label</span>
3527
+ <button type="button" class="sk-tag-remove" aria-label="Remove">
3528
+ <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24"
3529
+ viewBox="0 0 24 24" fill="none" stroke="currentColor"
3530
+ stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
3531
+ <line x1="18" y1="6" x2="6" y2="18"></line>
3532
+ <line x1="6" y1="6" x2="18" y2="18"></line>
3533
+ </svg>
3534
+ </button>
3535
+ </span>
3536
+ ```
3537
+
3538
+ ---
3539
+
3540
+ ### avatar {#avatar}
3541
+
3542
+ ```typescript
3543
+ avatar(props?: AvatarStaticProps): string
3544
+ ```
3545
+
3546
+ **Props:**
3547
+
3548
+ | Prop | Type | Default | Description |
3549
+ |------|------|---------|-------------|
3550
+ | `kind` | `ComponentKind` | `'neutral'` | Kind color |
3551
+ | `size` | `SkAvatarSize` | `'md'` | Avatar size |
3552
+ | `src` | `string` | — | Image URL — highest priority |
3553
+ | `alt` | `string` | `''` | Image alt text (used with `src`) |
3554
+ | `initials` | `string` | — | Up to 2 chars shown when no `src` — second priority |
3555
+ | `baseColor` | `string` | — | Override via `--sk-avatar-color-base` |
3556
+ | `textColor` | `string` | — | Override via `--sk-avatar-fg` |
3557
+
3558
+ Note: no `shape` prop — the Vue component doesn't expose one.
3559
+
3560
+ Fallback priority: `src` → `initials` → default person icon SVG.
3561
+
3562
+ **Output (with src):**
3563
+
3564
+ ```html
3565
+ <div class="sk-avatar sk-neutral sk-md">
3566
+ <img src="/avatar.jpg" alt="User name" class="sk-avatar-image">
3567
+ </div>
3568
+ ```
3569
+
3570
+ **Output (with initials "John Doe" → "JO"):**
3571
+
3572
+ ```html
3573
+ <div class="sk-avatar sk-primary sk-md">
3574
+ <span class="sk-avatar-initials">JO</span>
3575
+ </div>
3576
+ ```
3577
+
3578
+ **Output (default fallback):**
3579
+
3580
+ ```html
3581
+ <div class="sk-avatar sk-neutral sk-md">
3582
+ <svg class="sk-avatar-icon" viewBox="0 0 24 24" fill="currentColor">
3583
+ <path d="M12 12c2.21 0 4-1.79 4-4s-1.79-4-4-4-4 1.79-4 4 1.79 4 4 4zm0 2c-2.67 0-8 1.34-8 4v2h16v-2c0-2.66-5.33-4-8-4z"></path>
3584
+ </svg>
3585
+ </div>
3586
+ ```
3587
+
3588
+ ---
3589
+
3590
+ ### field {#field}
3591
+
3592
+ ```typescript
3593
+ field(props?: FieldStaticProps, children?: string): string
3594
+ ```
3595
+
3596
+ **Props:**
3597
+
3598
+ | Prop | Type | Default | Description |
3599
+ |------|------|---------|-------------|
3600
+ | `label` | `string` | — | Label text |
3601
+ | `description` | `string` | — | Help text below the input (suppressed when `error` is set) |
3602
+ | `error` | `string` | — | Error message — also triggers `sk-has-error` class |
3603
+ | `required` | `boolean` | `false` | Adds `*` span to label |
3604
+ | `labelPosition` | `SkFieldLabelPosition` | `'top'` | Label placement |
3605
+ | `id` | `string` | — | Field ID — forwarded to `label[for]` and error/description `id` attrs |
3606
+
3607
+ The `sk-field-input-wrapper` div is always emitted. Label, description, and error paragraphs
3608
+ are only emitted when their props are set. Description is suppressed when an error is present.
3609
+
3610
+ **Output (label + input):**
3611
+
3612
+ ```html
3613
+ <div class="sk-field sk-label-top">
3614
+ <label for="email" class="sk-field-label">Email</label>
3615
+ <div class="sk-field-input-wrapper"><!-- children --></div>
3616
+ </div>
3617
+ ```
3618
+
3619
+ **Output (with error):**
3620
+
3621
+ ```html
3622
+ <div class="sk-field sk-label-top sk-has-error">
3623
+ <label for="email" class="sk-field-label">Email</label>
3624
+ <div class="sk-field-input-wrapper"><!-- children --></div>
3625
+ <p id="email-error" class="sk-field-error">Please enter a valid email.</p>
3626
+ </div>
3627
+ ```
3628
+
3629
+ **Output (required + description):**
3630
+
3631
+ ```html
3632
+ <div class="sk-field sk-label-top">
3633
+ <label for="bio" class="sk-field-label">Bio<span class="sk-field-required">*</span></label>
3634
+ <div class="sk-field-input-wrapper"><!-- children --></div>
3635
+ <p id="bio-description" class="sk-field-description">Max 160 characters.</p>
3636
+ </div>
3637
+ ```
3638
+
3639
+ ---
3640
+
3641
+ ### table {#table}
3642
+
3643
+ ```typescript
3644
+ table(props?: TableStaticProps, children?: string): string
3645
+ ```
3646
+
3647
+ **Props:**
3648
+
3649
+ | Prop | Type | Default | Description |
3650
+ |------|------|---------|-------------|
3651
+ | `kind` | `SkTableKind` | `'neutral'` | Kind color |
3652
+ | `variant` | `SkTableVariant` | `'default'` | Visual variant |
3653
+ | `striped` | `boolean` | `false` | Alternating row backgrounds |
3654
+ | `hoverable` | `boolean` | `true` | Row hover highlight |
3655
+ | `bordered` | `boolean` | `true` | Outer border |
3656
+ | `innerBorders` | `boolean` | `false` | Inner cell borders (suppressed by default) |
3657
+ | `darkBackground` | `boolean` | `false` | Dark background on wrapper |
3658
+ | `subtle` | `boolean` | `false` | Reduced contrast on wrapper + table |
3659
+ | `baseColor` | `string` | — | Override via `--sk-table-color-base` |
3660
+ | `textColor` | `string` | — | Override via `--sk-table-fg` |
3661
+
3662
+ Emits a `sk-table-wrapper` div wrapping a `<table>`. Both elements receive modifier classes.
3663
+
3664
+ **Output (defaults — hoverable + bordered + no-inner-borders):**
3665
+
3666
+ ```html
3667
+ <div class="sk-table-wrapper sk-table-wrapper-neutral">
3668
+ <table class="sk-table sk-neutral sk-default sk-hoverable sk-bordered sk-no-inner-borders">
3669
+ <!-- thead + tbody -->
3670
+ </table>
3671
+ </div>
3672
+ ```
3673
+
3674
+ **Output (striped, inner borders enabled, dark background):**
3675
+
3676
+ ```html
3677
+ <div class="sk-table-wrapper sk-table-wrapper-neutral sk-dark-background">
3678
+ <table class="sk-table sk-neutral sk-default sk-striped sk-hoverable sk-bordered">
3679
+ <!-- thead + tbody -->
3680
+ </table>
3681
+ </div>
3682
+ ```
3683
+
3684
+ ---
3685
+
3686
+ ### tooltip
3687
+
3688
+ ```typescript
3689
+ tooltip(props?: TooltipStaticProps, children?: string): string
3690
+ ```
3691
+
3692
+ **Props:**
3693
+
3694
+ | Prop | Type | Default | Description |
3695
+ |------|------|---------|-------------|
3696
+ | `kind` | `SkTooltipKind` | `'neutral'` | Kind color |
3697
+ | `variant` | `SkTooltipVariant` | `'solid'` | Visual style |
3698
+ | `placement` | `SkTooltipSide` | `'top'` | Tooltip position |
3699
+ | `baseColor` | `string` | — | Custom color override |
3700
+
3701
+ **Output:**
3702
+
3703
+ ```html
3704
+ <div class="sk-tooltip sk-neutral sk-solid sk-placement-top" role="tooltip">
3705
+ <!-- children -->
3706
+ </div>
3707
+ ```
3708
+
3709
+ ---
3710
+
3711
+ ### button
3712
+
3713
+ ```typescript
3714
+ button(props?: ButtonStaticProps, children?: string): string
3715
+ ```
3716
+
3717
+ **Props:**
3718
+
3719
+ | Prop | Type | Default | Description |
3720
+ |------|------|---------|-------------|
3721
+ | `kind` | `SkButtonKind` | `'neutral'` | Kind color |
3722
+ | `size` | `SkButtonSize` | `'md'` | Button size |
3723
+ | `variant` | `SkButtonVariant` | `'solid'` | Visual style |
3724
+ | `type` | `SkButtonType` | `'button'` | HTML button type |
3725
+ | `disabled` | `boolean` | `false` | Disabled state |
3726
+ | `loading` | `boolean` | `false` | Loading state (adds `aria-busy="true"`) |
3727
+ | `pressed` | `boolean` | `false` | Pressed state (adds `aria-pressed="true"`) |
3728
+ | `dense` | `boolean` | `false` | Compact padding |
3729
+ | `href` | `string` | — | Render as `<a>` instead of `<button>` |
3730
+
3731
+ Children are always wrapped in `sk-button-chrome`.
3732
+
3733
+ **Output (button):**
3734
+
3735
+ ```html
3736
+ <button class="sk-button sk-neutral sk-md sk-solid" type="button">
3737
+ <span class="sk-button-chrome">Label</span>
3738
+ </button>
3739
+ ```
3740
+
3741
+ **Output (anchor):**
3742
+
3743
+ ```html
3744
+ <a class="sk-button sk-accent sk-md sk-outline" href="/docs">
3745
+ <span class="sk-button-chrome">Read the docs</span>
3746
+ </a>
3747
+ ```
3748
+
3749
+ ---
3750
+
3751
+ ### input
3752
+
3753
+ ```typescript
3754
+ input(props?: InputStaticProps): string
3755
+ ```
3756
+
3757
+ **Props:** `kind`, `size`, `type`, `value`, `placeholder`, `name`, `id`, `disabled`, `readonly`, `required`
3758
+
3759
+ **Output:**
3760
+
3761
+ ```html
3762
+ <input class="sk-input sk-neutral sk-md" type="text" />
3763
+ ```
3764
+
3765
+ ---
3766
+
3767
+ ### textarea
3768
+
3769
+ ```typescript
3770
+ textarea(props?: TextareaStaticProps, children?: string): string
3771
+ ```
3772
+
3773
+ **Props:** `kind`, `size`, `placeholder`, `name`, `id`, `disabled`, `readonly`, `required`
3774
+
3775
+ **Output:**
3776
+
3777
+ ```html
3778
+ <textarea class="sk-textarea sk-neutral sk-md"></textarea>
3779
+ ```
3780
+
3781
+ ---
3782
+
3783
+ ### select
3784
+
3785
+ ```typescript
3786
+ select(props?: SelectStaticProps, children?: string): string
3787
+ ```
3788
+
3789
+ **Props:** `kind`, `size`, `name`, `id`, `disabled`, `required`
3790
+
3791
+ Children are `<option>` elements composed by the caller.
3792
+
3793
+ **Output:**
3794
+
3795
+ ```html
3796
+ <select class="sk-select sk-neutral sk-md">
3797
+ <option value="">Choose…</option>
3798
+ <option value="a">Option A</option>
3799
+ </select>
3800
+ ```
3801
+
3802
+ ---
3803
+
3804
+ ### slider
3805
+
3806
+ ```typescript
3807
+ slider(props?: SliderStaticProps): string
3808
+ ```
3809
+
3810
+ **Props:** `kind`, `size`, `min`, `max`, `step`, `value`, `name`, `disabled`
3811
+
3812
+ Single thumb only. All numeric props are accepted as strings.
3813
+
3814
+ **Output:**
3815
+
3816
+ ```html
3817
+ <input class="sk-slider sk-neutral sk-md" type="range" min="0" max="100" value="40" />
3818
+ ```
3819
+
3820
+ ---
3821
+
3822
+ ### colorPicker
3823
+
3824
+ ```typescript
3825
+ colorPicker(props?: ColorPickerStaticProps): string
3826
+ ```
3827
+
3828
+ **Props:** `size`, `value`, `name`, `disabled`
3829
+
3830
+ Note: no `kind` prop — ColorPicker has no kind modifier.
3831
+
3832
+ **Output:**
3833
+
3834
+ ```html
3835
+ <input class="sk-color-picker sk-md" type="color" value="#c4842d" />
3836
+ ```
3837
+
3838
+ ---
3839
+
3840
+ ### checkbox
3841
+
3842
+ ```typescript
3843
+ checkbox(props?: CheckboxStaticProps, children?: string): string
3844
+ ```
3845
+
3846
+ **Props:** `kind`, `size`, `checked`, `disabled`, `required`, `name`
3847
+
3848
+ Children become the label text inside `sk-checkbox-label`.
3849
+
3850
+ **Output:**
3851
+
3852
+ ```html
3853
+ <label class="sk-checkbox sk-neutral sk-md">
3854
+ <input type="checkbox" />
3855
+ <span class="sk-checkbox-box"></span>
3856
+ <span class="sk-checkbox-label">I agree to the terms</span>
3857
+ </label>
3858
+ ```
3859
+
3860
+ ---
3861
+
3862
+ ### radio
3863
+
3864
+ ```typescript
3865
+ radio(props?: RadioStaticProps, children?: string): string
3866
+ ```
3867
+
3868
+ **Props:** `kind`, `size`, `name`, `value`, `checked`, `disabled`, `required`
3869
+
3870
+ **Output:**
3871
+
3872
+ ```html
3873
+ <label class="sk-radio sk-neutral sk-md">
3874
+ <input type="radio" name="color" value="red" />
3875
+ <span class="sk-radio-dot"></span>
3876
+ <span class="sk-radio-label">Red</span>
3877
+ </label>
3878
+ ```
3879
+
3880
+ ---
3881
+
3882
+ ### switchInput
3883
+
3884
+ ```typescript
3885
+ switchInput(props?: SwitchStaticProps, children?: string): string
3886
+ ```
3887
+
3888
+ Named `switchInput` because `switch` is a reserved word in TypeScript/JavaScript.
3889
+
3890
+ **Props:** `kind`, `size`, `name`, `checked`, `disabled`, `required`
3891
+
3892
+ **Output:**
3893
+
3894
+ ```html
3895
+ <label class="sk-switch sk-neutral sk-md">
3896
+ <input type="checkbox" />
3897
+ <span class="sk-switch-track">
3898
+ <span class="sk-switch-thumb"></span>
3899
+ </span>
3900
+ <span class="sk-switch-label">Enable notifications</span>
3901
+ </label>
3902
+ ```
3903
+
3904
+ ---
3905
+
3906
+ ### numberInput
3907
+
3908
+ ```typescript
3909
+ numberInput(props?: NumberInputStaticProps): string
3910
+ ```
3911
+
3912
+ Stepper buttons are intentionally omitted — they require JS.
3913
+
3914
+ **Props:** `kind`, `size`, `value`, `min`, `max`, `step`, `name`, `placeholder`, `disabled`, `readonly`, `required`
3915
+
3916
+ **Output:**
3917
+
3918
+ ```html
3919
+ <div class="sk-number-input-wrapper sk-neutral sk-md">
3920
+ <input class="sk-number-input-field" type="number" />
3921
+ </div>
3922
+ ```
3923
+
3924
+ ---
3925
+
3926
+ ### tagsInput
3927
+
3928
+ ```typescript
3929
+ tagsInput(props?: TagsInputStaticProps, children?: string): string
3930
+ ```
3931
+
3932
+ **Props:** `kind`, `size`, `disabled`
3933
+
3934
+ Children are pre-composed `tag()` elements. The add/remove chip behavior requires Vue.
3935
+
3936
+ **Output:**
3937
+
3938
+ ```html
3939
+ <div class="sk-tags-input sk-neutral sk-md">
3940
+ <!-- tag chip elements -->
3941
+ </div>
3942
+ ```
3943
+
3944
+ ---
3945
+
3946
+ ### dropdown
3947
+
3948
+ ```typescript
3949
+ dropdown(props: DropdownStaticProps, children?: string): string
3950
+ ```
3951
+
3952
+ Note: `summary` is a **required** prop.
3953
+
3954
+ **Props:**
3955
+
3956
+ | Prop | Type | Default | Description |
3957
+ |------|------|---------|-------------|
3958
+ | `summary` | `string` | — | **Required.** Text/HTML for the `<summary>` trigger |
3959
+ | `kind` | `SemanticKind` | `'neutral'` | Kind color |
3960
+ | `size` | `'sm' \| 'md' \| 'lg'` | `'md'` | Size |
3961
+ | `open` | `boolean` | `false` | Initial open state |
3962
+
3963
+ This is a disclosure widget (`<details>`), not a menu. No focus trap, no keyboard navigation.
3964
+
3965
+ **Output:**
3966
+
3967
+ ```html
3968
+ <details class="sk-dropdown sk-neutral sk-md">
3969
+ <summary>Options ▾</summary>
3970
+ <!-- children -->
3971
+ </details>
3972
+ ```
3973
+
3974
+ ---
3975
+
3976
+ ## Type safety notes
3977
+
3978
+ All helpers export their props interface. Import them if you want to type your own wrapper:
3979
+
3980
+ ```typescript
3981
+ import type { PanelStaticProps } from '@skewedaspect/sleekspace-ui/static';
3982
+
3983
+ function myPanel(props: PanelStaticProps, content: string): string {
3984
+ return panel(props, content);
3985
+ }
3986
+ ```
3987
+
3988
+ # Pure-CSS Limitations
3989
+
3990
+ Let's be direct: pure-CSS Sleekspace is not Sleekspace. It's the presentational subset — the
3991
+ parts that are just CSS talking to HTML structure. If you need interactivity, you need Vue.
3992
+
3993
+ This page tells you exactly what that means so you can make the right call before you start.
3994
+
3995
+ ---
3996
+
3997
+ ## What's completely out of scope
3998
+
3999
+ These components are Vue-only. There is no class-API, custom-element, or static-helper form
4000
+ for them, and there won't be — they fundamentally require JS state management.
4001
+
4002
+ ### Modal, Popover, ContextMenu, Toast
4003
+
4004
+ All four require:
4005
+ - Portal/teleport rendering to a document-level container
4006
+ - Focus trapping and restoration
4007
+ - Escape-key and click-outside dismiss
4008
+ - ARIA attributes that change dynamically (`aria-expanded`, `aria-modal`)
4009
+
4010
+ You cannot replicate a production-quality modal with CSS alone. Use the Vue components.
4011
+
4012
+ ### Tabs, Accordion, Collapsible, TreeView
4013
+
4014
+ These are state machines:
4015
+ - Tabs track which panel is active, activate on click/keyboard, and update `aria-selected`
4016
+ - Accordion and Collapsible manage open/closed state and animate height
4017
+ - TreeView manages selection, expansion, keyboard navigation (arrow keys, Home/End)
4018
+
4019
+ The `<details>` / CSS `:checked` tricks can approximate some of this for simple cases, but
4020
+ they break on complex trees, keyboard navigation, and multi-open scenarios. The Vue versions
4021
+ are correct; the CSS approximations are not.
4022
+
4023
+ ### Listbox, ScrollArea, Splitter
4024
+
4025
+ - **Listbox** — needs selection state, keyboard navigation, and `aria-activedescendant`
4026
+ - **ScrollArea** — provides custom scrollbars via overflow regions; the pure-CSS scroll
4027
+ styling applies to native scrollbars, not the JS-managed virtualized variant
4028
+ - **Splitter** — requires pointer capture and drag tracking to resize panes
4029
+
4030
+ ---
4031
+
4032
+ ## What's in scope but reduced
4033
+
4034
+ These components exist in the pure-CSS layer but are missing capabilities present in the
4035
+ Vue versions.
4036
+
4037
+ ### Slider — single thumb only
4038
+
4039
+ The static helper and class API render `<input type="range">`, which is inherently single-thumb.
4040
+ The Vue `SkSlider` supports dual-thumb range selection via two overlapping range inputs managed
4041
+ in JS. There is no CSS-only dual-thumb solution.
4042
+
4043
+ **What you get:** A fully styled single-thumb slider with kind + size modifiers.
4044
+ **What's missing:** `min`/`max` value range selection (dual thumb).
4045
+
4046
+ ### Dropdown — `<details>` disclosure, not a menu
4047
+
4048
+ The static helper renders `<details class="sk-dropdown"><summary>…</summary>…</details>`.
4049
+ This gives you a zero-JS disclosure widget that opens and closes. It is **not** a menu:
4050
+ - No focus trap
4051
+ - No arrow-key navigation between items
4052
+ - No `role="menu"` / `role="menuitem"` semantics
4053
+ - Items don't get `aria-checked` or keyboard activation
4054
+
4055
+ Use this for simple show/hide disclosure patterns. For actual menus (accessible, keyboard-navigable
4056
+ dropdowns), use the Vue `SkDropdown`.
4057
+
4058
+ ### Select — popup styling is Chromium-only
4059
+
4060
+ The class API applies `sk-select` to a native `<select>`. The closed button state (the
4061
+ select trigger) is fully cross-browser styled. However, the open popup panel (the dropdown
4062
+ list of options) only supports `appearance: base-select` styling in Chromium-based browsers
4063
+ (Chrome, Edge) as of 2026. Firefox and Safari show the native OS popup.
4064
+
4065
+ If cross-browser custom select styling matters, use the Vue `SkSelect` which uses a custom
4066
+ floating-UI panel in all browsers.
4067
+
4068
+ ### ColorPicker — native swatch only
4069
+
4070
+ The static helper renders `<input type="color">`. This gives you a styled color swatch button
4071
+ that opens the browser's native color picker on click. It respects the `size` modifier.
4072
+
4073
+ **What's missing:**
4074
+ - The OKLCH palette panel
4075
+ - Hex / RGB / HSL / OKLCH format switching
4076
+ - The alpha channel slider
4077
+ - Any kind of themed appearance inside the popup (that's browser chrome)
4078
+
4079
+ Use Vue `SkColorPicker` for the full-featured picker.
4080
+
4081
+ ### Alert, Spinner, NavBar, Sidebar, Tag, Avatar, Field, Table — inner DOM not auto-injected by custom elements
4082
+
4083
+ The static helpers and Vue components for these 8 components emit an inner DOM structure beyond
4084
+ the root element (icon wrappers, content wrappers, inner panels, etc.). The custom-element
4085
+ form applies CSS via attribute selectors but does **not** inject this inner DOM — you must
4086
+ write it yourself when using `<sk-alert>`, `<sk-spinner>`, etc. as custom elements.
4087
+
4088
+ Use the [static helpers](./static-helpers.md) or [class API examples](./class-api.md) to see
4089
+ the expected inner structure for each component.
4090
+
4091
+ ---
4092
+
4093
+ ## Browser caveats
4094
+
4095
+ ### `corner-shape: bevel`
4096
+
4097
+ Sleekspace's beveled corners use `corner-shape: bevel` (CSS Shapes Level 2). This is supported
4098
+ in modern Chrome and emerging in other engines. Older browsers fall back to `clip-path: polygon(…)`
4099
+ which preserves the visual shape but loses the border rendering on cut edges. The fallback is
4100
+ provided automatically — no author action needed.
4101
+
4102
+ ### `color-mix(in oklch, …)`
4103
+
4104
+ Theme colors are computed with `color-mix()` in the OKLCH color space for perceptually uniform
4105
+ mixing. This requires a modern browser (Chrome 111+, Firefox 113+, Safari 16.2+). Older browsers
4106
+ see the fallback static color values baked into the CSS custom properties.
4107
+
4108
+ ### `:where(:not(…))` chains
4109
+
4110
+ Default modifier behavior (e.g., applying `sk-neutral` styles when no `kind` attribute is
4111
+ set) uses zero-specificity `:where()` with negation chains. This requires browsers that
4112
+ support `:where()` — all evergreen browsers since 2021. IE11 is not supported and never will be.
4113
+
4114
+ ---
4115
+
4116
+ ## When to reach for Vue instead
4117
+
4118
+ Use the pure-CSS layer when:
4119
+ - You're building a static site (VitePress, Astro, 11ty) and want Sleekspace visuals without JS
4120
+ - You need the CSS for a non-JS environment (email templates, print stylesheets)
4121
+ - You're prototyping layout and just need the styling primitives
4122
+ - You want the look of Sleekspace in a non-Vue app (React, Svelte, plain HTML)
4123
+
4124
+ Reach for the Vue components when:
4125
+ - You need any interactive component (Modal, Tabs, Accordion, etc.)
4126
+ - You need a production-quality Dropdown with keyboard navigation
4127
+ - You need dual-thumb Slider
4128
+ - You need cross-browser custom Select styling
4129
+ - You need the full ColorPicker palette UI
4130
+ - You need form validation integration (Vue components emit update events and expose validation state)
4131
+ - You need theme switching at runtime (Vue components react to the reactive theme store)
4132
+
4133
+ The answer isn't always "use Vue." For purely presentational output — especially build-time
4134
+ HTML generation — the pure-CSS layer is lighter and perfectly correct.
4135
+
4136
+
4137
+ ---
4138
+
4139
+ # AI & LLMs
4140
+
4141
+ SleekSpace UI ships with LLM-friendly documentation files that make it easy for AI assistants like Claude, ChatGPT, GitHub Copilot, and Cursor to understand and help with the library.
4142
+
4143
+ ## Available Files
4144
+
4145
+ Two documentation files are available, optimized for different use cases:
4146
+
4147
+ | File | Size | Best For |
4148
+ |------|------|----------|
4149
+ | `llms.txt` | ~7 KB | Quick context, token-efficient prompts |
4150
+ | `llms-full.txt` | ~196 KB | Complete reference, in-depth help |
4151
+
4152
+ **llms.txt** is a concise index with component summaries. It gives AI assistants enough context to understand what the library offers and how components work together.
4153
+
4154
+ **llms-full.txt** is the complete reference. It includes all guide documentation, every component's usage examples, and full API reference tables with all props, slots, and events.
4155
+
4156
+ ## How to Use
4157
+
4158
+ ### AI-Powered IDEs (Claude Code, Cursor, Windsurf)
4159
+
4160
+ Point your AI assistant to fetch the documentation from our docs site:
4161
+
4162
+ - https://sleekspace.skewedaspect.com/llms.txt
4163
+ - https://sleekspace.skewedaspect.com/llms-full.txt
4164
+
4165
+ Example: "Fetch https://sleekspace.skewedaspect.com/llms.txt and help me create a form with validation."
4166
+
4167
+ ### Web-Based AI (ChatGPT, Claude.ai)
4168
+
4169
+ Direct the AI to read the documentation URLs:
4170
+
4171
+ Example prompt:
4172
+
4173
+ > "Read https://sleekspace.skewedaspect.com/llms.txt and then help me create a themed dashboard layout."
4174
+
4175
+ ### Paste Into Context
4176
+
4177
+ For quick questions, copy the content of `llms.txt` and paste it into your conversation. For in-depth help with complex implementations, use `llms-full.txt`.
4178
+
4179
+ ## What's Included
4180
+
4181
+ The documentation files contain:
4182
+
4183
+ - **All guides** -- Installation, theming, design tokens, custom colors
4184
+ - **Every component** -- Usage examples and documentation for all 46 components
4185
+ - **Complete API reference** -- Props, slots, and events in structured tables
4186
+ - **Best practices** -- Common patterns and recommended approaches
4187
+
4188
+ The files are auto-generated from the source documentation, so they stay in sync with the library.
4189
+
4190
+ ## Why This Matters
4191
+
4192
+ AI assistants work best when they have accurate, up-to-date context about the tools you are using. With these files:
4193
+
4194
+ - **Accurate help** -- AI responses are based on real documentation, not training data that may be outdated
4195
+ - **No hallucinations** -- Props, events, and usage patterns match what the library actually provides
4196
+ - **Better suggestions** -- AI can recommend appropriate components, theming approaches, and composition patterns
4197
+ - **Faster development** -- Get library-specific help without searching through documentation manually
4198
+
4199
+
4200
+ ---
4201
+
4202
+
4203
+ # Components
4204
+
4205
+ # SkAccordion
4206
+
4207
+ A collapsible sections container for organizing content into expandable panels. Supports single or multiple open items with smooth animations. Built on RekaUI's Accordion primitive with full WAI-ARIA support.
4208
+
4209
+
4210
+ Use `v-model` to control which item is open. In single mode (default), only one item can be open at a time. Each `SkAccordionItem` requires a unique `value` prop.
4211
+
4212
+ ```vue
4213
+ <script setup>
4214
+ import { ref } from 'vue';
4215
+
4216
+ const openItem = ref('item-1');
4217
+ </script>
4218
+
4219
+ <template>
4220
+ <SkAccordion v-model="openItem" kind="primary">
4221
+ <SkAccordionItem value="item-1" title="What is SleekSpace UI?">
4222
+ SleekSpace UI is a Vue 3 component library...
4223
+ </SkAccordionItem>
4224
+ <SkAccordionItem value="item-2" title="How do I install it?">
4225
+ Install via npm...
4226
+ </SkAccordionItem>
4227
+ <SkAccordionItem value="item-3" title="Is it customizable?">
4228
+ Yes! Every component supports custom colors...
4229
+ </SkAccordionItem>
4230
+ </SkAccordion>
4231
+ </template>
4232
+ ```
4233
+
4234
+
4235
+ Set `type="multiple"` to allow multiple items open simultaneously. The `v-model` becomes an array of open item values.
4236
+
4237
+ ```vue
4238
+ <script setup>
4239
+ import { ref } from 'vue';
4240
+
4241
+ const openItems = ref(['feature-1', 'feature-2']);
4242
+ </script>
4243
+
4244
+ <template>
4245
+ <SkAccordion v-model="openItems" type="multiple" kind="accent">
4246
+ <SkAccordionItem value="feature-1" title="Theming">
4247
+ Full theme support...
4248
+ </SkAccordionItem>
4249
+ <SkAccordionItem value="feature-2" title="Accessibility">
4250
+ ARIA compliant...
4251
+ </SkAccordionItem>
4252
+ <SkAccordionItem value="feature-3" title="Performance">
4253
+ Optimized animations...
4254
+ </SkAccordionItem>
4255
+ </SkAccordion>
4256
+ </template>
4257
+ ```
4258
+
4259
+
4260
+ All seven semantic kinds adapt to your theme colors. The `kind` prop on SkAccordion is inherited by all child items, but individual items can override with their own `kind` prop.
4261
+
4262
+ ```vue
4263
+ <SkAccordion kind="neutral">
4264
+ <SkAccordionItem value="n1" title="Neutral">Content</SkAccordionItem>
4265
+ </SkAccordion>
4266
+ <SkAccordion kind="primary">
4267
+ <SkAccordionItem value="p1" title="Primary">Content</SkAccordionItem>
4268
+ </SkAccordion>
4269
+ <SkAccordion kind="accent">
4270
+ <SkAccordionItem value="a1" title="Accent">Content</SkAccordionItem>
4271
+ </SkAccordion>
4272
+ <SkAccordion kind="success">
4273
+ <SkAccordionItem value="s1" title="Success">Content</SkAccordionItem>
4274
+ </SkAccordion>
4275
+ <SkAccordion kind="warning">
4276
+ <SkAccordionItem value="w1" title="Warning">Content</SkAccordionItem>
4277
+ </SkAccordion>
4278
+ <SkAccordion kind="danger">
4279
+ <SkAccordionItem value="d1" title="Danger">Content</SkAccordionItem>
4280
+ </SkAccordion>
4281
+ <SkAccordion kind="info">
4282
+ <SkAccordionItem value="i1" title="Info">Content</SkAccordionItem>
4283
+ </SkAccordion>
4284
+ ```
4285
+
4286
+
4287
+ Override the kind with custom `baseColor` and `textColor` props. Supports hex, OKLCH, or any valid CSS color value.
4288
+
4289
+ ```vue
4290
+ <SkAccordion base-color="#8B5CF6" collapsible>
4291
+ <SkAccordionItem value="c1" title="Custom Purple">
4292
+ Using hex color #8B5CF6
4293
+ </SkAccordionItem>
4294
+ </SkAccordion>
4295
+
4296
+ <SkAccordion base-color="oklch(0.75 0.2 180)" collapsible>
4297
+ <SkAccordionItem value="c2" title="Custom Teal">
4298
+ Using OKLCH color
4299
+ </SkAccordionItem>
4300
+ </SkAccordion>
4301
+ ```
4302
+
4303
+
4304
+ Classic use case for accordions - frequently asked questions. Set `collapsible` in single mode to allow closing all items.
4305
+
4306
+ ```vue
4307
+ <script setup>
4308
+ import { ref } from 'vue';
4309
+
4310
+ const faqOpen = ref('faq-1');
4311
+ </script>
4312
+
4313
+ <template>
4314
+ <SkAccordion v-model="faqOpen" kind="info" collapsible>
4315
+ <SkAccordionItem value="faq-1" title="Do you offer a free trial?">
4316
+ Yes! We offer a 14-day free trial...
4317
+ </SkAccordionItem>
4318
+ <SkAccordionItem value="faq-2" title="Can I cancel anytime?">
4319
+ Absolutely. You can cancel your subscription...
4320
+ </SkAccordionItem>
4321
+ <SkAccordionItem value="faq-3" title="What payment methods do you accept?">
4322
+ We accept all major credit cards...
4323
+ </SkAccordionItem>
4324
+ <SkAccordionItem value="faq-4" title="Is my data secure?">
4325
+ Yes. We use bank-level encryption...
4326
+ </SkAccordionItem>
4327
+ </SkAccordion>
4328
+ </template>
4329
+ ```
4330
+
4331
+
4332
+ ### Props
4333
+
4334
+ | Prop | Type | Default | Required | Description |
4335
+ |------|------|---------|----------|-------------|
4336
+ | borderColor | string | — | false | Border color for the component. Accepts the same kind names and CSS color values as
4337
+ `baseColor`. Only honoured by components that render a visible border (panels, cards,
4338
+ inputs, etc.); ignored elsewhere. |
4339
+ | textColor | string | — | false | Text/foreground color for the component. Accepts the same kind names and CSS color values
4340
+ as `baseColor`. If not provided, falls back to the theme's neutral text color for legibility
4341
+ on arbitrary custom backgrounds. |
4342
+ | baseColor | string | — | false | Base color for the component. Accepts either:
4343
+ - A SleekSpace kind name: `"neutral"`, `"primary"`, `"accent"`, `"info"`, `"success"`,
4344
+ `"warning"`, `"danger"`, `"neon-blue"`, `"light-blue"`, `"neon-orange"`,
4345
+ `"neon-purple"`, `"neon-green"`, `"neon-mint"`, `"neon-pink"`, `"yellow"`, `"red"`,
4346
+ `"boulder"` — resolves to the matching `--sk-<kind>-base` token.
4347
+ - Any CSS color value: hex (`"#8B5CF6"`), oklch (`"oklch(0.7 0.25 300)"`),
4348
+ rgb/hsl (`"rgb(139, 92, 246)"`), a CSS variable (`"var(--my-color)"`), or a
4349
+ named color (`"rebeccapurple"`).
4350
+
4351
+ When provided, this overrides the color from the `kind` prop. |
4352
+ | type | "single" \| "multiple" | 'single' | false | Controls whether one or multiple accordion items can be open simultaneously.
4353
+ In 'single' mode, opening a new item automatically closes the previously open item.
4354
+ In 'multiple' mode, users can expand any number of items independently. |
4355
+ | modelValue | string \| string[] | undefined | false | The value(s) of currently open accordion item(s). Use with `v-model` for two-way binding.
4356
+ In 'single' mode, this is a string matching one item's `value` prop.
4357
+ In 'multiple' mode, this is an array of strings matching multiple items' `value` props. |
4358
+ | collapsible | boolean | false | false | When true and in 'single' mode, allows all items to be collapsed by clicking the open item again.
4359
+ When false, one item must always remain open (the first click selects, subsequent clicks don't collapse).
4360
+ This prop has no effect in 'multiple' mode where items are always independently collapsible. |
4361
+ | kind | "neutral" \| "primary" \| "accent" \| "danger" \| "info" \| "success" \| "warning" \| "boulder" \| "neon-blue" \| "light-blue" \| "neon-orange" \| "neon-purple" \| "neon-green" \| "neon-mint" \| "neon-pink" \| "yellow" \| "red" | 'neutral' | false | Semantic color kind that controls the accordion's header and border colors. The kind is automatically
4362
+ inherited by all child SkAccordionItem components unless they specify their own kind.
4363
+ Semantic kinds (neutral, primary, accent, etc.) adapt to your theme. |
4364
+ | disabled | boolean | false | false | When true, disables all accordion items. Items cannot be expanded or collapsed, and
4365
+ the accordion appears with reduced opacity. Individual items can also be disabled
4366
+ independently via their own `disabled` prop. |
4367
+
4368
+ ### Slots
4369
+
4370
+ | Slot | Description |
4371
+ |------|-------------|
4372
+ | default | Container for SkAccordionItem components. Each item becomes a collapsible section. |
4373
+
4374
+ ### Events
4375
+
4376
+ | Event | Description |
4377
+ |-------|-------------|
4378
+ | update:modelValue | |
4379
+
4380
+
4381
+ ---
4382
+
4383
+ # SkAlert
4384
+
4385
+ A feedback component for displaying informational messages. Each kind renders a corresponding icon (info circle, checkmark, warning triangle, or error cross) alongside the message content. Renders with `role="alert"` for screen reader announcements.
4386
+
4387
+
4388
+ Use alerts to provide feedback, display status, or draw attention to important information. Each kind includes an appropriate default icon.
4389
+
4390
+ ```vue
4391
+ <SkAlert kind="info">
4392
+ This is an informational alert message. Use it to provide helpful information to users.
4393
+ </SkAlert>
4394
+ ```
4395
+
4396
+
4397
+ Four semantic kinds with built-in icons: `info` for information, `success` for positive feedback, `warning` for caution, and `danger` for errors or critical messages.
4398
+
4399
+ ```vue
4400
+ <SkAlert kind="info">
4401
+ <strong>Info:</strong> Your changes will be saved automatically.
4402
+ </SkAlert>
4403
+
4404
+ <SkAlert kind="success">
4405
+ <strong>Success:</strong> Your profile has been updated successfully.
4406
+ </SkAlert>
4407
+
4408
+ <SkAlert kind="warning">
4409
+ <strong>Warning:</strong> This action cannot be undone.
4410
+ </SkAlert>
4411
+
4412
+ <SkAlert kind="danger">
4413
+ <strong>Error:</strong> Failed to save changes. Please try again.
4414
+ </SkAlert>
4415
+ ```
4416
+
4417
+
4418
+ Use `prominent` for critical messages that require immediate attention. Prominent alerts have stronger colors and increased visual weight.
4419
+
4420
+ ```vue
4421
+ <SkAlert kind="info" :prominent="true">
4422
+ <strong>System Maintenance:</strong> The system will undergo scheduled maintenance on Sunday at 2 AM UTC.
4423
+ </SkAlert>
4424
+
4425
+ <SkAlert kind="warning" :prominent="true">
4426
+ <strong>Storage Limit:</strong> You're using 95% of your storage space.
4427
+ </SkAlert>
4428
+ ```
4429
+
4430
+
4431
+ Alerts can contain any content including headings, paragraphs, lists, buttons, and links for comprehensive messaging.
4432
+
4433
+ ```vue
4434
+ <SkAlert kind="info">
4435
+ <h4 class="font-semibold mb-2">New Features Available</h4>
4436
+ <p class="mb-2">We've added several new features to improve your experience:</p>
4437
+ <ul class="list-disc list-inside mb-3 space-y-1">
4438
+ <li>Dark mode support</li>
4439
+ <li>Keyboard shortcuts</li>
4440
+ <li>Export to PDF</li>
4441
+ </ul>
4442
+ <SkButton size="sm" kind="info">Learn More</SkButton>
4443
+ </SkAlert>
4444
+ ```
4445
+
4446
+
4447
+ Override the default icon using the `icon` slot for custom branding or specific message types.
4448
+
4449
+ ```vue
4450
+ <SkAlert kind="info">
4451
+ <template #icon>
4452
+ <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
4453
+ <path d="M12 2l3.09 6.26L22 9.27l-5 4.87 1.18 6.88L12 17.77l-6.18 3.25L7 14.14 2 9.27l6.91-1.01L12 2z" />
4454
+ </svg>
4455
+ </template>
4456
+ <strong>Pro Tip:</strong> Use keyboard shortcut Ctrl+S to save your work quickly.
4457
+ </SkAlert>
4458
+ ```
4459
+
4460
+
4461
+ Use `base-color` for any CSS color value. Provide `text-color` for optimal contrast, or it will default to the theme's neutral text color.
4462
+
4463
+ ```vue
4464
+ <SkAlert
4465
+ base-color="oklch(0.65 0.25 280)"
4466
+ text-color="white"
4467
+ >
4468
+ <strong>Custom Purple:</strong> This alert uses a custom purple base color with white text.
4469
+ </SkAlert>
4470
+
4471
+ <SkAlert
4472
+ base-color="oklch(0.75 0.2 150)"
4473
+ text-color="oklch(0.2 0.05 150)"
4474
+ >
1385
4475
  <strong>Custom Green:</strong> A custom green alert with manually specified text color.
1386
4476
  </SkAlert>
1387
4477
 
@@ -1399,6 +4489,22 @@ Use `base-color` for any CSS color value. Provide `text-color` for optimal contr
1399
4489
 
1400
4490
  | Prop | Type | Default | Required | Description |
1401
4491
  |------|------|---------|----------|-------------|
4492
+ | borderColor | string | — | false | Border color for the component. Accepts the same kind names and CSS color values as
4493
+ `baseColor`. Only honoured by components that render a visible border (panels, cards,
4494
+ inputs, etc.); ignored elsewhere. |
4495
+ | textColor | string | — | false | Text/foreground color for the component. Accepts the same kind names and CSS color values
4496
+ as `baseColor`. If not provided, falls back to the theme's neutral text color for legibility
4497
+ on arbitrary custom backgrounds. |
4498
+ | baseColor | string | — | false | Base color for the component. Accepts either:
4499
+ - A SleekSpace kind name: `"neutral"`, `"primary"`, `"accent"`, `"info"`, `"success"`,
4500
+ `"warning"`, `"danger"`, `"neon-blue"`, `"light-blue"`, `"neon-orange"`,
4501
+ `"neon-purple"`, `"neon-green"`, `"neon-mint"`, `"neon-pink"`, `"yellow"`, `"red"`,
4502
+ `"boulder"` — resolves to the matching `--sk-<kind>-base` token.
4503
+ - Any CSS color value: hex (`"#8B5CF6"`), oklch (`"oklch(0.7 0.25 300)"`),
4504
+ rgb/hsl (`"rgb(139, 92, 246)"`), a CSS variable (`"var(--my-color)"`), or a
4505
+ named color (`"rebeccapurple"`).
4506
+
4507
+ When provided, this overrides the color from the `kind` prop. |
1402
4508
  | kind | "neutral" \| "primary" \| "accent" \| "danger" \| "info" \| "success" \| "warning" \| "boulder" \| "neon-blue" \| "light-blue" \| "neon-orange" \| "neon-purple" \| "neon-green" \| "neon-mint" \| "neon-pink" \| "yellow" \| "red" | 'info' | false | Semantic kind that determines the alert's color scheme and default icon. Supports all
1403
4509
  semantic kinds (neutral, primary, accent, info, success, warning, danger) as well as
1404
4510
  direct color kinds (neon-blue, neon-purple, etc.). Default icons are provided for the
@@ -1535,7 +4641,8 @@ displaying initials or the fallback icon. |
1535
4641
 
1536
4642
  | Slot | Description |
1537
4643
  |------|-------------|
1538
- | icon | Custom fallback icon displayed when no image or initials are provided. Defaults to a generic user silhouette icon. Use for bots, system users, or other non-person entities. |
4644
+ | icon | Custom fallback icon displayed when no image or initials are provided. Defaults to a generic
4645
+ user silhouette icon. Use for bots, system users, or other non-person entities. |
1539
4646
 
1540
4647
 
1541
4648
  ---
@@ -1625,6 +4732,9 @@ Common usage patterns including e-commerce navigation, application settings, and
1625
4732
 
1626
4733
  | Prop | Type | Default | Required | Description |
1627
4734
  |------|------|---------|----------|-------------|
4735
+ | borderColor | string | — | false | Border color for the component. Accepts the same kind names and CSS color values as
4736
+ `baseColor`. Only honoured by components that render a visible border (panels, cards,
4737
+ inputs, etc.); ignored elsewhere. |
1628
4738
  | textColor | string | undefined | false | |
1629
4739
  | baseColor | string | undefined | false | |
1630
4740
  | kind | TSIndexedAccessType | 'neutral' | false | Semantic color kind that controls the appearance of breadcrumb links. The kind affects link colors
@@ -1633,6 +4743,12 @@ for normal, hover, and active states. All child `SkBreadcrumbItem` components in
1633
4743
  unicode characters like '\u203A' (single right-pointing angle quotation mark). Can be overridden
1634
4744
  on individual `SkBreadcrumbSeparator` components for custom patterns. |
1635
4745
 
4746
+ ### Slots
4747
+
4748
+ | Slot | Description |
4749
+ |------|-------------|
4750
+ | default | Contains `SkBreadcrumbItem` components representing each level in the navigation hierarchy. |
4751
+
1636
4752
 
1637
4753
  ---
1638
4754
 
@@ -1774,6 +4890,22 @@ When using icon-only buttons, provide an `aria-label` for screen readers:
1774
4890
 
1775
4891
  | Prop | Type | Default | Required | Description |
1776
4892
  |------|------|---------|----------|-------------|
4893
+ | borderColor | string | — | false | Border color for the component. Accepts the same kind names and CSS color values as
4894
+ `baseColor`. Only honoured by components that render a visible border (panels, cards,
4895
+ inputs, etc.); ignored elsewhere. |
4896
+ | textColor | string | — | false | Text/foreground color for the component. Accepts the same kind names and CSS color values
4897
+ as `baseColor`. If not provided, falls back to the theme's neutral text color for legibility
4898
+ on arbitrary custom backgrounds. |
4899
+ | baseColor | string | — | false | Base color for the component. Accepts either:
4900
+ - A SleekSpace kind name: `"neutral"`, `"primary"`, `"accent"`, `"info"`, `"success"`,
4901
+ `"warning"`, `"danger"`, `"neon-blue"`, `"light-blue"`, `"neon-orange"`,
4902
+ `"neon-purple"`, `"neon-green"`, `"neon-mint"`, `"neon-pink"`, `"yellow"`, `"red"`,
4903
+ `"boulder"` — resolves to the matching `--sk-<kind>-base` token.
4904
+ - Any CSS color value: hex (`"#8B5CF6"`), oklch (`"oklch(0.7 0.25 300)"`),
4905
+ rgb/hsl (`"rgb(139, 92, 246)"`), a CSS variable (`"var(--my-color)"`), or a
4906
+ named color (`"rebeccapurple"`).
4907
+
4908
+ When provided, this overrides the color from the `kind` prop. |
1777
4909
  | type | "button" \| "submit" \| "reset" | 'button' | false | The HTML `type` attribute for the button element. Only applies when rendering as a `<button>`
1778
4910
  (i.e., when neither `href` nor `to` props are provided). Use 'submit' for form submission
1779
4911
  buttons and 'reset' for form reset buttons. |
@@ -1931,6 +5063,22 @@ Remove the corner decoration for a cleaner, more minimalist appearance using the
1931
5063
 
1932
5064
  | Prop | Type | Default | Required | Description |
1933
5065
  |------|------|---------|----------|-------------|
5066
+ | borderColor | string | — | false | Border color for the component. Accepts the same kind names and CSS color values as
5067
+ `baseColor`. Only honoured by components that render a visible border (panels, cards,
5068
+ inputs, etc.); ignored elsewhere. |
5069
+ | textColor | string | — | false | Text/foreground color for the component. Accepts the same kind names and CSS color values
5070
+ as `baseColor`. If not provided, falls back to the theme's neutral text color for legibility
5071
+ on arbitrary custom backgrounds. |
5072
+ | baseColor | string | — | false | Base color for the component. Accepts either:
5073
+ - A SleekSpace kind name: `"neutral"`, `"primary"`, `"accent"`, `"info"`, `"success"`,
5074
+ `"warning"`, `"danger"`, `"neon-blue"`, `"light-blue"`, `"neon-orange"`,
5075
+ `"neon-purple"`, `"neon-green"`, `"neon-mint"`, `"neon-pink"`, `"yellow"`, `"red"`,
5076
+ `"boulder"` — resolves to the matching `--sk-<kind>-base` token.
5077
+ - Any CSS color value: hex (`"#8B5CF6"`), oklch (`"oklch(0.7 0.25 300)"`),
5078
+ rgb/hsl (`"rgb(139, 92, 246)"`), a CSS variable (`"var(--my-color)"`), or a
5079
+ named color (`"rebeccapurple"`).
5080
+
5081
+ When provided, this overrides the color from the `kind` prop. |
1934
5082
  | kind | "neutral" \| "primary" \| "accent" \| "danger" \| "info" \| "success" \| "warning" \| "boulder" \| "neon-blue" \| "light-blue" \| "neon-orange" \| "neon-purple" \| "neon-green" \| "neon-mint" \| "neon-pink" \| "yellow" \| "red" | 'neutral' | false | Semantic color kind that controls the card's border color and decorative accent stripe.
1935
5083
  Semantic kinds (neutral, primary, accent, etc.) automatically adapt to your current theme,
1936
5084
  while color kinds (neon-blue, neon-purple, etc.) provide fixed branding colors. |
@@ -1962,10 +5110,13 @@ to take effect. Header and footer remain fixed while content scrolls. |
1962
5110
 
1963
5111
  | Slot | Description |
1964
5112
  |------|-------------|
1965
- | header | Custom header content. Renders alongside or instead of the `title` prop. Use for action buttons, badges, or complex header layouts. |
1966
- | media | Media content area (images, videos, etc.) that spans the full width without padding. Displays between the header and content sections. |
5113
+ | header | Custom header content. Renders alongside or instead of the `title` prop. Use for action buttons,
5114
+ badges, or complex header layouts. |
5115
+ | media | Media content area (images, videos, etc.) that spans the full width without padding. Displays
5116
+ between the header and content sections. |
1967
5117
  | default | The main content area of the card. Displays below the header and media sections. |
1968
- | footer | Footer content area for actions, links, or metadata. Displays at the bottom of the card with appropriate spacing. |
5118
+ | footer | Footer content area for actions, links, or metadata. Displays at the bottom of the card with
5119
+ appropriate spacing. |
1969
5120
 
1970
5121
 
1971
5122
  ---
@@ -2080,6 +5231,22 @@ const newsletter = ref(false)
2080
5231
 
2081
5232
  | Prop | Type | Default | Required | Description |
2082
5233
  |------|------|---------|----------|-------------|
5234
+ | borderColor | string | — | false | Border color for the component. Accepts the same kind names and CSS color values as
5235
+ `baseColor`. Only honoured by components that render a visible border (panels, cards,
5236
+ inputs, etc.); ignored elsewhere. |
5237
+ | textColor | string | — | false | Text/foreground color for the component. Accepts the same kind names and CSS color values
5238
+ as `baseColor`. If not provided, falls back to the theme's neutral text color for legibility
5239
+ on arbitrary custom backgrounds. |
5240
+ | baseColor | string | — | false | Base color for the component. Accepts either:
5241
+ - A SleekSpace kind name: `"neutral"`, `"primary"`, `"accent"`, `"info"`, `"success"`,
5242
+ `"warning"`, `"danger"`, `"neon-blue"`, `"light-blue"`, `"neon-orange"`,
5243
+ `"neon-purple"`, `"neon-green"`, `"neon-mint"`, `"neon-pink"`, `"yellow"`, `"red"`,
5244
+ `"boulder"` — resolves to the matching `--sk-<kind>-base` token.
5245
+ - Any CSS color value: hex (`"#8B5CF6"`), oklch (`"oklch(0.7 0.25 300)"`),
5246
+ rgb/hsl (`"rgb(139, 92, 246)"`), a CSS variable (`"var(--my-color)"`), or a
5247
+ named color (`"rebeccapurple"`).
5248
+
5249
+ When provided, this overrides the color from the `kind` prop. |
2083
5250
  | kind | "neutral" \| "primary" \| "accent" \| "danger" \| "info" \| "success" \| "warning" \| "boulder" \| "neon-blue" \| "light-blue" \| "neon-orange" \| "neon-purple" \| "neon-green" \| "neon-mint" \| "neon-pink" \| "yellow" \| "red" | 'neutral' | false | Semantic color kind that controls the checkbox appearance when checked. Semantic kinds
2084
5251
  (neutral, primary, accent, etc.) adapt to your theme, while color kinds (neon-blue,
2085
5252
  neon-purple, etc.) provide fixed branding colors. |
@@ -2192,6 +5359,22 @@ Built on RekaUI Collapsible which provides `aria-expanded` on the trigger and `a
2192
5359
 
2193
5360
  | Prop | Type | Default | Required | Description |
2194
5361
  |------|------|---------|----------|-------------|
5362
+ | borderColor | string | — | false | Border color for the component. Accepts the same kind names and CSS color values as
5363
+ `baseColor`. Only honoured by components that render a visible border (panels, cards,
5364
+ inputs, etc.); ignored elsewhere. |
5365
+ | textColor | string | — | false | Text/foreground color for the component. Accepts the same kind names and CSS color values
5366
+ as `baseColor`. If not provided, falls back to the theme's neutral text color for legibility
5367
+ on arbitrary custom backgrounds. |
5368
+ | baseColor | string | — | false | Base color for the component. Accepts either:
5369
+ - A SleekSpace kind name: `"neutral"`, `"primary"`, `"accent"`, `"info"`, `"success"`,
5370
+ `"warning"`, `"danger"`, `"neon-blue"`, `"light-blue"`, `"neon-orange"`,
5371
+ `"neon-purple"`, `"neon-green"`, `"neon-mint"`, `"neon-pink"`, `"yellow"`, `"red"`,
5372
+ `"boulder"` — resolves to the matching `--sk-<kind>-base` token.
5373
+ - Any CSS color value: hex (`"#8B5CF6"`), oklch (`"oklch(0.7 0.25 300)"`),
5374
+ rgb/hsl (`"rgb(139, 92, 246)"`), a CSS variable (`"var(--my-color)"`), or a
5375
+ named color (`"rebeccapurple"`).
5376
+
5377
+ When provided, this overrides the color from the `kind` prop. |
2195
5378
  | open | boolean | undefined | false | Controls the expanded/collapsed state of the component. Use with `v-model:open` for
2196
5379
  two-way binding. When true, the content is visible; when false, it's hidden. If not
2197
5380
  provided, the component manages its own state internally starting with `defaultOpen`. |
@@ -2213,8 +5396,10 @@ trigger appearance, use the trigger slot instead. |
2213
5396
 
2214
5397
  | Slot | Description |
2215
5398
  |------|-------------|
2216
- | trigger | Custom trigger element. Receives `{ open: boolean }` slot props to allow the trigger to reflect the current state. When not provided, a default SkButton with chevron icon is rendered. |
2217
- | default | The collapsible content that is shown/hidden. This content animates smoothly when the collapsed state changes. |
5399
+ | trigger | Custom trigger element. Receives `{ open: boolean }` slot props to allow the trigger to
5400
+ reflect the current state. When not provided, a default SkButton with chevron icon is rendered. |
5401
+ | default | The collapsible content that is shown/hidden. This content animates smoothly when the
5402
+ collapsed state changes. |
2218
5403
 
2219
5404
  ### Events
2220
5405
 
@@ -2451,6 +5636,22 @@ Built on RekaUI DropdownMenu which provides full WAI-ARIA menu pattern. Arrow ke
2451
5636
 
2452
5637
  | Prop | Type | Default | Required | Description |
2453
5638
  |------|------|---------|----------|-------------|
5639
+ | borderColor | string | — | false | Border color for the component. Accepts the same kind names and CSS color values as
5640
+ `baseColor`. Only honoured by components that render a visible border (panels, cards,
5641
+ inputs, etc.); ignored elsewhere. |
5642
+ | textColor | string | — | false | Text/foreground color for the component. Accepts the same kind names and CSS color values
5643
+ as `baseColor`. If not provided, falls back to the theme's neutral text color for legibility
5644
+ on arbitrary custom backgrounds. |
5645
+ | baseColor | string | — | false | Base color for the component. Accepts either:
5646
+ - A SleekSpace kind name: `"neutral"`, `"primary"`, `"accent"`, `"info"`, `"success"`,
5647
+ `"warning"`, `"danger"`, `"neon-blue"`, `"light-blue"`, `"neon-orange"`,
5648
+ `"neon-purple"`, `"neon-green"`, `"neon-mint"`, `"neon-pink"`, `"yellow"`, `"red"`,
5649
+ `"boulder"` — resolves to the matching `--sk-<kind>-base` token.
5650
+ - Any CSS color value: hex (`"#8B5CF6"`), oklch (`"oklch(0.7 0.25 300)"`),
5651
+ rgb/hsl (`"rgb(139, 92, 246)"`), a CSS variable (`"var(--my-color)"`), or a
5652
+ named color (`"rebeccapurple"`).
5653
+
5654
+ When provided, this overrides the color from the `kind` prop. |
2454
5655
  | kind | "neutral" \| "primary" \| "accent" \| "danger" \| "info" \| "success" \| "warning" \| "boulder" \| "neon-blue" \| "light-blue" \| "neon-orange" \| "neon-purple" \| "neon-green" \| "neon-mint" \| "neon-pink" \| "yellow" \| "red" | 'neutral' | false | Semantic color kind that controls the menu's accent colors for hover states and
2455
5656
  focus indicators. The kind is inherited by nested SkDropdownSubmenu components
2456
5657
  unless they specify their own kind. |
@@ -2466,13 +5667,18 @@ the menu, and 'end' aligns right edges. |
2466
5667
  | sideOffset | number | 4 | false | Distance in pixels between the trigger element and the dropdown menu.
2467
5668
  Increase for more visual separation or decrease for a tighter connection
2468
5669
  to the trigger element. |
5670
+ | size | "xs" \| "sm" \| "md" \| "lg" \| "xl" | undefined | false | Size of the default trigger button. When omitted and the dropdown is rendered inside
5671
+ an SkNavBar, falls back to the navbar's `size` prop so the trigger naturally matches
5672
+ surrounding nav controls. Ignored when the `trigger` slot is used. |
2469
5673
 
2470
5674
  ### Slots
2471
5675
 
2472
5676
  | Slot | Description |
2473
5677
  |------|-------------|
2474
- | trigger | Custom trigger element. When provided, replaces the default SkButton trigger. The slot content should be an interactive element (button, link, etc.). |
2475
- | default | Menu content containing SkDropdownMenuItem, SkDropdownMenuSeparator, and/or SkDropdownSubmenu components. |
5678
+ | trigger | Custom trigger element. When provided, replaces the default SkButton trigger.
5679
+ The slot content should be an interactive element (button, link, etc.). |
5680
+ | default | Menu content containing SkDropdownMenuItem, SkDropdownMenuSeparator, and/or
5681
+ SkDropdownSubmenu components. |
2476
5682
 
2477
5683
 
2478
5684
  ---
@@ -2601,7 +5807,9 @@ inputs via Vue's provide/inject system. |
2601
5807
 
2602
5808
  | Slot | Description |
2603
5809
  |------|-------------|
2604
- | default | The form input component (SkInput, SkTextarea, SkNumberInput, etc.). Receives slot props: `id` (string) - unique ID for the input, `aria-describedby` (string) - ID of description/error element, `aria-invalid` (string) - "true" when error present, `kind` (string) - semantic kind based on state. |
5810
+ | default | The form input component (SkInput, SkTextarea, SkNumberInput, etc.). Receives slot props:
5811
+ `id` (string) - unique ID for the input, `aria-describedby` (string) - ID of description/error element,
5812
+ `aria-invalid` (string) - "true" when error present, `kind` (string) - semantic kind based on state. |
2605
5813
 
2606
5814
 
2607
5815
  ---
@@ -2656,7 +5864,8 @@ for stacked layouts (like form field groups or menu items). |
2656
5864
 
2657
5865
  | Slot | Description |
2658
5866
  |------|-------------|
2659
- | default | The child elements to be grouped. All direct children will be arranged according to the orientation prop with consistent spacing between them. |
5867
+ | default | The child elements to be grouped. All direct children will be arranged according to the
5868
+ orientation prop with consistent spacing between them. |
2660
5869
 
2661
5870
 
2662
5871
  ---
@@ -2749,6 +5958,22 @@ Renders as a native `<input>` element. All standard HTML attributes are forwarde
2749
5958
 
2750
5959
  | Prop | Type | Default | Required | Description |
2751
5960
  |------|------|---------|----------|-------------|
5961
+ | borderColor | string | — | false | Border color for the component. Accepts the same kind names and CSS color values as
5962
+ `baseColor`. Only honoured by components that render a visible border (panels, cards,
5963
+ inputs, etc.); ignored elsewhere. |
5964
+ | textColor | string | — | false | Text/foreground color for the component. Accepts the same kind names and CSS color values
5965
+ as `baseColor`. If not provided, falls back to the theme's neutral text color for legibility
5966
+ on arbitrary custom backgrounds. |
5967
+ | baseColor | string | — | false | Base color for the component. Accepts either:
5968
+ - A SleekSpace kind name: `"neutral"`, `"primary"`, `"accent"`, `"info"`, `"success"`,
5969
+ `"warning"`, `"danger"`, `"neon-blue"`, `"light-blue"`, `"neon-orange"`,
5970
+ `"neon-purple"`, `"neon-green"`, `"neon-mint"`, `"neon-pink"`, `"yellow"`, `"red"`,
5971
+ `"boulder"` — resolves to the matching `--sk-<kind>-base` token.
5972
+ - Any CSS color value: hex (`"#8B5CF6"`), oklch (`"oklch(0.7 0.25 300)"`),
5973
+ rgb/hsl (`"rgb(139, 92, 246)"`), a CSS variable (`"var(--my-color)"`), or a
5974
+ named color (`"rebeccapurple"`).
5975
+
5976
+ When provided, this overrides the color from the `kind` prop. |
2752
5977
  | type | "number" \| "text" \| "email" \| "password" \| "url" \| "tel" \| "search" | 'text' | false | The HTML input type attribute controlling the input behavior and keyboard on mobile devices.
2753
5978
  Common types include 'text', 'email', 'password', 'tel', 'url', 'search', and 'number'.
2754
5979
  Note: For numeric inputs with stepper buttons, consider using SkNumberInput instead. |
@@ -2958,6 +6183,22 @@ const validate = () => {
2958
6183
 
2959
6184
  | Prop | Type | Default | Required | Description |
2960
6185
  |------|------|---------|----------|-------------|
6186
+ | borderColor | string | — | false | Border color for the component. Accepts the same kind names and CSS color values as
6187
+ `baseColor`. Only honoured by components that render a visible border (panels, cards,
6188
+ inputs, etc.); ignored elsewhere. |
6189
+ | textColor | string | — | false | Text/foreground color for the component. Accepts the same kind names and CSS color values
6190
+ as `baseColor`. If not provided, falls back to the theme's neutral text color for legibility
6191
+ on arbitrary custom backgrounds. |
6192
+ | baseColor | string | — | false | Base color for the component. Accepts either:
6193
+ - A SleekSpace kind name: `"neutral"`, `"primary"`, `"accent"`, `"info"`, `"success"`,
6194
+ `"warning"`, `"danger"`, `"neon-blue"`, `"light-blue"`, `"neon-orange"`,
6195
+ `"neon-purple"`, `"neon-green"`, `"neon-mint"`, `"neon-pink"`, `"yellow"`, `"red"`,
6196
+ `"boulder"` — resolves to the matching `--sk-<kind>-base` token.
6197
+ - Any CSS color value: hex (`"#8B5CF6"`), oklch (`"oklch(0.7 0.25 300)"`),
6198
+ rgb/hsl (`"rgb(139, 92, 246)"`), a CSS variable (`"var(--my-color)"`), or a
6199
+ named color (`"rebeccapurple"`).
6200
+
6201
+ When provided, this overrides the color from the `kind` prop. |
2961
6202
  | kind | "neutral" \| "primary" \| "accent" \| "danger" \| "info" \| "success" \| "warning" \| "boulder" \| "neon-blue" \| "light-blue" \| "neon-orange" \| "neon-purple" \| "neon-green" \| "neon-mint" \| "neon-pink" \| "yellow" \| "red" | undefined | false | Semantic color kind that controls the input border, focus ring, and selected
2962
6203
  item highlight appearance. When used inside SkField, inherits the field's
2963
6204
  kind if not explicitly set. |
@@ -2975,7 +6216,8 @@ appears with reduced opacity and the cursor changes to not-allowed. |
2975
6216
 
2976
6217
  | Slot | Description |
2977
6218
  |------|-------------|
2978
- | default | SkListboxItem components representing the available options. Use SkListboxSeparator to create visual dividers between groups of options. |
6219
+ | default | SkListboxItem components representing the available options. Use SkListboxSeparator
6220
+ to create visual dividers between groups of options. |
2979
6221
 
2980
6222
 
2981
6223
  ---
@@ -3201,6 +6443,22 @@ Control how the modal can be dismissed using `no-close-on-escape` and `no-close-
3201
6443
 
3202
6444
  | Prop | Type | Default | Required | Description |
3203
6445
  |------|------|---------|----------|-------------|
6446
+ | borderColor | string | — | false | Border color for the component. Accepts the same kind names and CSS color values as
6447
+ `baseColor`. Only honoured by components that render a visible border (panels, cards,
6448
+ inputs, etc.); ignored elsewhere. |
6449
+ | textColor | string | — | false | Text/foreground color for the component. Accepts the same kind names and CSS color values
6450
+ as `baseColor`. If not provided, falls back to the theme's neutral text color for legibility
6451
+ on arbitrary custom backgrounds. |
6452
+ | baseColor | string | — | false | Base color for the component. Accepts either:
6453
+ - A SleekSpace kind name: `"neutral"`, `"primary"`, `"accent"`, `"info"`, `"success"`,
6454
+ `"warning"`, `"danger"`, `"neon-blue"`, `"light-blue"`, `"neon-orange"`,
6455
+ `"neon-purple"`, `"neon-green"`, `"neon-mint"`, `"neon-pink"`, `"yellow"`, `"red"`,
6456
+ `"boulder"` — resolves to the matching `--sk-<kind>-base` token.
6457
+ - Any CSS color value: hex (`"#8B5CF6"`), oklch (`"oklch(0.7 0.25 300)"`),
6458
+ rgb/hsl (`"rgb(139, 92, 246)"`), a CSS variable (`"var(--my-color)"`), or a
6459
+ named color (`"rebeccapurple"`).
6460
+
6461
+ When provided, this overrides the color from the `kind` prop. |
3204
6462
  | kind | "neutral" \| "primary" \| "accent" \| "danger" \| "info" \| "success" \| "warning" \| "boulder" \| "neon-blue" \| "light-blue" \| "neon-orange" \| "neon-purple" \| "neon-green" \| "neon-mint" \| "neon-pink" \| "yellow" \| "red" | 'neutral' | false | Semantic color kind that controls the modal's accent colors, including the header,
3205
6463
  close button, and any kind-styled elements within the modal. Semantic kinds
3206
6464
  (neutral, primary, accent, etc.) adapt to your theme. |
@@ -3230,7 +6488,8 @@ require users to interact with modal buttons rather than dismissing accidentally
3230
6488
 
3231
6489
  | Slot | Description |
3232
6490
  |------|-------------|
3233
- | trigger | Custom trigger element to open the modal. Receives no slot props. If not provided, uses a default SkButton with `triggerText`. |
6491
+ | trigger | Custom trigger element to open the modal. Receives no slot props. If not provided, uses
6492
+ a default SkButton with `triggerText`. |
3234
6493
  | title | Custom title content. Receives `{ close }` slot prop for programmatic closing. |
3235
6494
  | default | The main modal body content. Receives `{ close }` slot prop for programmatic closing. |
3236
6495
  | footer | Footer content, typically containing action buttons. Receives `{ close }` slot prop. |
@@ -3564,6 +6823,22 @@ const validateQuantity = () => {
3564
6823
 
3565
6824
  | Prop | Type | Default | Required | Description |
3566
6825
  |------|------|---------|----------|-------------|
6826
+ | borderColor | string | — | false | Border color for the component. Accepts the same kind names and CSS color values as
6827
+ `baseColor`. Only honoured by components that render a visible border (panels, cards,
6828
+ inputs, etc.); ignored elsewhere. |
6829
+ | textColor | string | — | false | Text/foreground color for the component. Accepts the same kind names and CSS color values
6830
+ as `baseColor`. If not provided, falls back to the theme's neutral text color for legibility
6831
+ on arbitrary custom backgrounds. |
6832
+ | baseColor | string | — | false | Base color for the component. Accepts either:
6833
+ - A SleekSpace kind name: `"neutral"`, `"primary"`, `"accent"`, `"info"`, `"success"`,
6834
+ `"warning"`, `"danger"`, `"neon-blue"`, `"light-blue"`, `"neon-orange"`,
6835
+ `"neon-purple"`, `"neon-green"`, `"neon-mint"`, `"neon-pink"`, `"yellow"`, `"red"`,
6836
+ `"boulder"` — resolves to the matching `--sk-<kind>-base` token.
6837
+ - Any CSS color value: hex (`"#8B5CF6"`), oklch (`"oklch(0.7 0.25 300)"`),
6838
+ rgb/hsl (`"rgb(139, 92, 246)"`), a CSS variable (`"var(--my-color)"`), or a
6839
+ named color (`"rebeccapurple"`).
6840
+
6841
+ When provided, this overrides the color from the `kind` prop. |
3567
6842
  | kind | "neutral" \| "primary" \| "accent" \| "danger" \| "info" \| "success" \| "warning" \| "boulder" \| "neon-blue" \| "light-blue" \| "neon-orange" \| "neon-purple" \| "neon-green" \| "neon-mint" \| "neon-pink" \| "yellow" \| "red" | undefined | false | Semantic color kind for the input border and focus ring. Use semantic kinds like
3568
6843
  'success' or 'danger' to indicate validation states. When used inside an SkField
3569
6844
  with a `state` prop, the field's kind automatically overrides this value. |
@@ -3592,6 +6867,9 @@ or inventory caps. |
3592
6867
  | step | number | 1 | false | The increment/decrement step amount when using stepper buttons or arrow keys. Use
3593
6868
  fractional values like 0.01 for currency or 0.1 for percentages. Pressing Shift while
3594
6869
  stepping may multiply the step for faster navigation. |
6870
+ | showSteppers | boolean | true | false | When true, renders the increment/decrement stepper buttons on the right side of the
6871
+ input. Set to false for a plain numeric text field (users can still use arrow keys
6872
+ and type values directly). |
3595
6873
 
3596
6874
 
3597
6875
  ---
@@ -3734,6 +7012,10 @@ on the root element and providing theme context for descendant components (inclu
3734
7012
  components like dropdowns and modals). |
3735
7013
  | flush | boolean | false | false | When true, zeroes out `--sk-page-gap` and `--sk-page-content-padding` so panels and content
3736
7014
  sit flush against the header, footer, edges, and each other. |
7015
+ | noBounce | boolean | false | false | When true, disables the bouncy overscroll / rubber-band effect on the page's scroll
7016
+ containers (main content, sidebar body, aside body). Applies `overscroll-behavior: none`
7017
+ to every scrollable region owned by SkPage. Note: the document-level bounce from scrolling
7018
+ the page itself (outside SkPage's containers) can only be killed on `html`/`body`. |
3737
7019
 
3738
7020
  ### Slots
3739
7021
 
@@ -3741,15 +7023,21 @@ sit flush against the header, footer, edges, and each other. |
3741
7023
  |------|-------------|
3742
7024
  | header | Top-of-page header. Typically a SkNavBar. |
3743
7025
  | subheader | Full-width strip between the header and the main row. Good for breadcrumbs or sub-tabs. |
3744
- | sidebar-header | Pinned top of the sidebar (e.g. logo, search). Renders in the drawer too. Slot props: `{ isDrawer: boolean }`. |
3745
- | sidebar | Left sidebar body. Renders inline when persistent, inside a drawer when in drawer mode. Slot props: `{ isDrawer: boolean }` — true when this invocation is the off-canvas drawer. |
3746
- | sidebar-footer | Pinned bottom of the sidebar (e.g. user menu). Renders in the drawer too. Slot props: `{ isDrawer: boolean }`. |
7026
+ | sidebar-header | Pinned top of the sidebar (e.g. logo, search). Renders in the drawer too.
7027
+ Slot props: `{ isDrawer: boolean }`. |
7028
+ | sidebar | Left sidebar body. Renders inline when persistent, inside a drawer when in drawer mode.
7029
+ Slot props: `{ isDrawer: boolean }` — true when this invocation is the off-canvas drawer. |
7030
+ | sidebar-footer | Pinned bottom of the sidebar (e.g. user menu). Renders in the drawer too.
7031
+ Slot props: `{ isDrawer: boolean }`. |
3747
7032
  | main-header | Pinned top of the center column (e.g. breadcrumbs, sub-tabs). Does not scroll. |
3748
7033
  | default | Main content. Scrolls inside the content area and receives the default content padding. |
3749
7034
  | main-footer | Pinned bottom of the center column (e.g. status bar). Does not scroll. |
3750
- | aside-header | Pinned top of the aside (e.g. panel title). Renders in the drawer too. Slot props: `{ isDrawer: boolean }`. |
3751
- | aside | Right aside body. Persistent or drawer, mirror of the sidebar on the opposite side. Slot props: `{ isDrawer: boolean }` — use to add chrome only when rendering in the drawer. |
3752
- | aside-footer | Pinned bottom of the aside (e.g. action buttons). Renders in the drawer too. Slot props: `{ isDrawer: boolean }`. |
7035
+ | aside-header | Pinned top of the aside (e.g. panel title). Renders in the drawer too.
7036
+ Slot props: `{ isDrawer: boolean }`. |
7037
+ | aside | Right aside body. Persistent or drawer, mirror of the sidebar on the opposite side.
7038
+ Slot props: `{ isDrawer: boolean }` — use to add chrome only when rendering in the drawer. |
7039
+ | aside-footer | Pinned bottom of the aside (e.g. action buttons). Renders in the drawer too.
7040
+ Slot props: `{ isDrawer: boolean }`. |
3753
7041
  | footer | Bottom-of-page footer. |
3754
7042
 
3755
7043
  ### Events
@@ -3867,6 +7155,9 @@ Pagination integrated with a data table showing items per page. A common pattern
3867
7155
 
3868
7156
  | Prop | Type | Default | Required | Description |
3869
7157
  |------|------|---------|----------|-------------|
7158
+ | borderColor | string | — | false | Border color for the component. Accepts the same kind names and CSS color values as
7159
+ `baseColor`. Only honoured by components that render a visible border (panels, cards,
7160
+ inputs, etc.); ignored elsewhere. |
3870
7161
  | textColor | string | undefined | false | |
3871
7162
  | baseColor | string | undefined | false | |
3872
7163
  | total | number | — | true | The total number of pages available. This is a required prop that determines
@@ -4005,6 +7296,22 @@ Use `base-color` for custom CSS colors. Text color is automatically calculated f
4005
7296
 
4006
7297
  | Prop | Type | Default | Required | Description |
4007
7298
  |------|------|---------|----------|-------------|
7299
+ | borderColor | string | — | false | Border color for the component. Accepts the same kind names and CSS color values as
7300
+ `baseColor`. Only honoured by components that render a visible border (panels, cards,
7301
+ inputs, etc.); ignored elsewhere. |
7302
+ | textColor | string | — | false | Text/foreground color for the component. Accepts the same kind names and CSS color values
7303
+ as `baseColor`. If not provided, falls back to the theme's neutral text color for legibility
7304
+ on arbitrary custom backgrounds. |
7305
+ | baseColor | string | — | false | Base color for the component. Accepts either:
7306
+ - A SleekSpace kind name: `"neutral"`, `"primary"`, `"accent"`, `"info"`, `"success"`,
7307
+ `"warning"`, `"danger"`, `"neon-blue"`, `"light-blue"`, `"neon-orange"`,
7308
+ `"neon-purple"`, `"neon-green"`, `"neon-mint"`, `"neon-pink"`, `"yellow"`, `"red"`,
7309
+ `"boulder"` — resolves to the matching `--sk-<kind>-base` token.
7310
+ - Any CSS color value: hex (`"#8B5CF6"`), oklch (`"oklch(0.7 0.25 300)"`),
7311
+ rgb/hsl (`"rgb(139, 92, 246)"`), a CSS variable (`"var(--my-color)"`), or a
7312
+ named color (`"rebeccapurple"`).
7313
+
7314
+ When provided, this overrides the color from the `kind` prop. |
4008
7315
  | kind | "neutral" \| "primary" \| "accent" \| "danger" \| "info" \| "success" \| "warning" \| "boulder" \| "neon-blue" \| "light-blue" \| "neon-orange" \| "neon-purple" \| "neon-green" \| "neon-mint" \| "neon-pink" \| "yellow" \| "red" | 'neutral' | false | Semantic color kind that controls the panel's border color and decorative accent stripe.
4009
7316
  Semantic kinds (neutral, primary, accent, etc.) automatically adapt to your current theme,
4010
7317
  while color kinds (neon-blue, neon-purple, etc.) provide fixed branding colors that remain
@@ -4135,6 +7442,22 @@ Use `baseColor` and `textColor` for custom styling.
4135
7442
 
4136
7443
  | Prop | Type | Default | Required | Description |
4137
7444
  |------|------|---------|----------|-------------|
7445
+ | borderColor | string | — | false | Border color for the component. Accepts the same kind names and CSS color values as
7446
+ `baseColor`. Only honoured by components that render a visible border (panels, cards,
7447
+ inputs, etc.); ignored elsewhere. |
7448
+ | textColor | string | — | false | Text/foreground color for the component. Accepts the same kind names and CSS color values
7449
+ as `baseColor`. If not provided, falls back to the theme's neutral text color for legibility
7450
+ on arbitrary custom backgrounds. |
7451
+ | baseColor | string | — | false | Base color for the component. Accepts either:
7452
+ - A SleekSpace kind name: `"neutral"`, `"primary"`, `"accent"`, `"info"`, `"success"`,
7453
+ `"warning"`, `"danger"`, `"neon-blue"`, `"light-blue"`, `"neon-orange"`,
7454
+ `"neon-purple"`, `"neon-green"`, `"neon-mint"`, `"neon-pink"`, `"yellow"`, `"red"`,
7455
+ `"boulder"` — resolves to the matching `--sk-<kind>-base` token.
7456
+ - Any CSS color value: hex (`"#8B5CF6"`), oklch (`"oklch(0.7 0.25 300)"`),
7457
+ rgb/hsl (`"rgb(139, 92, 246)"`), a CSS variable (`"var(--my-color)"`), or a
7458
+ named color (`"rebeccapurple"`).
7459
+
7460
+ When provided, this overrides the color from the `kind` prop. |
4138
7461
  | kind | "neutral" \| "primary" \| "accent" \| "danger" \| "info" \| "success" \| "warning" \| "boulder" \| "neon-blue" \| "light-blue" \| "neon-orange" \| "neon-purple" \| "neon-green" \| "neon-mint" \| "neon-pink" \| "yellow" \| "red" | 'neutral' | false | Semantic color kind that controls the popover's header accent and overall color scheme.
4139
7462
  Semantic kinds (neutral, primary, accent, info, success, warning, danger) adapt to your
4140
7463
  theme. Use 'neutral' for general popovers, or match the kind to contextual meaning
@@ -4166,10 +7489,14 @@ state internally (opens on trigger click, closes on outside click or Escape). |
4166
7489
 
4167
7490
  | Slot | Description |
4168
7491
  |------|-------------|
4169
- | trigger | The element that opens the popover when clicked. Uses `as-child` behavior so your trigger element becomes the actual clickable trigger. Required slot. |
4170
- | header | Optional header content displayed after the title. Use for additional header elements like badges, status indicators, or secondary actions. |
4171
- | default | Main body content of the popover. Can include any components, forms, or interactive content. Scrolls if content exceeds available space. |
4172
- | footer | Optional footer content, typically for action buttons. Commonly contains Cancel/Confirm button pairs or other closing actions. |
7492
+ | trigger | The element that opens the popover when clicked. Uses `as-child` behavior so your
7493
+ trigger element becomes the actual clickable trigger. Required slot. |
7494
+ | header | Optional header content displayed after the title. Use for additional header elements
7495
+ like badges, status indicators, or secondary actions. |
7496
+ | default | Main body content of the popover. Can include any components, forms, or interactive content.
7497
+ Scrolls if content exceeds available space. |
7498
+ | footer | Optional footer content, typically for action buttons. Commonly contains Cancel/Confirm
7499
+ button pairs or other closing actions. |
4173
7500
 
4174
7501
  ### Events
4175
7502
 
@@ -4401,6 +7728,22 @@ Override radio colors with custom OKLCH, hex, or CSS variable values.
4401
7728
 
4402
7729
  | Prop | Type | Default | Required | Description |
4403
7730
  |------|------|---------|----------|-------------|
7731
+ | borderColor | string | — | false | Border color for the component. Accepts the same kind names and CSS color values as
7732
+ `baseColor`. Only honoured by components that render a visible border (panels, cards,
7733
+ inputs, etc.); ignored elsewhere. |
7734
+ | textColor | string | — | false | Text/foreground color for the component. Accepts the same kind names and CSS color values
7735
+ as `baseColor`. If not provided, falls back to the theme's neutral text color for legibility
7736
+ on arbitrary custom backgrounds. |
7737
+ | baseColor | string | — | false | Base color for the component. Accepts either:
7738
+ - A SleekSpace kind name: `"neutral"`, `"primary"`, `"accent"`, `"info"`, `"success"`,
7739
+ `"warning"`, `"danger"`, `"neon-blue"`, `"light-blue"`, `"neon-orange"`,
7740
+ `"neon-purple"`, `"neon-green"`, `"neon-mint"`, `"neon-pink"`, `"yellow"`, `"red"`,
7741
+ `"boulder"` — resolves to the matching `--sk-<kind>-base` token.
7742
+ - Any CSS color value: hex (`"#8B5CF6"`), oklch (`"oklch(0.7 0.25 300)"`),
7743
+ rgb/hsl (`"rgb(139, 92, 246)"`), a CSS variable (`"var(--my-color)"`), or a
7744
+ named color (`"rebeccapurple"`).
7745
+
7746
+ When provided, this overrides the color from the `kind` prop. |
4404
7747
  | value | string \| string[] | — | true | The value this radio option represents. When selected, the parent SkRadioGroup's
4405
7748
  v-model will be set to this value. Must be unique within the radio group to ensure
4406
7749
  proper selection behavior. |
@@ -4421,7 +7764,8 @@ Available sizes: 'sm' (small), 'md' (medium), 'lg' (large), 'xl' (extra large).
4421
7764
 
4422
7765
  | Slot | Description |
4423
7766
  |------|-------------|
4424
- | default | Custom label content. Overrides the `label` prop when provided, allowing for rich formatting, icons, or complex layouts alongside the radio button. |
7767
+ | default | Custom label content. Overrides the `label` prop when provided, allowing for rich
7768
+ formatting, icons, or complex layouts alongside the radio button. |
4425
7769
 
4426
7770
 
4427
7771
  ---
@@ -4567,6 +7911,22 @@ Use `base-color` to customize the sidebar background with any CSS color value. P
4567
7911
 
4568
7912
  | Prop | Type | Default | Required | Description |
4569
7913
  |------|------|---------|----------|-------------|
7914
+ | borderColor | string | — | false | Border color for the component. Accepts the same kind names and CSS color values as
7915
+ `baseColor`. Only honoured by components that render a visible border (panels, cards,
7916
+ inputs, etc.); ignored elsewhere. |
7917
+ | textColor | string | — | false | Text/foreground color for the component. Accepts the same kind names and CSS color values
7918
+ as `baseColor`. If not provided, falls back to the theme's neutral text color for legibility
7919
+ on arbitrary custom backgrounds. |
7920
+ | baseColor | string | — | false | Base color for the component. Accepts either:
7921
+ - A SleekSpace kind name: `"neutral"`, `"primary"`, `"accent"`, `"info"`, `"success"`,
7922
+ `"warning"`, `"danger"`, `"neon-blue"`, `"light-blue"`, `"neon-orange"`,
7923
+ `"neon-purple"`, `"neon-green"`, `"neon-mint"`, `"neon-pink"`, `"yellow"`, `"red"`,
7924
+ `"boulder"` — resolves to the matching `--sk-<kind>-base` token.
7925
+ - Any CSS color value: hex (`"#8B5CF6"`), oklch (`"oklch(0.7 0.25 300)"`),
7926
+ rgb/hsl (`"rgb(139, 92, 246)"`), a CSS variable (`"var(--my-color)"`), or a
7927
+ named color (`"rebeccapurple"`).
7928
+
7929
+ When provided, this overrides the color from the `kind` prop. |
4570
7930
  | kind | "neutral" \| "primary" \| "accent" \| "danger" \| "info" \| "success" \| "warning" \| "boulder" \| "neon-blue" \| "light-blue" \| "neon-orange" \| "neon-purple" \| "neon-green" \| "neon-mint" \| "neon-pink" \| "yellow" \| "red" | 'neutral' | false | Semantic color kind that controls the sidebar panel's background, border, and text colors.
4571
7931
  The kind is passed to the underlying SkPanel component. Use semantic kinds like 'neutral'
4572
7932
  or 'primary' to match your theme, or use `baseColor`/`textColor` props for custom colors. |
@@ -4583,7 +7943,9 @@ tap comfort. No effect on fine-pointer (mouse) devices. |
4583
7943
 
4584
7944
  | Slot | Description |
4585
7945
  |------|-------------|
4586
- | default | Container for SkSidebarSection and/or SkSidebarItem components. Content is wrapped in a scrollable nav element, allowing long navigation lists to scroll independently of the main page content. |
7946
+ | default | Container for SkSidebarSection and/or SkSidebarItem components. Content is wrapped
7947
+ in a scrollable nav element, allowing long navigation lists to scroll independently
7948
+ of the main page content. |
4587
7949
 
4588
7950
 
4589
7951
  ---
@@ -5000,6 +8362,22 @@ Built on RekaUI Switch which provides `role="switch"` and `aria-checked`. The la
5000
8362
 
5001
8363
  | Prop | Type | Default | Required | Description |
5002
8364
  |------|------|---------|----------|-------------|
8365
+ | borderColor | string | — | false | Border color for the component. Accepts the same kind names and CSS color values as
8366
+ `baseColor`. Only honoured by components that render a visible border (panels, cards,
8367
+ inputs, etc.); ignored elsewhere. |
8368
+ | textColor | string | — | false | Text/foreground color for the component. Accepts the same kind names and CSS color values
8369
+ as `baseColor`. If not provided, falls back to the theme's neutral text color for legibility
8370
+ on arbitrary custom backgrounds. |
8371
+ | baseColor | string | — | false | Base color for the component. Accepts either:
8372
+ - A SleekSpace kind name: `"neutral"`, `"primary"`, `"accent"`, `"info"`, `"success"`,
8373
+ `"warning"`, `"danger"`, `"neon-blue"`, `"light-blue"`, `"neon-orange"`,
8374
+ `"neon-purple"`, `"neon-green"`, `"neon-mint"`, `"neon-pink"`, `"yellow"`, `"red"`,
8375
+ `"boulder"` — resolves to the matching `--sk-<kind>-base` token.
8376
+ - Any CSS color value: hex (`"#8B5CF6"`), oklch (`"oklch(0.7 0.25 300)"`),
8377
+ rgb/hsl (`"rgb(139, 92, 246)"`), a CSS variable (`"var(--my-color)"`), or a
8378
+ named color (`"rebeccapurple"`).
8379
+
8380
+ When provided, this overrides the color from the `kind` prop. |
5003
8381
  | modelValue | boolean | — | true | The current state of the switch. `true` means on (checked), `false` means off (unchecked).
5004
8382
  Use with `v-model` for two-way binding. Required prop that must be explicitly provided. |
5005
8383
  | label | string | undefined | false | Static label text displayed next to the switch. When `labelOn` or `labelOff` are not
@@ -5209,6 +8587,22 @@ SkTable renders as a standard `<table>` element. Use semantic `<thead>`, `<tbody
5209
8587
 
5210
8588
  | Prop | Type | Default | Required | Description |
5211
8589
  |------|------|---------|----------|-------------|
8590
+ | borderColor | string | — | false | Border color for the component. Accepts the same kind names and CSS color values as
8591
+ `baseColor`. Only honoured by components that render a visible border (panels, cards,
8592
+ inputs, etc.); ignored elsewhere. |
8593
+ | textColor | string | — | false | Text/foreground color for the component. Accepts the same kind names and CSS color values
8594
+ as `baseColor`. If not provided, falls back to the theme's neutral text color for legibility
8595
+ on arbitrary custom backgrounds. |
8596
+ | baseColor | string | — | false | Base color for the component. Accepts either:
8597
+ - A SleekSpace kind name: `"neutral"`, `"primary"`, `"accent"`, `"info"`, `"success"`,
8598
+ `"warning"`, `"danger"`, `"neon-blue"`, `"light-blue"`, `"neon-orange"`,
8599
+ `"neon-purple"`, `"neon-green"`, `"neon-mint"`, `"neon-pink"`, `"yellow"`, `"red"`,
8600
+ `"boulder"` — resolves to the matching `--sk-<kind>-base` token.
8601
+ - Any CSS color value: hex (`"#8B5CF6"`), oklch (`"oklch(0.7 0.25 300)"`),
8602
+ rgb/hsl (`"rgb(139, 92, 246)"`), a CSS variable (`"var(--my-color)"`), or a
8603
+ named color (`"rebeccapurple"`).
8604
+
8605
+ When provided, this overrides the color from the `kind` prop. |
5212
8606
  | kind | "neutral" \| "primary" \| "accent" \| "danger" \| "info" \| "success" \| "warning" \| "boulder" \| "neon-blue" \| "light-blue" \| "neon-orange" \| "neon-purple" \| "neon-green" \| "neon-mint" \| "neon-pink" \| "yellow" \| "red" | 'neutral' | false | Semantic color kind that controls header backgrounds and accent colors. The kind
5213
8607
  affects the table header row styling and can subtly influence row hover colors.
5214
8608
  Use semantic kinds to match your application's color language. |
@@ -5238,7 +8632,8 @@ secondary data alongside more prominent content. |
5238
8632
 
5239
8633
  | Slot | Description |
5240
8634
  |------|-------------|
5241
- | default | Standard HTML table content including `<thead>`, `<tbody>`, `<tfoot>`, `<tr>`, `<th>`, and `<td>` elements. |
8635
+ | default | Standard HTML table content including `<thead>`, `<tbody>`, `<tfoot>`, `<tr>`, `<th>`,
8636
+ and `<td>` elements. |
5242
8637
 
5243
8638
 
5244
8639
  ---
@@ -5377,6 +8772,22 @@ Built on RekaUI Tabs which provides `role="tablist"`, `role="tab"`, and `role="t
5377
8772
 
5378
8773
  | Prop | Type | Default | Required | Description |
5379
8774
  |------|------|---------|----------|-------------|
8775
+ | borderColor | string | — | false | Border color for the component. Accepts the same kind names and CSS color values as
8776
+ `baseColor`. Only honoured by components that render a visible border (panels, cards,
8777
+ inputs, etc.); ignored elsewhere. |
8778
+ | textColor | string | — | false | Text/foreground color for the component. Accepts the same kind names and CSS color values
8779
+ as `baseColor`. If not provided, falls back to the theme's neutral text color for legibility
8780
+ on arbitrary custom backgrounds. |
8781
+ | baseColor | string | — | false | Base color for the component. Accepts either:
8782
+ - A SleekSpace kind name: `"neutral"`, `"primary"`, `"accent"`, `"info"`, `"success"`,
8783
+ `"warning"`, `"danger"`, `"neon-blue"`, `"light-blue"`, `"neon-orange"`,
8784
+ `"neon-purple"`, `"neon-green"`, `"neon-mint"`, `"neon-pink"`, `"yellow"`, `"red"`,
8785
+ `"boulder"` — resolves to the matching `--sk-<kind>-base` token.
8786
+ - Any CSS color value: hex (`"#8B5CF6"`), oklch (`"oklch(0.7 0.25 300)"`),
8787
+ rgb/hsl (`"rgb(139, 92, 246)"`), a CSS variable (`"var(--my-color)"`), or a
8788
+ named color (`"rebeccapurple"`).
8789
+
8790
+ When provided, this overrides the color from the `kind` prop. |
5380
8791
  | modelValue | string \| string[] | — | true | The currently active tab identifier, matching the `name` prop of the corresponding `SkTab`
5381
8792
  and `SkTabPanel`. Use with `v-model` for two-way binding to control which tab is displayed. |
5382
8793
  | orientation | "horizontal" \| "vertical" | 'horizontal' | false | Layout orientation for the tab list. In 'horizontal' mode, tabs are arranged in a row and
@@ -5519,6 +8930,22 @@ The remove button is keyboard-accessible. Developers should provide context (suc
5519
8930
 
5520
8931
  | Prop | Type | Default | Required | Description |
5521
8932
  |------|------|---------|----------|-------------|
8933
+ | borderColor | string | — | false | Border color for the component. Accepts the same kind names and CSS color values as
8934
+ `baseColor`. Only honoured by components that render a visible border (panels, cards,
8935
+ inputs, etc.); ignored elsewhere. |
8936
+ | textColor | string | — | false | Text/foreground color for the component. Accepts the same kind names and CSS color values
8937
+ as `baseColor`. If not provided, falls back to the theme's neutral text color for legibility
8938
+ on arbitrary custom backgrounds. |
8939
+ | baseColor | string | — | false | Base color for the component. Accepts either:
8940
+ - A SleekSpace kind name: `"neutral"`, `"primary"`, `"accent"`, `"info"`, `"success"`,
8941
+ `"warning"`, `"danger"`, `"neon-blue"`, `"light-blue"`, `"neon-orange"`,
8942
+ `"neon-purple"`, `"neon-green"`, `"neon-mint"`, `"neon-pink"`, `"yellow"`, `"red"`,
8943
+ `"boulder"` — resolves to the matching `--sk-<kind>-base` token.
8944
+ - Any CSS color value: hex (`"#8B5CF6"`), oklch (`"oklch(0.7 0.25 300)"`),
8945
+ rgb/hsl (`"rgb(139, 92, 246)"`), a CSS variable (`"var(--my-color)"`), or a
8946
+ named color (`"rebeccapurple"`).
8947
+
8948
+ When provided, this overrides the color from the `kind` prop. |
5522
8949
  | kind | "neutral" \| "primary" \| "accent" \| "danger" \| "info" \| "success" \| "warning" \| "boulder" \| "neon-blue" \| "light-blue" \| "neon-orange" \| "neon-purple" \| "neon-green" \| "neon-mint" \| "neon-pink" \| "yellow" \| "red" | 'neutral' | false | Semantic color kind that controls the tag's color scheme. The kind determines both
5523
8950
  background and text colors across all variants. Use semantic kinds (primary, success,
5524
8951
  danger, etc.) to convey meaning, or use accent for decorative highlighting. |
@@ -5680,6 +9107,22 @@ const validate = () => {
5680
9107
 
5681
9108
  | Prop | Type | Default | Required | Description |
5682
9109
  |------|------|---------|----------|-------------|
9110
+ | borderColor | string | — | false | Border color for the component. Accepts the same kind names and CSS color values as
9111
+ `baseColor`. Only honoured by components that render a visible border (panels, cards,
9112
+ inputs, etc.); ignored elsewhere. |
9113
+ | textColor | string | — | false | Text/foreground color for the component. Accepts the same kind names and CSS color values
9114
+ as `baseColor`. If not provided, falls back to the theme's neutral text color for legibility
9115
+ on arbitrary custom backgrounds. |
9116
+ | baseColor | string | — | false | Base color for the component. Accepts either:
9117
+ - A SleekSpace kind name: `"neutral"`, `"primary"`, `"accent"`, `"info"`, `"success"`,
9118
+ `"warning"`, `"danger"`, `"neon-blue"`, `"light-blue"`, `"neon-orange"`,
9119
+ `"neon-purple"`, `"neon-green"`, `"neon-mint"`, `"neon-pink"`, `"yellow"`, `"red"`,
9120
+ `"boulder"` — resolves to the matching `--sk-<kind>-base` token.
9121
+ - Any CSS color value: hex (`"#8B5CF6"`), oklch (`"oklch(0.7 0.25 300)"`),
9122
+ rgb/hsl (`"rgb(139, 92, 246)"`), a CSS variable (`"var(--my-color)"`), or a
9123
+ named color (`"rebeccapurple"`).
9124
+
9125
+ When provided, this overrides the color from the `kind` prop. |
5683
9126
  | kind | "neutral" \| "primary" \| "accent" \| "danger" \| "info" \| "success" \| "warning" \| "boulder" \| "neon-blue" \| "light-blue" \| "neon-orange" \| "neon-purple" \| "neon-green" \| "neon-mint" \| "neon-pink" \| "yellow" \| "red" | undefined | false | Semantic color kind that controls the input border and focus ring appearance.
5684
9127
  Also sets the default color for tags unless overridden by `tagKind`. When used
5685
9128
  inside SkField, inherits the field's kind if not explicitly set. |
@@ -5838,6 +9281,22 @@ const comments = ref('Looking good so far!')
5838
9281
 
5839
9282
  | Prop | Type | Default | Required | Description |
5840
9283
  |------|------|---------|----------|-------------|
9284
+ | borderColor | string | — | false | Border color for the component. Accepts the same kind names and CSS color values as
9285
+ `baseColor`. Only honoured by components that render a visible border (panels, cards,
9286
+ inputs, etc.); ignored elsewhere. |
9287
+ | textColor | string | — | false | Text/foreground color for the component. Accepts the same kind names and CSS color values
9288
+ as `baseColor`. If not provided, falls back to the theme's neutral text color for legibility
9289
+ on arbitrary custom backgrounds. |
9290
+ | baseColor | string | — | false | Base color for the component. Accepts either:
9291
+ - A SleekSpace kind name: `"neutral"`, `"primary"`, `"accent"`, `"info"`, `"success"`,
9292
+ `"warning"`, `"danger"`, `"neon-blue"`, `"light-blue"`, `"neon-orange"`,
9293
+ `"neon-purple"`, `"neon-green"`, `"neon-mint"`, `"neon-pink"`, `"yellow"`, `"red"`,
9294
+ `"boulder"` — resolves to the matching `--sk-<kind>-base` token.
9295
+ - Any CSS color value: hex (`"#8B5CF6"`), oklch (`"oklch(0.7 0.25 300)"`),
9296
+ rgb/hsl (`"rgb(139, 92, 246)"`), a CSS variable (`"var(--my-color)"`), or a
9297
+ named color (`"rebeccapurple"`).
9298
+
9299
+ When provided, this overrides the color from the `kind` prop. |
5841
9300
  | kind | "neutral" \| "primary" \| "accent" \| "danger" \| "info" \| "success" \| "warning" \| "boulder" \| "neon-blue" \| "light-blue" \| "neon-orange" \| "neon-purple" \| "neon-green" \| "neon-mint" \| "neon-pink" \| "yellow" \| "red" | undefined | false | Semantic color kind for the textarea border and focus ring. Use semantic kinds like
5842
9301
  'success' or 'danger' to indicate validation states. When used inside an SkField with
5843
9302
  a `state` prop, the field's kind automatically overrides this value. |
@@ -5956,7 +9415,8 @@ theme even though they render outside the DOM hierarchy. |
5956
9415
 
5957
9416
  | Slot | Description |
5958
9417
  |------|-------------|
5959
- | default | All application content that should inherit this theme context. Nested SkTheme components can override the theme for subsections of the UI. |
9418
+ | default | All application content that should inherit this theme context. Nested SkTheme components
9419
+ can override the theme for subsections of the UI. |
5960
9420
 
5961
9421
 
5962
9422
  ---
@@ -6316,6 +9776,22 @@ Common tooltip use cases in applications: icon buttons, help text, and disabled
6316
9776
 
6317
9777
  | Prop | Type | Default | Required | Description |
6318
9778
  |------|------|---------|----------|-------------|
9779
+ | borderColor | string | — | false | Border color for the component. Accepts the same kind names and CSS color values as
9780
+ `baseColor`. Only honoured by components that render a visible border (panels, cards,
9781
+ inputs, etc.); ignored elsewhere. |
9782
+ | textColor | string | — | false | Text/foreground color for the component. Accepts the same kind names and CSS color values
9783
+ as `baseColor`. If not provided, falls back to the theme's neutral text color for legibility
9784
+ on arbitrary custom backgrounds. |
9785
+ | baseColor | string | — | false | Base color for the component. Accepts either:
9786
+ - A SleekSpace kind name: `"neutral"`, `"primary"`, `"accent"`, `"info"`, `"success"`,
9787
+ `"warning"`, `"danger"`, `"neon-blue"`, `"light-blue"`, `"neon-orange"`,
9788
+ `"neon-purple"`, `"neon-green"`, `"neon-mint"`, `"neon-pink"`, `"yellow"`, `"red"`,
9789
+ `"boulder"` — resolves to the matching `--sk-<kind>-base` token.
9790
+ - Any CSS color value: hex (`"#8B5CF6"`), oklch (`"oklch(0.7 0.25 300)"`),
9791
+ rgb/hsl (`"rgb(139, 92, 246)"`), a CSS variable (`"var(--my-color)"`), or a
9792
+ named color (`"rebeccapurple"`).
9793
+
9794
+ When provided, this overrides the color from the `kind` prop. |
6319
9795
  | kind | "neutral" \| "primary" \| "accent" \| "danger" \| "info" \| "success" \| "warning" \| "boulder" \| "neon-blue" \| "light-blue" \| "neon-orange" \| "neon-purple" \| "neon-green" \| "neon-mint" \| "neon-pink" \| "yellow" \| "red" | 'neutral' | false | Semantic color kind that controls the tooltip's background and text colors. Semantic kinds
6320
9796
  (neutral, primary, accent, info, success, warning, danger) adapt to your theme. Use 'neutral'
6321
9797
  for general hints, or match the kind to contextual meaning (e.g., 'warning' for caution tips). |
@@ -6342,8 +9818,10 @@ interactive elements are close together. Disable for a cleaner, more minimal app
6342
9818
 
6343
9819
  | Slot | Description |
6344
9820
  |------|-------------|
6345
- | trigger | The element that triggers the tooltip on hover/focus. Use `as-child` behavior - the trigger slot content becomes the actual trigger element. Required slot. |
6346
- | default | The tooltip content to display. Can include text, formatted content, or simple components. Keep content brief for tooltips; use SkPopover for richer interactions. |
9821
+ | trigger | The element that triggers the tooltip on hover/focus. Use `as-child` behavior - the trigger
9822
+ slot content becomes the actual trigger element. Required slot. |
9823
+ | default | The tooltip content to display. Can include text, formatted content, or simple components.
9824
+ Keep content brief for tooltips; use SkPopover for richer interactions. |
6347
9825
 
6348
9826
 
6349
9827
  ---