@skewedaspect/sleekspace-ui 0.5.1 → 0.7.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 (121) hide show
  1. package/dist/components/Card/SkCard.vue.d.ts +13 -1
  2. package/dist/components/ColorPicker/SkColorPicker.vue.d.ts +29 -0
  3. package/dist/components/ColorPicker/index.d.ts +2 -0
  4. package/dist/components/ColorPicker/types.d.ts +4 -0
  5. package/dist/components/ContextMenu/SkContextMenu.vue.d.ts +25 -0
  6. package/dist/components/ContextMenu/SkContextMenuCheckboxItem.vue.d.ts +28 -0
  7. package/dist/components/ContextMenu/SkContextMenuItem.vue.d.ts +26 -0
  8. package/dist/components/ContextMenu/SkContextMenuLabel.vue.d.ts +17 -0
  9. package/dist/components/ContextMenu/SkContextMenuRadioGroup.vue.d.ts +26 -0
  10. package/dist/components/ContextMenu/SkContextMenuRadioItem.vue.d.ts +23 -0
  11. package/dist/components/ContextMenu/SkContextMenuSeparator.vue.d.ts +2 -0
  12. package/dist/components/ContextMenu/SkContextMenuSubmenu.vue.d.ts +24 -0
  13. package/dist/components/ContextMenu/index.d.ts +9 -0
  14. package/dist/components/ContextMenu/types.d.ts +2 -0
  15. package/dist/components/Dropdown/SkDropdown.vue.d.ts +1 -1
  16. package/dist/components/Dropdown/SkDropdownCheckboxItem.vue.d.ts +28 -0
  17. package/dist/components/Dropdown/SkDropdownMenuLabel.vue.d.ts +17 -0
  18. package/dist/components/Dropdown/SkDropdownRadioGroup.vue.d.ts +26 -0
  19. package/dist/components/Dropdown/SkDropdownRadioItem.vue.d.ts +23 -0
  20. package/dist/components/Dropdown/index.d.ts +4 -0
  21. package/dist/components/Panel/SkPanel.vue.d.ts +15 -1
  22. package/dist/components/Panel/types.d.ts +1 -0
  23. package/dist/components/Popover/SkPopover.vue.d.ts +1 -1
  24. package/dist/components/ScrollArea/SkScrollArea.vue.d.ts +31 -0
  25. package/dist/components/ScrollArea/index.d.ts +2 -0
  26. package/dist/components/ScrollArea/types.d.ts +4 -0
  27. package/dist/components/Select/SkSelect.vue.d.ts +61 -0
  28. package/dist/components/Select/SkSelectItem.vue.d.ts +134 -0
  29. package/dist/components/Select/SkSelectSeparator.vue.d.ts +2 -0
  30. package/dist/components/Select/index.d.ts +4 -0
  31. package/dist/components/Select/types.d.ts +3 -0
  32. package/dist/components/Sidebar/SkSidebar.vue.d.ts +8 -1
  33. package/dist/components/Sidebar/types.d.ts +1 -0
  34. package/dist/components/Skeleton/SkSkeleton.vue.d.ts +2 -2
  35. package/dist/components/Splitter/SkSplitter.vue.d.ts +29 -0
  36. package/dist/components/Splitter/SkSplitterHandle.vue.d.ts +7 -0
  37. package/dist/components/Splitter/SkSplitterPanel.vue.d.ts +30 -0
  38. package/dist/components/Splitter/index.d.ts +4 -0
  39. package/dist/components/Splitter/types.d.ts +3 -0
  40. package/dist/components/Toolbar/SkToolbar.vue.d.ts +31 -0
  41. package/dist/components/Toolbar/SkToolbarButton.vue.d.ts +22 -0
  42. package/dist/components/Toolbar/SkToolbarSeparator.vue.d.ts +2 -0
  43. package/dist/components/Toolbar/SkToolbarToggleGroup.vue.d.ts +31 -0
  44. package/dist/components/Toolbar/SkToolbarToggleItem.vue.d.ts +23 -0
  45. package/dist/components/Toolbar/index.d.ts +6 -0
  46. package/dist/components/Toolbar/types.d.ts +5 -0
  47. package/dist/components/Tooltip/SkTooltip.vue.d.ts +1 -1
  48. package/dist/components/TreeView/SkTreeItem.vue.d.ts +39 -0
  49. package/dist/components/TreeView/SkTreeView.vue.d.ts +31 -0
  50. package/dist/components/TreeView/index.d.ts +3 -0
  51. package/dist/components/TreeView/types.d.ts +3 -0
  52. package/dist/index.d.ts +61 -0
  53. package/dist/sleekspace-ui.css +1644 -65
  54. package/dist/sleekspace-ui.es.js +17444 -6063
  55. package/dist/sleekspace-ui.umd.js +17426 -6045
  56. package/package.json +2 -1
  57. package/src/components/Card/SkCard.vue +17 -1
  58. package/src/components/ColorPicker/SkColorPicker.vue +355 -0
  59. package/src/components/ColorPicker/index.ts +6 -0
  60. package/src/components/ColorPicker/types.ts +11 -0
  61. package/src/components/ContextMenu/SkContextMenu.vue +83 -0
  62. package/src/components/ContextMenu/SkContextMenuCheckboxItem.vue +72 -0
  63. package/src/components/ContextMenu/SkContextMenuItem.vue +49 -0
  64. package/src/components/ContextMenu/SkContextMenuLabel.vue +17 -0
  65. package/src/components/ContextMenu/SkContextMenuRadioGroup.vue +36 -0
  66. package/src/components/ContextMenu/SkContextMenuRadioItem.vue +53 -0
  67. package/src/components/ContextMenu/SkContextMenuSeparator.vue +21 -0
  68. package/src/components/ContextMenu/SkContextMenuSubmenu.vue +94 -0
  69. package/src/components/ContextMenu/index.ts +15 -0
  70. package/src/components/ContextMenu/types.ts +9 -0
  71. package/src/components/Dropdown/SkDropdown.vue +1 -1
  72. package/src/components/Dropdown/SkDropdownCheckboxItem.vue +72 -0
  73. package/src/components/Dropdown/SkDropdownMenuItem.vue +1 -1
  74. package/src/components/Dropdown/SkDropdownMenuLabel.vue +17 -0
  75. package/src/components/Dropdown/SkDropdownRadioGroup.vue +36 -0
  76. package/src/components/Dropdown/SkDropdownRadioItem.vue +53 -0
  77. package/src/components/Dropdown/SkDropdownSubmenu.vue +2 -2
  78. package/src/components/Dropdown/index.ts +4 -0
  79. package/src/components/Panel/SkPanel.vue +29 -4
  80. package/src/components/Panel/types.ts +3 -0
  81. package/src/components/ScrollArea/SkScrollArea.vue +87 -0
  82. package/src/components/ScrollArea/index.ts +8 -0
  83. package/src/components/ScrollArea/types.ts +11 -0
  84. package/src/components/Select/SkSelect.vue +210 -0
  85. package/src/components/Select/SkSelectItem.vue +112 -0
  86. package/src/components/Select/SkSelectSeparator.vue +40 -0
  87. package/src/components/Select/index.ts +10 -0
  88. package/src/components/Select/types.ts +10 -0
  89. package/src/components/Sidebar/SkSidebar.vue +39 -2
  90. package/src/components/Sidebar/types.ts +2 -0
  91. package/src/components/Splitter/SkSplitter.vue +65 -0
  92. package/src/components/Splitter/SkSplitterHandle.vue +40 -0
  93. package/src/components/Splitter/SkSplitterPanel.vue +45 -0
  94. package/src/components/Splitter/index.ts +10 -0
  95. package/src/components/Splitter/types.ts +10 -0
  96. package/src/components/Toolbar/SkToolbar.vue +69 -0
  97. package/src/components/Toolbar/SkToolbarButton.vue +36 -0
  98. package/src/components/Toolbar/SkToolbarSeparator.vue +15 -0
  99. package/src/components/Toolbar/SkToolbarToggleGroup.vue +49 -0
  100. package/src/components/Toolbar/SkToolbarToggleItem.vue +37 -0
  101. package/src/components/Toolbar/index.ts +12 -0
  102. package/src/components/Toolbar/types.ts +12 -0
  103. package/src/components/TreeView/SkTreeItem.vue +84 -0
  104. package/src/components/TreeView/SkTreeView.vue +120 -0
  105. package/src/components/TreeView/index.ts +9 -0
  106. package/src/components/TreeView/types.ts +10 -0
  107. package/src/global.d.ts +22 -0
  108. package/src/index.ts +110 -0
  109. package/src/styles/components/_card.scss +45 -9
  110. package/src/styles/components/_color-picker.scss +552 -0
  111. package/src/styles/components/_index.scss +6 -0
  112. package/src/styles/components/_listbox.scss +1 -0
  113. package/src/styles/components/_menu.scss +52 -3
  114. package/src/styles/components/_panel.scss +119 -13
  115. package/src/styles/components/_scroll-area.scss +120 -0
  116. package/src/styles/components/_select.scss +439 -0
  117. package/src/styles/components/_sidebar.scss +83 -4
  118. package/src/styles/components/_splitter.scss +136 -0
  119. package/src/styles/components/_toolbar.scss +296 -0
  120. package/src/styles/components/_tree-view.scss +187 -0
  121. package/web-types.json +1244 -197
