@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,107 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<button
|
|
3
|
+
:class="classes"
|
|
4
|
+
:disabled="disabled || type === 'ellipsis'"
|
|
5
|
+
:aria-label="ariaLabel"
|
|
6
|
+
:aria-current="active ? 'page' : undefined"
|
|
7
|
+
@click="handleClick"
|
|
8
|
+
>
|
|
9
|
+
<span v-if="type === 'prev'">‹</span>
|
|
10
|
+
<span v-else-if="type === 'next'">›</span>
|
|
11
|
+
<span v-else-if="type === 'first'">‹‹</span>
|
|
12
|
+
<span v-else-if="type === 'last'">››</span>
|
|
13
|
+
<span v-else-if="type === 'ellipsis'">...</span>
|
|
14
|
+
<span v-else>{{ page }}</span>
|
|
15
|
+
</button>
|
|
16
|
+
</template>
|
|
17
|
+
|
|
18
|
+
<!--------------------------------------------------------------------------------------------------------------------->
|
|
19
|
+
|
|
20
|
+
<style lang="scss" scoped>
|
|
21
|
+
// Styles implemented in /src/styles/components/_pagination.scss
|
|
22
|
+
</style>
|
|
23
|
+
|
|
24
|
+
<!--------------------------------------------------------------------------------------------------------------------->
|
|
25
|
+
|
|
26
|
+
<script setup lang="ts">
|
|
27
|
+
import { type Ref, computed, inject } from 'vue';
|
|
28
|
+
|
|
29
|
+
// Types
|
|
30
|
+
import type { SkPaginationItemProps, SkPaginationKind, SkPaginationSize, SkPaginationVariant } from './types';
|
|
31
|
+
|
|
32
|
+
//------------------------------------------------------------------------------------------------------------------
|
|
33
|
+
|
|
34
|
+
export type SkPaginationItemComponentProps = SkPaginationItemProps;
|
|
35
|
+
|
|
36
|
+
//------------------------------------------------------------------------------------------------------------------
|
|
37
|
+
|
|
38
|
+
const props = withDefaults(defineProps<SkPaginationItemComponentProps>(), {
|
|
39
|
+
page: undefined,
|
|
40
|
+
active: false,
|
|
41
|
+
disabled: false,
|
|
42
|
+
type: 'page',
|
|
43
|
+
});
|
|
44
|
+
|
|
45
|
+
const emit = defineEmits<{
|
|
46
|
+
click : [ page : number ];
|
|
47
|
+
}>();
|
|
48
|
+
|
|
49
|
+
//------------------------------------------------------------------------------------------------------------------
|
|
50
|
+
|
|
51
|
+
const kindRef = inject<Ref<SkPaginationKind>>('pagination-kind');
|
|
52
|
+
const sizeRef = inject<Ref<SkPaginationSize>>('pagination-size');
|
|
53
|
+
const variantRef = inject<Ref<SkPaginationVariant>>('pagination-variant');
|
|
54
|
+
|
|
55
|
+
const kind = computed(() => kindRef?.value ?? 'neutral');
|
|
56
|
+
const size = computed(() => sizeRef?.value ?? 'md');
|
|
57
|
+
const variant = computed(() => variantRef?.value ?? 'solid');
|
|
58
|
+
|
|
59
|
+
//------------------------------------------------------------------------------------------------------------------
|
|
60
|
+
|
|
61
|
+
const classes = computed(() => ({
|
|
62
|
+
'sk-pagination-item': true,
|
|
63
|
+
[`sk-${ kind.value }`]: true,
|
|
64
|
+
[`sk-${ size.value }`]: true,
|
|
65
|
+
[`sk-${ variant.value }`]: true,
|
|
66
|
+
'sk-active': props.active,
|
|
67
|
+
'sk-ellipsis': props.type === 'ellipsis',
|
|
68
|
+
}));
|
|
69
|
+
|
|
70
|
+
const ariaLabel = computed(() =>
|
|
71
|
+
{
|
|
72
|
+
switch (props.type)
|
|
73
|
+
{
|
|
74
|
+
case 'prev':
|
|
75
|
+
return 'Previous page';
|
|
76
|
+
case 'next':
|
|
77
|
+
return 'Next page';
|
|
78
|
+
case 'first':
|
|
79
|
+
return 'First page';
|
|
80
|
+
case 'last':
|
|
81
|
+
return 'Last page';
|
|
82
|
+
case 'page':
|
|
83
|
+
return `Page ${ props.page }`;
|
|
84
|
+
default:
|
|
85
|
+
return undefined;
|
|
86
|
+
}
|
|
87
|
+
});
|
|
88
|
+
|
|
89
|
+
//------------------------------------------------------------------------------------------------------------------
|
|
90
|
+
|
|
91
|
+
function handleClick() : void
|
|
92
|
+
{
|
|
93
|
+
if(props.type === 'ellipsis' || props.disabled)
|
|
94
|
+
{
|
|
95
|
+
return;
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
if(props.page !== undefined)
|
|
99
|
+
{
|
|
100
|
+
emit('click', props.page);
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
//------------------------------------------------------------------------------------------------------------------
|
|
105
|
+
</script>
|
|
106
|
+
|
|
107
|
+
<!--------------------------------------------------------------------------------------------------------------------->
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
//----------------------------------------------------------------------------------------------------------------------
|
|
2
|
+
// Pagination Components
|
|
3
|
+
//----------------------------------------------------------------------------------------------------------------------
|
|
4
|
+
|
|
5
|
+
export { default as SkPagination } from './SkPagination.vue';
|
|
6
|
+
export { default as SkPaginationItem } from './SkPaginationItem.vue';
|
|
7
|
+
export * from './types';
|
|
8
|
+
|
|
9
|
+
//----------------------------------------------------------------------------------------------------------------------
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
//----------------------------------------------------------------------------------------------------------------------
|
|
2
|
+
// Types for SkPagination
|
|
3
|
+
//----------------------------------------------------------------------------------------------------------------------
|
|
4
|
+
|
|
5
|
+
// Types
|
|
6
|
+
import type { ComponentKind, ComponentSize } from '@/types';
|
|
7
|
+
|
|
8
|
+
//----------------------------------------------------------------------------------------------------------------------
|
|
9
|
+
|
|
10
|
+
export type SkPaginationKind = ComponentKind;
|
|
11
|
+
export type SkPaginationSize = ComponentSize;
|
|
12
|
+
export type SkPaginationVariant = 'solid' | 'outline' | 'subtle' | 'ghost';
|
|
13
|
+
export type SkPaginationItemType = 'page' | 'prev' | 'next' | 'ellipsis' | 'first' | 'last';
|
|
14
|
+
|
|
15
|
+
//----------------------------------------------------------------------------------------------------------------------
|
|
16
|
+
|
|
17
|
+
export interface SkPaginationProps
|
|
18
|
+
{
|
|
19
|
+
modelValue ?: number;
|
|
20
|
+
total : number;
|
|
21
|
+
siblingCount ?: number;
|
|
22
|
+
showFirstLast ?: boolean;
|
|
23
|
+
showPrevNext ?: boolean;
|
|
24
|
+
kind ?: SkPaginationKind;
|
|
25
|
+
size ?: SkPaginationSize;
|
|
26
|
+
variant ?: SkPaginationVariant;
|
|
27
|
+
disabled ?: boolean;
|
|
28
|
+
baseColor ?: string;
|
|
29
|
+
textColor ?: string;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
export interface SkPaginationItemProps
|
|
33
|
+
{
|
|
34
|
+
page ?: number;
|
|
35
|
+
active ?: boolean;
|
|
36
|
+
disabled ?: boolean;
|
|
37
|
+
type : SkPaginationItemType;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
//----------------------------------------------------------------------------------------------------------------------
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
<!----------------------------------------------------------------------------------------------------------------------
|
|
2
|
+
- Panel Component
|
|
3
|
+
--------------------------------------------------------------------------------------------------------------------->
|
|
4
|
+
|
|
5
|
+
<template>
|
|
6
|
+
<div :class="classes" :style="customColorStyles">
|
|
7
|
+
<slot />
|
|
8
|
+
</div>
|
|
9
|
+
</template>
|
|
10
|
+
|
|
11
|
+
<!--------------------------------------------------------------------------------------------------------------------->
|
|
12
|
+
|
|
13
|
+
<style lang="scss" scoped>
|
|
14
|
+
// Control decoration visibility via v-bind
|
|
15
|
+
.sk-panel::after {
|
|
16
|
+
display: v-bind('decorationDisplay');
|
|
17
|
+
}
|
|
18
|
+
</style>
|
|
19
|
+
|
|
20
|
+
<!--------------------------------------------------------------------------------------------------------------------->
|
|
21
|
+
|
|
22
|
+
<script setup lang="ts">
|
|
23
|
+
/**
|
|
24
|
+
* @component
|
|
25
|
+
* A foundational container component with borders, background colors, and optional decorative accents.
|
|
26
|
+
* Serves as the base for other components like SkCard and SkSidebar.
|
|
27
|
+
*/
|
|
28
|
+
|
|
29
|
+
import { computed, toRef } from 'vue';
|
|
30
|
+
import type { SkPanelKind, SkPanelSize } from './types';
|
|
31
|
+
import type { ComponentCustomColors } from '@/types';
|
|
32
|
+
import { useCustomColors } from '@/composables/useCustomColors';
|
|
33
|
+
|
|
34
|
+
//------------------------------------------------------------------------------------------------------------------
|
|
35
|
+
|
|
36
|
+
/**
|
|
37
|
+
* A foundational container component with borders, background colors, and optional decorative accents.
|
|
38
|
+
* Serves as the base for other components like SkCard and SkSidebar.
|
|
39
|
+
*/
|
|
40
|
+
export interface SkPanelComponentProps extends ComponentCustomColors
|
|
41
|
+
{
|
|
42
|
+
/** Semantic color kind for the panel */
|
|
43
|
+
kind ?: SkPanelKind;
|
|
44
|
+
/** Size affecting padding and spacing inside the panel */
|
|
45
|
+
size ?: SkPanelSize;
|
|
46
|
+
/** Whether to display the decorative accent border */
|
|
47
|
+
showDecoration ?: boolean;
|
|
48
|
+
/** Whether to remove the border entirely */
|
|
49
|
+
noBorder ?: boolean;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
//------------------------------------------------------------------------------------------------------------------
|
|
53
|
+
|
|
54
|
+
const props = withDefaults(defineProps<SkPanelComponentProps>(), {
|
|
55
|
+
kind: 'neutral',
|
|
56
|
+
size: 'md',
|
|
57
|
+
showDecoration: true,
|
|
58
|
+
noBorder: false,
|
|
59
|
+
});
|
|
60
|
+
|
|
61
|
+
//------------------------------------------------------------------------------------------------------------------
|
|
62
|
+
|
|
63
|
+
const classes = computed(() =>
|
|
64
|
+
{
|
|
65
|
+
return {
|
|
66
|
+
'sk-panel': true,
|
|
67
|
+
[`sk-${ props.kind }`]: true,
|
|
68
|
+
[`sk-${ props.size }`]: true,
|
|
69
|
+
'sk-no-border': props.noBorder,
|
|
70
|
+
};
|
|
71
|
+
});
|
|
72
|
+
|
|
73
|
+
//------------------------------------------------------------------------------------------------------------------
|
|
74
|
+
|
|
75
|
+
// Custom color styles
|
|
76
|
+
const customColorStyles = useCustomColors(
|
|
77
|
+
'panel',
|
|
78
|
+
toRef(() => props.baseColor),
|
|
79
|
+
toRef(() => props.textColor)
|
|
80
|
+
);
|
|
81
|
+
|
|
82
|
+
//------------------------------------------------------------------------------------------------------------------
|
|
83
|
+
|
|
84
|
+
// Control decoration visibility
|
|
85
|
+
// Note: noBorder automatically disables decoration
|
|
86
|
+
const decorationDisplay = computed(() =>
|
|
87
|
+
{
|
|
88
|
+
if(props.noBorder)
|
|
89
|
+
{
|
|
90
|
+
return 'none';
|
|
91
|
+
}
|
|
92
|
+
return props.showDecoration ? 'block' : 'none';
|
|
93
|
+
});
|
|
94
|
+
</script>
|
|
95
|
+
|
|
96
|
+
<!--------------------------------------------------------------------------------------------------------------------->
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
//----------------------------------------------------------------------------------------------------------------------
|
|
2
|
+
// Panel Component Types
|
|
3
|
+
//----------------------------------------------------------------------------------------------------------------------
|
|
4
|
+
|
|
5
|
+
import type { ComponentKind } from '@/types';
|
|
6
|
+
|
|
7
|
+
//----------------------------------------------------------------------------------------------------------------------
|
|
8
|
+
|
|
9
|
+
// Panel semantic kinds (uses common types)
|
|
10
|
+
export type SkPanelKind = ComponentKind;
|
|
11
|
+
|
|
12
|
+
// Panel sizes (only affects cut size, not padding or dimensions)
|
|
13
|
+
export type SkPanelSize = 'xs' | 'sm' | 'md' | 'lg' | 'xl';
|
|
14
|
+
|
|
15
|
+
//----------------------------------------------------------------------------------------------------------------------
|
|
@@ -0,0 +1,185 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<PopoverRoot v-model:open="isOpen">
|
|
3
|
+
<PopoverTrigger as-child>
|
|
4
|
+
<slot name="trigger" />
|
|
5
|
+
</PopoverTrigger>
|
|
6
|
+
<PopoverPortal>
|
|
7
|
+
<PopoverContent
|
|
8
|
+
:class="contentClasses"
|
|
9
|
+
:style="customColorStyles"
|
|
10
|
+
:data-scheme="theme"
|
|
11
|
+
:side="side"
|
|
12
|
+
:align="align"
|
|
13
|
+
:side-offset="sideOffset"
|
|
14
|
+
:collision-padding="8"
|
|
15
|
+
>
|
|
16
|
+
<!-- Header -->
|
|
17
|
+
<div v-if="title || $slots.header" class="sk-popover-header">
|
|
18
|
+
<h3 v-if="title" class="sk-popover-title">
|
|
19
|
+
{{ title }}
|
|
20
|
+
</h3>
|
|
21
|
+
<slot name="header" />
|
|
22
|
+
<PopoverClose
|
|
23
|
+
v-if="closable"
|
|
24
|
+
class="sk-popover-close"
|
|
25
|
+
aria-label="Close"
|
|
26
|
+
>
|
|
27
|
+
<svg
|
|
28
|
+
xmlns="http://www.w3.org/2000/svg"
|
|
29
|
+
width="16"
|
|
30
|
+
height="16"
|
|
31
|
+
viewBox="0 0 24 24"
|
|
32
|
+
fill="none"
|
|
33
|
+
stroke="currentColor"
|
|
34
|
+
stroke-width="2"
|
|
35
|
+
stroke-linecap="round"
|
|
36
|
+
stroke-linejoin="round"
|
|
37
|
+
>
|
|
38
|
+
<line x1="18" y1="6" x2="6" y2="18" />
|
|
39
|
+
<line x1="6" y1="6" x2="18" y2="18" />
|
|
40
|
+
</svg>
|
|
41
|
+
</PopoverClose>
|
|
42
|
+
</div>
|
|
43
|
+
|
|
44
|
+
<!-- Content -->
|
|
45
|
+
<div v-if="$slots.default" class="sk-popover-body">
|
|
46
|
+
<slot />
|
|
47
|
+
</div>
|
|
48
|
+
|
|
49
|
+
<!-- Footer -->
|
|
50
|
+
<div v-if="$slots.footer" class="sk-popover-footer">
|
|
51
|
+
<slot name="footer" />
|
|
52
|
+
</div>
|
|
53
|
+
|
|
54
|
+
<!-- Arrow -->
|
|
55
|
+
<PopoverArrow v-if="showArrow" class="sk-popover-arrow" />
|
|
56
|
+
</PopoverContent>
|
|
57
|
+
</PopoverPortal>
|
|
58
|
+
</PopoverRoot>
|
|
59
|
+
</template>
|
|
60
|
+
|
|
61
|
+
<!--------------------------------------------------------------------------------------------------------------------->
|
|
62
|
+
|
|
63
|
+
<style lang="scss" scoped>
|
|
64
|
+
// Popover styles are implemented in /src/styles/components/_popover.scss
|
|
65
|
+
</style>
|
|
66
|
+
|
|
67
|
+
<!--------------------------------------------------------------------------------------------------------------------->
|
|
68
|
+
|
|
69
|
+
<script setup lang="ts">
|
|
70
|
+
/**
|
|
71
|
+
* @component
|
|
72
|
+
* Popover component for floating panels positioned relative to a trigger.
|
|
73
|
+
* Combines tooltip-like positioning with card-like structure.
|
|
74
|
+
*/
|
|
75
|
+
|
|
76
|
+
import { computed, toRef } from 'vue';
|
|
77
|
+
import {
|
|
78
|
+
PopoverArrow,
|
|
79
|
+
PopoverClose,
|
|
80
|
+
PopoverContent,
|
|
81
|
+
PopoverPortal,
|
|
82
|
+
PopoverRoot,
|
|
83
|
+
PopoverTrigger,
|
|
84
|
+
} from 'reka-ui';
|
|
85
|
+
|
|
86
|
+
// Types
|
|
87
|
+
import type { ComponentCustomColors, ComponentKind } from '@/types';
|
|
88
|
+
import type { SkPopoverAlign, SkPopoverSide } from './types';
|
|
89
|
+
|
|
90
|
+
// Composables
|
|
91
|
+
import { useCustomColors } from '@/composables/useCustomColors';
|
|
92
|
+
import { usePortalContext } from '@/composables/usePortalContext';
|
|
93
|
+
|
|
94
|
+
//------------------------------------------------------------------------------------------------------------------
|
|
95
|
+
|
|
96
|
+
/**
|
|
97
|
+
* Popover component for floating panels positioned relative to a trigger.
|
|
98
|
+
*
|
|
99
|
+
* Combines tooltip-like positioning with card-like structure for rich content.
|
|
100
|
+
*
|
|
101
|
+
* @example Basic usage with title
|
|
102
|
+
* ```vue
|
|
103
|
+
* <SkPopover title="Settings">
|
|
104
|
+
* <template #trigger><SkButton>Open</SkButton></template>
|
|
105
|
+
* <p>Popover content here</p>
|
|
106
|
+
* </SkPopover>
|
|
107
|
+
* ```
|
|
108
|
+
*
|
|
109
|
+
* @example With footer actions
|
|
110
|
+
* ```vue
|
|
111
|
+
* <SkPopover title="Confirm Action" kind="danger">
|
|
112
|
+
* <template #trigger><SkButton kind="danger">Delete</SkButton></template>
|
|
113
|
+
* <p>Are you sure you want to delete this item?</p>
|
|
114
|
+
* <template #footer>
|
|
115
|
+
* <SkButton variant="ghost" size="sm">Cancel</SkButton>
|
|
116
|
+
* <SkButton kind="danger" size="sm">Delete</SkButton>
|
|
117
|
+
* </template>
|
|
118
|
+
* </SkPopover>
|
|
119
|
+
* ```
|
|
120
|
+
*/
|
|
121
|
+
export interface SkPopoverComponentProps extends ComponentCustomColors
|
|
122
|
+
{
|
|
123
|
+
/** Semantic color kind */
|
|
124
|
+
kind ?: ComponentKind;
|
|
125
|
+
/** Which side of the trigger to show the popover */
|
|
126
|
+
side ?: SkPopoverSide;
|
|
127
|
+
/** Alignment along the side */
|
|
128
|
+
align ?: SkPopoverAlign;
|
|
129
|
+
/** Offset from the trigger in pixels */
|
|
130
|
+
sideOffset ?: number;
|
|
131
|
+
/** Whether to show the arrow pointing to the trigger */
|
|
132
|
+
showArrow ?: boolean;
|
|
133
|
+
/** Optional title displayed in the header */
|
|
134
|
+
title ?: string;
|
|
135
|
+
/** Whether to show a close button in the header */
|
|
136
|
+
closable ?: boolean;
|
|
137
|
+
/** Control the open state (v-model) */
|
|
138
|
+
open ?: boolean;
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
//------------------------------------------------------------------------------------------------------------------
|
|
142
|
+
|
|
143
|
+
const props = withDefaults(defineProps<SkPopoverComponentProps>(), {
|
|
144
|
+
kind: 'neutral',
|
|
145
|
+
side: 'bottom',
|
|
146
|
+
align: 'center',
|
|
147
|
+
sideOffset: 8,
|
|
148
|
+
showArrow: true,
|
|
149
|
+
title: undefined,
|
|
150
|
+
closable: true,
|
|
151
|
+
open: undefined,
|
|
152
|
+
});
|
|
153
|
+
|
|
154
|
+
const emit = defineEmits<{
|
|
155
|
+
'update:open' : [ value : boolean ];
|
|
156
|
+
}>();
|
|
157
|
+
|
|
158
|
+
//------------------------------------------------------------------------------------------------------------------
|
|
159
|
+
|
|
160
|
+
// Two-way binding for open state
|
|
161
|
+
const isOpen = computed({
|
|
162
|
+
get: () => props.open,
|
|
163
|
+
set: (value) => emit('update:open', value ?? false),
|
|
164
|
+
});
|
|
165
|
+
|
|
166
|
+
// Handle portal context (theme injection/re-provision for nested portal components)
|
|
167
|
+
const { theme } = usePortalContext();
|
|
168
|
+
|
|
169
|
+
//------------------------------------------------------------------------------------------------------------------
|
|
170
|
+
|
|
171
|
+
const contentClasses = computed(() => ({
|
|
172
|
+
'sk-popover-content': true,
|
|
173
|
+
[`sk-${ props.kind }`]: true,
|
|
174
|
+
}));
|
|
175
|
+
|
|
176
|
+
//------------------------------------------------------------------------------------------------------------------
|
|
177
|
+
|
|
178
|
+
const customColorStyles = useCustomColors(
|
|
179
|
+
'popover',
|
|
180
|
+
toRef(() => props.baseColor),
|
|
181
|
+
toRef(() => props.textColor)
|
|
182
|
+
);
|
|
183
|
+
</script>
|
|
184
|
+
|
|
185
|
+
<!--------------------------------------------------------------------------------------------------------------------->
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
//----------------------------------------------------------------------------------------------------------------------
|
|
2
|
+
// Popover Component Exports
|
|
3
|
+
//----------------------------------------------------------------------------------------------------------------------
|
|
4
|
+
|
|
5
|
+
export { default as SkPopover } from './SkPopover.vue';
|
|
6
|
+
export type { SkPopoverAlign, SkPopoverSide } from './types';
|
|
7
|
+
|
|
8
|
+
//----------------------------------------------------------------------------------------------------------------------
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
//----------------------------------------------------------------------------------------------------------------------
|
|
2
|
+
// Popover Types
|
|
3
|
+
//----------------------------------------------------------------------------------------------------------------------
|
|
4
|
+
|
|
5
|
+
/** Popover positioning side */
|
|
6
|
+
export type SkPopoverSide = 'top' | 'right' | 'bottom' | 'left';
|
|
7
|
+
|
|
8
|
+
/** Popover alignment */
|
|
9
|
+
export type SkPopoverAlign = 'start' | 'center' | 'end';
|
|
10
|
+
|
|
11
|
+
//----------------------------------------------------------------------------------------------------------------------
|
|
@@ -0,0 +1,144 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<ProgressRoot
|
|
3
|
+
v-model="internalValue"
|
|
4
|
+
:max="max"
|
|
5
|
+
:class="rootClasses"
|
|
6
|
+
:style="customStyles"
|
|
7
|
+
>
|
|
8
|
+
<ProgressIndicator
|
|
9
|
+
class="sk-progress-indicator"
|
|
10
|
+
:style="indicatorStyle"
|
|
11
|
+
/>
|
|
12
|
+
<span
|
|
13
|
+
v-if="showValue && !isIndeterminate"
|
|
14
|
+
:class="['sk-progress-value', `sk-value-${ props.valuePosition }`]"
|
|
15
|
+
>
|
|
16
|
+
{{ Math.round(percentage) }}%
|
|
17
|
+
</span>
|
|
18
|
+
</ProgressRoot>
|
|
19
|
+
</template>
|
|
20
|
+
|
|
21
|
+
<!--------------------------------------------------------------------------------------------------------------------->
|
|
22
|
+
|
|
23
|
+
<style lang="scss" scoped>
|
|
24
|
+
// Component styles are implemented in /src/styles/components/_progress.scss
|
|
25
|
+
</style>
|
|
26
|
+
|
|
27
|
+
<!--------------------------------------------------------------------------------------------------------------------->
|
|
28
|
+
|
|
29
|
+
<script setup lang="ts">
|
|
30
|
+
/**
|
|
31
|
+
* @component SkProgress
|
|
32
|
+
* A progress bar component with determinate and indeterminate modes.
|
|
33
|
+
* Supports all 7 semantic kinds and custom colors.
|
|
34
|
+
*/
|
|
35
|
+
|
|
36
|
+
import { computed } from 'vue';
|
|
37
|
+
import { ProgressIndicator, ProgressRoot } from 'reka-ui';
|
|
38
|
+
|
|
39
|
+
// Types
|
|
40
|
+
import type { ComponentKind } from '@/types';
|
|
41
|
+
import type { SkProgressSize, SkProgressValuePosition } from './types';
|
|
42
|
+
|
|
43
|
+
//------------------------------------------------------------------------------------------------------------------
|
|
44
|
+
|
|
45
|
+
export interface SkProgressComponentProps
|
|
46
|
+
{
|
|
47
|
+
/** Progress value (0 to max). Use null or undefined for indeterminate state */
|
|
48
|
+
value ?: number | null;
|
|
49
|
+
/** Maximum value */
|
|
50
|
+
max ?: number;
|
|
51
|
+
/** Semantic color kind */
|
|
52
|
+
kind ?: ComponentKind;
|
|
53
|
+
/** Bar height size */
|
|
54
|
+
size ?: SkProgressSize;
|
|
55
|
+
/** Show percentage label */
|
|
56
|
+
showValue ?: boolean;
|
|
57
|
+
/** Position of the value label */
|
|
58
|
+
valuePosition ?: SkProgressValuePosition;
|
|
59
|
+
/** Custom bar color (overrides kind) */
|
|
60
|
+
baseColor ?: string;
|
|
61
|
+
/** Custom track/background color */
|
|
62
|
+
trackColor ?: string;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
//------------------------------------------------------------------------------------------------------------------
|
|
66
|
+
|
|
67
|
+
const props = withDefaults(defineProps<SkProgressComponentProps>(), {
|
|
68
|
+
value: null,
|
|
69
|
+
max: 100,
|
|
70
|
+
kind: 'primary',
|
|
71
|
+
size: 'md',
|
|
72
|
+
showValue: false,
|
|
73
|
+
valuePosition: 'center',
|
|
74
|
+
baseColor: undefined,
|
|
75
|
+
trackColor: undefined,
|
|
76
|
+
});
|
|
77
|
+
|
|
78
|
+
//------------------------------------------------------------------------------------------------------------------
|
|
79
|
+
|
|
80
|
+
// Reka UI expects undefined for indeterminate, not null
|
|
81
|
+
const internalValue = computed(() =>
|
|
82
|
+
{
|
|
83
|
+
return props.value === null ? undefined : props.value;
|
|
84
|
+
});
|
|
85
|
+
|
|
86
|
+
const isIndeterminate = computed(() => props.value === null || props.value === undefined);
|
|
87
|
+
|
|
88
|
+
const percentage = computed(() =>
|
|
89
|
+
{
|
|
90
|
+
if(isIndeterminate.value)
|
|
91
|
+
{
|
|
92
|
+
return 0;
|
|
93
|
+
}
|
|
94
|
+
return ((props.value ?? 0) / props.max) * 100;
|
|
95
|
+
});
|
|
96
|
+
|
|
97
|
+
//------------------------------------------------------------------------------------------------------------------
|
|
98
|
+
// Classes
|
|
99
|
+
//------------------------------------------------------------------------------------------------------------------
|
|
100
|
+
|
|
101
|
+
const rootClasses = computed(() => ({
|
|
102
|
+
'sk-progress': true,
|
|
103
|
+
[`sk-${ props.kind }`]: true,
|
|
104
|
+
[`sk-${ props.size }`]: true,
|
|
105
|
+
'sk-indeterminate': isIndeterminate.value,
|
|
106
|
+
'sk-empty': !isIndeterminate.value && percentage.value === 0,
|
|
107
|
+
'sk-complete': !isIndeterminate.value && percentage.value >= 100,
|
|
108
|
+
}));
|
|
109
|
+
|
|
110
|
+
//------------------------------------------------------------------------------------------------------------------
|
|
111
|
+
// Custom Colors
|
|
112
|
+
//------------------------------------------------------------------------------------------------------------------
|
|
113
|
+
|
|
114
|
+
const customStyles = computed(() =>
|
|
115
|
+
{
|
|
116
|
+
const styles : Record<string, string> = {};
|
|
117
|
+
|
|
118
|
+
if(props.baseColor)
|
|
119
|
+
{
|
|
120
|
+
styles['--sk-progress-color-base'] = props.baseColor;
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
if(props.trackColor)
|
|
124
|
+
{
|
|
125
|
+
styles['--sk-progress-track-bg'] = props.trackColor;
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
return styles;
|
|
129
|
+
});
|
|
130
|
+
|
|
131
|
+
const indicatorStyle = computed(() =>
|
|
132
|
+
{
|
|
133
|
+
if(isIndeterminate.value)
|
|
134
|
+
{
|
|
135
|
+
return {};
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
return {
|
|
139
|
+
width: `${ percentage.value }%`,
|
|
140
|
+
};
|
|
141
|
+
});
|
|
142
|
+
</script>
|
|
143
|
+
|
|
144
|
+
<!--------------------------------------------------------------------------------------------------------------------->
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
//----------------------------------------------------------------------------------------------------------------------
|
|
2
|
+
// Progress Component Exports
|
|
3
|
+
//----------------------------------------------------------------------------------------------------------------------
|
|
4
|
+
|
|
5
|
+
export { default as SkProgress } from './SkProgress.vue';
|
|
6
|
+
export * from './types';
|
|
7
|
+
|
|
8
|
+
//----------------------------------------------------------------------------------------------------------------------
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
//----------------------------------------------------------------------------------------------------------------------
|
|
2
|
+
// Progress Types
|
|
3
|
+
//----------------------------------------------------------------------------------------------------------------------
|
|
4
|
+
|
|
5
|
+
import type { ComponentKind, ComponentSize } from '@/types';
|
|
6
|
+
|
|
7
|
+
//----------------------------------------------------------------------------------------------------------------------
|
|
8
|
+
|
|
9
|
+
/** Progress bar size */
|
|
10
|
+
export type SkProgressSize = ComponentSize;
|
|
11
|
+
|
|
12
|
+
/** Progress value label position */
|
|
13
|
+
export type SkProgressValuePosition = 'left' | 'center' | 'right';
|
|
14
|
+
|
|
15
|
+
/** Progress bar props interface */
|
|
16
|
+
export interface SkProgressProps
|
|
17
|
+
{
|
|
18
|
+
/** Progress value (0 to max). Use null or undefined for indeterminate state */
|
|
19
|
+
modelValue ?: number | null;
|
|
20
|
+
/** Maximum value */
|
|
21
|
+
max ?: number;
|
|
22
|
+
/** Semantic color kind */
|
|
23
|
+
kind ?: ComponentKind;
|
|
24
|
+
/** Bar height size */
|
|
25
|
+
size ?: SkProgressSize;
|
|
26
|
+
/** Show percentage label */
|
|
27
|
+
showValue ?: boolean;
|
|
28
|
+
/** Custom bar color (overrides kind) */
|
|
29
|
+
baseColor ?: string;
|
|
30
|
+
/** Custom track/background color */
|
|
31
|
+
trackColor ?: string;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
//----------------------------------------------------------------------------------------------------------------------
|