@skewedaspect/sleekspace-ui 0.9.0 → 0.10.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (210) hide show
  1. package/dist/components/Accordion/context.d.ts +4 -0
  2. package/dist/components/Autocomplete/SkAutocomplete.vue.d.ts +87 -0
  3. package/dist/components/Autocomplete/SkAutocompleteEmpty.vue.d.ts +17 -0
  4. package/dist/components/Autocomplete/SkAutocompleteGroup.vue.d.ts +17 -0
  5. package/dist/components/Autocomplete/SkAutocompleteGroupLabel.vue.d.ts +17 -0
  6. package/dist/components/Autocomplete/SkAutocompleteItem.vue.d.ts +39 -0
  7. package/dist/components/Autocomplete/SkAutocompleteSeparator.vue.d.ts +2 -0
  8. package/dist/components/Autocomplete/index.d.ts +7 -0
  9. package/dist/components/Autocomplete/types.d.ts +3 -0
  10. package/dist/components/Breadcrumbs/context.d.ts +4 -0
  11. package/dist/components/Button/SkButton.vue.d.ts +8 -1
  12. package/dist/components/Button/types.d.ts +2 -0
  13. package/dist/components/Card/SkCard.vue.d.ts +1 -1
  14. package/dist/components/ContextMenu/context.d.ts +3 -0
  15. package/dist/components/Dropdown/SkDropdown.vue.d.ts +1 -1
  16. package/dist/components/Dropdown/context.d.ts +3 -0
  17. package/dist/components/Field/SkField.vue.d.ts +7 -6
  18. package/dist/components/Input/SkInput.vue.d.ts +9 -2
  19. package/dist/components/Input/types.d.ts +2 -0
  20. package/dist/components/InputGroup/SkInputGroup.vue.d.ts +23 -0
  21. package/dist/components/InputGroup/SkInputGroupAddon.vue.d.ts +33 -0
  22. package/dist/components/InputGroup/types.d.ts +13 -0
  23. package/dist/components/NumberInput/SkNumberInput.vue.d.ts +15 -1
  24. package/dist/components/NumberInput/types.d.ts +2 -0
  25. package/dist/components/Pagination/context.d.ts +5 -0
  26. package/dist/components/Panel/SkPanel.vue.d.ts +1 -1
  27. package/dist/components/Panel/types.d.ts +2 -1
  28. package/dist/components/Radio/context.d.ts +4 -0
  29. package/dist/components/Select/SkSelect.vue.d.ts +7 -1
  30. package/dist/components/Select/types.d.ts +2 -0
  31. package/dist/components/Sidebar/SkSidebar.vue.d.ts +1 -1
  32. package/dist/components/Tabs/context.d.ts +6 -0
  33. package/dist/components/Textarea/SkTextarea.vue.d.ts +1 -1
  34. package/dist/components/Tooltip/SkTooltip.vue.d.ts +1 -1
  35. package/dist/composables/injectionKeys.d.ts +9 -0
  36. package/dist/global.d.ts +4 -0
  37. package/dist/index.d.ts +18 -0
  38. package/dist/sleekspace-ui.css +836 -280
  39. package/dist/sleekspace-ui.es.js +3759 -2545
  40. package/dist/sleekspace-ui.umd.js +3765 -2543
  41. package/dist/static/components/alert.d.ts +2 -1
  42. package/dist/static/components/avatar.d.ts +2 -1
  43. package/dist/static/components/breadcrumbs.d.ts +2 -1
  44. package/dist/static/components/button.d.ts +4 -2
  45. package/dist/static/components/card.d.ts +2 -1
  46. package/dist/static/components/checkbox.d.ts +2 -1
  47. package/dist/static/components/colorPicker.d.ts +2 -1
  48. package/dist/static/components/divider.d.ts +2 -1
  49. package/dist/static/components/dropdown.d.ts +2 -1
  50. package/dist/static/components/field.d.ts +2 -1
  51. package/dist/static/components/group.d.ts +2 -1
  52. package/dist/static/components/input.d.ts +4 -2
  53. package/dist/static/components/inputGroup.d.ts +8 -0
  54. package/dist/static/components/inputGroupAddon.d.ts +7 -0
  55. package/dist/static/components/navBar.d.ts +2 -1
  56. package/dist/static/components/numberInput.d.ts +4 -2
  57. package/dist/static/components/page.d.ts +2 -1
  58. package/dist/static/components/pagination.d.ts +2 -1
  59. package/dist/static/components/panel.d.ts +2 -1
  60. package/dist/static/components/progress.d.ts +2 -1
  61. package/dist/static/components/radio.d.ts +2 -1
  62. package/dist/static/components/select.d.ts +4 -2
  63. package/dist/static/components/sidebar.d.ts +2 -1
  64. package/dist/static/components/skeleton.d.ts +2 -1
  65. package/dist/static/components/slider.d.ts +2 -1
  66. package/dist/static/components/spinner.d.ts +2 -1
  67. package/dist/static/components/switchInput.d.ts +2 -1
  68. package/dist/static/components/table.d.ts +2 -1
  69. package/dist/static/components/tag.d.ts +2 -1
  70. package/dist/static/components/tagsInput.d.ts +2 -1
  71. package/dist/static/components/textarea.d.ts +2 -1
  72. package/dist/static/components/toolbar.d.ts +2 -1
  73. package/dist/static/components/tooltip.d.ts +2 -1
  74. package/dist/static/h.d.ts +2 -0
  75. package/dist/static/index.cjs.js +1 -1
  76. package/dist/static/index.d.ts +6 -0
  77. package/dist/static/index.es.js +366 -216
  78. package/dist/static/render.d.ts +2 -1
  79. package/dist/static/stringH.d.ts +2 -0
  80. package/dist/static/types.d.ts +5 -0
  81. package/dist/tailwind.css +222 -0
  82. package/dist/tokens.css +0 -223
  83. package/dist/types/corners.d.ts +1 -0
  84. package/dist/utils/slots.d.ts +6 -0
  85. package/llms-full.txt +17 -9
  86. package/package.json +9 -3
  87. package/src/components/Accordion/SkAccordion.vue +5 -2
  88. package/src/components/Accordion/SkAccordionItem.vue +7 -4
  89. package/src/components/Accordion/context.ts +23 -0
  90. package/src/components/Alert/SkAlert.vue +4 -2
  91. package/src/components/Autocomplete/SkAutocomplete.test.ts +83 -0
  92. package/src/components/Autocomplete/SkAutocomplete.vue +305 -0
  93. package/src/components/Autocomplete/SkAutocompleteEmpty.vue +39 -0
  94. package/src/components/Autocomplete/SkAutocompleteGroup.vue +46 -0
  95. package/src/components/Autocomplete/SkAutocompleteGroupLabel.vue +39 -0
  96. package/src/components/Autocomplete/SkAutocompleteItem.vue +85 -0
  97. package/src/components/Autocomplete/SkAutocompleteSeparator.vue +39 -0
  98. package/src/components/Autocomplete/index.ts +13 -0
  99. package/src/components/Autocomplete/types.ts +10 -0
  100. package/src/components/Breadcrumbs/SkBreadcrumbItem.vue +8 -3
  101. package/src/components/Breadcrumbs/SkBreadcrumbSeparator.vue +8 -2
  102. package/src/components/Breadcrumbs/SkBreadcrumbs.vue +11 -14
  103. package/src/components/Breadcrumbs/context.ts +20 -0
  104. package/src/components/Button/SkButton.vue +54 -11
  105. package/src/components/Button/types.ts +6 -0
  106. package/src/components/Card/SkCard.vue +12 -5
  107. package/src/components/Checkbox/SkCheckbox.vue +9 -2
  108. package/src/components/ColorPicker/SkColorPicker.vue +27 -5
  109. package/src/components/ContextMenu/SkContextMenu.vue +4 -1
  110. package/src/components/ContextMenu/SkContextMenuSubmenu.vue +5 -2
  111. package/src/components/ContextMenu/context.ts +17 -0
  112. package/src/components/Dropdown/SkDropdown.vue +2 -1
  113. package/src/components/Dropdown/SkDropdownSubmenu.vue +4 -3
  114. package/src/components/Dropdown/context.ts +16 -0
  115. package/src/components/Field/SkField.test.ts +88 -0
  116. package/src/components/Field/SkField.vue +15 -7
  117. package/src/components/Input/SkInput.test.ts +61 -0
  118. package/src/components/Input/SkInput.vue +42 -7
  119. package/src/components/Input/types.ts +2 -0
  120. package/src/components/InputGroup/SkInputGroup.test.ts +171 -0
  121. package/src/components/InputGroup/SkInputGroup.vue +131 -0
  122. package/src/components/InputGroup/SkInputGroupAddon.test.ts +104 -0
  123. package/src/components/InputGroup/SkInputGroupAddon.vue +107 -0
  124. package/src/components/InputGroup/types.ts +27 -0
  125. package/src/components/Listbox/SkListbox.vue +27 -6
  126. package/src/components/Modal/SkModal.vue +11 -4
  127. package/src/components/NavBar/SkNavBar.vue +5 -4
  128. package/src/components/NumberInput/SkNumberInput.vue +49 -8
  129. package/src/components/NumberInput/types.ts +2 -0
  130. package/src/components/Page/SkPage.vue +18 -15
  131. package/src/components/Pagination/SkPagination.vue +6 -3
  132. package/src/components/Pagination/SkPaginationItem.vue +8 -5
  133. package/src/components/Pagination/context.ts +19 -0
  134. package/src/components/Panel/types.ts +3 -2
  135. package/src/components/Popover/SkPopover.vue +11 -4
  136. package/src/components/Radio/SkRadio.vue +14 -4
  137. package/src/components/Radio/SkRadioGroup.vue +4 -2
  138. package/src/components/Radio/context.ts +17 -0
  139. package/src/components/Select/SkSelect.vue +39 -7
  140. package/src/components/Select/types.ts +2 -0
  141. package/src/components/Switch/SkSwitch.vue +14 -13
  142. package/src/components/Tabs/SkTab.vue +10 -3
  143. package/src/components/Tabs/SkTabList.vue +4 -2
  144. package/src/components/Tabs/SkTabs.vue +5 -3
  145. package/src/components/Tabs/context.ts +19 -0
  146. package/src/components/TagsInput/SkTagsInput.vue +28 -7
  147. package/src/components/Textarea/SkTextarea.vue +27 -6
  148. package/src/components/TreeView/SkTreeItem.vue +10 -2
  149. package/src/composables/injectionKeys.ts +52 -0
  150. package/src/index.ts +28 -0
  151. package/src/static/__tests__/parity.test.ts +2 -1
  152. package/src/static/__tests__/parityHarness.ts +5 -2
  153. package/src/static/components/__tests__/helpers.test.ts +191 -99
  154. package/src/static/components/alert.ts +12 -11
  155. package/src/static/components/avatar.ts +15 -16
  156. package/src/static/components/breadcrumbs.ts +3 -2
  157. package/src/static/components/button.ts +23 -27
  158. package/src/static/components/card.ts +3 -2
  159. package/src/static/components/checkbox.ts +11 -14
  160. package/src/static/components/colorPicker.ts +7 -9
  161. package/src/static/components/divider.ts +4 -3
  162. package/src/static/components/dropdown.ts +15 -6
  163. package/src/static/components/field.ts +32 -15
  164. package/src/static/components/group.ts +3 -2
  165. package/src/static/components/input.ts +20 -15
  166. package/src/static/components/inputGroup.ts +30 -0
  167. package/src/static/components/inputGroupAddon.ts +29 -0
  168. package/src/static/components/navBar.ts +30 -17
  169. package/src/static/components/numberInput.ts +17 -17
  170. package/src/static/components/page.ts +3 -2
  171. package/src/static/components/pagination.ts +3 -2
  172. package/src/static/components/panel.ts +3 -2
  173. package/src/static/components/progress.ts +3 -2
  174. package/src/static/components/radio.ts +14 -20
  175. package/src/static/components/select.ts +18 -15
  176. package/src/static/components/sidebar.ts +9 -13
  177. package/src/static/components/skeleton.ts +7 -10
  178. package/src/static/components/slider.ts +7 -9
  179. package/src/static/components/spinner.ts +22 -22
  180. package/src/static/components/switchInput.ts +12 -14
  181. package/src/static/components/table.ts +8 -10
  182. package/src/static/components/tag.ts +17 -11
  183. package/src/static/components/tagsInput.ts +3 -3
  184. package/src/static/components/textarea.ts +8 -13
  185. package/src/static/components/toolbar.ts +7 -10
  186. package/src/static/components/tooltip.ts +3 -2
  187. package/src/static/generated/defaults.ts +25 -9
  188. package/src/static/generated/propTypes.ts +19 -2
  189. package/src/static/h.ts +16 -0
  190. package/src/static/index.ts +8 -0
  191. package/src/static/render.test.ts +14 -10
  192. package/src/static/render.ts +33 -18
  193. package/src/static/specs.test.ts +1 -0
  194. package/src/static/specs.ts +22 -2
  195. package/src/static/stringH.ts +104 -0
  196. package/src/static/types.ts +25 -0
  197. package/src/styles/components/_autocomplete.scss +498 -0
  198. package/src/styles/components/_button.scss +55 -6
  199. package/src/styles/components/_index.scss +2 -0
  200. package/src/styles/components/_input-group.scss +292 -0
  201. package/src/styles/components/_input.scss +57 -9
  202. package/src/styles/components/_number-input.scss +88 -14
  203. package/src/styles/components/_select.scss +56 -9
  204. package/src/styles/mixins/_cut-border.scss +83 -0
  205. package/src/styles/tailwind.scss +262 -0
  206. package/src/styles/tokens.scss +8 -255
  207. package/src/types/corners.ts +10 -0
  208. package/src/utils/slots.test.ts +89 -0
  209. package/src/utils/slots.ts +80 -0
  210. package/web-types.json +392 -12
