@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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@skewedaspect/sleekspace-ui",
3
- "version": "0.8.1",
3
+ "version": "0.9.1",
4
4
  "description": "A Vue 3 component library with a cyberpunk aesthetic, featuring OKLCH colors, beveled corners, and a powerful design token system",
5
5
  "type": "module",
6
6
  "main": "dist/sleekspace-ui.umd.js",
@@ -13,10 +13,19 @@
13
13
  "import": "./dist/sleekspace-ui.es.js",
14
14
  "require": "./dist/sleekspace-ui.umd.js"
15
15
  },
16
+ "./global": {
17
+ "types": "./dist/global.d.ts"
18
+ },
16
19
  "./style": "./dist/sleekspace-ui.css",
20
+ "./css": "./dist/sleekspace-ui.css",
17
21
  "./styles/source": "./src/styles/index.scss",
18
22
  "./styles/mixins/responsive": "./src/styles/mixins/_responsive.scss",
19
- "./tokens.css": "./dist/tokens.css"
23
+ "./tokens.css": "./dist/tokens.css",
24
+ "./static": {
25
+ "types": "./dist/static/index.d.ts",
26
+ "import": "./dist/static/index.es.js",
27
+ "require": "./dist/static/index.cjs.js"
28
+ }
20
29
  },
21
30
  "files": [
22
31
  "dist",
@@ -29,12 +38,17 @@
29
38
  "LICENSE"
30
39
  ],
31
40
  "scripts": {
32
- "dev": "vite build --watch",
33
- "build": "npm run generate:types && vue-docgen-web-types && vite build && npm run build:tokens && npm run copy:docs && npm run generate:llms",
41
+ "dev": "concurrently -n vite,tokens -c cyan,magenta \"npm run dev:vite\" \"npm run dev:tokens\"",
42
+ "dev:vite": "vite build --watch",
43
+ "dev:tokens": "sass --watch src/styles/tokens.scss dist/tokens.css --no-source-map",
44
+ "build": "npm run clean && npm run generate:static-types && npm run generate:web-types && vite build && npm run generate:types && npm run build:static && npm run build:tokens && npm run copy:docs && npm run generate:llms",
45
+ "clean": "rm -rf dist",
46
+ "build:static": "vite build -c vite.static.config.ts",
34
47
  "build:tokens": "sass src/styles/tokens.scss dist/tokens.css --no-source-map",
35
48
  "copy:docs": "cp ../../Readme.md README.md && cp ../../LICENSE LICENSE",
36
49
  "generate:types": "tsx scripts/generate-global-types.ts",
37
- "generate:web-types": "vue-docgen-web-types",
50
+ "generate:static-types": "node scripts/generate-static-types.ts",
51
+ "generate:web-types": "vue-docgen-web-types --configFile web-types.config.cjs && tsx scripts/patch-web-types.ts",
38
52
  "generate:api-docs": "node ../docs-site/scripts/generate-api-docs.ts",
39
53
  "generate:llms": "npm run generate:api-docs && node ../docs-site/scripts/generate-llms-txt.ts --output-dir=.",
40
54
  "lint": "eslint src"
@@ -94,6 +94,9 @@
94
94
  // Composables
95
95
  import { useCustomColors } from '@/composables/useCustomColors';
96
96
 
97
+ // Utils
98
+ import { hasSlotContent } from '@/utils/slots';
99
+
97
100
  //------------------------------------------------------------------------------------------------------------------
98
101
 
99
102
  // Kinds that have default icons
@@ -162,9 +165,8 @@
162
165
 
163
166
  // Auto-show if kind has a default icon or if slot content is provided
164
167
  const hasDefaultIcon = FEEDBACK_KINDS.includes(props.kind as typeof FEEDBACK_KINDS[number]);
165
- const hasSlotContent = !!slots.icon;
166
168
 
167
- return hasDefaultIcon || hasSlotContent;
169
+ return hasDefaultIcon || hasSlotContent(slots.icon);
168
170
  });
169
171
 
170
172
  //------------------------------------------------------------------------------------------------------------------
@@ -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
@@ -109,18 +112,9 @@
109
112
 
110
113
  const processedItems = computed<VNode[]>(() =>
111
114
  {
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;
115
+ if(!slots.default) { return []; }
116
+
117
+ return filterRenderableVNodes(slots.default());
124
118
  });