@@ -0,0 +1,210 @@
1
+ <!----------------------------------------------------------------------------------------------------------------------
2
+ - Select Component
3
+ --------------------------------------------------------------------------------------------------------------------->
4
+
5
+ <template>
6
+ <div :class="wrapperClasses" :style="customColorStyles">
7
+ <SelectRoot v-model="modelValue" :disabled="disabled">
8
+ <SelectTrigger :class="triggerClasses">
9
+ <SelectValue :placeholder="placeholder">
10
+ <template v-if="displayText">
11
+ {{ displayText }}
12
+ </template>
13
+ </SelectValue>
14
+ <svg
15
+ xmlns="http://www.w3.org/2000/svg"
16
+ viewBox="0 0 24 24"
17
+ fill="none"
18
+ stroke="currentColor"
19
+ stroke-width="2"
20
+ stroke-linecap="square"
21
+ stroke-linejoin="miter"
22
+ style="width: 1rem; height: 1rem; flex-shrink: 0;"
23
+ >
24
+ <polyline points="6 9 12 15 18 9" />
25
+ </svg>
26
+ </SelectTrigger>
27
+
28
+ <SelectPortal>
29
+ <SelectContent
30
+ :data-scheme="theme"
31
+ :class="contentClasses"
32
+ :style="customColorStyles"
33
+ position="popper"
34
+ side="bottom"
35
+ align="start"
36
+ :side-offset="4"
37
+ >
38
+ <SelectViewport>
39
+ <slot />
40
+ </SelectViewport>
41
+ </SelectContent>
42
+ </SelectPortal>
43
+ </SelectRoot>
44
+ </div>
45
+ </template>
46
+
47
+ <!--------------------------------------------------------------------------------------------------------------------->
48
+
49
+ <style lang="scss" scoped>
50
+ // Component styles are in /src/styles/components/_select.scss
51
+ </style>
52
+
53
+ <!--------------------------------------------------------------------------------------------------------------------->
54
+
55
+ <script setup lang="ts">
56
+ /**
57
+ * @component SkSelect
58
+ * @description A simple dropdown select for picking from predefined options. Unlike SkListbox which includes
59
+ * a search input for filtering, SkSelect provides a clean trigger button that opens a dropdown panel.
60
+ * Built on RekaUI's Select primitive with full keyboard navigation and portal rendering.
61
+ *
62
+ * @example
63
+ * ```vue
64
+ * <SkSelect v-model="selectedCountry" kind="primary" placeholder="Select a country...">
65
+ * <SkSelectItem value="us">United States</SkSelectItem>
66
+ * <SkSelectItem value="uk">United Kingdom</SkSelectItem>
67
+ * <SkSelectItem value="ca">Canada</SkSelectItem>
68
+ * </SkSelect>
69
+ * ```
70
+ *
71
+ * @slot default - SkSelectItem components representing the available options. Use SkSelectSeparator
72
+ * to create visual dividers between groups of options.
73
+ */
74
+
75
+ import { type ComputedRef, computed, inject, provide, reactive, toRef } from 'vue';
76
+ import {
77
+ SelectContent,
78
+ SelectPortal,
79
+ SelectRoot,
80
+ SelectTrigger,
81
+ SelectValue,
82
+ SelectViewport,
83
+ } from 'reka-ui';
84
+
85
+ // Types
86
+ import type { ComponentCustomColors } from '@/types';
87
+ import type { SkSelectKind, SkSelectSize } from './types';
88
+
89
+ // Composables
90
+ import { useCustomColors } from '@/composables/useCustomColors';
91
+ import { usePortalContext } from '@/composables/usePortalContext';
92
+
93
+ //------------------------------------------------------------------------------------------------------------------
94
+
95
+ export interface SkSelectComponentProps extends ComponentCustomColors
96
+ {
97
+ /**
98
+ * Semantic color kind that controls the trigger border, focus ring, and selected
99
+ * item highlight appearance. When used inside SkField, inherits the field's
100
+ * kind if not explicitly set.
101
+ * @default 'neutral' (or inherited from parent SkField)
102
+ */
103
+ kind ?: SkSelectKind;
104
+
105
+ /**
106
+ * Size of the trigger and dropdown content. Controls the trigger height,
107
+ * text size, and option item dimensions. Available sizes: 'sm' (small),
108
+ * 'md' (medium), 'lg' (large).
109
+ * @default 'md'
110
+ */
111
+ size ?: SkSelectSize;
112
+
113
+ /**
114
+ * Placeholder text displayed in the trigger when no option is selected.
115
+ * Use to guide users on what type of selection to make.
116
+ * @default 'Select...'
117
+ */
118
+ placeholder ?: string;
119
+
120
+ /**
121
+ * When true, the select is disabled and cannot be interacted with. The trigger
122
+ * is non-clickable and the dropdown cannot be opened. The component appears
123
+ * with reduced opacity and the cursor changes to not-allowed.
124
+ * @default false
125
+ */
126
+ disabled ?: boolean;
127
+ }
128
+
129
+ //------------------------------------------------------------------------------------------------------------------
130
+
131
+ const props = withDefaults(defineProps<SkSelectComponentProps>(), {
132
+ kind: undefined,
133
+ size: 'md',
134
+ placeholder: 'Select...',
135
+ disabled: false,
136
+ });
137
+
138
+ //------------------------------------------------------------------------------------------------------------------
139
+
140
+ /**
141
+ * The selected value. Use with `v-model` for two-way binding. The value corresponds
142
+ * to the `value` prop of the selected SkSelectItem.
143
+ */
144
+ const modelValue = defineModel<string>();
145
+
146
+ //------------------------------------------------------------------------------------------------------------------
147
+
148
+ // Handle portal context (theme injection/re-provision for nested portal components)
149
+ const { theme } = usePortalContext();
150
+
151
+ // Inject field kind from parent SkField
152
+ const fieldKind = inject<ComputedRef<SkSelectKind | undefined>>('field-kind', computed(() => undefined));
153
+
154
+ //------------------------------------------------------------------------------------------------------------------
155
+
156
+ // Item label registry -- items register their value→label on mount so we can display
157
+ // the selected text synchronously, avoiding the flash from SelectValue's async detection.
158
+ const itemLabels = reactive(new Map<string, string>());
159
+
160
+ provide('sk-select-register', (value : string, label : string) =>
161
+ {
162
+ itemLabels.set(value, label);
163
+ });
164
+
165
+ provide('sk-select-unregister', (value : string) =>
166
+ {
167
+ itemLabels.delete(value);
168
+ });
169
+
170
+ const displayText = computed(() =>
171
+ {
172
+ if(!modelValue.value) { return ''; }
173
+ return itemLabels.get(modelValue.value) || modelValue.value;
174
+ });
175
+
176
+ //------------------------------------------------------------------------------------------------------------------
177
+
178
+ const effectiveKind = computed(() => fieldKind.value || props.kind || 'neutral');
179
+
180
+ //------------------------------------------------------------------------------------------------------------------
181
+
182
+ const wrapperClasses = computed(() => ({
183
+ 'sk-select': true,
184
+ [`sk-${ effectiveKind.value }`]: true,
185
+ [`sk-${ props.size }`]: true,
186
+ }));
187
+
188
+ //------------------------------------------------------------------------------------------------------------------
189
+
190
+ const triggerClasses = computed(() => ({
191
+ 'sk-select-trigger': true,
192
+ }));
193
+
194
+ //------------------------------------------------------------------------------------------------------------------
195
+
196
+ const contentClasses = computed(() => ({
197
+ 'sk-select-content': true,
198
+ [`sk-${ effectiveKind.value }`]: true,
199
+ }));
200
+
201
+ //------------------------------------------------------------------------------------------------------------------
202
+
203
+ const customColorStyles = useCustomColors(
204
+ 'select',
205
+ toRef(() => props.baseColor),
206
+ toRef(() => props.textColor)
207
+ );
208
+ </script>
209
+
210
+ <!--------------------------------------------------------------------------------------------------------------------->
@@ -0,0 +1,112 @@
1
+ <!----------------------------------------------------------------------------------------------------------------------
2
+ - SelectItem Component
3
+ --------------------------------------------------------------------------------------------------------------------->
4
+
5
+ <template>
6
+ <SelectItem :class="classes" :value="value" :disabled="disabled">
7
+ <SelectItemText ref="textEl">
8
+ <slot />
9
+ </SelectItemText>
10
+ <SelectItemIndicator class="sk-select-item-indicator">
11
+ <svg
12
+ xmlns="http://www.w3.org/2000/svg"
13
+ viewBox="0 0 24 24"
14
+ fill="none"
15
+ stroke="currentColor"
16
+ stroke-width="3"
17
+ stroke-linecap="square"
18
+ stroke-linejoin="miter"
19
+ style="width: 1rem; height: 1rem;"
20
+ >
21
+ <polyline points="20 6 9 17 4 12" />
22
+ </svg>
23
+ </SelectItemIndicator>
24
+ </SelectItem>
25
+ </template>
26
+
27
+ <!--------------------------------------------------------------------------------------------------------------------->
28
+
29
+ <style lang="scss" scoped>
30
+ // Component styles are in /src/styles/components/_select.scss
31
+ </style>
32
+
33
+ <!--------------------------------------------------------------------------------------------------------------------->
34
+
35
+ <script setup lang="ts">
36
+ /**
37
+ * @component SkSelectItem
38
+ * @description A selectable option within an SkSelect dropdown. When selected, the item displays a
39
+ * checkmark indicator and its value is set as the select's v-model. Built on RekaUI's SelectItem
40
+ * with keyboard navigation support.
41
+ *
42
+ * @example
43
+ * ```vue
44
+ * <SkSelect v-model="selected">
45
+ * <SkSelectItem value="option1">First Option</SkSelectItem>
46
+ * <SkSelectItem value="option2">Second Option</SkSelectItem>
47
+ * <SkSelectItem value="option3" disabled>Unavailable Option</SkSelectItem>
48
+ * </SkSelect>
49
+ * ```
50
+ *
51
+ * @slot default - The display content for this option. Can be plain text or rich content including
52
+ * icons, formatted text, or custom layouts. This is what users see in the dropdown.
53
+ */
54
+
55
+ import { computed, inject, onMounted, onUnmounted, useTemplateRef } from 'vue';
56
+ import { SelectItem, SelectItemIndicator, SelectItemText } from 'reka-ui';
57
+
58
+ //------------------------------------------------------------------------------------------------------------------
59
+
60
+ export interface SkSelectItemComponentProps
61
+ {
62
+ /**
63
+ * The value this option represents. When selected, the parent SkSelect's v-model
64
+ * will be set to this value. Must be a string and unique within the select.
65
+ */
66
+ value : string;
67
+
68
+ /**
69
+ * When true, this option is disabled and cannot be selected. The item appears
70
+ * with reduced opacity and is skipped during keyboard navigation.
71
+ * @default false
72
+ */
73
+ disabled ?: boolean;
74
+ }
75
+
76
+ //------------------------------------------------------------------------------------------------------------------
77
+
78
+ const props = withDefaults(defineProps<SkSelectItemComponentProps>(), {
79
+ disabled: false,
80
+ });
81
+
82
+ //------------------------------------------------------------------------------------------------------------------
83
+
84
+ const textEl = useTemplateRef<InstanceType<typeof SelectItemText>>('textEl');
85
+ const register = inject<(value : string, label : string) => void>('sk-select-register', undefined);
86
+ const unregister = inject<(value : string) => void>('sk-select-unregister', undefined);
87
+
88
+ onMounted(() =>
89
+ {
90
+ const el = (textEl.value as unknown as { $el ?: HTMLElement })?.$el;
91
+ if(register)
92
+ {
93
+ register(props.value, el?.textContent?.trim() || props.value);
94
+ }
95
+ });
96
+
97
+ onUnmounted(() =>
98
+ {
99
+ if(unregister)
100
+ {
101
+ unregister(props.value);
102
+ }
103
+ });
104
+
105
+ //------------------------------------------------------------------------------------------------------------------
106
+
107
+ const classes = computed(() => ({
108
+ 'sk-select-item': true,
109
+ }));
110
+ </script>
111
+
112
+ <!--------------------------------------------------------------------------------------------------------------------->
@@ -0,0 +1,40 @@
1
+ <!----------------------------------------------------------------------------------------------------------------------
2
+ - SelectSeparator Component
3
+ --------------------------------------------------------------------------------------------------------------------->
4
+
5
+ <template>
6
+ <SelectSeparator class="sk-select-separator" />
7
+ </template>
8
+
9
+ <!--------------------------------------------------------------------------------------------------------------------->
10
+
11
+ <style lang="scss" scoped>
12
+ // Component styles are in /src/styles/components/_select.scss
13
+ </style>
14
+
15
+ <!--------------------------------------------------------------------------------------------------------------------->
16
+
17
+ <script setup lang="ts">
18
+ /**
19
+ * @component SkSelectSeparator
20
+ * @description A visual divider for organizing options within an SkSelect dropdown. Use to create
21
+ * logical groups of related options without affecting selection behavior. Renders as a horizontal
22
+ * line between items with appropriate spacing.
23
+ *
24
+ * @example
25
+ * ```vue
26
+ * <SkSelect v-model="selected">
27
+ * <SkSelectItem value="recent1">Recent Document 1</SkSelectItem>
28
+ * <SkSelectItem value="recent2">Recent Document 2</SkSelectItem>
29
+ * <SkSelectSeparator />
30
+ * <SkSelectItem value="all">Browse All Documents...</SkSelectItem>
31
+ * </SkSelect>
32
+ * ```
33
+ *
34
+ * @slot - Not applicable. This component does not accept slot content.
35
+ */
36
+
37
+ import { SelectSeparator } from 'reka-ui';
38
+ </script>
39
+
40
+ <!--------------------------------------------------------------------------------------------------------------------->
@@ -0,0 +1,10 @@
1
+ //----------------------------------------------------------------------------------------------------------------------
2
+ // Select Component Exports
3
+ //----------------------------------------------------------------------------------------------------------------------
4
+
5
+ export { default as SkSelect } from './SkSelect.vue';
6
+ export { default as SkSelectItem } from './SkSelectItem.vue';
7
+ export { default as SkSelectSeparator } from './SkSelectSeparator.vue';
8
+ export type { SkSelectKind, SkSelectSize } from './types';
9
+
10
+ //----------------------------------------------------------------------------------------------------------------------
@@ -0,0 +1,10 @@
1
+ //----------------------------------------------------------------------------------------------------------------------
2
+ // Select Component Types
3
+ //----------------------------------------------------------------------------------------------------------------------
4
+
5
+ import type { ComponentKind, ComponentSize } from '@/types';
6
+
7
+ export type SkSelectKind = ComponentKind;
8
+ export type SkSelectSize = ComponentSize;
9
+
10
+ //----------------------------------------------------------------------------------------------------------------------
@@ -3,11 +3,13 @@
3
3
  --------------------------------------------------------------------------------------------------------------------->