@@ -0,0 +1,85 @@
1
+ <!----------------------------------------------------------------------------------------------------------------------
2
+ - AutocompleteItem Component
3
+ --------------------------------------------------------------------------------------------------------------------->
4
+
5
+ <template>
6
+ <AutocompleteItem
7
+ :class="classes"
8
+ :value="value"
9
+ :disabled="disabled"
10
+ :text-value="textValue"
11
+ >
12
+ <slot />
13
+ </AutocompleteItem>
14
+ </template>
15
+
16
+ <!--------------------------------------------------------------------------------------------------------------------->
17
+
18
+ <style lang="scss" scoped>
19
+ // Component styles are in /src/styles/components/_autocomplete.scss
20
+ </style>
21
+
22
+ <!--------------------------------------------------------------------------------------------------------------------->
23
+
24
+ <script setup lang="ts">
25
+ /**
26
+ * @component SkAutocompleteItem
27
+ * @description A selectable suggestion within an SkAutocomplete dropdown. When chosen, the item's
28
+ * `value` is written into the input. Built on RekaUI's AutocompleteItem with keyboard navigation
29
+ * and type-ahead support.
30
+ *
31
+ * @example
32
+ * ```vue
33
+ * <SkAutocomplete v-model="query">
34
+ * <SkAutocompleteItem value="apple">Apple</SkAutocompleteItem>
35
+ * <SkAutocompleteItem value="banana">Banana</SkAutocompleteItem>
36
+ * <SkAutocompleteItem value="cherry" disabled>Cherry (out of stock)</SkAutocompleteItem>
37
+ * </SkAutocomplete>
38
+ * ```
39
+ *
40
+ * @slot default - The display content for this suggestion. Can be plain text or rich content.
41
+ */
42
+
43
+ import { computed } from 'vue';
44
+ import { AutocompleteItem } from 'reka-ui';
45
+
46
+ //------------------------------------------------------------------------------------------------------------------
47
+
48
+ export interface SkAutocompleteItemComponentProps
49
+ {
50
+ /**
51
+ * The string written into the input when this item is selected. Must be unique
52
+ * within the autocomplete to ensure proper highlight/match behavior.
53
+ */
54
+ value : string;
55
+
56
+ /**
57
+ * When true, this suggestion is disabled and cannot be selected. Skipped during
58
+ * keyboard navigation.
59
+ * @default false
60
+ */
61
+ disabled ?: boolean;
62
+
63
+ /**
64
+ * Optional override for filter/typeahead matching. Use when the slot content is
65
+ * non-textual (icons, custom layouts) and you need to specify what text the
66
+ * client-side filter should match against.
67
+ */
68
+ textValue ?: string;
69
+ }
70
+
71
+ //------------------------------------------------------------------------------------------------------------------
72
+
73
+ withDefaults(defineProps<SkAutocompleteItemComponentProps>(), {
74
+ disabled: false,
75
+ textValue: undefined,
76
+ });
77
+
78
+ //------------------------------------------------------------------------------------------------------------------
79
+
80
+ const classes = computed(() => ({
81
+ 'sk-autocomplete-item': true,
82
+ }));
83
+ </script>
84
+
85
+ <!--------------------------------------------------------------------------------------------------------------------->
@@ -0,0 +1,39 @@
1
+ <!----------------------------------------------------------------------------------------------------------------------
2
+ - AutocompleteSeparator Component
3
+ --------------------------------------------------------------------------------------------------------------------->
4
+
5
+ <template>
6
+ <AutocompleteSeparator class="sk-autocomplete-separator" />
7
+ </template>
8
+
9
+ <!--------------------------------------------------------------------------------------------------------------------->
10
+
11
+ <style lang="scss" scoped>
12
+ // Component styles are in /src/styles/components/_autocomplete.scss
13
+ </style>
14
+
15
+ <!--------------------------------------------------------------------------------------------------------------------->
16
+
17
+ <script setup lang="ts">
18
+ /**
19
+ * @component SkAutocompleteSeparator
20
+ * @description A visual divider for organizing suggestions within an SkAutocomplete dropdown. Renders
21
+ * as a horizontal line between items with appropriate spacing.
22
+ *
23
+ * @example
24
+ * ```vue
25
+ * <SkAutocomplete v-model="query">
26
+ * <SkAutocompleteItem value="recent1">Recent search 1</SkAutocompleteItem>
27
+ * <SkAutocompleteItem value="recent2">Recent search 2</SkAutocompleteItem>
28
+ * <SkAutocompleteSeparator />
29
+ * <SkAutocompleteItem value="popular">Popular searches...</SkAutocompleteItem>
30
+ * </SkAutocomplete>
31
+ * ```
32
+ *
33
+ * @slot - Not applicable. This component does not accept slot content.
34
+ */
35
+
36
+ import { AutocompleteSeparator } from 'reka-ui';
37
+ </script>
38
+
39
+ <!--------------------------------------------------------------------------------------------------------------------->
@@ -0,0 +1,13 @@
1
+ //----------------------------------------------------------------------------------------------------------------------
2
+ // Autocomplete Component Exports
3
+ //----------------------------------------------------------------------------------------------------------------------
4
+
5
+ export { default as SkAutocomplete } from './SkAutocomplete.vue';
6
+ export { default as SkAutocompleteEmpty } from './SkAutocompleteEmpty.vue';
7
+ export { default as SkAutocompleteGroup } from './SkAutocompleteGroup.vue';
8
+ export { default as SkAutocompleteGroupLabel } from './SkAutocompleteGroupLabel.vue';
9
+ export { default as SkAutocompleteItem } from './SkAutocompleteItem.vue';
10
+ export { default as SkAutocompleteSeparator } from './SkAutocompleteSeparator.vue';
11
+ export type { SkAutocompleteKind, SkAutocompleteSize } from './types';
12
+
13
+ //----------------------------------------------------------------------------------------------------------------------
@@ -0,0 +1,10 @@
1
+ //----------------------------------------------------------------------------------------------------------------------
2
+ // Autocomplete Component Types
3
+ //----------------------------------------------------------------------------------------------------------------------
4
+
5
+ import type { ComponentKind, ComponentSize } from '@/types';
6
+
7
+ export type SkAutocompleteKind = ComponentKind;
8
+ export type SkAutocompleteSize = ComponentSize;
9
+
10
+ //----------------------------------------------------------------------------------------------------------------------
@@ -59,7 +59,10 @@
59
59
  import { RouterLink } from 'vue-router';