125
119
 
126
120
  //------------------------------------------------------------------------------------------------------------------
@@ -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>
@@ -72,6 +72,9 @@
72
72
  // Composables
73
73
  import { useCustomColors } from '@/composables/useCustomColors';
74
74
 
75
+ // Utils
76
+ import { hasSlotContent } from '@/utils/slots';
77
+
75
78
  //------------------------------------------------------------------------------------------------------------------
76
79
 
77
80
  export interface SkButtonComponentProps extends ComponentCustomColors
@@ -199,7 +202,7 @@
199
202
 
200
203
  const classes = computed<Record<string, boolean>>(() =>
201
204
  {
202
- const isIconOnly = !!(slots.icon && !slots.default);
205
+ const isIconOnly = hasSlotContent(slots.icon) && !hasSlotContent(slots.default);
203
206
 
204
207
  return {
205
208
  'sk-button': true,
@@ -10,23 +10,24 @@
10
10
  :no-border="noBorder"
11
11
  :base-color="baseColor"
12
12
  :text-color="textColor"
13
+ :border-color="borderColor"
13
14
  :corners="corners"
14
15
  :decoration-corner="decorationCorner"
15
16
  :class="classes"
16
17
  >
17
- <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">
18
19
  <h3 v-if="title" class="sk-card-title">
19
20
  {{ title }}
20
21
  </h3>
21
22
  <slot name="header" />
22
23
  </div>
23
- <div v-if="$slots.media" class="sk-card-media">
24
+ <div v-if="hasSlotContent(slots.media)" class="sk-card-media">
24
25
  <slot name="media" />
25
26
  </div>
26
- <div v-if="$slots.default" :class="contentClasses">
27
+ <div v-if="hasSlotContent(slots.default)" :class="contentClasses">
27
28
  <slot />
28
29
  </div>
29
- <div v-if="$slots.footer" class="sk-card-footer">
30
+ <div v-if="hasSlotContent(slots.footer)" class="sk-card-footer">
30
31
  <slot name="footer" />
31
32
  </div>
32
33
  </SkPanel>
@@ -63,7 +64,7 @@
63
64
  * appropriate spacing.
64
65
  */
65
66
 
66
- import { computed } from 'vue';
67
+ import { computed, useSlots } from 'vue';
67
68
 
68
69
  // Types
69
70
  import type { ComponentCustomColors } from '@/types';
@@ -73,6 +74,9 @@
73
74
  // Components
74
75
  import SkPanel from '../Panel/SkPanel.vue';
75
76
 
77
+ // Utils
78
+ import { hasSlotContent } from '@/utils/slots';
79
+
76
80
  //------------------------------------------------------------------------------------------------------------------
77
81
 
78
82
  export interface SkCardComponentProps extends ComponentCustomColors
@@ -169,6 +173,10 @@
169
173
 
170
174
  //------------------------------------------------------------------------------------------------------------------
171
175
 
176
+ const slots = useSlots();
177
+
178
+ //------------------------------------------------------------------------------------------------------------------
179
+
172
180
  const classes = computed(() =>
173
181
  {
174
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,
@@ -3,7 +3,10 @@
3
3
  --------------------------------------------------------------------------------------------------------------------->
4
4
 
5
5
  <template>
6
- <ContextMenuRadioGroup :model-value="modelValue" @update:model-value="$emit('update:modelValue', $event)">
6
+ <ContextMenuRadioGroup
7
+ :model-value="modelValue"
8
+ @update:model-value="$emit('update:modelValue', $event as string)"
9
+ >
7
10
  <slot />
8
11
  </ContextMenuRadioGroup>
9
12
  </template>
@@ -6,7 +6,7 @@
6
6
  <DropdownMenuRoot>
7
7
  <DropdownMenuTrigger as-child>
8
8
  <slot name="trigger">
9
- <SkButton :kind="kind">
9
+ <SkButton :kind="kind" :size="effectiveSize">
10
10
  {{ triggerText }}
11
11
  <template #trailing>
12
12
  <svg
@@ -73,7 +73,7 @@
73
73
  * SkDropdownSubmenu components.
74
74
  */
75
75
 
76
- import { computed, provide, toRef } from 'vue';
76
+ import { type Ref, computed, inject, provide, toRef } from 'vue';
77
77
  import {
78
78
  DropdownMenuContent,
79
79
  DropdownMenuPortal,
@@ -83,7 +83,7 @@
83
83
 
84
84
  // Types
85
85
  import type { ComponentCustomColors } from '@/types';
86
- import type { SkDropdownAlign, SkDropdownKind, SkDropdownSide } from './types';
86
+ import type { SkDropdownAlign, SkDropdownKind, SkDropdownSide, SkDropdownSize } from './types';
87
87
 
88
88
  // Components
89
89
  import SkButton from '../Button/SkButton.vue';
@@ -92,6 +92,9 @@
92
92
  import { useCustomColors } from '@/composables/useCustomColors';
93
93
  import { usePortalContext } from '@/composables/usePortalContext';
94
94
 
95
+ // Context
96
+ import { NAVBAR_SIZE_KEY } from '../NavBar/context';
97
+
95
98
  //------------------------------------------------------------------------------------------------------------------
96
99
 
97
100
  export interface SkDropdownComponentProps extends ComponentCustomColors
@@ -135,6 +138,14 @@
135
138
  * @default 4
136
139
  */
137
140
  sideOffset ?: number;
141
+
142
+ /**
143
+ * Size of the default trigger button. When omitted and the dropdown is rendered inside
144
+ * an SkNavBar, falls back to the navbar's `size` prop so the trigger naturally matches
145
+ * surrounding nav controls. Ignored when the `trigger` slot is used.
146
+ * @default 'md' (or navbar size when nested in an SkNavBar)
147
+ */
148
+ size ?: SkDropdownSize;
138
149
  }
139
150
 
140
151
  //------------------------------------------------------------------------------------------------------------------
@@ -145,6 +156,7 @@
145
156
  side: 'bottom',
146
157
  align: 'start',
147
158
  sideOffset: 4,
159
+ size: undefined,
148
160
  });
149
161
 
150
162
  //------------------------------------------------------------------------------------------------------------------
@@ -152,6 +164,11 @@
152
164
  // Handle portal context (theme injection/re-provision for nested portal components)
153
165
  const { theme } = usePortalContext();
154
166
 
167
+ // Pick up the navbar's size when nested inside an SkNavBar so the trigger fits the bar.
168
+ const navbarSize = inject<Ref<SkDropdownSize> | undefined>(NAVBAR_SIZE_KEY, undefined);
169
+
170
+ const effectiveSize = computed<SkDropdownSize>(() => props.size ?? navbarSize?.value ?? 'md');
171
+
155
172
  // Provide kind for submenus (reactive computed so changes propagate)
156
173
  provide('dropdown-kind', computed(() => props.kind));
157
174
 
@@ -3,7 +3,10 @@
3
3
  --------------------------------------------------------------------------------------------------------------------->
4
4
 
5
5
  <template>
6
- <DropdownMenuRadioGroup :model-value="modelValue" @update:model-value="$emit('update:modelValue', $event)">
6
+ <DropdownMenuRadioGroup
7
+ :model-value="modelValue"
8
+ @update:model-value="$emit('update:modelValue', $event as string)"
9
+ >
7
10
  <slot />
8
11
  </DropdownMenuRadioGroup>
9
12
  </template>
@@ -2,9 +2,10 @@
2
2
  // Dropdown Component Types
3
3
  //----------------------------------------------------------------------------------------------------------------------
4
4
 
5
- import type { ComponentKind } from '@/types';
5
+ import type { ComponentKind, ComponentSize } from '@/types';
6
6
 
7
7
  export type SkDropdownKind = ComponentKind;
8
+ export type SkDropdownSize = ComponentSize;
8
9
  export type SkDropdownSide = 'top' | 'right' | 'bottom' | 'left';
9
10
  export type SkDropdownAlign = 'start' | 'center' | 'end';
10
11
 
@@ -1,6 +1,6 @@
1
1
  <template>
2
2
  <DialogRoot v-model:open="isOpen">
3
- <DialogTrigger v-if="$slots.trigger || triggerText" as-child>
3
+ <DialogTrigger v-if="hasSlotContent(slots.trigger) || triggerText" as-child>
4
4
  <slot name="trigger">
5
5
  <SkButton :kind="kind">
6
6
  {{ triggerText }}
@@ -17,7 +17,7 @@
17
17
  @pointer-down-outside="handleOverlayClick"
18
18
  @interact-outside="handleOverlayClick"
19
19
  >
20
- <div v-if="$slots.title || title" class="sk-modal-header">
20
+ <div v-if="hasSlotContent(slots.title) || title" class="sk-modal-header">
21
21
  <DialogTitle class="sk-modal-title">
22
22
  <slot name="title" :close="close">
23
23
  {{ title }}
@@ -40,7 +40,7 @@
40
40
  <div class="sk-modal-body">
41
41
  <slot :close="close" />
42
42
  </div>
43
- <div v-if="$slots.footer" class="sk-modal-footer">
43
+ <div v-if="hasSlotContent(slots.footer)" class="sk-modal-footer">
44
44
  <slot name="footer" :close="close" />
45
45
  </div>
46
46
  </DialogContent>
@@ -88,7 +88,7 @@
88
88
  * @slot footer - Footer content, typically containing action buttons. Receives `{ close }` slot prop.
89
89
  */
90
90
 
91
- import { computed, ref, toRef, watch } from 'vue';
91
+ import { type Slots, computed, ref, toRef, useSlots, watch } from 'vue';
92
92
  import {
93
93
  DialogClose,
94
94
  DialogContent,
@@ -106,6 +106,9 @@
106
106
  import { useCustomColors } from '@/composables/useCustomColors';
107
107
  import { usePortalContext } from '@/composables/usePortalContext';
108
108
 
109
+ // Utils
110
+ import { hasSlotContent } from '@/utils/slots';
111
+
109
112
  // Components
110
113
  import SkButton from '../Button/SkButton.vue';
111
114
 
@@ -206,6 +209,10 @@
206
209
 
207
210
  //------------------------------------------------------------------------------------------------------------------
208
211
 
212
+ const slots : Slots = useSlots();
213
+
214
+ //------------------------------------------------------------------------------------------------------------------
215
+
209
216
  const isOpen = ref(props.open);
210
217
 
211
218
  watch(() => props.open, (newValue) =>
@@ -5,19 +5,19 @@
5
5
  <template>
6
6
  <nav :class="classes" :style="customColorStyles">
7
7
  <div class="sk-navbar-content">
8
- <div v-if="slots.leading" class="sk-navbar-leading">
8
+ <div v-if="hasSlotContent(slots.leading)" class="sk-navbar-leading">
9
9
  <slot name="leading" />
10
10
  </div>
11
11
 
12
- <div v-if="slots.brand" class="sk-navbar-brand">
12
+ <div v-if="hasSlotContent(slots.brand)" class="sk-navbar-brand">
13
13
  <slot name="brand" />
14
14
  </div>
15
15
 
16
- <div v-if="slots.default" class="sk-navbar-nav">
16
+ <div v-if="hasSlotContent(slots.default)" class="sk-navbar-nav">
17
17
  <slot />
18
18
  </div>
19
19
 
20
- <div v-if="slots.actions" class="sk-navbar-actions">
20
+ <div v-if="hasSlotContent(slots.actions)" class="sk-navbar-actions">
21
21
  <slot name="actions" />
22
22
  </div>
23
23
  </div>
@@ -59,10 +59,11 @@
59
59
  */
60
60
 
61
61
  import { computed, provide, toRef, useSlots } from 'vue';
62
- import type { SkNavBarKind } from './types';
62
+ import type { SkNavBarKind, SkNavBarSize } from './types';
63
63
  import type { ComponentCustomColors } from '@/types';
64
64
  import { useCustomColors } from '@/composables/useCustomColors';
65
- import { NAVBAR_KIND_KEY } from './context';
65
+ import { hasSlotContent } from '@/utils/slots';
66
+ import { NAVBAR_KIND_KEY, NAVBAR_SIZE_KEY } from './context';
66
67
 
67
68
  //------------------------------------------------------------------------------------------------------------------
68
69
 
@@ -83,6 +84,14 @@
83
84
  * @default true
84
85
  */
85
86
  sticky ?: boolean;
87
+
88
+ /**
89
+ * Default size for descendant components (buttons, dropdowns, sidebar toggles, etc.) that
90
+ * read the navbar context. Picks a size that fits the navbar's 4rem height without
91
+ * overflowing. Descendants can still override with their own `size` prop.
92
+ * @default 'md'
93
+ */
94
+ size ?: SkNavBarSize;
86
95
  }
87
96
 
88
97
  //------------------------------------------------------------------------------------------------------------------
@@ -90,11 +99,13 @@
90
99
  const props = withDefaults(defineProps<SkNavBarComponentProps>(), {
91
100
  kind: 'neutral',
92
101
  sticky: true,
102
+ size: 'md',
93
103
  });
94
104
 
95
- // Expose the navbar's kind to descendants so components like SkPageSidebarToggle can default
96
- // to the surrounding navbar's color scheme without the user wiring it manually.
105
+ // Expose the navbar's kind and size to descendants so components like SkPageSidebarToggle and
106
+ // SkDropdown can default to the surrounding navbar's look without the user wiring it manually.
97
107
  provide(NAVBAR_KIND_KEY, toRef(() => props.kind));
108
+ provide(NAVBAR_SIZE_KEY, toRef(() => props.size));
98
109
 
99
110
  //------------------------------------------------------------------------------------------------------------------
100
111
 
@@ -1,16 +1,18 @@
1
1
  //----------------------------------------------------------------------------------------------------------------------
2
2
  // NavBar Context
3
3
  //
4
- // Injection key for descendants (e.g. SkPageSidebarToggle) that want to inherit the surrounding
5
- // navbar's kind without the user wiring it manually.
4
+ // Injection keys for descendants (e.g. SkPageSidebarToggle, SkDropdown) that want to inherit the
5
+ // surrounding navbar's kind/size without the user wiring it manually.
6
6
  //----------------------------------------------------------------------------------------------------------------------
7
7
 
8
8
  import type { InjectionKey, Ref } from 'vue';
9
9
 
10
+ import type { ComponentSize } from '@/types';
10
11
  import type { SkNavBarKind } from './types';
11
12
 
12
13
  //----------------------------------------------------------------------------------------------------------------------
13
14
 
14
15
  export const NAVBAR_KIND_KEY : InjectionKey<Ref<SkNavBarKind>> = Symbol('sk-navbar-kind');
16
+ export const NAVBAR_SIZE_KEY : InjectionKey<Ref<ComponentSize>> = Symbol('sk-navbar-size');
15
17
 
16
18
  //----------------------------------------------------------------------------------------------------------------------
@@ -2,7 +2,7 @@
2
2
  // NavBar Types
3
3
  //----------------------------------------------------------------------------------------------------------------------
4
4
 
5
- import type { ComponentKind } from '@/types';
5
+ import type { ComponentKind, ComponentSize } from '@/types';
6
6
 
7
7
  //----------------------------------------------------------------------------------------------------------------------
8
8
 
@@ -12,4 +12,9 @@ import type { ComponentKind } from '@/types';
12
12
  */
13
13
  export type SkNavBarKind = ComponentKind;
14
14
 
15
+ /**
16
+ * Size hint propagated to descendant controls (buttons, dropdowns, sidebar toggles).
17
+ */
18
+ export type SkNavBarSize = ComponentSize;
19
+
15
20
  //----------------------------------------------------------------------------------------------------------------------
@@ -17,7 +17,7 @@
17
17
  :step="step"
18
18
  >
19
19
  <NumberFieldInput :class="inputClasses" :placeholder="placeholder" />
20
- <div class="sk-number-input-steppers">
20
+ <div v-if="showSteppers" class="sk-number-input-steppers">
21
21
  <NumberFieldIncrement class="sk-number-input-increment">
22
22
  <svg
23
23
  xmlns="http://www.w3.org/2000/svg"
@@ -170,6 +170,14 @@
170
170
  * @default 1
171
171
  */
172
172
  step ?: number;
173
+
174
+ /**
175
+ * When true, renders the increment/decrement stepper buttons on the right side of the
176
+ * input. Set to false for a plain numeric text field (users can still use arrow keys
177
+ * and type values directly).
178
+ * @default true
179
+ */
180
+ showSteppers ?: boolean;
173
181
  }
174
182
 
175
183
  //------------------------------------------------------------------------------------------------------------------
@@ -185,6 +193,7 @@
185
193
  min: undefined,
186
194
  max: undefined,
187
195
  step: 1,
196
+ showSteppers: true,
188
197
  });
189
198
 
190
199
  //------------------------------------------------------------------------------------------------------------------