4
4
 
5
5
  <template>
6
- <aside :class="classes">
6
+ <aside :class="classes" :style="sidebarStyles">
7
7
  <SkPanel
8
8
  :kind="kind"
9
9
  :base-color="baseColor"
10
10
  :text-color="textColor"
11
+ :corners="panelCorners"
12
+ :decoration-corner="panelDecorationCorner"
11
13
  class="sk-sidebar-panel"
12
14
  >
13
15
  <div class="sk-panel-scroll-content">
@@ -49,8 +51,13 @@
49
51
  */
50
52
 
51
53
  import { computed } from 'vue';
52
- import type { SkSidebarKind } from './types';
54
+
55
+ // Types
56
+ import type { SkSidebarKind, SkSidebarSide } from './types';
53
57
  import type { ComponentCustomColors } from '@/types';
58
+ import type { SkPanelCorner } from '../Panel/types';
59
+
60
+ // Components
54
61
  import SkPanel from '../Panel/SkPanel.vue';
55
62
 
56
63
  //------------------------------------------------------------------------------------------------------------------
@@ -72,6 +79,13 @@
72
79
  * @default '180px'
73
80
  */
74
81
  width ?: string;
82
+
83
+ /**
84
+ * Which side of the layout the sidebar is placed on. Controls the direction of the
85
+ * panel bevel and the sidebar-item clip-path cuts so they mirror appropriately.
86
+ * @default 'left'
87
+ */
88
+ side ?: SkSidebarSide;
75
89
  }