60
60
 
61
61
  // Types
62
- import type { SkBreadcrumbItemProps, SkBreadcrumbsKind } from './types';
62
+ import type { SkBreadcrumbItemProps } from './types';
63
+
64
+ // Context
65
+ import { BREADCRUMBS_KIND_KEY } from './context';
63
66
 
64
67
  //------------------------------------------------------------------------------------------------------------------
65
68
 
@@ -106,7 +109,9 @@
106
109
 
107
110
  //------------------------------------------------------------------------------------------------------------------
108
111
 
109
- const kind = inject<SkBreadcrumbsKind>('breadcrumbs-kind', 'neutral');
112
+ // BREADCRUMBS_KIND_KEY carries a Ref<SkBreadcrumbsKind | undefined>, so we read .value below.
113
+ // (Pre-typed-key code mistakenly treated this as a plain string and rendered `sk-[object Object]`.)
114
+ const kindRef = inject(BREADCRUMBS_KIND_KEY, computed(() => undefined));
110
115
 
111
116
  //------------------------------------------------------------------------------------------------------------------
112
117
 
@@ -129,7 +134,7 @@
129
134
 
130
135
  const linkClasses = computed(() => ({
131
136
  'sk-breadcrumb-link': true,
132
- [`sk-${ kind }`]: true,
137
+ [`sk-${ kindRef.value ?? 'neutral' }`]: true,
133
138
  }));
