@skewedaspect/sleekspace-ui 0.2.0-beta.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +111 -0
- package/dist/sleekspace-ui.css +12844 -0
- package/dist/sleekspace-ui.es.js +19021 -0
- package/dist/sleekspace-ui.umd.js +19040 -0
- package/docs/components/accordion.md +92 -0
- package/docs/components/alert.md +72 -0
- package/docs/components/avatar.md +69 -0
- package/docs/components/breadcrumbs.md +65 -0
- package/docs/components/button/_meta.yaml +12 -0
- package/docs/components/button/accessibility.md +16 -0
- package/docs/components/button/custom-colors.md +18 -0
- package/docs/components/button/icons.md +31 -0
- package/docs/components/button/intro.md +8 -0
- package/docs/components/button/kinds.md +25 -0
- package/docs/components/button/sizes.md +14 -0
- package/docs/components/button/states.md +12 -0
- package/docs/components/button/usage.md +23 -0
- package/docs/components/button/variants.md +14 -0
- package/docs/components/button.md +110 -0
- package/docs/components/card.md +87 -0
- package/docs/components/checkbox.md +77 -0
- package/docs/components/collapsible.md +71 -0
- package/docs/components/divider.md +62 -0
- package/docs/components/dropdown.md +88 -0
- package/docs/components/field.md +80 -0
- package/docs/components/group.md +41 -0
- package/docs/components/input.md +84 -0
- package/docs/components/listbox.md +82 -0
- package/docs/components/modal.md +101 -0
- package/docs/components/navbar.md +64 -0
- package/docs/components/number-input.md +78 -0
- package/docs/components/page.md +77 -0
- package/docs/components/pagination.md +88 -0
- package/docs/components/panel.md +74 -0
- package/docs/components/popover.md +93 -0
- package/docs/components/progress.md +76 -0
- package/docs/components/radio.md +86 -0
- package/docs/components/sidebar.md +74 -0
- package/docs/components/skeleton.md +76 -0
- package/docs/components/slider.md +94 -0
- package/docs/components/spinner.md +59 -0
- package/docs/components/switch.md +97 -0
- package/docs/components/table.md +91 -0
- package/docs/components/tabs.md +108 -0
- package/docs/components/tag.md +75 -0
- package/docs/components/tags-input.md +88 -0
- package/docs/components/textarea.md +80 -0
- package/docs/components/theme.md +65 -0
- package/docs/components/toast.md +95 -0
- package/docs/components/tooltip.md +90 -0
- package/docs/guides/custom-colors.md +84 -0
- package/docs/guides/design-tokens.md +105 -0
- package/docs/guides/getting-started.md +144 -0
- package/docs/guides/installation.md +62 -0
- package/docs/guides/theming.md +101 -0
- package/package.json +76 -0
- package/src/components/Accordion/SkAccordion.vue +133 -0
- package/src/components/Accordion/SkAccordionItem.vue +131 -0
- package/src/components/Accordion/index.ts +3 -0
- package/src/components/Accordion/types.ts +9 -0
- package/src/components/Alert/SkAlert.vue +137 -0
- package/src/components/Alert/types.ts +10 -0
- package/src/components/Avatar/SkAvatar.vue +141 -0
- package/src/components/Avatar/index.ts +8 -0
- package/src/components/Avatar/types.ts +31 -0
- package/src/components/Breadcrumbs/SkBreadcrumbItem.vue +76 -0
- package/src/components/Breadcrumbs/SkBreadcrumbSeparator.vue +38 -0
- package/src/components/Breadcrumbs/SkBreadcrumbs.vue +93 -0
- package/src/components/Breadcrumbs/index.ts +10 -0
- package/src/components/Breadcrumbs/types.ts +36 -0
- package/src/components/Button/SkButton.vue +148 -0
- package/src/components/Button/types.ts +21 -0
- package/src/components/Card/SkCard.vue +144 -0
- package/src/components/Card/types.ts +12 -0
- package/src/components/Checkbox/SkCheckbox.vue +136 -0
- package/src/components/Checkbox/index.ts +8 -0
- package/src/components/Checkbox/types.ts +10 -0
- package/src/components/Collapsible/SkCollapsible.vue +159 -0
- package/src/components/Collapsible/index.ts +2 -0
- package/src/components/Collapsible/types.ts +8 -0
- package/src/components/Divider/SkDivider.vue +63 -0
- package/src/components/Divider/types.ts +15 -0
- package/src/components/Dropdown/SkDropdown.vue +150 -0
- package/src/components/Dropdown/SkDropdownMenuItem.vue +58 -0
- package/src/components/Dropdown/SkDropdownMenuSeparator.vue +26 -0
- package/src/components/Dropdown/SkDropdownSubmenu.vue +107 -0
- package/src/components/Dropdown/index.ts +11 -0
- package/src/components/Dropdown/types.ts +11 -0
- package/src/components/Field/SkField.vue +152 -0
- package/src/components/Field/index.ts +8 -0
- package/src/components/Field/types.ts +7 -0
- package/src/components/Group/SkGroup.vue +52 -0
- package/src/components/Group/types.ts +10 -0
- package/src/components/Input/SkInput.vue +117 -0
- package/src/components/Input/index.ts +8 -0
- package/src/components/Input/types.ts +11 -0
- package/src/components/Listbox/SkListbox.vue +164 -0
- package/src/components/Listbox/SkListboxItem.vue +68 -0
- package/src/components/Listbox/SkListboxSeparator.vue +26 -0
- package/src/components/Listbox/index.ts +10 -0
- package/src/components/Listbox/types.ts +10 -0
- package/src/components/Modal/SkModal.vue +231 -0
- package/src/components/Modal/index.ts +8 -0
- package/src/components/Modal/types.ts +12 -0
- package/src/components/NavBar/SkNavBar.vue +83 -0
- package/src/components/NavBar/index.ts +8 -0
- package/src/components/NavBar/types.ts +15 -0
- package/src/components/NumberInput/SkNumberInput.vue +168 -0
- package/src/components/NumberInput/index.ts +8 -0
- package/src/components/NumberInput/types.ts +10 -0
- package/src/components/Page/SkPage.vue +94 -0
- package/src/components/Page/index.ts +8 -0
- package/src/components/Page/types.ts +21 -0
- package/src/components/Pagination/SkPagination.vue +185 -0
- package/src/components/Pagination/SkPaginationItem.vue +107 -0
- package/src/components/Pagination/index.ts +9 -0
- package/src/components/Pagination/types.ts +40 -0
- package/src/components/Panel/SkPanel.vue +96 -0
- package/src/components/Panel/types.ts +15 -0
- package/src/components/Popover/SkPopover.vue +185 -0
- package/src/components/Popover/index.ts +8 -0
- package/src/components/Popover/types.ts +11 -0
- package/src/components/Progress/SkProgress.vue +144 -0
- package/src/components/Progress/index.ts +8 -0
- package/src/components/Progress/types.ts +34 -0
- package/src/components/Radio/SkRadio.vue +110 -0
- package/src/components/Radio/SkRadioGroup.vue +92 -0
- package/src/components/Radio/index.ts +9 -0
- package/src/components/Radio/types.ts +11 -0
- package/src/components/Sidebar/README.md +405 -0
- package/src/components/Sidebar/SkSidebar.vue +88 -0
- package/src/components/Sidebar/SkSidebarItem.vue +58 -0
- package/src/components/Sidebar/SkSidebarSection.vue +40 -0
- package/src/components/Sidebar/types.ts +3 -0
- package/src/components/Skeleton/SkSkeleton.vue +171 -0
- package/src/components/Skeleton/index.ts +8 -0
- package/src/components/Skeleton/types.ts +31 -0
- package/src/components/Slider/SkSlider.vue +165 -0
- package/src/components/Slider/index.ts +8 -0
- package/src/components/Slider/types.ts +44 -0
- package/src/components/Spinner/SkSpinner.vue +105 -0
- package/src/components/Spinner/index.ts +8 -0
- package/src/components/Spinner/types.ts +28 -0
- package/src/components/Switch/SkSwitch.vue +215 -0
- package/src/components/Switch/index.ts +8 -0
- package/src/components/Switch/types.ts +12 -0
- package/src/components/Table/SkTable.vue +109 -0
- package/src/components/Table/index.ts +2 -0
- package/src/components/Table/types.ts +15 -0
- package/src/components/Tabs/README.md +331 -0
- package/src/components/Tabs/SkTab.vue +84 -0
- package/src/components/Tabs/SkTabList.vue +62 -0
- package/src/components/Tabs/SkTabPanel.vue +47 -0
- package/src/components/Tabs/SkTabPanels.vue +23 -0
- package/src/components/Tabs/SkTabs.vue +124 -0
- package/src/components/Tabs/types.ts +21 -0
- package/src/components/Tag/SkTag.vue +129 -0
- package/src/components/Tag/types.ts +15 -0
- package/src/components/TagsInput/SkTagsInput.vue +184 -0
- package/src/components/TagsInput/index.ts +8 -0
- package/src/components/TagsInput/types.ts +10 -0
- package/src/components/Textarea/SkTextarea.vue +117 -0
- package/src/components/Textarea/index.ts +8 -0
- package/src/components/Textarea/types.ts +10 -0
- package/src/components/Theme/SkTheme.vue +47 -0
- package/src/components/Theme/types.ts +17 -0
- package/src/components/Theme/useTheme.ts +131 -0
- package/src/components/Toast/SkToast.vue +156 -0
- package/src/components/Toast/SkToastProvider.vue +180 -0
- package/src/components/Toast/index.ts +15 -0
- package/src/components/Toast/types.ts +63 -0
- package/src/components/Toast/useToast.ts +78 -0
- package/src/components/Tooltip/SkTooltip.vue +162 -0
- package/src/components/Tooltip/SkTooltipProvider.vue +114 -0
- package/src/components/Tooltip/index.ts +9 -0
- package/src/components/Tooltip/types.ts +13 -0
- package/src/composables/useCustomColors.test.ts +505 -0
- package/src/composables/useCustomColors.ts +124 -0
- package/src/composables/usePortalContext.test.ts +402 -0
- package/src/composables/usePortalContext.ts +95 -0
- package/src/global.d.ts +76 -0
- package/src/index.ts +259 -0
- package/src/styles/_scrollbar.scss +100 -0
- package/src/styles/base/_fonts.scss +105 -0
- package/src/styles/base/_global.scss +47 -0
- package/src/styles/base/_index.scss +24 -0
- package/src/styles/base/_reset.scss +11 -0
- package/src/styles/base/_typography.scss +178 -0
- package/src/styles/components/_accordion.scss +250 -0
- package/src/styles/components/_alert.scss +239 -0
- package/src/styles/components/_avatar.scss +133 -0
- package/src/styles/components/_breadcrumbs.scss +137 -0
- package/src/styles/components/_button.scss +731 -0
- package/src/styles/components/_card.scss +141 -0
- package/src/styles/components/_checkbox.scss +232 -0
- package/src/styles/components/_collapsible.scss +158 -0
- package/src/styles/components/_divider.scss +121 -0
- package/src/styles/components/_field.scss +87 -0
- package/src/styles/components/_group.scss +138 -0
- package/src/styles/components/_index.scss +46 -0
- package/src/styles/components/_input.scss +205 -0
- package/src/styles/components/_listbox.scss +453 -0
- package/src/styles/components/_menu.scss +216 -0
- package/src/styles/components/_modal.scss +329 -0
- package/src/styles/components/_navbar.scss +258 -0
- package/src/styles/components/_number-input.scss +352 -0
- package/src/styles/components/_page.scss +98 -0
- package/src/styles/components/_pagination.scss +411 -0
- package/src/styles/components/_panel.scss +281 -0
- package/src/styles/components/_popover.scss +258 -0
- package/src/styles/components/_progress.scss +280 -0
- package/src/styles/components/_radio.scss +255 -0
- package/src/styles/components/_sidebar.scss +92 -0
- package/src/styles/components/_skeleton.scss +138 -0
- package/src/styles/components/_slider.scss +262 -0
- package/src/styles/components/_spinner.scss +331 -0
- package/src/styles/components/_switch.scss +370 -0
- package/src/styles/components/_table.scss +405 -0
- package/src/styles/components/_tabs.scss +486 -0
- package/src/styles/components/_tag.scss +425 -0
- package/src/styles/components/_tags-input.scss +279 -0
- package/src/styles/components/_textarea.scss +208 -0
- package/src/styles/components/_toast.scss +331 -0
- package/src/styles/components/_tooltip.scss +206 -0
- package/src/styles/fonts/Titillium_Web/OFL.txt +93 -0
- package/src/styles/fonts/Titillium_Web/TitilliumWeb-Black.ttf +0 -0
- package/src/styles/fonts/Titillium_Web/TitilliumWeb-Bold.ttf +0 -0
- package/src/styles/fonts/Titillium_Web/TitilliumWeb-BoldItalic.ttf +0 -0
- package/src/styles/fonts/Titillium_Web/TitilliumWeb-ExtraLight.ttf +0 -0
- package/src/styles/fonts/Titillium_Web/TitilliumWeb-ExtraLightItalic.ttf +0 -0
- package/src/styles/fonts/Titillium_Web/TitilliumWeb-Italic.ttf +0 -0
- package/src/styles/fonts/Titillium_Web/TitilliumWeb-Light.ttf +0 -0
- package/src/styles/fonts/Titillium_Web/TitilliumWeb-LightItalic.ttf +0 -0
- package/src/styles/fonts/Titillium_Web/TitilliumWeb-Regular.ttf +0 -0
- package/src/styles/fonts/Titillium_Web/TitilliumWeb-SemiBold.ttf +0 -0
- package/src/styles/fonts/Titillium_Web/TitilliumWeb-SemiBoldItalic.ttf +0 -0
- package/src/styles/index.scss +17 -0
- package/src/styles/mixins/_cut-border.scss +254 -0
- package/src/styles/mixins/_index.scss +7 -0
- package/src/styles/theme/_variables.scss +42 -0
- package/src/styles/themes/README.md +127 -0
- package/src/styles/themes/_colorful.scss +58 -0
- package/src/styles/themes/_greyscale.scss +58 -0
- package/src/styles/themes/index.scss +9 -0
- package/src/styles/tokens/README.md +268 -0
- package/src/styles/tokens/_foundation-borders.scss +26 -0
- package/src/styles/tokens/_foundation-colors.scss +169 -0
- package/src/styles/tokens/_foundation-glow.scss +36 -0
- package/src/styles/tokens/_foundation-radius.scss +53 -0
- package/src/styles/tokens/_foundation-scrollbar.scss +31 -0
- package/src/styles/tokens/_foundation-shadows.scss +37 -0
- package/src/styles/tokens/_foundation-space.scss +36 -0
- package/src/styles/tokens/_foundation-transitions.scss +37 -0
- package/src/styles/tokens/_foundation-typography.scss +58 -0
- package/src/styles/tokens/_semantic-color-kinds.scss +112 -0
- package/src/styles/tokens/_semantic-colors.scss +10 -0
- package/src/styles/tokens/_semantic-interactive.scss +29 -0
- package/src/styles/tokens/_semantic-scrollbar.scss +48 -0
- package/src/styles/tokens/_semantic-surfaces.scss +36 -0
- package/src/styles/tokens/index.scss +38 -0
- package/src/styles/tokens.scss +268 -0
- package/src/styles/utilities/_index.scss +9 -0
- package/src/styles/utilities/_typography.scss +121 -0
- package/src/types.ts +50 -0
- package/web-types.json +3524 -0
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
<!--------------------------------------------------------------------------------------------------------------------
|
|
2
|
+
- Divider Component
|
|
3
|
+
-------------------------------------------------------------------------------------------------------------------->
|
|
4
|
+
|
|
5
|
+
<template>
|
|
6
|
+
<hr :class="classes" role="separator" :aria-orientation="orientation">
|
|
7
|
+
</template>
|
|
8
|
+
|
|
9
|
+
<!--------------------------------------------------------------------------------------------------------------------->
|
|
10
|
+
|
|
11
|
+
<script setup lang="ts">
|
|
12
|
+
/**
|
|
13
|
+
* @component
|
|
14
|
+
* A visual separator component for dividing content.
|
|
15
|
+
* Supports horizontal and vertical orientations with subtle or default styling.
|
|
16
|
+
*/
|
|
17
|
+
|
|
18
|
+
import { computed } from 'vue';
|
|
19
|
+
import type { ComponentKind, ComponentSize } from '@/types';
|
|
20
|
+
import type { SkDividerOrientation, SkDividerVariant } from './types';
|
|
21
|
+
|
|
22
|
+
//------------------------------------------------------------------------------------------------------------------
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* A visual separator component for dividing content.
|
|
26
|
+
* Supports horizontal and vertical orientations with subtle or default styling.
|
|
27
|
+
*/
|
|
28
|
+
export interface SkDividerComponentProps
|
|
29
|
+
{
|
|
30
|
+
/** Orientation of the divider line (horizontal or vertical) */
|
|
31
|
+
orientation ?: SkDividerOrientation;
|
|
32
|
+
/** Semantic color kind for the divider */
|
|
33
|
+
kind ?: ComponentKind;
|
|
34
|
+
/** Visual variant (subtle for lighter appearance) */
|
|
35
|
+
variant ?: SkDividerVariant;
|
|
36
|
+
/** Size of the divider (controls thickness and spacing) */
|
|
37
|
+
size ?: ComponentSize;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
//------------------------------------------------------------------------------------------------------------------
|
|
41
|
+
|
|
42
|
+
const props = withDefaults(defineProps<SkDividerComponentProps>(), {
|
|
43
|
+
orientation: 'horizontal',
|
|
44
|
+
kind: 'neutral',
|
|
45
|
+
variant: undefined,
|
|
46
|
+
size: 'md',
|
|
47
|
+
});
|
|
48
|
+
|
|
49
|
+
//------------------------------------------------------------------------------------------------------------------
|
|
50
|
+
|
|
51
|
+
const classes = computed(() =>
|
|
52
|
+
{
|
|
53
|
+
return {
|
|
54
|
+
'sk-divider': true,
|
|
55
|
+
[`sk-${ props.orientation }`]: true,
|
|
56
|
+
[`sk-${ props.kind }`]: true,
|
|
57
|
+
[`sk-${ props.size }`]: true,
|
|
58
|
+
'sk-subtle': props.variant === 'subtle',
|
|
59
|
+
};
|
|
60
|
+
});
|
|
61
|
+
</script>
|
|
62
|
+
|
|
63
|
+
<!--------------------------------------------------------------------------------------------------------------------->
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
//----------------------------------------------------------------------------------------------------------------------
|
|
2
|
+
// Divider Component Types
|
|
3
|
+
//----------------------------------------------------------------------------------------------------------------------
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Divider orientation options
|
|
7
|
+
*/
|
|
8
|
+
export type SkDividerOrientation = 'horizontal' | 'vertical';
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* Divider variant options
|
|
12
|
+
*/
|
|
13
|
+
export type SkDividerVariant = 'subtle';
|
|
14
|
+
|
|
15
|
+
//----------------------------------------------------------------------------------------------------------------------
|
|
@@ -0,0 +1,150 @@
|
|
|
1
|
+
<!----------------------------------------------------------------------------------------------------------------------
|
|
2
|
+
- Dropdown Component
|
|
3
|
+
--------------------------------------------------------------------------------------------------------------------->
|
|
4
|
+
|
|
5
|
+
<template>
|
|
6
|
+
<DropdownMenuRoot>
|
|
7
|
+
<DropdownMenuTrigger as-child>
|
|
8
|
+
<slot name="trigger">
|
|
9
|
+
<SkButton :kind="kind">
|
|
10
|
+
{{ triggerText }}
|
|
11
|
+
<template #trailing>
|
|
12
|
+
<svg
|
|
13
|
+
xmlns="http://www.w3.org/2000/svg"
|
|
14
|
+
viewBox="0 0 24 24"
|
|
15
|
+
fill="none"
|
|
16
|
+
stroke="currentColor"
|
|
17
|
+
stroke-width="2"
|
|
18
|
+
stroke-linecap="square"
|
|
19
|
+
stroke-linejoin="miter"
|
|
20
|
+
style="width: 1rem; height: 1rem;"
|
|
21
|
+
>
|
|
22
|
+
<polyline :points="caretPoints" />
|
|
23
|
+
</svg>
|
|
24
|
+
</template>
|
|
25
|
+
</SkButton>
|
|
26
|
+
</slot>
|
|
27
|
+
</DropdownMenuTrigger>
|
|
28
|
+
|
|
29
|
+
<DropdownMenuPortal>
|
|
30
|
+
<DropdownMenuContent
|
|
31
|
+
:data-scheme="theme"
|
|
32
|
+
:class="classes"
|
|
33
|
+
:style="customColorStyles"
|
|
34
|
+
:side="side"
|
|
35
|
+
:align="align"
|
|
36
|
+
:side-offset="sideOffset"
|
|
37
|
+
>
|
|
38
|
+
<slot />
|
|
39
|
+
</DropdownMenuContent>
|
|
40
|
+
</DropdownMenuPortal>
|
|
41
|
+
</DropdownMenuRoot>
|
|
42
|
+
</template>
|
|
43
|
+
|
|
44
|
+
<!--------------------------------------------------------------------------------------------------------------------->
|
|
45
|
+
|
|
46
|
+
<style lang="scss" scoped>
|
|
47
|
+
// Component styles use shared menu styles from /src/styles/components/_menu.scss
|
|
48
|
+
</style>
|
|
49
|
+
|
|
50
|
+
<!--------------------------------------------------------------------------------------------------------------------->
|
|
51
|
+
|
|
52
|
+
<script setup lang="ts">
|
|
53
|
+
/**
|
|
54
|
+
* @component
|
|
55
|
+
* A dropdown menu component combining a trigger button and menu content powered by RekaUI.
|
|
56
|
+
* Use with SkMenuItem and SkMenuSeparator components.
|
|
57
|
+
*/
|
|
58
|
+
|
|
59
|
+
import { computed, provide, toRef } from 'vue';
|
|
60
|
+
import {
|
|
61
|
+
DropdownMenuContent,
|
|
62
|
+
DropdownMenuPortal,
|
|
63
|
+
DropdownMenuRoot,
|
|
64
|
+
DropdownMenuTrigger,
|
|
65
|
+
} from 'reka-ui';
|
|
66
|
+
|
|
67
|
+
// Types
|
|
68
|
+
import type { ComponentCustomColors } from '@/types';
|
|
69
|
+
import type { SkDropdownAlign, SkDropdownKind, SkDropdownSide } from './types';
|
|
70
|
+
|
|
71
|
+
// Components
|
|
72
|
+
import SkButton from '../Button/SkButton.vue';
|
|
73
|
+
|
|
74
|
+
// Composables
|
|
75
|
+
import { useCustomColors } from '@/composables/useCustomColors';
|
|
76
|
+
import { usePortalContext } from '@/composables/usePortalContext';
|
|
77
|
+
|
|
78
|
+
//------------------------------------------------------------------------------------------------------------------
|
|
79
|
+
|
|
80
|
+
/**
|
|
81
|
+
* A dropdown menu component combining a trigger button and menu content powered by RekaUI.
|
|
82
|
+
*/
|
|
83
|
+
export interface SkDropdownComponentProps extends ComponentCustomColors
|
|
84
|
+
{
|
|
85
|
+
/** Semantic color kind */
|
|
86
|
+
kind ?: SkDropdownKind;
|
|
87
|
+
/** Text for default trigger button (use trigger slot for custom trigger) */
|
|
88
|
+
triggerText ?: string;
|
|
89
|
+
/** Side of the trigger to position menu */
|
|
90
|
+
side ?: SkDropdownSide;
|
|
91
|
+
/** Alignment relative to trigger */
|
|
92
|
+
align ?: SkDropdownAlign;
|
|
93
|
+
/** Offset from the trigger in pixels */
|
|
94
|
+
sideOffset ?: number;
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
//------------------------------------------------------------------------------------------------------------------
|
|
98
|
+
|
|
99
|
+
const props = withDefaults(defineProps<SkDropdownComponentProps>(), {
|
|
100
|
+
kind: 'neutral',
|
|
101
|
+
triggerText: 'Menu',
|
|
102
|
+
side: 'bottom',
|
|
103
|
+
align: 'start',
|
|
104
|
+
sideOffset: 4,
|
|
105
|
+
});
|
|
106
|
+
|
|
107
|
+
//------------------------------------------------------------------------------------------------------------------
|
|
108
|
+
|
|
109
|
+
// Handle portal context (theme injection/re-provision for nested portal components)
|
|
110
|
+
const { theme } = usePortalContext();
|
|
111
|
+
|
|
112
|
+
// Provide kind for submenus (reactive computed so changes propagate)
|
|
113
|
+
provide('dropdown-kind', computed(() => props.kind));
|
|
114
|
+
|
|
115
|
+
//------------------------------------------------------------------------------------------------------------------
|
|
116
|
+
|
|
117
|
+
// Caret direction based on menu side
|
|
118
|
+
const caretPoints = computed(() =>
|
|
119
|
+
{
|
|
120
|
+
switch (props.side)
|
|
121
|
+
{
|
|
122
|
+
case 'top':
|
|
123
|
+
return '6 15 12 9 18 15'; // Point up
|
|
124
|
+
case 'right':
|
|
125
|
+
return '9 6 15 12 9 18'; // Point right
|
|
126
|
+
case 'left':
|
|
127
|
+
return '15 6 9 12 15 18'; // Point left
|
|
128
|
+
case 'bottom':
|
|
129
|
+
default:
|
|
130
|
+
return '6 9 12 15 18 9'; // Point down
|
|
131
|
+
}
|
|
132
|
+
});
|
|
133
|
+
|
|
134
|
+
//------------------------------------------------------------------------------------------------------------------
|
|
135
|
+
|
|
136
|
+
const classes = computed(() => ({
|
|
137
|
+
'sk-dropdown-menu-content': true,
|
|
138
|
+
[`sk-${ props.kind }`]: true,
|
|
139
|
+
}));
|
|
140
|
+
|
|
141
|
+
//------------------------------------------------------------------------------------------------------------------
|
|
142
|
+
|
|
143
|
+
const customColorStyles = useCustomColors(
|
|
144
|
+
'dropdown',
|
|
145
|
+
toRef(() => props.baseColor),
|
|
146
|
+
toRef(() => props.textColor)
|
|
147
|
+
);
|
|
148
|
+
</script>
|
|
149
|
+
|
|
150
|
+
<!--------------------------------------------------------------------------------------------------------------------->
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
<!----------------------------------------------------------------------------------------------------------------------
|
|
2
|
+
- MenuItem Component
|
|
3
|
+
--------------------------------------------------------------------------------------------------------------------->
|
|
4
|
+
|
|
5
|
+
<template>
|
|
6
|
+
<DropdownMenuItem :class="classes" :disabled="disabled" @click="$emit('click', $event)">
|
|
7
|
+
<slot />
|
|
8
|
+
</DropdownMenuItem>
|
|
9
|
+
</template>
|
|
10
|
+
|
|
11
|
+
<!--------------------------------------------------------------------------------------------------------------------->
|
|
12
|
+
|
|
13
|
+
<style lang="scss" scoped>
|
|
14
|
+
// Component styles are in /src/styles/components/_menu.scss
|
|
15
|
+
</style>
|
|
16
|
+
|
|
17
|
+
<!--------------------------------------------------------------------------------------------------------------------->
|
|
18
|
+
|
|
19
|
+
<script setup lang="ts">
|
|
20
|
+
/**
|
|
21
|
+
* @component
|
|
22
|
+
* A menu item component for use within SkDropdown.
|
|
23
|
+
*/
|
|
24
|
+
|
|
25
|
+
import { computed } from 'vue';
|
|
26
|
+
import { DropdownMenuItem } from 'reka-ui';
|
|
27
|
+
|
|
28
|
+
//------------------------------------------------------------------------------------------------------------------
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* A menu item component for use within SkDropdown.
|
|
32
|
+
*/
|
|
33
|
+
export interface SkDropdownMenuItemComponentProps
|
|
34
|
+
{
|
|
35
|
+
/** Disabled state */
|
|
36
|
+
disabled ?: boolean;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
//------------------------------------------------------------------------------------------------------------------
|
|
40
|
+
|
|
41
|
+
withDefaults(defineProps<SkDropdownMenuItemComponentProps>(), {
|
|
42
|
+
disabled: false,
|
|
43
|
+
});
|
|
44
|
+
|
|
45
|
+
//------------------------------------------------------------------------------------------------------------------
|
|
46
|
+
|
|
47
|
+
defineEmits<{
|
|
48
|
+
click : [event : Event];
|
|
49
|
+
}>();
|
|
50
|
+
|
|
51
|
+
//------------------------------------------------------------------------------------------------------------------
|
|
52
|
+
|
|
53
|
+
const classes = computed(() => ({
|
|
54
|
+
'sk-dropdown-menu-item': true,
|
|
55
|
+
}));
|
|
56
|
+
</script>
|
|
57
|
+
|
|
58
|
+
<!--------------------------------------------------------------------------------------------------------------------->
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
<!----------------------------------------------------------------------------------------------------------------------
|
|
2
|
+
- MenuSeparator Component
|
|
3
|
+
--------------------------------------------------------------------------------------------------------------------->
|
|
4
|
+
|
|
5
|
+
<template>
|
|
6
|
+
<DropdownMenuSeparator class="sk-menu-separator" />
|
|
7
|
+
</template>
|
|
8
|
+
|
|
9
|
+
<!--------------------------------------------------------------------------------------------------------------------->
|
|
10
|
+
|
|
11
|
+
<style lang="scss" scoped>
|
|
12
|
+
// Component styles are in /src/styles/components/_menu.scss
|
|
13
|
+
</style>
|
|
14
|
+
|
|
15
|
+
<!--------------------------------------------------------------------------------------------------------------------->
|
|
16
|
+
|
|
17
|
+
<script setup lang="ts">
|
|
18
|
+
/**
|
|
19
|
+
* @component
|
|
20
|
+
* A menu separator component for use within SkDropdown.
|
|
21
|
+
*/
|
|
22
|
+
|
|
23
|
+
import { DropdownMenuSeparator } from 'reka-ui';
|
|
24
|
+
</script>
|
|
25
|
+
|
|
26
|
+
<!--------------------------------------------------------------------------------------------------------------------->
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
<!----------------------------------------------------------------------------------------------------------------------
|
|
2
|
+
- DropdownSubmenu Component
|
|
3
|
+
--------------------------------------------------------------------------------------------------------------------->
|
|
4
|
+
|
|
5
|
+
<template>
|
|
6
|
+
<DropdownMenuSub>
|
|
7
|
+
<DropdownMenuSubTrigger :class="triggerClasses">
|
|
8
|
+
{{ triggerText }}
|
|
9
|
+
<svg
|
|
10
|
+
xmlns="http://www.w3.org/2000/svg"
|
|
11
|
+
viewBox="0 0 24 24"
|
|
12
|
+
fill="none"
|
|
13
|
+
stroke="currentColor"
|
|
14
|
+
stroke-width="2"
|
|
15
|
+
stroke-linecap="square"
|
|
16
|
+
stroke-linejoin="miter"
|
|
17
|
+
class="sk-submenu-caret"
|
|
18
|
+
>
|
|
19
|
+
<polyline points="9 6 15 12 9 18" />
|
|
20
|
+
</svg>
|
|
21
|
+
</DropdownMenuSubTrigger>
|
|
22
|
+
<DropdownMenuPortal>
|
|
23
|
+
<DropdownMenuSubContent
|
|
24
|
+
:data-scheme="theme"
|
|
25
|
+
:class="contentClasses"
|
|
26
|
+
>
|
|
27
|
+
<slot />
|
|
28
|
+
</DropdownMenuSubContent>
|
|
29
|
+
</DropdownMenuPortal>
|
|
30
|
+
</DropdownMenuSub>
|
|
31
|
+
</template>
|
|
32
|
+
|
|
33
|
+
<!--------------------------------------------------------------------------------------------------------------------->
|
|
34
|
+
|
|
35
|
+
<style lang="scss" scoped>
|
|
36
|
+
// Component styles use shared menu styles from /src/styles/components/_menu.scss
|
|
37
|
+
</style>
|
|
38
|
+
|
|
39
|
+
<!--------------------------------------------------------------------------------------------------------------------->
|
|
40
|
+
|
|
41
|
+
<script setup lang="ts">
|
|
42
|
+
/**
|
|
43
|
+
* @component
|
|
44
|
+
* A dropdown submenu component for nested menus.
|
|
45
|
+
* Use with SkDropdownMenuItem components in default slot.
|
|
46
|
+
*/
|
|
47
|
+
|
|
48
|
+
import { computed, inject } from 'vue';
|
|
49
|
+
|
|
50
|
+
// Composables
|
|
51
|
+
import { usePortalContext } from '@/composables/usePortalContext';
|
|
52
|
+
import {
|
|
53
|
+
DropdownMenuPortal,
|
|
54
|
+
DropdownMenuSub,
|
|
55
|
+
DropdownMenuSubContent,
|
|
56
|
+
DropdownMenuSubTrigger,
|
|
57
|
+
} from 'reka-ui';
|
|
58
|
+
|
|
59
|
+
// Types
|
|
60
|
+
import type { SkDropdownKind } from './types';
|
|
61
|
+
|
|
62
|
+
//------------------------------------------------------------------------------------------------------------------
|
|
63
|
+
|
|
64
|
+
/**
|
|
65
|
+
* A dropdown submenu component for nested menus.
|
|
66
|
+
*/
|
|
67
|
+
export interface SkDropdownSubmenuComponentProps
|
|
68
|
+
{
|
|
69
|
+
/** Text for submenu trigger */
|
|
70
|
+
triggerText : string;
|
|
71
|
+
/** Semantic color kind (inherits from parent dropdown if not set) */
|
|
72
|
+
kind ?: SkDropdownKind;
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
//------------------------------------------------------------------------------------------------------------------
|
|
76
|
+
|
|
77
|
+
const props = withDefaults(defineProps<SkDropdownSubmenuComponentProps>(), {
|
|
78
|
+
kind: undefined,
|
|
79
|
+
});
|
|
80
|
+
|
|
81
|
+
//------------------------------------------------------------------------------------------------------------------
|
|
82
|
+
|
|
83
|
+
// Handle portal context (theme injection/re-provision for nested portal components)
|
|
84
|
+
const { theme } = usePortalContext();
|
|
85
|
+
|
|
86
|
+
// Inject parent dropdown kind (will be a ComputedRef)
|
|
87
|
+
const parentKind = inject<any>('dropdown-kind', computed(() => 'neutral'));
|
|
88
|
+
|
|
89
|
+
//------------------------------------------------------------------------------------------------------------------
|
|
90
|
+
|
|
91
|
+
const effectiveKind = computed(() => props.kind || parentKind.value || 'neutral');
|
|
92
|
+
|
|
93
|
+
//------------------------------------------------------------------------------------------------------------------
|
|
94
|
+
|
|
95
|
+
const triggerClasses = computed(() => ({
|
|
96
|
+
'sk-dropdown-menu-item': true,
|
|
97
|
+
}));
|
|
98
|
+
|
|
99
|
+
//------------------------------------------------------------------------------------------------------------------
|
|
100
|
+
|
|
101
|
+
const contentClasses = computed(() => ({
|
|
102
|
+
'sk-dropdown-menu-content': true,
|
|
103
|
+
[`sk-${ effectiveKind.value }`]: true,
|
|
104
|
+
}));
|
|
105
|
+
</script>
|
|
106
|
+
|
|
107
|
+
<!--------------------------------------------------------------------------------------------------------------------->
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
//----------------------------------------------------------------------------------------------------------------------
|
|
2
|
+
// Dropdown Component Exports
|
|
3
|
+
//----------------------------------------------------------------------------------------------------------------------
|
|
4
|
+
|
|
5
|
+
export { default as SkDropdown } from './SkDropdown.vue';
|
|
6
|
+
export { default as SkDropdownMenuItem } from './SkDropdownMenuItem.vue';
|
|
7
|
+
export { default as SkDropdownMenuSeparator } from './SkDropdownMenuSeparator.vue';
|
|
8
|
+
export { default as SkDropdownSubmenu } from './SkDropdownSubmenu.vue';
|
|
9
|
+
export type { SkDropdownAlign, SkDropdownKind, SkDropdownSide } from './types';
|
|
10
|
+
|
|
11
|
+
//----------------------------------------------------------------------------------------------------------------------
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
//----------------------------------------------------------------------------------------------------------------------
|
|
2
|
+
// Dropdown Component Types
|
|
3
|
+
//----------------------------------------------------------------------------------------------------------------------
|
|
4
|
+
|
|
5
|
+
import type { ComponentKind } from '@/types';
|
|
6
|
+
|
|
7
|
+
export type SkDropdownKind = ComponentKind;
|
|
8
|
+
export type SkDropdownSide = 'top' | 'right' | 'bottom' | 'left';
|
|
9
|
+
export type SkDropdownAlign = 'start' | 'center' | 'end';
|
|
10
|
+
|
|
11
|
+
//----------------------------------------------------------------------------------------------------------------------
|
|
@@ -0,0 +1,152 @@
|
|
|
1
|
+
<!----------------------------------------------------------------------------------------------------------------------
|
|
2
|
+
- Field Component
|
|
3
|
+
--------------------------------------------------------------------------------------------------------------------->
|
|
4
|
+
|
|
5
|
+
<template>
|
|
6
|
+
<div :class="classes">
|
|
7
|
+
<label v-if="label" :for="fieldId" class="sk-field-label">
|
|
8
|
+
{{ label }}
|
|
9
|
+
<span v-if="required" class="sk-field-required">*</span>
|
|
10
|
+
</label>
|
|
11
|
+
|
|
12
|
+
<div class="sk-field-input-wrapper">
|
|
13
|
+
<slot :id="fieldId" :aria-describedby="ariaDescribedBy" :aria-invalid="ariaInvalid" :kind="effectiveKind" />
|
|
14
|
+
</div>
|
|
15
|
+
|
|
16
|
+
<p v-if="description && !error" :id="descriptionId" class="sk-field-description">
|
|
17
|
+
{{ description }}
|
|
18
|
+
</p>
|
|
19
|
+
|
|
20
|
+
<p v-if="error" :id="errorId" class="sk-field-error">
|
|
21
|
+
{{ error }}
|
|
22
|
+
</p>
|
|
23
|
+
</div>
|
|
24
|
+
</template>
|
|
25
|
+
|
|
26
|
+
<!--------------------------------------------------------------------------------------------------------------------->
|
|
27
|
+
|
|
28
|
+
<style lang="scss" scoped>
|
|
29
|
+
// Component styles are implemented in /src/styles/components/_field.scss
|
|
30
|
+
</style>
|
|
31
|
+
|
|
32
|
+
<!--------------------------------------------------------------------------------------------------------------------->
|
|
33
|
+
|
|
34
|
+
<script setup lang="ts">
|
|
35
|
+
/**
|
|
36
|
+
* @component
|
|
37
|
+
* A form field wrapper that provides label, description, and error message support.
|
|
38
|
+
* Automatically wires up accessibility attributes (id, aria-describedby, aria-invalid).
|
|
39
|
+
*/
|
|
40
|
+
|
|
41
|
+
import { computed, provide } from 'vue';
|
|
42
|
+
|
|
43
|
+
// Types
|
|
44
|
+
import type { SkFieldLabelPosition } from './types';
|
|
45
|
+
|
|
46
|
+
//------------------------------------------------------------------------------------------------------------------
|
|
47
|
+
|
|
48
|
+
/**
|
|
49
|
+
* A form field wrapper that provides label, description, and error message support.
|
|
50
|
+
*/
|
|
51
|
+
export interface SkFieldComponentProps
|
|
52
|
+
{
|
|
53
|
+
/** Label text for the field */
|
|
54
|
+
label ?: string;
|
|
55
|
+
/** Description/help text */
|
|
56
|
+
description ?: string;
|
|
57
|
+
/** Error message (overrides description when present) */
|
|
58
|
+
error ?: string;
|
|
59
|
+
/** Required field indicator */
|
|
60
|
+
required ?: boolean;
|
|
61
|
+
/** Label position */
|
|
62
|
+
labelPosition ?: SkFieldLabelPosition;
|
|
63
|
+
/** Custom field ID (auto-generated if not provided) */
|
|
64
|
+
id ?: string;
|
|
65
|
+
/** Validation state (true = valid, false = invalid, null/undefined = neutral) */
|
|
66
|
+
state ?: boolean | null;
|
|
67
|
+
/** Kind to use when state is true (valid) */
|
|
68
|
+
validKind ?: string;
|
|
69
|
+
/** Kind to use when state is false (invalid) */
|
|
70
|
+
invalidKind ?: string;
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
//------------------------------------------------------------------------------------------------------------------
|
|
74
|
+
|
|
75
|
+
const props = withDefaults(defineProps<SkFieldComponentProps>(), {
|
|
76
|
+
label: undefined,
|
|
77
|
+
description: undefined,
|
|
78
|
+
error: undefined,
|
|
79
|
+
required: false,
|
|
80
|
+
labelPosition: 'top',
|
|
81
|
+
id: undefined,
|
|
82
|
+
state: null,
|
|
83
|
+
validKind: 'success',
|
|
84
|
+
invalidKind: 'danger',
|
|
85
|
+
});
|
|
86
|
+
|
|
87
|
+
//------------------------------------------------------------------------------------------------------------------
|
|
88
|
+
|
|
89
|
+
// Generate unique ID for field
|
|
90
|
+
const fieldId = computed(() =>
|
|
91
|
+
{
|
|
92
|
+
return props.id || `sk-field-${ Math.random()
|
|
93
|
+
.toString(36)
|
|
94
|
+
.substr(2, 9) }`;
|
|
95
|
+
});
|
|
96
|
+
|
|
97
|
+
const descriptionId = computed(() => `${ fieldId.value }-description`);
|
|
98
|
+
const errorId = computed(() => `${ fieldId.value }-error`);
|
|
99
|
+
|
|
100
|
+
//------------------------------------------------------------------------------------------------------------------
|
|
101
|
+
|
|
102
|
+
const ariaDescribedBy = computed(() =>
|
|
103
|
+
{
|
|
104
|
+
if(props.error)
|
|
105
|
+
{
|
|
106
|
+
return errorId.value;
|
|
107
|
+
}
|
|
108
|
+
else if(props.description)
|
|
109
|
+
{
|
|
110
|
+
return descriptionId.value;
|
|
111
|
+
}
|
|
112
|
+
return undefined;
|
|
113
|
+
});
|
|
114
|
+
|
|
115
|
+
//------------------------------------------------------------------------------------------------------------------
|
|
116
|
+
|
|
117
|
+
const ariaInvalid = computed(() =>
|
|
118
|
+
{
|
|
119
|
+
return props.error ? 'true' : undefined;
|
|
120
|
+
});
|
|
121
|
+
|
|
122
|
+
//------------------------------------------------------------------------------------------------------------------
|
|
123
|
+
|
|
124
|
+
// Determine the kind to apply based on state prop
|
|
125
|
+
const effectiveKind = computed(() =>
|
|
126
|
+
{
|
|
127
|
+
if(props.state === true)
|
|
128
|
+
{
|
|
129
|
+
return props.validKind;
|
|
130
|
+
}
|
|
131
|
+
else if(props.state === false)
|
|
132
|
+
{
|
|
133
|
+
return props.invalidKind;
|
|
134
|
+
}
|
|
135
|
+
return undefined; // Let the input use its own kind prop
|
|
136
|
+
});
|
|
137
|
+
|
|
138
|
+
//------------------------------------------------------------------------------------------------------------------
|
|
139
|
+
|
|
140
|
+
// Provide kind to child inputs so they can automatically pick it up
|
|
141
|
+
provide('field-kind', effectiveKind);
|
|
142
|
+
|
|
143
|
+
//------------------------------------------------------------------------------------------------------------------
|
|
144
|
+
|
|
145
|
+
const classes = computed(() => ({
|
|
146
|
+
'sk-field': true,
|
|
147
|
+
[`sk-label-${ props.labelPosition }`]: true,
|
|
148
|
+
'sk-has-error': !!props.error,
|
|
149
|
+
}));
|
|
150
|
+
</script>
|
|
151
|
+
|
|
152
|
+
<!--------------------------------------------------------------------------------------------------------------------->
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
//----------------------------------------------------------------------------------------------------------------------
|
|
2
|
+
// Field Component Exports
|
|
3
|
+
//----------------------------------------------------------------------------------------------------------------------
|
|
4
|
+
|
|
5
|
+
export { default as SkField } from './SkField.vue';
|
|
6
|
+
export type { SkFieldLabelPosition } from './types';
|
|
7
|
+
|
|
8
|
+
//----------------------------------------------------------------------------------------------------------------------
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
//----------------------------------------------------------------------------------------------------------------------
|
|
2
|
+
// Field Component Types
|
|
3
|
+
//----------------------------------------------------------------------------------------------------------------------
|
|
4
|
+
|
|
5
|
+
export type SkFieldLabelPosition = 'top' | 'left';
|
|
6
|
+
|
|
7
|
+
//----------------------------------------------------------------------------------------------------------------------
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
<!----------------------------------------------------------------------------------------------------------------------
|
|
2
|
+
- Group Component
|
|
3
|
+
--------------------------------------------------------------------------------------------------------------------->
|
|
4
|
+
|
|
5
|
+
<template>
|
|
6
|
+
<div :class="classes">
|
|
7
|
+
<slot />
|
|
8
|
+
</div>
|
|
9
|
+
</template>
|
|
10
|
+
|
|
11
|
+
<!--------------------------------------------------------------------------------------------------------------------->
|
|
12
|
+
|
|
13
|
+
<script setup lang="ts">
|
|
14
|
+
/**
|
|
15
|
+
* @component
|
|
16
|
+
* A layout container that groups child elements with consistent spacing.
|
|
17
|
+
* Automatically arranges children in horizontal or vertical orientation.
|
|
18
|
+
*/
|
|
19
|
+
|
|
20
|
+
import { computed } from 'vue';
|
|
21
|
+
import type { SkGroupOrientation } from './types.ts';
|
|
22
|
+
|
|
23
|
+
//------------------------------------------------------------------------------------------------------------------
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* A layout container that groups child elements with consistent spacing.
|
|
27
|
+
* Automatically arranges children in horizontal or vertical orientation.
|
|
28
|
+
*/
|
|
29
|
+
export interface SkGroupComponentProps
|
|
30
|
+
{
|
|
31
|
+
/** Orientation for arranging child elements (horizontal or vertical) */
|
|
32
|
+
orientation ?: SkGroupOrientation;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
//------------------------------------------------------------------------------------------------------------------
|
|
36
|
+
|
|
37
|
+
const props = withDefaults(defineProps<SkGroupComponentProps>(), {
|
|
38
|
+
orientation: 'horizontal',
|
|
39
|
+
});
|
|
40
|
+
|
|
41
|
+
//------------------------------------------------------------------------------------------------------------------
|
|
42
|
+
|
|
43
|
+
const classes = computed(() =>
|
|
44
|
+
{
|
|
45
|
+
return {
|
|
46
|
+
'sk-group': true,
|
|
47
|
+
[`sk-${ props.orientation }`]: true,
|
|
48
|
+
};
|
|
49
|
+
});
|
|
50
|
+
</script>
|
|
51
|
+
|
|
52
|
+
<!--------------------------------------------------------------------------------------------------------------------->
|