@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,88 @@
|
|
|
1
|
+
<!----------------------------------------------------------------------------------------------------------------------
|
|
2
|
+
- Sidebar Component
|
|
3
|
+
--------------------------------------------------------------------------------------------------------------------->
|
|
4
|
+
|
|
5
|
+
<template>
|
|
6
|
+
<aside :class="classes">
|
|
7
|
+
<SkPanel
|
|
8
|
+
:kind="kind"
|
|
9
|
+
:base-color="baseColor"
|
|
10
|
+
:text-color="textColor"
|
|
11
|
+
class="sk-sidebar-panel"
|
|
12
|
+
>
|
|
13
|
+
<div class="sk-panel-scroll-content">
|
|
14
|
+
<nav class="sk-sidebar-nav">
|
|
15
|
+
<slot />
|
|
16
|
+
</nav>
|
|
17
|
+
</div>
|
|
18
|
+
</SkPanel>
|
|
19
|
+
</aside>
|
|
20
|
+
</template>
|
|
21
|
+
|
|
22
|
+
<!--------------------------------------------------------------------------------------------------------------------->
|
|
23
|
+
|
|
24
|
+
<script setup lang="ts">
|
|
25
|
+
/**
|
|
26
|
+
* @component
|
|
27
|
+
* A sticky navigation sidebar container with semantic color theming.
|
|
28
|
+
* Wrap SkSidebarSection and SkSidebarItem components inside.
|
|
29
|
+
*/
|
|
30
|
+
|
|
31
|
+
import { computed } from 'vue';
|
|
32
|
+
import type { SkSidebarKind } from './types';
|
|
33
|
+
import type { ComponentCustomColors } from '@/types';
|
|
34
|
+
import SkPanel from '../Panel/SkPanel.vue';
|
|
35
|
+
|
|
36
|
+
//------------------------------------------------------------------------------------------------------------------
|
|
37
|
+
|
|
38
|
+
/**
|
|
39
|
+
* A sticky navigation sidebar container with semantic color theming.
|
|
40
|
+
* Wrap SkSidebarSection and SkSidebarItem components inside.
|
|
41
|
+
*
|
|
42
|
+
* @example Basic sidebar
|
|
43
|
+
* ```vue
|
|
44
|
+
* <SkSidebar>
|
|
45
|
+
* <SkSidebarSection title="Navigation">
|
|
46
|
+
* <SkSidebarItem to="/home">Home</SkSidebarItem>
|
|
47
|
+
* <SkSidebarItem to="/about">About</SkSidebarItem>
|
|
48
|
+
* </SkSidebarSection>
|
|
49
|
+
* </SkSidebar>
|
|
50
|
+
* ```
|
|
51
|
+
*
|
|
52
|
+
* @example Custom colors
|
|
53
|
+
* ```vue
|
|
54
|
+
* <SkSidebar
|
|
55
|
+
* base-color="oklch(0.3 0.15 260)"
|
|
56
|
+
* text-color="oklch(0.85 0.05 260)"
|
|
57
|
+
* >
|
|
58
|
+
* <!-- Sidebar content -->
|
|
59
|
+
* </SkSidebar>
|
|
60
|
+
* ```
|
|
61
|
+
*/
|
|
62
|
+
export interface SkSidebarComponentProps extends ComponentCustomColors
|
|
63
|
+
{
|
|
64
|
+
/** Semantic color kind for the sidebar */
|
|
65
|
+
kind ?: SkSidebarKind;
|
|
66
|
+
/** CSS width value for the sidebar */
|
|
67
|
+
width ?: string;
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
//------------------------------------------------------------------------------------------------------------------
|
|
71
|
+
|
|
72
|
+
const props = withDefaults(defineProps<SkSidebarComponentProps>(), {
|
|
73
|
+
kind: 'neutral',
|
|
74
|
+
width: '180px',
|
|
75
|
+
});
|
|
76
|
+
|
|
77
|
+
//------------------------------------------------------------------------------------------------------------------
|
|
78
|
+
|
|
79
|
+
const classes = computed(() =>
|
|
80
|
+
{
|
|
81
|
+
return {
|
|
82
|
+
'sk-sidebar': true,
|
|
83
|
+
[`sk-${ props.kind }`]: true,
|
|
84
|
+
};
|
|
85
|
+
});
|
|
86
|
+
</script>
|
|
87
|
+
|
|
88
|
+
<!--------------------------------------------------------------------------------------------------------------------->
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
<!----------------------------------------------------------------------------------------------------------------------
|
|
2
|
+
- Sidebar Item Component
|
|
3
|
+
--------------------------------------------------------------------------------------------------------------------->
|
|
4
|
+
|
|
5
|
+
<template>
|
|
6
|
+
<component
|
|
7
|
+
:is="as"
|
|
8
|
+
:class="classes"
|
|
9
|
+
v-bind="$attrs"
|
|
10
|
+
>
|
|
11
|
+
<slot />
|
|
12
|
+
</component>
|
|
13
|
+
</template>
|
|
14
|
+
|
|
15
|
+
<!--------------------------------------------------------------------------------------------------------------------->
|
|
16
|
+
|
|
17
|
+
<script setup lang="ts">
|
|
18
|
+
/**
|
|
19
|
+
* @component
|
|
20
|
+
* An individual navigation item in the sidebar.
|
|
21
|
+
* Can render as any element (a, RouterLink, button, etc).
|
|
22
|
+
*/
|
|
23
|
+
|
|
24
|
+
import { computed } from 'vue';
|
|
25
|
+
|
|
26
|
+
//------------------------------------------------------------------------------------------------------------------
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* An individual navigation item in the sidebar.
|
|
30
|
+
* Can render as any element (a, RouterLink, button, etc).
|
|
31
|
+
*/
|
|
32
|
+
export interface SkSidebarItemComponentProps
|
|
33
|
+
{
|
|
34
|
+
/** HTML tag or component name to render as */
|
|
35
|
+
as ?: string;
|
|
36
|
+
/** Whether this item is currently active */
|
|
37
|
+
active ?: boolean;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
//------------------------------------------------------------------------------------------------------------------
|
|
41
|
+
|
|
42
|
+
const props = withDefaults(defineProps<SkSidebarItemComponentProps>(), {
|
|
43
|
+
as: 'a',
|
|
44
|
+
active: false,
|
|
45
|
+
});
|
|
46
|
+
|
|
47
|
+
//------------------------------------------------------------------------------------------------------------------
|
|
48
|
+
|
|
49
|
+
const classes = computed(() =>
|
|
50
|
+
{
|
|
51
|
+
return {
|
|
52
|
+
'sk-sidebar-item': true,
|
|
53
|
+
'sk-active': props.active,
|
|
54
|
+
};
|
|
55
|
+
});
|
|
56
|
+
</script>
|
|
57
|
+
|
|
58
|
+
<!--------------------------------------------------------------------------------------------------------------------->
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
<!----------------------------------------------------------------------------------------------------------------------
|
|
2
|
+
- Sidebar Section Component
|
|
3
|
+
--------------------------------------------------------------------------------------------------------------------->
|
|
4
|
+
|
|
5
|
+
<template>
|
|
6
|
+
<div class="sk-sidebar-section">
|
|
7
|
+
<h3 v-if="title" class="sk-sidebar-section-title">
|
|
8
|
+
{{ title }}
|
|
9
|
+
</h3>
|
|
10
|
+
<slot />
|
|
11
|
+
</div>
|
|
12
|
+
</template>
|
|
13
|
+
|
|
14
|
+
<!--------------------------------------------------------------------------------------------------------------------->
|
|
15
|
+
|
|
16
|
+
<script setup lang="ts">
|
|
17
|
+
/**
|
|
18
|
+
* @component
|
|
19
|
+
* Groups sidebar items under an optional heading.
|
|
20
|
+
* Use this to organize navigation into logical sections.
|
|
21
|
+
*/
|
|
22
|
+
|
|
23
|
+
//------------------------------------------------------------------------------------------------------------------
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* Groups sidebar items under an optional heading.
|
|
27
|
+
* Use this to organize navigation into logical sections.
|
|
28
|
+
*/
|
|
29
|
+
export interface SkSidebarSectionComponentProps
|
|
30
|
+
{
|
|
31
|
+
/** Optional section heading */
|
|
32
|
+
title ?: string;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
//------------------------------------------------------------------------------------------------------------------
|
|
36
|
+
|
|
37
|
+
defineProps<SkSidebarSectionComponentProps>();
|
|
38
|
+
</script>
|
|
39
|
+
|
|
40
|
+
<!--------------------------------------------------------------------------------------------------------------------->
|
|
@@ -0,0 +1,171 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<div
|
|
3
|
+
:class="classes"
|
|
4
|
+
:style="styles"
|
|
5
|
+
/>
|
|
6
|
+
</template>
|
|
7
|
+
|
|
8
|
+
<!--------------------------------------------------------------------------------------------------------------------->
|
|
9
|
+
|
|
10
|
+
<style lang="scss" scoped>
|
|
11
|
+
// Component styles are implemented in /src/styles/components/_skeleton.scss
|
|
12
|
+
</style>
|
|
13
|
+
|
|
14
|
+
<!--------------------------------------------------------------------------------------------------------------------->
|
|
15
|
+
|
|
16
|
+
<script setup lang="ts">
|
|
17
|
+
/**
|
|
18
|
+
* @component SkSkeleton
|
|
19
|
+
* A loading placeholder component with shimmer or pulse animation.
|
|
20
|
+
* Use to indicate loading state while content is being fetched.
|
|
21
|
+
*/
|
|
22
|
+
|
|
23
|
+
import { computed } from 'vue';
|
|
24
|
+
|
|
25
|
+
// Types
|
|
26
|
+
import type { SkSkeletonAnimation, SkSkeletonCorner, SkSkeletonVariant } from './types';
|
|
27
|
+
|
|
28
|
+
//------------------------------------------------------------------------------------------------------------------
|
|
29
|
+
|
|
30
|
+
export interface SkSkeletonComponentProps
|
|
31
|
+
{
|
|
32
|
+
/** Shape variant */
|
|
33
|
+
variant ?: SkSkeletonVariant;
|
|
34
|
+
/** Width (CSS value) */
|
|
35
|
+
width ?: string;
|
|
36
|
+
/** Height (CSS value) */
|
|
37
|
+
height ?: string;
|
|
38
|
+
/** Animation style */
|
|
39
|
+
animation ?: SkSkeletonAnimation;
|
|
40
|
+
/** Custom corners to bevel (overrides variant default) */
|
|
41
|
+
corners ?: SkSkeletonCorner[];
|
|
42
|
+
/** Custom bevel size (CSS value, e.g. '0.5rem', '8px') */
|
|
43
|
+
bevel ?: string;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
//------------------------------------------------------------------------------------------------------------------
|
|
47
|
+
|
|
48
|
+
const props = withDefaults(defineProps<SkSkeletonComponentProps>(), {
|
|
49
|
+
variant: 'text',
|
|
50
|
+
width: '100%',
|
|
51
|
+
height: undefined,
|
|
52
|
+
animation: 'shimmer',
|
|
53
|
+
corners: undefined,
|
|
54
|
+
bevel: undefined,
|
|
55
|
+
});
|
|
56
|
+
|
|
57
|
+
//------------------------------------------------------------------------------------------------------------------
|
|
58
|
+
// Clip Path Generation
|
|
59
|
+
//------------------------------------------------------------------------------------------------------------------
|
|
60
|
+
|
|
61
|
+
/**
|
|
62
|
+
* Generates a clip-path polygon for beveled corners.
|
|
63
|
+
* @param corners - Array of corners to bevel
|
|
64
|
+
* @param bevel - CSS value for bevel size
|
|
65
|
+
*/
|
|
66
|
+
function generateClipPath(corners : SkSkeletonCorner[], bevel : string) : string
|
|
67
|
+
{
|
|
68
|
+
const hasCorner = (corner : SkSkeletonCorner) : boolean => corners.includes(corner);
|
|
69
|
+
|
|
70
|
+
// Build polygon points clockwise from top-left
|
|
71
|
+
const points : string[] = [];
|
|
72
|
+
|
|
73
|
+
// Top-left corner
|
|
74
|
+
if(hasCorner('top-left'))
|
|
75
|
+
{
|
|
76
|
+
points.push(`${ bevel } 0`);
|
|
77
|
+
}
|
|
78
|
+
else
|
|
79
|
+
{
|
|
80
|
+
points.push('0 0');
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
// Top-right corner
|
|
84
|
+
if(hasCorner('top-right'))
|
|
85
|
+
{
|
|
86
|
+
points.push(`calc(100% - ${ bevel }) 0`);
|
|
87
|
+
points.push(`100% ${ bevel }`);
|
|
88
|
+
}
|
|
89
|
+
else
|
|
90
|
+
{
|
|
91
|
+
points.push('100% 0');
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
// Bottom-right corner
|
|
95
|
+
if(hasCorner('bottom-right'))
|
|
96
|
+
{
|
|
97
|
+
points.push(`100% calc(100% - ${ bevel })`);
|
|
98
|
+
points.push(`calc(100% - ${ bevel }) 100%`);
|
|
99
|
+
}
|
|
100
|
+
else
|
|
101
|
+
{
|
|
102
|
+
points.push('100% 100%');
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
// Bottom-left corner
|
|
106
|
+
if(hasCorner('bottom-left'))
|
|
107
|
+
{
|
|
108
|
+
points.push(`${ bevel } 100%`);
|
|
109
|
+
points.push(`0 calc(100% - ${ bevel })`);
|
|
110
|
+
}
|
|
111
|
+
else
|
|
112
|
+
{
|
|
113
|
+
points.push('0 100%');
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
// Close top-left if beveled
|
|
117
|
+
if(hasCorner('top-left'))
|
|
118
|
+
{
|
|
119
|
+
points.push(`0 ${ bevel }`);
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
return `polygon(${ points.join(', ') })`;
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
//------------------------------------------------------------------------------------------------------------------
|
|
126
|
+
// Classes
|
|
127
|
+
//------------------------------------------------------------------------------------------------------------------
|
|
128
|
+
|
|
129
|
+
const classes = computed(() => ({
|
|
130
|
+
'sk-skeleton': true,
|
|
131
|
+
[`sk-${ props.variant }`]: true,
|
|
132
|
+
[`sk-${ props.animation }`]: props.animation !== 'none',
|
|
133
|
+
'sk-custom-corners': !!props.corners,
|
|
134
|
+
}));
|
|
135
|
+
|
|
136
|
+
//------------------------------------------------------------------------------------------------------------------
|
|
137
|
+
// Styles
|
|
138
|
+
//------------------------------------------------------------------------------------------------------------------
|
|
139
|
+
|
|
140
|
+
const styles = computed(() =>
|
|
141
|
+
{
|
|
142
|
+
const result : Record<string, string> = {};
|
|
143
|
+
|
|
144
|
+
if(props.width)
|
|
145
|
+
{
|
|
146
|
+
result.width = props.width;
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
if(props.height)
|
|
150
|
+
{
|
|
151
|
+
result.height = props.height;
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
// For circular or square variant, if only width is set, make it square
|
|
155
|
+
if((props.variant === 'circular' || props.variant === 'square') && props.width && !props.height)
|
|
156
|
+
{
|
|
157
|
+
result.height = props.width;
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
// Generate custom clip-path if corners are specified
|
|
161
|
+
if(props.corners && props.corners.length > 0)
|
|
162
|
+
{
|
|
163
|
+
const bevelSize = props.bevel ?? '0.5rem';
|
|
164
|
+
result.clipPath = generateClipPath(props.corners, bevelSize);
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
return result;
|
|
168
|
+
});
|
|
169
|
+
</script>
|
|
170
|
+
|
|
171
|
+
<!--------------------------------------------------------------------------------------------------------------------->
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
//----------------------------------------------------------------------------------------------------------------------
|
|
2
|
+
// Skeleton Component Exports
|
|
3
|
+
//----------------------------------------------------------------------------------------------------------------------
|
|
4
|
+
|
|
5
|
+
export { default as SkSkeleton } from './SkSkeleton.vue';
|
|
6
|
+
export * from './types';
|
|
7
|
+
|
|
8
|
+
//----------------------------------------------------------------------------------------------------------------------
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
//----------------------------------------------------------------------------------------------------------------------
|
|
2
|
+
// Skeleton Types
|
|
3
|
+
//----------------------------------------------------------------------------------------------------------------------
|
|
4
|
+
|
|
5
|
+
/** Skeleton shape variant */
|
|
6
|
+
export type SkSkeletonVariant = 'text' | 'circular' | 'rectangular' | 'square';
|
|
7
|
+
|
|
8
|
+
/** Skeleton animation style */
|
|
9
|
+
export type SkSkeletonAnimation = 'shimmer' | 'pulse' | 'none';
|
|
10
|
+
|
|
11
|
+
/** Corner positions for beveling */
|
|
12
|
+
export type SkSkeletonCorner = 'top-left' | 'top-right' | 'bottom-left' | 'bottom-right';
|
|
13
|
+
|
|
14
|
+
/** Skeleton props interface */
|
|
15
|
+
export interface SkSkeletonProps
|
|
16
|
+
{
|
|
17
|
+
/** Shape variant */
|
|
18
|
+
variant ?: SkSkeletonVariant;
|
|
19
|
+
/** Width (CSS value) */
|
|
20
|
+
width ?: string;
|
|
21
|
+
/** Height (CSS value) */
|
|
22
|
+
height ?: string;
|
|
23
|
+
/** Animation style */
|
|
24
|
+
animation ?: SkSkeletonAnimation;
|
|
25
|
+
/** Custom corners to bevel (overrides variant default) */
|
|
26
|
+
corners ?: SkSkeletonCorner[];
|
|
27
|
+
/** Custom bevel size (CSS value, e.g. '0.5rem', '8px') */
|
|
28
|
+
bevel ?: string;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
//----------------------------------------------------------------------------------------------------------------------
|
|
@@ -0,0 +1,165 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<SliderRoot
|
|
3
|
+
:model-value="normalizedValue"
|
|
4
|
+
:min="min"
|
|
5
|
+
:max="max"
|
|
6
|
+
:step="step"
|
|
7
|
+
:orientation="orientation"
|
|
8
|
+
:disabled="disabled"
|
|
9
|
+
:name="name"
|
|
10
|
+
:min-steps-between-thumbs="minStepsBetweenThumbs"
|
|
11
|
+
:class="classes"
|
|
12
|
+
:style="customStyles"
|
|
13
|
+
@update:model-value="handleUpdate"
|
|
14
|
+
>
|
|
15
|
+
<SliderTrack class="sk-slider-track">
|
|
16
|
+
<SliderRange class="sk-slider-range" />
|
|
17
|
+
</SliderTrack>
|
|
18
|
+
<SliderThumb
|
|
19
|
+
v-for="(_, index) in thumbCount"
|
|
20
|
+
:key="index"
|
|
21
|
+
class="sk-slider-thumb"
|
|
22
|
+
/>
|
|
23
|
+
</SliderRoot>
|
|
24
|
+
</template>
|
|
25
|
+
|
|
26
|
+
<!--------------------------------------------------------------------------------------------------------------------->
|
|
27
|
+
|
|
28
|
+
<style lang="scss" scoped>
|
|
29
|
+
// Component styles are implemented in /src/styles/components/_slider.scss
|
|
30
|
+
</style>
|
|
31
|
+
|
|
32
|
+
<!--------------------------------------------------------------------------------------------------------------------->
|
|
33
|
+
|
|
34
|
+
<script setup lang="ts">
|
|
35
|
+
/**
|
|
36
|
+
* @component SkSlider
|
|
37
|
+
* A range slider component for selecting numeric values.
|
|
38
|
+
* Supports single and multi-thumb (range) modes.
|
|
39
|
+
* Powered by RekaUI with all 7 semantic kinds and custom colors.
|
|
40
|
+
*/
|
|
41
|
+
|
|
42
|
+
import { computed } from 'vue';
|
|
43
|
+
import { SliderRange, SliderRoot, SliderThumb, SliderTrack } from 'reka-ui';
|
|
44
|
+
|
|
45
|
+
// Types
|
|
46
|
+
import type { ComponentKind } from '@/types';
|
|
47
|
+
import type { SkSliderOrientation, SkSliderSize } from './types';
|
|
48
|
+
|
|
49
|
+
//------------------------------------------------------------------------------------------------------------------
|
|
50
|
+
|
|
51
|
+
export interface SkSliderComponentProps
|
|
52
|
+
{
|
|
53
|
+
/** Current value(s) of the slider */
|
|
54
|
+
modelValue : number | number[];
|
|
55
|
+
/** Minimum value */
|
|
56
|
+
min ?: number;
|
|
57
|
+
/** Maximum value */
|
|
58
|
+
max ?: number;
|
|
59
|
+
/** Step increment */
|
|
60
|
+
step ?: number;
|
|
61
|
+
/** Semantic color kind */
|
|
62
|
+
kind ?: ComponentKind;
|
|
63
|
+
/** Slider size */
|
|
64
|
+
size ?: SkSliderSize;
|
|
65
|
+
/** Slider orientation */
|
|
66
|
+
orientation ?: SkSliderOrientation;
|
|
67
|
+
/** Whether the slider is disabled */
|
|
68
|
+
disabled ?: boolean;
|
|
69
|
+
/** Name attribute for form submission */
|
|
70
|
+
name ?: string;
|
|
71
|
+
/** Minimum steps between thumbs for range slider */
|
|
72
|
+
minStepsBetweenThumbs ?: number;
|
|
73
|
+
/** Custom track color (overrides kind) */
|
|
74
|
+
baseColor ?: string;
|
|
75
|
+
/** Custom thumb color */
|
|
76
|
+
thumbColor ?: string;
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
//------------------------------------------------------------------------------------------------------------------
|
|
80
|
+
|
|
81
|
+
const props = withDefaults(defineProps<SkSliderComponentProps>(), {
|
|
82
|
+
min: 0,
|
|
83
|
+
max: 100,
|
|
84
|
+
step: 1,
|
|
85
|
+
kind: 'primary',
|
|
86
|
+
size: 'md',
|
|
87
|
+
orientation: 'horizontal',
|
|
88
|
+
disabled: false,
|
|
89
|
+
name: undefined,
|
|
90
|
+
minStepsBetweenThumbs: 0,
|
|
91
|
+
baseColor: undefined,
|
|
92
|
+
thumbColor: undefined,
|
|
93
|
+
});
|
|
94
|
+
|
|
95
|
+
const emit = defineEmits<{
|
|
96
|
+
'update:modelValue' : [value : number | number[]];
|
|
97
|
+
}>();
|
|
98
|
+
|
|
99
|
+
//------------------------------------------------------------------------------------------------------------------
|
|
100
|
+
// Computed
|
|
101
|
+
//------------------------------------------------------------------------------------------------------------------
|
|
102
|
+
|
|
103
|
+
// Normalize single value to array for RekaUI
|
|
104
|
+
const normalizedValue = computed(() =>
|
|
105
|
+
{
|
|
106
|
+
return Array.isArray(props.modelValue) ? props.modelValue : [ props.modelValue ];
|
|
107
|
+
});
|
|
108
|
+
|
|
109
|
+
const thumbCount = computed(() =>
|
|
110
|
+
{
|
|
111
|
+
return normalizedValue.value.length;
|
|
112
|
+
});
|
|
113
|
+
|
|
114
|
+
const classes = computed(() => ({
|
|
115
|
+
'sk-slider': true,
|
|
116
|
+
[`sk-${ props.kind }`]: true,
|
|
117
|
+
[`sk-${ props.size }`]: true,
|
|
118
|
+
[`sk-${ props.orientation }`]: true,
|
|
119
|
+
}));
|
|
120
|
+
|
|
121
|
+
//------------------------------------------------------------------------------------------------------------------
|
|
122
|
+
// Custom Colors
|
|
123
|
+
//------------------------------------------------------------------------------------------------------------------
|
|
124
|
+
|
|
125
|
+
const customStyles = computed(() =>
|
|
126
|
+
{
|
|
127
|
+
const styles : Record<string, string> = {};
|
|
128
|
+
|
|
129
|
+
if(props.baseColor)
|
|
130
|
+
{
|
|
131
|
+
styles['--sk-slider-color-base'] = props.baseColor;
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
if(props.thumbColor)
|
|
135
|
+
{
|
|
136
|
+
styles['--sk-slider-thumb-color'] = props.thumbColor;
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
return styles;
|
|
140
|
+
});
|
|
141
|
+
|
|
142
|
+
//------------------------------------------------------------------------------------------------------------------
|
|
143
|
+
// Methods
|
|
144
|
+
//------------------------------------------------------------------------------------------------------------------
|
|
145
|
+
|
|
146
|
+
function handleUpdate(value : number[] | undefined) : void
|
|
147
|
+
{
|
|
148
|
+
if(!value)
|
|
149
|
+
{
|
|
150
|
+
return;
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
// If original modelValue was a single number, emit single number
|
|
154
|
+
if(!Array.isArray(props.modelValue))
|
|
155
|
+
{
|
|
156
|
+
emit('update:modelValue', value[0]);
|
|
157
|
+
}
|
|
158
|
+
else
|
|
159
|
+
{
|
|
160
|
+
emit('update:modelValue', value);
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
</script>
|
|
164
|
+
|
|
165
|
+
<!--------------------------------------------------------------------------------------------------------------------->
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
//----------------------------------------------------------------------------------------------------------------------
|
|
2
|
+
// Slider Component
|
|
3
|
+
//----------------------------------------------------------------------------------------------------------------------
|
|
4
|
+
|
|
5
|
+
export { default } from './SkSlider.vue';
|
|
6
|
+
export * from './types';
|
|
7
|
+
|
|
8
|
+
//----------------------------------------------------------------------------------------------------------------------
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
//----------------------------------------------------------------------------------------------------------------------
|
|
2
|
+
// Slider Types
|
|
3
|
+
//----------------------------------------------------------------------------------------------------------------------
|
|
4
|
+
|
|
5
|
+
import type { ComponentKind, ComponentSize } from '@/types';
|
|
6
|
+
|
|
7
|
+
//----------------------------------------------------------------------------------------------------------------------
|
|
8
|
+
|
|
9
|
+
/** Slider size */
|
|
10
|
+
export type SkSliderSize = ComponentSize;
|
|
11
|
+
|
|
12
|
+
/** Slider orientation */
|
|
13
|
+
export type SkSliderOrientation = 'horizontal' | 'vertical';
|
|
14
|
+
|
|
15
|
+
/** Slider props interface */
|
|
16
|
+
export interface SkSliderProps
|
|
17
|
+
{
|
|
18
|
+
/** Current value(s) of the slider */
|
|
19
|
+
modelValue : number | number[];
|
|
20
|
+
/** Minimum value */
|
|
21
|
+
min ?: number;
|
|
22
|
+
/** Maximum value */
|
|
23
|
+
max ?: number;
|
|
24
|
+
/** Step increment */
|
|
25
|
+
step ?: number;
|
|
26
|
+
/** Semantic color kind */
|
|
27
|
+
kind ?: ComponentKind;
|
|
28
|
+
/** Slider size */
|
|
29
|
+
size ?: SkSliderSize;
|
|
30
|
+
/** Slider orientation */
|
|
31
|
+
orientation ?: SkSliderOrientation;
|
|
32
|
+
/** Whether the slider is disabled */
|
|
33
|
+
disabled ?: boolean;
|
|
34
|
+
/** Name attribute for form submission */
|
|
35
|
+
name ?: string;
|
|
36
|
+
/** Whether multiple thumbs are allowed (range slider) */
|
|
37
|
+
minStepsBetweenThumbs ?: number;
|
|
38
|
+
/** Custom track color (overrides kind) */
|
|
39
|
+
baseColor ?: string;
|
|
40
|
+
/** Custom thumb color */
|
|
41
|
+
thumbColor ?: string;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
//----------------------------------------------------------------------------------------------------------------------
|