134
139
 
135
140
  //------------------------------------------------------------------------------------------------------------------
@@ -34,6 +34,9 @@
34
34
 
35
35
  import { computed, inject } from 'vue';
36
36
 
37
+ // Context
38
+ import { BREADCRUMBS_SEPARATOR_KEY } from './context';
39
+
37
40
  //------------------------------------------------------------------------------------------------------------------
38
41
 
39
42
  export interface SkBreadcrumbSeparatorComponentProps
@@ -55,11 +58,14 @@
55
58
 
56
59
  //------------------------------------------------------------------------------------------------------------------
57
60
 
58
- const parentSeparator = inject<string>('breadcrumbs-separator', '/');
61
+ // BREADCRUMBS_SEPARATOR_KEY carries a Ref<string | undefined>, so we read .value below.
62
+ // (Pre-typed-key code mistakenly treated this as a plain string and rendered `[object Object]`
63
+ // for the separator inside an SkBreadcrumbs.)
64
+ const parentSeparator = inject(BREADCRUMBS_SEPARATOR_KEY, computed(() => undefined));
59
65
 
60
66
  //------------------------------------------------------------------------------------------------------------------
61
67
 
62
- const displaySeparator = computed<string>(() => props.separator ?? parentSeparator);
68
+ const displaySeparator = computed<string>(() => props.separator ?? parentSeparator.value ?? '/');
63
69
 