76
90
 
77
91
  //------------------------------------------------------------------------------------------------------------------
@@ -79,17 +93,40 @@
79
93
  const props = withDefaults(defineProps<SkSidebarComponentProps>(), {
80
94
  kind: 'neutral',
81
95
  width: '180px',
96
+ side: 'left',
82
97
  });
83
98
 
84
99
  //------------------------------------------------------------------------------------------------------------------
85
100
 
101
+ const panelCorners = computed<SkPanelCorner[]>(() =>
102
+ {
103
+ return props.side === 'right' ? [ 'bottom-left' ] : [ 'bottom-right' ];
104
+ });
105
+
106
+ const panelDecorationCorner = computed<SkPanelCorner>(() =>
107
+ {
108
+ return props.side === 'right' ? 'bottom-left' : 'bottom-right';
109
+ });
110
+
86
111
  const classes = computed(() =>
87
112
  {
88
113
  return {
89
114
  'sk-sidebar': true,
90
115
  [`sk-${ props.kind }`]: true,
116
+ 'sk-sidebar-right': props.side === 'right',
91
117
  };
92
118
  });
119
+
120
+ // Bridge custom colors to sidebar item theming
121
+ const sidebarStyles = computed(() =>
122
+ {
123
+ const styles : Record<string, string> = {};
124
+ if(props.baseColor)
125
+ {
126
+ styles['--sk-sidebar-color-base'] = props.baseColor;
127
+ }
128
+ return styles;
129
+ });
93
130
  </script>
