@astrake/lumora-ui 0.2.0 → 0.2.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/CHANGELOG.md +141 -137
- package/dist/LuCodeBlock.vue_vue_type_script_setup_true_lang-BjwcjuXF.js +1623 -0
- package/dist/LuEmbeddedStatusBar.vue_vue_type_script_setup_true_lang-CIksvebU.js +218 -0
- package/dist/LuOverlay.vue_vue_type_script_setup_true_lang-DZch4Vrw.js +226 -0
- package/dist/components/LuAlert.vue.d.ts +20 -0
- package/dist/components/LuAvatar.vue.d.ts +19 -0
- package/dist/components/LuBadge.vue.d.ts +16 -0
- package/dist/components/LuBreadcrumb.vue.d.ts +16 -0
- package/dist/components/LuButton.vue.d.ts +24 -0
- package/dist/components/LuCard.vue.d.ts +21 -0
- package/dist/components/LuCheckbox.vue.d.ts +27 -0
- package/dist/components/LuCodeBlock.vue.d.ts +29 -0
- package/dist/components/LuCollapsible.vue.d.ts +25 -0
- package/dist/components/LuDivider.vue.d.ts +8 -0
- package/dist/components/LuForm.types.d.ts +18 -0
- package/dist/components/LuForm.vue.d.ts +55 -0
- package/dist/components/LuIcon.vue.d.ts +18 -0
- package/dist/components/LuInput.vue.d.ts +26 -0
- package/dist/components/LuLink.vue.d.ts +23 -0
- package/dist/components/LuMenu.vue.d.ts +26 -0
- package/dist/components/LuMenuItem.vue.d.ts +20 -0
- package/dist/components/LuModal.vue.d.ts +32 -0
- package/dist/components/LuPageHeader.vue.d.ts +10 -0
- package/dist/components/LuPagination.vue.d.ts +18 -0
- package/dist/components/LuProgressBar.vue.d.ts +7 -0
- package/dist/components/LuRadio.vue.d.ts +18 -0
- package/dist/components/LuRadioGroup.types.d.ts +8 -0
- package/dist/components/LuRadioGroup.vue.d.ts +24 -0
- package/dist/components/LuSelect.vue.d.ts +18 -0
- package/dist/components/LuSkeleton.vue.d.ts +5 -0
- package/dist/components/LuSpinner.vue.d.ts +5 -0
- package/dist/components/LuSwitch.vue.d.ts +15 -0
- package/dist/components/LuTab.vue.d.ts +16 -0
- package/dist/components/LuTabList.vue.d.ts +15 -0
- package/dist/components/LuTabPanel.vue.d.ts +16 -0
- package/dist/components/LuTable.vue.d.ts +15 -0
- package/dist/components/LuTableBody.vue.d.ts +15 -0
- package/dist/components/LuTableCell.vue.d.ts +15 -0
- package/dist/components/LuTableHead.vue.d.ts +15 -0
- package/dist/components/LuTableHeadCell.vue.d.ts +15 -0
- package/dist/components/LuTableRow.vue.d.ts +15 -0
- package/dist/components/LuTabs.vue.d.ts +20 -0
- package/dist/components/LuTag.vue.d.ts +20 -0
- package/dist/components/LuText.vue.d.ts +16 -0
- package/dist/components/LuTextarea.vue.d.ts +14 -0
- package/dist/components/LuThemeSelect.vue.d.ts +2 -0
- package/dist/components/LuThemeSwitch.vue.d.ts +2 -0
- package/dist/components/LuToggleButton.vue.d.ts +16 -0
- package/dist/components/LuToggleGroup.vue.d.ts +20 -0
- package/dist/components/LuTooltip.vue.d.ts +19 -0
- package/dist/components/__tests__/LuForm.test.d.ts +1 -0
- package/dist/components/index.js +47 -0
- package/{src/composables/index.ts → dist/composables/index.d.ts} +0 -1
- package/dist/composables/index.js +30 -0
- package/dist/composables/useRail.d.ts +6 -0
- package/dist/composables/useSplit.d.ts +4 -0
- package/dist/composables/useTheme.d.ts +7 -0
- package/dist/context-0gENwESP.js +62 -0
- package/dist/context.d.ts +8 -0
- package/{src/index.ts → dist/index.d.ts} +0 -1
- package/dist/index.js +94 -0
- package/dist/layout/LuDock.vue.d.ts +9 -0
- package/dist/layout/LuDockItem.vue.d.ts +16 -0
- package/dist/layout/LuFill.vue.d.ts +21 -0
- package/dist/layout/LuFixed.vue.d.ts +21 -0
- package/dist/layout/LuGrid.vue.d.ts +26 -0
- package/dist/layout/LuOverlay.vue.d.ts +15 -0
- package/dist/layout/LuScroll.vue.d.ts +15 -0
- package/dist/layout/LuSplit.vue.d.ts +16 -0
- package/dist/layout/LuSplitPane.vue.d.ts +18 -0
- package/dist/layout/LuSplitResizer.vue.d.ts +5 -0
- package/dist/layout/LuStack.vue.d.ts +23 -0
- package/{src/layout/index.ts → dist/layout/index.d.ts} +1 -14
- package/dist/layout/index.js +14 -0
- package/dist/plugin.d.ts +6 -0
- package/dist/shell/desktop/LuDesktopRailBar.vue.d.ts +17 -0
- package/dist/shell/desktop/LuDesktopRailItem.vue.d.ts +18 -0
- package/dist/shell/desktop/LuDesktopShell.vue.d.ts +23 -0
- package/dist/shell/desktop/LuDesktopSidebar.vue.d.ts +21 -0
- package/dist/shell/desktop/LuDesktopStatusBar.vue.d.ts +15 -0
- package/dist/shell/desktop/LuDesktopTopBar.vue.d.ts +15 -0
- package/dist/shell/embedded/LuEmbeddedShell.vue.d.ts +19 -0
- package/dist/shell/embedded/LuEmbeddedStatusBar.vue.d.ts +17 -0
- package/dist/shell/embedded/LuEmbeddedTopBar.vue.d.ts +19 -0
- package/{src/shell/index.ts → dist/shell/index.d.ts} +0 -1
- package/dist/shell/index.js +15 -0
- package/dist/shell/mobile/LuMobileHeader.vue.d.ts +19 -0
- package/dist/shell/mobile/LuMobileNavBar.vue.d.ts +15 -0
- package/dist/shell/mobile/LuMobileShell.vue.d.ts +21 -0
- package/dist/skins/default.d.ts +2 -0
- package/{src/skins/default.ts → dist/skins/index.js} +119 -129
- package/dist/tailwind.d.ts +1 -0
- package/dist/tailwind.js +13 -0
- package/dist/types.d.ts +15 -0
- package/dist/useTheme-Cd4wVaLs.js +21 -0
- package/dist/utils.d.ts +21 -0
- package/package.json +94 -69
- package/src/lumora.css +16 -16
- package/src/components/LuAlert.vue +0 -33
- package/src/components/LuAvatar.vue +0 -22
- package/src/components/LuBadge.vue +0 -15
- package/src/components/LuBreadcrumb.vue +0 -63
- package/src/components/LuButton.vue +0 -58
- package/src/components/LuCard.vue +0 -27
- package/src/components/LuCheckbox.vue +0 -94
- package/src/components/LuCodeBlock.vue +0 -168
- package/src/components/LuCollapsible.vue +0 -34
- package/src/components/LuDivider.vue +0 -18
- package/src/components/LuForm.types.ts +0 -24
- package/src/components/LuForm.vue +0 -121
- package/src/components/LuIcon.vue +0 -39
- package/src/components/LuInput.vue +0 -82
- package/src/components/LuLink.vue +0 -47
- package/src/components/LuMenu.vue +0 -86
- package/src/components/LuMenuItem.vue +0 -37
- package/src/components/LuModal.vue +0 -115
- package/src/components/LuPageHeader.vue +0 -24
- package/src/components/LuPagination.vue +0 -118
- package/src/components/LuProgressBar.vue +0 -21
- package/src/components/LuRadio.vue +0 -55
- package/src/components/LuRadioGroup.types.ts +0 -10
- package/src/components/LuRadioGroup.vue +0 -66
- package/src/components/LuSelect.vue +0 -67
- package/src/components/LuSkeleton.vue +0 -15
- package/src/components/LuSpinner.vue +0 -36
- package/src/components/LuSwitch.vue +0 -76
- package/src/components/LuTab.vue +0 -26
- package/src/components/LuTabList.vue +0 -15
- package/src/components/LuTabPanel.vue +0 -19
- package/src/components/LuTable.vue +0 -15
- package/src/components/LuTableBody.vue +0 -15
- package/src/components/LuTableCell.vue +0 -15
- package/src/components/LuTableHead.vue +0 -15
- package/src/components/LuTableHeadCell.vue +0 -15
- package/src/components/LuTableRow.vue +0 -15
- package/src/components/LuTabs.vue +0 -30
- package/src/components/LuTag.vue +0 -35
- package/src/components/LuText.vue +0 -18
- package/src/components/LuTextarea.vue +0 -62
- package/src/components/LuThemeSelect.vue +0 -26
- package/src/components/LuThemeSwitch.vue +0 -22
- package/src/components/LuToggleButton.vue +0 -35
- package/src/components/LuToggleGroup.vue +0 -27
- package/src/components/LuTooltip.vue +0 -36
- package/src/components/__tests__/LuForm.test.ts +0 -206
- package/src/composables/useRail.ts +0 -24
- package/src/composables/useSplit.ts +0 -17
- package/src/composables/useTheme.ts +0 -36
- package/src/context.ts +0 -39
- package/src/layout/LuDock.vue +0 -56
- package/src/layout/LuDockItem.vue +0 -20
- package/src/layout/LuFill.vue +0 -27
- package/src/layout/LuFixed.vue +0 -27
- package/src/layout/LuGrid.vue +0 -45
- package/src/layout/LuOverlay.vue +0 -17
- package/src/layout/LuScroll.vue +0 -19
- package/src/layout/LuSplit.vue +0 -23
- package/src/layout/LuSplitPane.vue +0 -32
- package/src/layout/LuSplitResizer.vue +0 -19
- package/src/layout/LuStack.vue +0 -29
- package/src/plugin.ts +0 -28
- package/src/shell/desktop/LuDesktopRailBar.vue +0 -23
- package/src/shell/desktop/LuDesktopRailItem.vue +0 -23
- package/src/shell/desktop/LuDesktopShell.vue +0 -25
- package/src/shell/desktop/LuDesktopSidebar.vue +0 -36
- package/src/shell/desktop/LuDesktopStatusBar.vue +0 -15
- package/src/shell/desktop/LuDesktopTopBar.vue +0 -15
- package/src/shell/embedded/LuEmbeddedShell.vue +0 -20
- package/src/shell/embedded/LuEmbeddedStatusBar.vue +0 -16
- package/src/shell/embedded/LuEmbeddedTopBar.vue +0 -17
- package/src/shell/mobile/LuMobileHeader.vue +0 -17
- package/src/shell/mobile/LuMobileNavBar.vue +0 -15
- package/src/shell/mobile/LuMobileShell.vue +0 -21
- package/src/tailwind.ts +0 -25
- package/src/types.ts +0 -18
- package/src/utils.ts +0 -95
- package/tsconfig.json +0 -10
- /package/{src/components/index.ts → dist/components/index.d.ts} +0 -0
- /package/{src/skins/index.ts → dist/skins/index.d.ts} +0 -0
|
@@ -1,115 +0,0 @@
|
|
|
1
|
-
<template>
|
|
2
|
-
<Teleport to="body">
|
|
3
|
-
<transition
|
|
4
|
-
enter-active-class="transition ease-out duration-200"
|
|
5
|
-
enter-from-class="opacity-0"
|
|
6
|
-
enter-to-class="opacity-100"
|
|
7
|
-
leave-active-class="transition ease-in duration-150"
|
|
8
|
-
leave-from-class="opacity-100"
|
|
9
|
-
leave-to-class="opacity-0"
|
|
10
|
-
>
|
|
11
|
-
<div v-if="modelValue" :class="resolvedOverlaySkin" @click="handleOverlayClick" aria-modal="true" role="dialog" tabindex="-1">
|
|
12
|
-
<transition
|
|
13
|
-
enter-active-class="transition ease-out duration-200"
|
|
14
|
-
enter-from-class="opacity-0 translate-y-4 sm:translate-y-0 sm:scale-95"
|
|
15
|
-
enter-to-class="opacity-100 translate-y-0 sm:scale-100"
|
|
16
|
-
leave-active-class="transition ease-in duration-150"
|
|
17
|
-
leave-from-class="opacity-100 translate-y-0 sm:scale-100"
|
|
18
|
-
leave-to-class="opacity-0 translate-y-4 sm:translate-y-0 sm:scale-95"
|
|
19
|
-
appear
|
|
20
|
-
>
|
|
21
|
-
<div v-if="modelValue" :class="resolvedSkin" @click.stop>
|
|
22
|
-
<div v-if="$slots.header || title" :class="resolvedHeaderSkin">
|
|
23
|
-
<slot name="header">
|
|
24
|
-
<LuText variant="section-title">{{ title }}</LuText>
|
|
25
|
-
</slot>
|
|
26
|
-
<button v-if="closable" type="button" :class="resolvedCloseButtonSkin" @click="close" aria-label="Close modal">
|
|
27
|
-
<LuIcon name="x" class="h-5 w-5" />
|
|
28
|
-
</button>
|
|
29
|
-
</div>
|
|
30
|
-
|
|
31
|
-
<div :class="resolvedContentSkin">
|
|
32
|
-
<slot />
|
|
33
|
-
</div>
|
|
34
|
-
|
|
35
|
-
<div v-if="$slots.footer" :class="resolvedFooterSkin">
|
|
36
|
-
<slot name="footer" />
|
|
37
|
-
</div>
|
|
38
|
-
</div>
|
|
39
|
-
</transition>
|
|
40
|
-
</div>
|
|
41
|
-
</transition>
|
|
42
|
-
</Teleport>
|
|
43
|
-
</template>
|
|
44
|
-
|
|
45
|
-
<script setup lang="ts">
|
|
46
|
-
import { computed, onMounted, onBeforeUnmount, watch } from "vue";
|
|
47
|
-
import { useLumoraConfig } from "../context";
|
|
48
|
-
import LuText from "./LuText.vue";
|
|
49
|
-
import LuIcon from "./LuIcon.vue";
|
|
50
|
-
|
|
51
|
-
const props = withDefaults(defineProps<{
|
|
52
|
-
modelValue: boolean;
|
|
53
|
-
title?: string;
|
|
54
|
-
variant?: string;
|
|
55
|
-
closable?: boolean;
|
|
56
|
-
closeOnOverlayClick?: boolean;
|
|
57
|
-
}>(), {
|
|
58
|
-
closable: true,
|
|
59
|
-
closeOnOverlayClick: true,
|
|
60
|
-
});
|
|
61
|
-
|
|
62
|
-
const emit = defineEmits<{
|
|
63
|
-
(e: "update:modelValue", value: boolean): void;
|
|
64
|
-
(e: "close"): void;
|
|
65
|
-
}>();
|
|
66
|
-
|
|
67
|
-
const { resolveSkin } = useLumoraConfig();
|
|
68
|
-
|
|
69
|
-
const resolvedOverlaySkin = computed(() => resolveSkin("LuModalOverlay", props.variant));
|
|
70
|
-
const resolvedSkin = computed(() => resolveSkin("LuModal", props.variant));
|
|
71
|
-
const resolvedHeaderSkin = computed(() => resolveSkin("LuModalHeader", props.variant));
|
|
72
|
-
const resolvedContentSkin = computed(() => resolveSkin("LuModalContent", props.variant));
|
|
73
|
-
const resolvedFooterSkin = computed(() => resolveSkin("LuModalFooter", props.variant));
|
|
74
|
-
const resolvedCloseButtonSkin = computed(() => resolveSkin("LuModalCloseButton", props.variant));
|
|
75
|
-
|
|
76
|
-
const close = () => {
|
|
77
|
-
if (props.closable) {
|
|
78
|
-
emit("update:modelValue", false);
|
|
79
|
-
emit("close");
|
|
80
|
-
}
|
|
81
|
-
};
|
|
82
|
-
|
|
83
|
-
const handleOverlayClick = () => {
|
|
84
|
-
if (props.closeOnOverlayClick) {
|
|
85
|
-
close();
|
|
86
|
-
}
|
|
87
|
-
};
|
|
88
|
-
|
|
89
|
-
const handleEscKey = (e: KeyboardEvent) => {
|
|
90
|
-
if (e.key === 'Escape' && props.modelValue) {
|
|
91
|
-
close();
|
|
92
|
-
}
|
|
93
|
-
};
|
|
94
|
-
|
|
95
|
-
watch(() => props.modelValue, (isOpen) => {
|
|
96
|
-
if (typeof document !== 'undefined') {
|
|
97
|
-
if (isOpen) {
|
|
98
|
-
document.body.style.overflow = 'hidden';
|
|
99
|
-
} else {
|
|
100
|
-
document.body.style.overflow = '';
|
|
101
|
-
}
|
|
102
|
-
}
|
|
103
|
-
}, { immediate: true });
|
|
104
|
-
|
|
105
|
-
onMounted(() => {
|
|
106
|
-
document.addEventListener('keydown', handleEscKey);
|
|
107
|
-
});
|
|
108
|
-
|
|
109
|
-
onBeforeUnmount(() => {
|
|
110
|
-
document.removeEventListener('keydown', handleEscKey);
|
|
111
|
-
if (typeof document !== 'undefined') {
|
|
112
|
-
document.body.style.overflow = '';
|
|
113
|
-
}
|
|
114
|
-
});
|
|
115
|
-
</script>
|
|
@@ -1,24 +0,0 @@
|
|
|
1
|
-
<template>
|
|
2
|
-
<div v-bind="$attrs" :class="resolvedSkin">
|
|
3
|
-
<LuText :as="level" variant="page-title">{{ title }}</LuText>
|
|
4
|
-
<LuText v-if="description" as="p" variant="page-subtitle" class="mt-2">{{ description }}</LuText>
|
|
5
|
-
</div>
|
|
6
|
-
</template>
|
|
7
|
-
|
|
8
|
-
<script setup lang="ts">
|
|
9
|
-
import { computed } from "vue";
|
|
10
|
-
import { useLumoraConfig } from "../context";
|
|
11
|
-
import LuText from "./LuText.vue";
|
|
12
|
-
|
|
13
|
-
const props = withDefaults(defineProps<{
|
|
14
|
-
variant?: string;
|
|
15
|
-
title: string;
|
|
16
|
-
description?: string;
|
|
17
|
-
level?: "h1" | "h2" | "h3" | "h4" | "h5" | "h6";
|
|
18
|
-
}>(), {
|
|
19
|
-
level: "h1"
|
|
20
|
-
});
|
|
21
|
-
|
|
22
|
-
const { resolveSkin } = useLumoraConfig();
|
|
23
|
-
const resolvedSkin = computed(() => resolveSkin("LuPageHeader", props.variant));
|
|
24
|
-
</script>
|
|
@@ -1,118 +0,0 @@
|
|
|
1
|
-
<template>
|
|
2
|
-
<nav aria-label="Pagination" :class="resolvedSkin">
|
|
3
|
-
<LuButton
|
|
4
|
-
variant="ghost"
|
|
5
|
-
:disabled="modelValue <= 1"
|
|
6
|
-
@click="prevPage"
|
|
7
|
-
:class="resolvedButtonSkin"
|
|
8
|
-
aria-label="Previous page"
|
|
9
|
-
>
|
|
10
|
-
<LuIcon name="chevron-left" class="h-4 w-4" />
|
|
11
|
-
</LuButton>
|
|
12
|
-
|
|
13
|
-
<div :class="resolvedPagesSkin">
|
|
14
|
-
<template v-for="page in pages" :key="page">
|
|
15
|
-
<span v-if="page === '...'" :class="resolvedEllipsisSkin">...</span>
|
|
16
|
-
<LuButton
|
|
17
|
-
v-else
|
|
18
|
-
:variant="page === modelValue ? 'primary' : 'ghost'"
|
|
19
|
-
@click="goToPage(page as number)"
|
|
20
|
-
:class="resolvedPageButtonSkin"
|
|
21
|
-
:aria-current="page === modelValue ? 'page' : undefined"
|
|
22
|
-
>
|
|
23
|
-
{{ page }}
|
|
24
|
-
</LuButton>
|
|
25
|
-
</template>
|
|
26
|
-
</div>
|
|
27
|
-
|
|
28
|
-
<LuButton
|
|
29
|
-
variant="ghost"
|
|
30
|
-
:disabled="modelValue >= totalPages"
|
|
31
|
-
@click="nextPage"
|
|
32
|
-
:class="resolvedButtonSkin"
|
|
33
|
-
aria-label="Next page"
|
|
34
|
-
>
|
|
35
|
-
<LuIcon name="chevron-right" class="h-4 w-4" />
|
|
36
|
-
</LuButton>
|
|
37
|
-
</nav>
|
|
38
|
-
</template>
|
|
39
|
-
|
|
40
|
-
<script setup lang="ts">
|
|
41
|
-
import { computed } from "vue";
|
|
42
|
-
import { useLumoraConfig } from "../context";
|
|
43
|
-
import LuButton from "./LuButton.vue";
|
|
44
|
-
import LuIcon from "./LuIcon.vue";
|
|
45
|
-
|
|
46
|
-
const props = withDefaults(defineProps<{
|
|
47
|
-
modelValue: number;
|
|
48
|
-
total: number;
|
|
49
|
-
pageSize?: number;
|
|
50
|
-
siblingCount?: number;
|
|
51
|
-
variant?: string;
|
|
52
|
-
}>(), {
|
|
53
|
-
pageSize: 10,
|
|
54
|
-
siblingCount: 1,
|
|
55
|
-
});
|
|
56
|
-
|
|
57
|
-
const emit = defineEmits<{
|
|
58
|
-
(e: "update:modelValue", value: number): void;
|
|
59
|
-
(e: "change", value: number): void;
|
|
60
|
-
}>();
|
|
61
|
-
|
|
62
|
-
const totalPages = computed(() => Math.ceil(props.total / props.pageSize));
|
|
63
|
-
|
|
64
|
-
const pages = computed(() => {
|
|
65
|
-
const current = props.modelValue;
|
|
66
|
-
const total = totalPages.value;
|
|
67
|
-
const siblings = props.siblingCount;
|
|
68
|
-
|
|
69
|
-
if (total <= 1) return [1];
|
|
70
|
-
|
|
71
|
-
const leftSiblingIndex = Math.max(current - siblings, 1);
|
|
72
|
-
const rightSiblingIndex = Math.min(current + siblings, total);
|
|
73
|
-
|
|
74
|
-
const showLeftEllipsis = leftSiblingIndex > 2;
|
|
75
|
-
const showRightEllipsis = rightSiblingIndex < total - 1;
|
|
76
|
-
|
|
77
|
-
if (!showLeftEllipsis && showRightEllipsis) {
|
|
78
|
-
const leftItemCount = 3 + 2 * siblings;
|
|
79
|
-
const leftRange = Array.from({ length: Math.min(leftItemCount, total) }, (_, i) => i + 1);
|
|
80
|
-
return [...leftRange, '...', total];
|
|
81
|
-
}
|
|
82
|
-
|
|
83
|
-
if (showLeftEllipsis && !showRightEllipsis) {
|
|
84
|
-
const rightItemCount = 3 + 2 * siblings;
|
|
85
|
-
const rightRange = Array.from({ length: Math.min(rightItemCount, total) }, (_, i) => total - rightItemCount + i + 1);
|
|
86
|
-
return [1, '...', ...rightRange];
|
|
87
|
-
}
|
|
88
|
-
|
|
89
|
-
if (showLeftEllipsis && showRightEllipsis) {
|
|
90
|
-
const middleRange = Array.from({ length: rightSiblingIndex - leftSiblingIndex + 1 }, (_, i) => leftSiblingIndex + i);
|
|
91
|
-
return [1, '...', ...middleRange, '...', total];
|
|
92
|
-
}
|
|
93
|
-
|
|
94
|
-
return Array.from({ length: total }, (_, i) => i + 1);
|
|
95
|
-
});
|
|
96
|
-
|
|
97
|
-
const { resolveSkin } = useLumoraConfig();
|
|
98
|
-
|
|
99
|
-
const resolvedSkin = computed(() => resolveSkin("LuPagination", props.variant));
|
|
100
|
-
const resolvedButtonSkin = computed(() => resolveSkin("LuPaginationButton", props.variant));
|
|
101
|
-
const resolvedPagesSkin = computed(() => resolveSkin("LuPaginationPages", props.variant));
|
|
102
|
-
const resolvedPageButtonSkin = computed(() => resolveSkin("LuPaginationPageButton", props.variant));
|
|
103
|
-
const resolvedEllipsisSkin = computed(() => resolveSkin("LuPaginationEllipsis", props.variant));
|
|
104
|
-
|
|
105
|
-
const goToPage = (page: number) => {
|
|
106
|
-
if (page === props.modelValue) return;
|
|
107
|
-
emit("update:modelValue", page);
|
|
108
|
-
emit("change", page);
|
|
109
|
-
};
|
|
110
|
-
|
|
111
|
-
const prevPage = () => {
|
|
112
|
-
if (props.modelValue > 1) goToPage(props.modelValue - 1);
|
|
113
|
-
};
|
|
114
|
-
|
|
115
|
-
const nextPage = () => {
|
|
116
|
-
if (props.modelValue < totalPages.value) goToPage(props.modelValue + 1);
|
|
117
|
-
};
|
|
118
|
-
</script>
|
|
@@ -1,21 +0,0 @@
|
|
|
1
|
-
<template>
|
|
2
|
-
<div v-bind="$attrs" :class="trackSkin">
|
|
3
|
-
<div :class="fillSkin" :style="{ width: `${percent}%` }"></div>
|
|
4
|
-
</div>
|
|
5
|
-
</template>
|
|
6
|
-
|
|
7
|
-
<script setup lang="ts">
|
|
8
|
-
import { computed } from "vue";
|
|
9
|
-
import { useLumoraConfig } from "../context";
|
|
10
|
-
|
|
11
|
-
const props = defineProps<{ variant?: string; value: number; max?: number }>();
|
|
12
|
-
|
|
13
|
-
const percent = computed(() => {
|
|
14
|
-
const m = props.max ?? 100;
|
|
15
|
-
return Math.max(0, Math.min(100, (props.value / m) * 100));
|
|
16
|
-
});
|
|
17
|
-
|
|
18
|
-
const { resolveSkin } = useLumoraConfig();
|
|
19
|
-
const trackSkin = computed(() => resolveSkin("LuProgressBar", props.variant));
|
|
20
|
-
const fillSkin = computed(() => resolveSkin("LuProgressBarFill", props.variant));
|
|
21
|
-
</script>
|
|
@@ -1,55 +0,0 @@
|
|
|
1
|
-
<template>
|
|
2
|
-
<div :class="resolvedContainerSkin">
|
|
3
|
-
<input
|
|
4
|
-
type="radio"
|
|
5
|
-
v-bind="$attrs"
|
|
6
|
-
:class="resolvedSkin"
|
|
7
|
-
:name="radioGroup?.name"
|
|
8
|
-
:value="value"
|
|
9
|
-
:checked="isChecked"
|
|
10
|
-
:disabled="radioGroup?.disabled.value || disabled"
|
|
11
|
-
@change="onChange"
|
|
12
|
-
/>
|
|
13
|
-
<label v-if="$slots.default || label" :class="resolvedLabelSkin" @click.prevent="onClick">
|
|
14
|
-
<slot>{{ label }}</slot>
|
|
15
|
-
</label>
|
|
16
|
-
</div>
|
|
17
|
-
</template>
|
|
18
|
-
|
|
19
|
-
<script setup lang="ts">
|
|
20
|
-
import { computed, inject } from "vue";
|
|
21
|
-
import { useLumoraConfig } from "../context";
|
|
22
|
-
import { LuRadioGroupContextKey } from "./LuRadioGroup.types";
|
|
23
|
-
|
|
24
|
-
const props = defineProps<{
|
|
25
|
-
value: string | number;
|
|
26
|
-
variant?: string;
|
|
27
|
-
label?: string;
|
|
28
|
-
disabled?: boolean;
|
|
29
|
-
}>();
|
|
30
|
-
|
|
31
|
-
const { resolveSkin } = useLumoraConfig();
|
|
32
|
-
const resolvedContainerSkin = computed(() => resolveSkin("LuRadioContainer", props.variant));
|
|
33
|
-
const resolvedSkin = computed(() => resolveSkin("LuRadio", props.variant));
|
|
34
|
-
const resolvedLabelSkin = computed(() => resolveSkin("LuRadioLabel", props.variant));
|
|
35
|
-
|
|
36
|
-
const radioGroup = inject(LuRadioGroupContextKey, null);
|
|
37
|
-
|
|
38
|
-
if (!radioGroup) {
|
|
39
|
-
console.warn("LuRadio must be used within a LuRadioGroup");
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
const isChecked = computed(() => {
|
|
43
|
-
return radioGroup?.modelValue.value === props.value;
|
|
44
|
-
});
|
|
45
|
-
|
|
46
|
-
const onChange = () => {
|
|
47
|
-
if (props.disabled || radioGroup?.disabled.value) return;
|
|
48
|
-
radioGroup?.updateValue(props.value);
|
|
49
|
-
};
|
|
50
|
-
|
|
51
|
-
const onClick = () => {
|
|
52
|
-
if (props.disabled || radioGroup?.disabled.value) return;
|
|
53
|
-
radioGroup?.updateValue(props.value);
|
|
54
|
-
};
|
|
55
|
-
</script>
|
|
@@ -1,10 +0,0 @@
|
|
|
1
|
-
import type { InjectionKey, Ref } from 'vue';
|
|
2
|
-
|
|
3
|
-
export interface LuRadioGroupContext {
|
|
4
|
-
name: string;
|
|
5
|
-
modelValue: Ref<string | number | undefined>;
|
|
6
|
-
updateValue: (value: string | number) => void;
|
|
7
|
-
disabled: Ref<boolean>;
|
|
8
|
-
}
|
|
9
|
-
|
|
10
|
-
export const LuRadioGroupContextKey: InjectionKey<LuRadioGroupContext> = Symbol('LuRadioGroupContext');
|
|
@@ -1,66 +0,0 @@
|
|
|
1
|
-
<template>
|
|
2
|
-
<div :class="resolvedSkin" role="radiogroup" :aria-disabled="disabled || formContext?.disabled.value">
|
|
3
|
-
<slot />
|
|
4
|
-
</div>
|
|
5
|
-
</template>
|
|
6
|
-
|
|
7
|
-
<script setup lang="ts">
|
|
8
|
-
import { computed, inject, onMounted, onUnmounted, provide, ref, watch } from "vue";
|
|
9
|
-
import { useLumoraConfig } from "../context";
|
|
10
|
-
import { LuFormContextKey } from "./LuForm.types";
|
|
11
|
-
import { LuRadioGroupContextKey } from "./LuRadioGroup.types";
|
|
12
|
-
|
|
13
|
-
const props = defineProps<{
|
|
14
|
-
modelValue?: string | number;
|
|
15
|
-
name: string;
|
|
16
|
-
variant?: string;
|
|
17
|
-
disabled?: boolean;
|
|
18
|
-
}>();
|
|
19
|
-
|
|
20
|
-
const emit = defineEmits<{
|
|
21
|
-
(e: "update:modelValue", value: string | number): void;
|
|
22
|
-
(e: "change", value: string | number): void;
|
|
23
|
-
}>();
|
|
24
|
-
|
|
25
|
-
const { resolveSkin } = useLumoraConfig();
|
|
26
|
-
const resolvedSkin = computed(() => resolveSkin("LuRadioGroup", props.variant));
|
|
27
|
-
|
|
28
|
-
const formContext = inject(LuFormContextKey, null);
|
|
29
|
-
const internalValue = ref<string | number | undefined>(props.modelValue);
|
|
30
|
-
|
|
31
|
-
watch(() => props.modelValue, (newVal) => {
|
|
32
|
-
internalValue.value = newVal;
|
|
33
|
-
});
|
|
34
|
-
|
|
35
|
-
const updateValue = (value: string | number) => {
|
|
36
|
-
if (props.disabled || formContext?.disabled.value) return;
|
|
37
|
-
internalValue.value = value;
|
|
38
|
-
emit("update:modelValue", value);
|
|
39
|
-
emit("change", value);
|
|
40
|
-
|
|
41
|
-
if (props.name && formContext && (formContext.validateOn.value === "blur" || formContext.validateOn.value === "both")) {
|
|
42
|
-
// validation
|
|
43
|
-
}
|
|
44
|
-
};
|
|
45
|
-
|
|
46
|
-
provide(LuRadioGroupContextKey, {
|
|
47
|
-
name: props.name,
|
|
48
|
-
modelValue: computed(() => internalValue.value),
|
|
49
|
-
updateValue,
|
|
50
|
-
disabled: computed(() => !!props.disabled || !!formContext?.disabled.value)
|
|
51
|
-
});
|
|
52
|
-
|
|
53
|
-
onMounted(() => {
|
|
54
|
-
if (!props.name || !formContext) return;
|
|
55
|
-
formContext.register({
|
|
56
|
-
name: props.name,
|
|
57
|
-
getValue: () => internalValue.value,
|
|
58
|
-
setValue: (v) => { internalValue.value = v as string | number; },
|
|
59
|
-
setError: (_msg) => {},
|
|
60
|
-
});
|
|
61
|
-
});
|
|
62
|
-
|
|
63
|
-
onUnmounted(() => {
|
|
64
|
-
if (props.name && formContext) formContext.unregister(props.name);
|
|
65
|
-
});
|
|
66
|
-
</script>
|
|
@@ -1,67 +0,0 @@
|
|
|
1
|
-
<template>
|
|
2
|
-
<select
|
|
3
|
-
v-bind="$attrs"
|
|
4
|
-
:class="resolvedSkin"
|
|
5
|
-
:value="modelValue"
|
|
6
|
-
:name="name"
|
|
7
|
-
:disabled="formContext?.disabled.value"
|
|
8
|
-
@change="onChange"
|
|
9
|
-
@blur="onBlur"
|
|
10
|
-
>
|
|
11
|
-
<option v-for="opt in options" :key="opt.value" :value="opt.value">
|
|
12
|
-
{{ opt.label }}
|
|
13
|
-
</option>
|
|
14
|
-
</select>
|
|
15
|
-
</template>
|
|
16
|
-
|
|
17
|
-
<script setup lang="ts">
|
|
18
|
-
import { computed, inject, onMounted, onUnmounted, ref } from "vue";
|
|
19
|
-
import { useLumoraConfig } from "../context";
|
|
20
|
-
import { LuFormContextKey } from "./LuForm.types";
|
|
21
|
-
|
|
22
|
-
const props = defineProps<{
|
|
23
|
-
modelValue?: string | number;
|
|
24
|
-
variant?: string;
|
|
25
|
-
options: Array<{ value: string | number; label: string }>;
|
|
26
|
-
name?: string;
|
|
27
|
-
error?: string | null;
|
|
28
|
-
}>();
|
|
29
|
-
|
|
30
|
-
const emit = defineEmits<{
|
|
31
|
-
(e: "update:modelValue", value: string | number): void;
|
|
32
|
-
(e: "blur"): void;
|
|
33
|
-
}>();
|
|
34
|
-
|
|
35
|
-
const { resolveSkin } = useLumoraConfig();
|
|
36
|
-
const resolvedSkin = computed(() => resolveSkin("LuSelect", props.variant));
|
|
37
|
-
|
|
38
|
-
const formContext = inject(LuFormContextKey, null);
|
|
39
|
-
const internalValue = ref<string | number | undefined>(props.modelValue);
|
|
40
|
-
|
|
41
|
-
const onChange = (event: Event) => {
|
|
42
|
-
const value = (event.target as HTMLSelectElement).value;
|
|
43
|
-
internalValue.value = value;
|
|
44
|
-
emit("update:modelValue", value);
|
|
45
|
-
};
|
|
46
|
-
|
|
47
|
-
const onBlur = () => {
|
|
48
|
-
if (props.name && formContext && (formContext.validateOn.value === "blur" || formContext.validateOn.value === "both")) {
|
|
49
|
-
// trigger single-field validation — handled by parent LuForm
|
|
50
|
-
}
|
|
51
|
-
emit("blur");
|
|
52
|
-
};
|
|
53
|
-
|
|
54
|
-
onMounted(() => {
|
|
55
|
-
if (!props.name || !formContext) return;
|
|
56
|
-
formContext.register({
|
|
57
|
-
name: props.name,
|
|
58
|
-
getValue: () => internalValue.value,
|
|
59
|
-
setValue: (v) => { internalValue.value = v as string | number; },
|
|
60
|
-
setError: (_msg) => { /* error display handled via formContext.getError in template if desired */ },
|
|
61
|
-
});
|
|
62
|
-
});
|
|
63
|
-
|
|
64
|
-
onUnmounted(() => {
|
|
65
|
-
if (props.name && formContext) formContext.unregister(props.name);
|
|
66
|
-
});
|
|
67
|
-
</script>
|
|
@@ -1,15 +0,0 @@
|
|
|
1
|
-
<template>
|
|
2
|
-
<div :class="resolvedSkin" aria-hidden="true" />
|
|
3
|
-
</template>
|
|
4
|
-
|
|
5
|
-
<script setup lang="ts">
|
|
6
|
-
import { computed } from "vue";
|
|
7
|
-
import { useLumoraConfig } from "../context";
|
|
8
|
-
|
|
9
|
-
const props = defineProps<{
|
|
10
|
-
variant?: string;
|
|
11
|
-
}>();
|
|
12
|
-
|
|
13
|
-
const { resolveSkin } = useLumoraConfig();
|
|
14
|
-
const resolvedSkin = computed(() => resolveSkin("LuSkeleton", props.variant));
|
|
15
|
-
</script>
|
|
@@ -1,36 +0,0 @@
|
|
|
1
|
-
<template>
|
|
2
|
-
<svg
|
|
3
|
-
:class="resolvedSkin"
|
|
4
|
-
xmlns="http://www.w3.org/2000/svg"
|
|
5
|
-
fill="none"
|
|
6
|
-
viewBox="0 0 24 24"
|
|
7
|
-
role="status"
|
|
8
|
-
aria-label="Loading"
|
|
9
|
-
>
|
|
10
|
-
<circle
|
|
11
|
-
class="opacity-25"
|
|
12
|
-
cx="12"
|
|
13
|
-
cy="12"
|
|
14
|
-
r="10"
|
|
15
|
-
stroke="currentColor"
|
|
16
|
-
stroke-width="4"
|
|
17
|
-
></circle>
|
|
18
|
-
<path
|
|
19
|
-
class="opacity-75"
|
|
20
|
-
fill="currentColor"
|
|
21
|
-
d="M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z"
|
|
22
|
-
></path>
|
|
23
|
-
</svg>
|
|
24
|
-
</template>
|
|
25
|
-
|
|
26
|
-
<script setup lang="ts">
|
|
27
|
-
import { computed } from "vue";
|
|
28
|
-
import { useLumoraConfig } from "../context";
|
|
29
|
-
|
|
30
|
-
const props = defineProps<{
|
|
31
|
-
variant?: string;
|
|
32
|
-
}>();
|
|
33
|
-
|
|
34
|
-
const { resolveSkin } = useLumoraConfig();
|
|
35
|
-
const resolvedSkin = computed(() => resolveSkin("LuSpinner", props.variant));
|
|
36
|
-
</script>
|
|
@@ -1,76 +0,0 @@
|
|
|
1
|
-
<template>
|
|
2
|
-
<button
|
|
3
|
-
role="switch"
|
|
4
|
-
type="button"
|
|
5
|
-
:name="name"
|
|
6
|
-
:aria-checked="isChecked"
|
|
7
|
-
:disabled="mergedDisabled"
|
|
8
|
-
:class="cn(resolvedSkin, isChecked ? activeSkin : '')"
|
|
9
|
-
@click="toggle"
|
|
10
|
-
@blur="onBlur"
|
|
11
|
-
>
|
|
12
|
-
<span :class="cn(thumbSkin, isChecked ? thumbActiveSkin : '')" />
|
|
13
|
-
</button>
|
|
14
|
-
</template>
|
|
15
|
-
|
|
16
|
-
<script setup lang="ts">
|
|
17
|
-
import { computed, inject, onMounted, onUnmounted, ref } from "vue";
|
|
18
|
-
import { useLumoraConfig } from "../context";
|
|
19
|
-
import { LuFormContextKey } from "./LuForm.types";
|
|
20
|
-
import { cn } from "../utils";
|
|
21
|
-
|
|
22
|
-
const props = defineProps<{
|
|
23
|
-
modelValue?: boolean;
|
|
24
|
-
variant?: string;
|
|
25
|
-
disabled?: boolean;
|
|
26
|
-
name?: string;
|
|
27
|
-
error?: string | null;
|
|
28
|
-
}>();
|
|
29
|
-
|
|
30
|
-
const emit = defineEmits<{
|
|
31
|
-
(e: "update:modelValue", value: boolean): void;
|
|
32
|
-
(e: "blur"): void;
|
|
33
|
-
}>();
|
|
34
|
-
|
|
35
|
-
const { resolveSkin } = useLumoraConfig();
|
|
36
|
-
|
|
37
|
-
const resolvedSkin = computed(() => resolveSkin("LuSwitch", props.variant));
|
|
38
|
-
const activeSkin = computed(() => resolveSkin("LuSwitch", "checked"));
|
|
39
|
-
|
|
40
|
-
const thumbSkin = computed(() => resolveSkin("LuSwitchThumb", props.variant));
|
|
41
|
-
const thumbActiveSkin = computed(() => resolveSkin("LuSwitchThumb", "checked"));
|
|
42
|
-
|
|
43
|
-
const formContext = inject(LuFormContextKey, null);
|
|
44
|
-
const internalValue = ref<boolean | undefined>(props.modelValue);
|
|
45
|
-
const isChecked = computed(() => props.modelValue !== undefined ? props.modelValue : !!internalValue.value);
|
|
46
|
-
|
|
47
|
-
const mergedDisabled = computed(() => props.disabled || formContext?.disabled.value);
|
|
48
|
-
|
|
49
|
-
const toggle = () => {
|
|
50
|
-
if (mergedDisabled.value) return;
|
|
51
|
-
const newValue = !isChecked.value;
|
|
52
|
-
internalValue.value = newValue;
|
|
53
|
-
emit("update:modelValue", newValue);
|
|
54
|
-
};
|
|
55
|
-
|
|
56
|
-
const onBlur = () => {
|
|
57
|
-
if (props.name && formContext && (formContext.validateOn.value === "blur" || formContext.validateOn.value === "both")) {
|
|
58
|
-
// trigger single-field validation — handled by parent LuForm
|
|
59
|
-
}
|
|
60
|
-
emit("blur");
|
|
61
|
-
};
|
|
62
|
-
|
|
63
|
-
onMounted(() => {
|
|
64
|
-
if (!props.name || !formContext) return;
|
|
65
|
-
formContext.register({
|
|
66
|
-
name: props.name,
|
|
67
|
-
getValue: () => internalValue.value,
|
|
68
|
-
setValue: (v) => { internalValue.value = Boolean(v); },
|
|
69
|
-
setError: (_msg) => { /* error display handled via formContext.getError in template if desired */ },
|
|
70
|
-
});
|
|
71
|
-
});
|
|
72
|
-
|
|
73
|
-
onUnmounted(() => {
|
|
74
|
-
if (props.name && formContext) formContext.unregister(props.name);
|
|
75
|
-
});
|
|
76
|
-
</script>
|
package/src/components/LuTab.vue
DELETED
|
@@ -1,26 +0,0 @@
|
|
|
1
|
-
<template>
|
|
2
|
-
<button v-bind="$attrs" :class="[resolvedSkin, isActive ? activeSkin : '']" @click="onClick">
|
|
3
|
-
<slot />
|
|
4
|
-
</button>
|
|
5
|
-
</template>
|
|
6
|
-
|
|
7
|
-
<script setup lang="ts">
|
|
8
|
-
import { computed, inject, type Ref } from "vue";
|
|
9
|
-
import { useLumoraConfig } from "../context";
|
|
10
|
-
|
|
11
|
-
const props = defineProps<{ variant?: string; value: string | number }>();
|
|
12
|
-
|
|
13
|
-
const activeTab = inject<Ref<string | number | undefined>>("lu-tabs-active");
|
|
14
|
-
|
|
15
|
-
const isActive = computed(() => activeTab?.value === props.value);
|
|
16
|
-
|
|
17
|
-
const onClick = () => {
|
|
18
|
-
if (activeTab) {
|
|
19
|
-
activeTab.value = props.value;
|
|
20
|
-
}
|
|
21
|
-
};
|
|
22
|
-
|
|
23
|
-
const { resolveSkin } = useLumoraConfig();
|
|
24
|
-
const resolvedSkin = computed(() => resolveSkin("LuTab", props.variant));
|
|
25
|
-
const activeSkin = computed(() => resolveSkin("LuTab", "active"));
|
|
26
|
-
</script>
|
|
@@ -1,15 +0,0 @@
|
|
|
1
|
-
<template>
|
|
2
|
-
<div v-bind="$attrs" :class="resolvedSkin">
|
|
3
|
-
<slot />
|
|
4
|
-
</div>
|
|
5
|
-
</template>
|
|
6
|
-
|
|
7
|
-
<script setup lang="ts">
|
|
8
|
-
import { computed } from "vue";
|
|
9
|
-
import { useLumoraConfig } from "../context";
|
|
10
|
-
|
|
11
|
-
const props = defineProps<{ variant?: string }>();
|
|
12
|
-
|
|
13
|
-
const { resolveSkin } = useLumoraConfig();
|
|
14
|
-
const resolvedSkin = computed(() => resolveSkin("LuTabList", props.variant));
|
|
15
|
-
</script>
|
|
@@ -1,19 +0,0 @@
|
|
|
1
|
-
<template>
|
|
2
|
-
<div v-show="isActive" v-bind="$attrs" :class="resolvedSkin">
|
|
3
|
-
<slot />
|
|
4
|
-
</div>
|
|
5
|
-
</template>
|
|
6
|
-
|
|
7
|
-
<script setup lang="ts">
|
|
8
|
-
import { computed, inject, type Ref } from "vue";
|
|
9
|
-
import { useLumoraConfig } from "../context";
|
|
10
|
-
|
|
11
|
-
const props = defineProps<{ variant?: string; value: string | number }>();
|
|
12
|
-
|
|
13
|
-
const activeTab = inject<Ref<string | number | undefined>>("lu-tabs-active");
|
|
14
|
-
|
|
15
|
-
const isActive = computed(() => activeTab?.value === props.value);
|
|
16
|
-
|
|
17
|
-
const { resolveSkin } = useLumoraConfig();
|
|
18
|
-
const resolvedSkin = computed(() => resolveSkin("LuTabPanel", props.variant));
|
|
19
|
-
</script>
|