64
70
  //------------------------------------------------------------------------------------------------------------------
65
71
  </script>
@@ -46,6 +46,9 @@
46
46
  import type { ComponentCustomColors } from '@/types';
47
47
  import type { SkBreadcrumbsProps } from './types';
48
48
 
49
+ // Utils
50
+ import { filterRenderableVNodes } from '@/utils/slots';
51
+
49
52
  //------------------------------------------------------------------------------------------------------------------
50
53
 
51
54
  export interface SkBreadcrumbsComponentProps extends SkBreadcrumbsProps, ComponentCustomColors
@@ -74,6 +77,9 @@
74
77
  // Composables
75
78
  import { useCustomColors } from '@/composables/useCustomColors';
76
79
 
80
+ // Context
81
+ import { BREADCRUMBS_KIND_KEY, BREADCRUMBS_SEPARATOR_KEY } from './context';
82
+
77
83
  //------------------------------------------------------------------------------------------------------------------
78
84
 
79
85
  const props = withDefaults(defineProps<SkBreadcrumbsComponentProps>(), {
@@ -89,8 +95,8 @@
89
95
 
90
96
  //------------------------------------------------------------------------------------------------------------------
91
97
 
92
- provide('breadcrumbs-kind', toRef(() => props.kind));
93
- provide('breadcrumbs-separator', toRef(() => props.separator));
98
+ provide(BREADCRUMBS_KIND_KEY, toRef(() => props.kind));
99
+ provide(BREADCRUMBS_SEPARATOR_KEY, toRef(() => props.separator));
94
100
 
95
101
  //------------------------------------------------------------------------------------------------------------------
96
102
 
@@ -109,18 +115,9 @@
109
115
 
110
116
  const processedItems = computed<VNode[]>(() =>
111
117
  {
112
- if(!slots.default)
113
- {
114
- return [];
115
- }
116
-
117
- const defaultSlot = slots.default();
118
- if(!defaultSlot || defaultSlot.length === 0)
119
- {
120
- return [];
121
- }
122
-
123
- return defaultSlot;
118
+ if(!slots.default) { return []; }
119
+
120
+ return filterRenderableVNodes(slots.default());
124
121
  });
125
122
 
126
123
  //------------------------------------------------------------------------------------------------------------------
@@ -0,0 +1,20 @@
1
+ //----------------------------------------------------------------------------------------------------------------------
2
+ // Breadcrumbs Context
3
+ //
4
+ // Injection keys for SkBreadcrumbItem and SkBreadcrumbSeparator descendants to inherit kind and
5
+ // separator from the surrounding SkBreadcrumbs without manual wiring.
6
+ //----------------------------------------------------------------------------------------------------------------------
7
+
8
+ import type { InjectionKey, Ref } from 'vue';
9
+
10
+ import type { SkBreadcrumbsKind } from './types';
11
+
12
+ //----------------------------------------------------------------------------------------------------------------------
13
+
14
+ export const BREADCRUMBS_KIND_KEY : InjectionKey<Ref<SkBreadcrumbsKind | undefined>>
15
+ = Symbol('sk-breadcrumbs-kind');
16
+
17
+ export const BREADCRUMBS_SEPARATOR_KEY : InjectionKey<Ref<string | undefined>>
18
+ = Symbol('sk-breadcrumbs-separator');
19
+
20
+ //----------------------------------------------------------------------------------------------------------------------
@@ -18,16 +18,16 @@
18
18
  <span class="sk-button-chrome">
19
19
  <span v-if="loading" class="sk-button-loader" aria-hidden="true" />
20
20
  <span :class="{ 'sk-button-content': true, 'loading': loading }">
21
- <span v-if="$slots.leading" class="sk-button-icon sk-button-icon-leading">
21
+ <span v-if="hasSlotContent(slots.leading)" class="sk-button-icon sk-button-icon-leading">
22
22
  <slot name="leading" />
23
23
  </span>
24
- <span v-if="$slots.icon" class="sk-button-icon sk-button-icon-only">
24
+ <span v-if="hasSlotContent(slots.icon)" class="sk-button-icon sk-button-icon-only">
25
25
  <slot name="icon" />
26
26
  </span>
27
- <span v-if="$slots.default" class="sk-button-text">
27
+ <span v-if="hasSlotContent(slots.default)" class="sk-button-text">
28
28
  <slot />
29
29
  </span>
30
- <span v-if="$slots.trailing" class="sk-button-icon sk-button-icon-trailing">
30
+ <span v-if="hasSlotContent(slots.trailing)" class="sk-button-icon sk-button-icon-trailing">
31
31
  <slot name="trailing" />
32
32
  </span>
33
33
  </span>
@@ -63,15 +63,25 @@
63
63
  * @slot icon - Icon for icon-only buttons. When used without the default slot, creates a square icon button.
64
64
  */
65
65
 
66
- import { type Slots, computed, toRef, useSlots } from 'vue';
66
+ import { type Slots, computed, inject, toRef, useSlots } from 'vue';
67
67
 
68
68
  // Types
69
69
  import type { ComponentCustomColors } from '@/types';
70
- import type { SkButtonKind, SkButtonSize, SkButtonType, SkButtonVariant } from './types';
70
+ import type { SkButtonCorner, SkButtonKind, SkButtonSize, SkButtonType, SkButtonVariant } from './types';
71
71
 
72
72
  // Composables
73
+ import {
74
+ NO_KIND,
75
+ NO_SIZE,
76
+ inheritedKindKey,
77
+ inputGroupSizeKey,
78
+ validationKindKey,
79
+ } from '@/composables/injectionKeys';
73
80
  import { useCustomColors } from '@/composables/useCustomColors';
74
81
 
82
+ // Utils
83
+ import { hasSlotContent } from '@/utils/slots';
84
+
75
85
  //------------------------------------------------------------------------------------------------------------------
76
86
 
77
87
  export interface SkButtonComponentProps extends ComponentCustomColors
@@ -140,6 +150,13 @@
140
150
  */
141
151
  dense ?: boolean;
142
152
 
153
+ /**
154
+ * Which corners receive the beveled cut. Pass an empty array for square corners.
155
+ * When omitted, defaults to the button's standalone visual (`top-left` + `bottom-right`).
156
+ * @default undefined (renders as ['top-left', 'bottom-right'])
157
+ */
158
+ corners ?: SkButtonCorner[];
159
+
143
160
  /**
144
161
  * URL for the button to navigate to. When provided, the button renders as an `<a>` element
145
162
  * instead of a `<button>`. Use for external links or simple navigation that doesn't require
@@ -161,13 +178,14 @@
161
178
 
162
179
  const props = withDefaults(defineProps<SkButtonComponentProps>(), {
163
180
  type: 'button',
164
- kind: 'neutral',
181
+ kind: undefined,
165
182
  variant: 'solid',
166
- size: 'md',
183
+ size: undefined,
167
184
  disabled: false,
168
185
  loading: false,
169
186
  pressed: false,
170
187
  dense: false,
188
+ corners: undefined,
171
189
  href: undefined,
172
190
  to: undefined,
173
191
  });
@@ -178,6 +196,27 @@
178
196
 
179
197
  //------------------------------------------------------------------------------------------------------------------
180
198
 
199
+ const validationKind = inject(validationKindKey, NO_KIND);
200
+ const inheritedKind = inject(inheritedKindKey, NO_KIND);
201
+ const inputGroupSize = inject(inputGroupSizeKey, NO_SIZE);
202
+
203
+ const effectiveKind = computed<SkButtonKind>(() =>
204
+ {
205
+ if(validationKind.value !== undefined) { return validationKind.value; }
206
+ if(props.kind !== undefined) { return props.kind; }
207
+ if(inheritedKind.value !== undefined) { return inheritedKind.value; }
208
+ return 'neutral';
209
+ });
210
+
211
+ const effectiveSize = computed<SkButtonSize>(() =>
212
+ {
213
+ if(props.size !== undefined) { return props.size; }
214
+ if(inputGroupSize.value !== undefined) { return inputGroupSize.value; }
215
+ return 'md';
216
+ });
217
+
218
+ //------------------------------------------------------------------------------------------------------------------
219
+
181
220
  // Determine which component to render
182
221
  const componentTag = computed<string>(() =>
183
222
  {
@@ -199,17 +238,21 @@
199
238
 
200
239
  const classes = computed<Record<string, boolean>>(() =>
201
240
  {
202
- const isIconOnly = !!(slots.icon && !slots.default);
241
+ const isIconOnly = hasSlotContent(slots.icon) && !hasSlotContent(slots.default);
203
242
 
204
243
  return {
205
244
  'sk-button': true,
206
- [`sk-${ props.kind }`]: true,
245
+ [`sk-${ effectiveKind.value }`]: true,
207
246
  [`sk-${ props.variant }`]: true,
208
- [`sk-${ props.size }`]: true,
247
+ [`sk-${ effectiveSize.value }`]: true,
209
248
  'sk-loading': props.loading,
210
249
  'sk-pressed': props.pressed,
211
250
  'sk-dense': props.dense,
212
251
  'sk-icon-only': isIconOnly,
252
+ 'sk-cut-top-left': props.corners?.includes('top-left') ?? false,
253
+ 'sk-cut-top-right': props.corners?.includes('top-right') ?? false,
254
+ 'sk-cut-bottom-right': props.corners?.includes('bottom-right') ?? false,
255
+ 'sk-cut-bottom-left': props.corners?.includes('bottom-left') ?? false,
213
256
  };
214
257
  });
215
258
 
@@ -4,11 +4,17 @@
4
4
 
5
5
  import type { ComponentKind, ComponentSize, ComponentVariant } from '@/types';
6
6
 
7
+ // Types
8
+ import type { SkCorner } from '@/types/corners';
9
+
7
10
  //----------------------------------------------------------------------------------------------------------------------
8
11
 
9
12
  // HTML button type attribute
10
13
  export type SkButtonType = 'button' | 'submit' | 'reset';
11
14
 
15
+ // Button corner type (controls which corners receive the beveled cut)
16
+ export type SkButtonCorner = SkCorner;
17
+
12
18
  // Button semantic kinds (uses common types)
13
19
  export type SkButtonKind = ComponentKind;
14
20
 
@@ -15,19 +15,19 @@
15
15
  :decoration-corner="decorationCorner"
16
16
  :class="classes"
17
17
  >
18
- <div v-if="title || $slots.header" class="sk-card-header" :style="headerStyles">
18
+ <div v-if="title || hasSlotContent(slots.header)" class="sk-card-header" :style="headerStyles">
19
19
  <h3 v-if="title" class="sk-card-title">
20
20
  {{ title }}
21
21
  </h3>
22
22
  <slot name="header" />
23
23
  </div>
24
- <div v-if="$slots.media" class="sk-card-media">
24
+ <div v-if="hasSlotContent(slots.media)" class="sk-card-media">
25
25
  <slot name="media" />
26
26
  </div>
27
- <div v-if="$slots.default" :class="contentClasses">
27
+ <div v-if="hasSlotContent(slots.default)" :class="contentClasses">
28
28
  <slot />
29
29
  </div>
30
- <div v-if="$slots.footer" class="sk-card-footer">
30
+ <div v-if="hasSlotContent(slots.footer)" class="sk-card-footer">
31
31
  <slot name="footer" />
32
32
  </div>
33
33
  </SkPanel>
@@ -64,7 +64,7 @@
64
64
  * appropriate spacing.
65
65
  */
66
66
 
67
- import { computed } from 'vue';
67
+ import { computed, useSlots } from 'vue';
68
68
 
69
69
  // Types
70
70
  import type { ComponentCustomColors } from '@/types';
@@ -74,6 +74,9 @@
74
74
  // Components
75
75
  import SkPanel from '../Panel/SkPanel.vue';
76
76
 
77
+ // Utils
78
+ import { hasSlotContent } from '@/utils/slots';
79
+
77
80
  //------------------------------------------------------------------------------------------------------------------
78
81
 
79
82
  export interface SkCardComponentProps extends ComponentCustomColors
@@ -170,6 +173,10 @@
170
173
 
171
174
  //------------------------------------------------------------------------------------------------------------------
172
175
 
176
+ const slots = useSlots();
177
+
178
+ //------------------------------------------------------------------------------------------------------------------
179
+
173
180
  const classes = computed(() =>
174
181
  {
175
182
  return {
@@ -42,7 +42,7 @@
42
42
  </svg>
43
43
  </CheckboxIndicator>
44
44
  </CheckboxRoot>
45
- <span v-if="label || $slots.default" class="sk-checkbox-label">
45
+ <span v-if="label || hasSlotContent(slots.default)" class="sk-checkbox-label">
46
46
  <slot>{{ label }}</slot>
47
47
  </span>
48
48
  </label>
@@ -71,7 +71,7 @@
71
71
  * @slot default - Custom label content. Overrides the `label` prop when provided.
72
72
  */
73
73
 
74
- import { computed, toRef } from 'vue';
74
+ import { computed, toRef, useSlots } from 'vue';
75
75
  import { CheckboxIndicator, CheckboxRoot } from 'reka-ui';
76
76
 
77
77
  // Types
@@ -81,6 +81,9 @@
81
81
  // Composables
82
82
  import { useCustomColors } from '@/composables/useCustomColors';
83
83
 
84
+ // Utils
85
+ import { hasSlotContent } from '@/utils/slots';
86
+
84
87
  //------------------------------------------------------------------------------------------------------------------
85
88
 
86
89
  export interface SkCheckboxComponentProps extends ComponentCustomColors
@@ -151,6 +154,10 @@
151
154
 
152
155
  //------------------------------------------------------------------------------------------------------------------
153
156
 
157
+ const slots = useSlots();
158
+
159
+ //------------------------------------------------------------------------------------------------------------------
160
+
154
161
  const classes = computed(() => ({
155
162
  'sk-checkbox': true,
156
163
  [`sk-${ props.kind }`]: true,
@@ -226,7 +226,7 @@
226
226
  <!--------------------------------------------------------------------------------------------------------------------->
227
227
 
228
228
  <script setup lang="ts">
229
- import { type Component, type ComputedRef, computed, inject, ref, toRef } from 'vue';
229
+ import { type Component, computed, inject, ref, toRef } from 'vue';
230
230
  import {
231
231
  type ColorObject,
232
232
  ColorPickerCanvas,
@@ -251,6 +251,13 @@
251
251
  import type { SkColorPickerFormat, SkColorPickerKind, SkColorPickerSize } from './types';
252
252
 
253
253
  // Composables
254
+ import {
255
+ NO_KIND,
256
+ NO_SIZE,
257
+ inheritedKindKey,
258
+ inputGroupSizeKey,
259
+ validationKindKey,
260
+ } from '@/composables/injectionKeys';
254
261
  import { useCustomColors } from '@/composables/useCustomColors';
255
262
  import { usePortalContext } from '@/composables/usePortalContext';
256
263
 
@@ -283,7 +290,7 @@
283
290
 
284
291
  const props = withDefaults(defineProps<SkColorPickerComponentProps>(), {
285
292
  kind: undefined,
286
- size: 'md',
293
+ size: undefined,
287
294
  format: 'hexa',
288
295
  showAlpha: true,
289
296
  disabled: false,
@@ -299,19 +306,34 @@
299
306
 
300
307
  const { theme } = usePortalContext();
301
308
 
302
- const fieldKind = inject<ComputedRef<SkColorPickerKind | undefined>>('field-kind', computed(() => undefined));
309
+ const validationKind = inject(validationKindKey, NO_KIND);
310
+ const inheritedKind = inject(inheritedKindKey, NO_KIND);
311
+ const inputGroupSize = inject(inputGroupSizeKey, NO_SIZE);
303
312
  const displayFormat = ref<DisplayFormat>('Hex');
304
313
 
305
314
  //------------------------------------------------------------------------------------------------------------------
306
315
 
307
- const effectiveKind = computed(() => fieldKind.value || props.kind || 'neutral');
316
+ const effectiveKind = computed<SkColorPickerKind>(() =>
317
+ {
318
+ if(validationKind.value !== undefined) { return validationKind.value; }
319
+ if(props.kind !== undefined) { return props.kind; }
320
+ if(inheritedKind.value !== undefined) { return inheritedKind.value; }
321
+ return 'neutral';
322
+ });
323
+
324
+ const effectiveSize = computed<SkColorPickerSize>(() =>
325
+ {
326
+ if(props.size !== undefined) { return props.size; }
327
+ if(inputGroupSize.value !== undefined) { return inputGroupSize.value; }
328
+ return 'md';
329
+ });
308
330
 
309
331
  //------------------------------------------------------------------------------------------------------------------
310
332
 
311
333
  const wrapperClasses = computed(() => ({
312
334
  'sk-color-picker': true,
313
335
  [`sk-${ effectiveKind.value }`]: true,
314
- [`sk-${ props.size }`]: true,
336
+ [`sk-${ effectiveSize.value }`]: true,
315
337
  'sk-disabled': props.disabled,
316
338
  }));
317
339
 
@@ -45,6 +45,9 @@
45
45
  import { useCustomColors } from '@/composables/useCustomColors';
46
46
  import { usePortalContext } from '@/composables/usePortalContext';
47
47
 
48
+ // Context
49
+ import { CONTEXT_MENU_KIND_KEY } from './context';
50
+
48
51
  //------------------------------------------------------------------------------------------------------------------
49
52
 
50
53
  export interface SkContextMenuComponentProps extends ComponentCustomColors
@@ -62,7 +65,7 @@
62
65
 
63
66
  const { theme } = usePortalContext();
64
67
 
65
- provide('context-menu-kind', computed(() => props.kind));
68
+ provide(CONTEXT_MENU_KIND_KEY, computed(() => props.kind));
66
69
 
67
70
  //------------------------------------------------------------------------------------------------------------------
68
71
 
@@ -53,6 +53,9 @@
53
53
  // Composables
54
54
  import { usePortalContext } from '@/composables/usePortalContext';
55
55
 
56
+ // Context
57
+ import { CONTEXT_MENU_KIND_KEY } from './context';
58
+
56
59
  //------------------------------------------------------------------------------------------------------------------
57
60
 
58
61
  export interface SkContextMenuSubmenuComponentProps
@@ -71,11 +74,11 @@
71
74
 
72
75
  const { theme } = usePortalContext();
73
76
 
74
- const parentKind = inject<any>('context-menu-kind', computed(() => 'neutral'));
77
+ const parentKind = inject(CONTEXT_MENU_KIND_KEY, computed(() => undefined));
75
78
 
76
79
  //------------------------------------------------------------------------------------------------------------------
77
80
 
78
- const effectiveKind = computed(() => props.kind || parentKind.value || 'neutral');
81
+ const effectiveKind = computed<SkContextMenuKind>(() => props.kind ?? parentKind.value ?? 'neutral');
79
82
 
80
83
  //------------------------------------------------------------------------------------------------------------------
81
84
 
@@ -0,0 +1,17 @@
1
+ //----------------------------------------------------------------------------------------------------------------------
2
+ // ContextMenu Context
3
+ //
4
+ // Injection key for nested SkContextMenuSubmenu descendants to inherit the surrounding
5
+ // SkContextMenu's kind without manual wiring.
6
+ //----------------------------------------------------------------------------------------------------------------------
7
+
8
+ import type { ComputedRef, InjectionKey } from 'vue';
9
+
10
+ import type { SkContextMenuKind } from './types';
11
+
12
+ //----------------------------------------------------------------------------------------------------------------------
13
+
14
+ export const CONTEXT_MENU_KIND_KEY : InjectionKey<ComputedRef<SkContextMenuKind | undefined>>
15
+ = Symbol('sk-context-menu-kind');
16
+
17
+ //----------------------------------------------------------------------------------------------------------------------