94
131
 
95
132
  <!--------------------------------------------------------------------------------------------------------------------->
@@ -1,3 +1,5 @@
1
1
  import type { ComponentKind } from '@/types';
2
2
 
3
3
  export type SkSidebarKind = ComponentKind;
4
+
5
+ export type SkSidebarSide = 'left' | 'right';
@@ -0,0 +1,65 @@
1
+ <!----------------------------------------------------------------------------------------------------------------------
2
+ - Splitter Component
3
+ --------------------------------------------------------------------------------------------------------------------->
4
+
5
+ <template>
6
+ <SplitterGroup :direction="direction" :class="classes" :style="customColorStyles">
7
+ <slot />
8
+ </SplitterGroup>
9
+ </template>
10
+
11
+ <!--------------------------------------------------------------------------------------------------------------------->
12
+
13
+ <style lang="scss" scoped>
14
+ // Component styles are in /src/styles/components/_splitter.scss
15
+ </style>
16
+
17
+ <!--------------------------------------------------------------------------------------------------------------------->
18
+
19
+ <script setup lang="ts">
20
+ import { computed, provide, toRef } from 'vue';
21
+ import { SplitterGroup } from 'reka-ui';
22
+
23
+ // Types
24
+ import type { SkSplitterDirection, SkSplitterKind } from './types';
25
+
26
+ // Composables
27
+ import { useCustomColors } from '@/composables/useCustomColors';
28
+
29
+ //------------------------------------------------------------------------------------------------------------------
30
+
31
+ export interface SkSplitterComponentProps
32
+ {
33
+ direction ?: SkSplitterDirection;
34
+ kind ?: SkSplitterKind;
35
+ baseColor ?: string;
36
+ textColor ?: string;
37
+ }
38
+
39
+ //------------------------------------------------------------------------------------------------------------------
40
+
41
+ const props = withDefaults(defineProps<SkSplitterComponentProps>(), {
42
+ direction: 'horizontal',
43
+ kind: 'neutral',
44
+ baseColor: undefined,
45
+ textColor: undefined,
46
+ });
47
+
48
+ //------------------------------------------------------------------------------------------------------------------
49
+
50
+ provide('splitter-kind', computed(() => props.kind));
51
+
52
+ const customColorStyles = useCustomColors(
53
+ 'splitter',
54
+ toRef(() => props.baseColor),
55
+ toRef(() => props.textColor)
56
+ );
57
+
58
+ const classes = computed(() => ({
59
+ 'sk-splitter': true,
60
+ [`sk-${ props.kind }`]: true,
61
+ [`sk-${ props.direction }`]: true,
62
+ }));
63
+ </script>
64
+
65
+ <!--------------------------------------------------------------------------------------------------------------------->
@@ -0,0 +1,40 @@
1
+ <!----------------------------------------------------------------------------------------------------------------------
2
+ - SplitterHandle Component
3
+ --------------------------------------------------------------------------------------------------------------------->
4
+
5
+ <template>
6
+ <SplitterResizeHandle class="sk-splitter-handle" :disabled="disabled">
7
+ <div class="sk-splitter-handle-grip">
8
+ <div class="sk-splitter-handle-dot" />
9
+ <div class="sk-splitter-handle-dot" />
10
+ <div class="sk-splitter-handle-dot" />
11
+ </div>
12
+ </SplitterResizeHandle>
13
+ </template>
14
+
15
+ <!--------------------------------------------------------------------------------------------------------------------->
16
+
17
+ <style lang="scss" scoped>
18
+ // Component styles are in /src/styles/components/_splitter.scss
19
+ </style>
20
+
21
+ <!--------------------------------------------------------------------------------------------------------------------->
22
+
23
+ <script setup lang="ts">
24
+ import { SplitterResizeHandle } from 'reka-ui';
25
+
26
+ //------------------------------------------------------------------------------------------------------------------
27
+
28
+ export interface SkSplitterHandleComponentProps
29
+ {
30
+ disabled ?: boolean;
31
+ }
32
+
33
+ //------------------------------------------------------------------------------------------------------------------
34
+
35
+ withDefaults(defineProps<SkSplitterHandleComponentProps>(), {
36
+ disabled: false,
37
+ });
38
+ </script>
39
+
40
+ <!--------------------------------------------------------------------------------------------------------------------->
@@ -0,0 +1,45 @@
1
+ <!----------------------------------------------------------------------------------------------------------------------
2
+ - SplitterPanel Component
3
+ --------------------------------------------------------------------------------------------------------------------->
4
+
5
+ <template>
6
+ <SplitterPanel
7
+ class="sk-splitter-panel"
8
+ :default-size="defaultSize"
9
+ :min-size="minSize"
10
+ :max-size="maxSize"
11
+ :collapsible="collapsible"
12
+ :collapsed-size="collapsedSize"
13
+ >
14
+ <slot />
15
+ </SplitterPanel>
16
+ </template>
17
+
18
+ <!--------------------------------------------------------------------------------------------------------------------->
19
+
20
+ <script setup lang="ts">
21
+ import { SplitterPanel } from 'reka-ui';
22
+
23
+ //------------------------------------------------------------------------------------------------------------------
24
+
25
+ export interface SkSplitterPanelComponentProps
26
+ {
27
+ defaultSize ?: number;
28
+ minSize ?: number;
29
+ maxSize ?: number;
30
+ collapsible ?: boolean;
31
+ collapsedSize ?: number;
32
+ }
33
+
34
+ //------------------------------------------------------------------------------------------------------------------
35
+
36
+ withDefaults(defineProps<SkSplitterPanelComponentProps>(), {
37
+ defaultSize: undefined,
38
+ minSize: undefined,
39
+ maxSize: undefined,
40
+ collapsible: false,
41
+ collapsedSize: undefined,
42
+ });
43
+ </script>
44
+
45
+ <!--------------------------------------------------------------------------------------------------------------------->
@@ -0,0 +1,10 @@
1
+ //----------------------------------------------------------------------------------------------------------------------
2
+ // Splitter Component Exports
3
+ //----------------------------------------------------------------------------------------------------------------------
4
+
5
+ export { default as SkSplitter } from './SkSplitter.vue';
6
+ export { default as SkSplitterHandle } from './SkSplitterHandle.vue';
7
+ export { default as SkSplitterPanel } from './SkSplitterPanel.vue';
8
+ export type { SkSplitterDirection, SkSplitterKind } from './types';
9
+
10
+ //----------------------------------------------------------------------------------------------------------------------
@@ -0,0 +1,10 @@
1
+ //----------------------------------------------------------------------------------------------------------------------
2
+ // Splitter Component Types
3
+ //----------------------------------------------------------------------------------------------------------------------
4
+
5
+ import type { ComponentKind } from '@/types';
6
+
7
+ export type SkSplitterKind = ComponentKind;
8
+ export type SkSplitterDirection = 'horizontal' | 'vertical';
9
+
10
+ //----------------------------------------------------------------------------------------------------------------------