@astrake/lumora-ui 0.2.0 → 0.2.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (187) hide show
  1. package/CHANGELOG.md +44 -1
  2. package/dist/LuCodeBlock.vue_vue_type_script_setup_true_lang-BdXflBkJ.js +1672 -0
  3. package/dist/LuEmbeddedStatusBar.vue_vue_type_script_setup_true_lang-D4rqklgo.js +218 -0
  4. package/dist/LuOverlay.vue_vue_type_script_setup_true_lang-C5jhqCgy.js +221 -0
  5. package/dist/components/LuAlert.vue.d.ts +20 -0
  6. package/dist/components/LuAvatar.vue.d.ts +19 -0
  7. package/dist/components/LuBadge.vue.d.ts +16 -0
  8. package/dist/components/LuBreadcrumb.vue.d.ts +16 -0
  9. package/dist/components/LuButton.vue.d.ts +24 -0
  10. package/dist/components/LuCard.vue.d.ts +18 -0
  11. package/dist/components/LuCheckbox.vue.d.ts +27 -0
  12. package/dist/components/LuCodeBlock.vue.d.ts +26 -0
  13. package/dist/components/LuCollapsible.vue.d.ts +25 -0
  14. package/dist/components/LuDivider.vue.d.ts +8 -0
  15. package/dist/components/LuForm.types.d.ts +18 -0
  16. package/dist/components/LuForm.vue.d.ts +55 -0
  17. package/dist/components/LuIcon.vue.d.ts +18 -0
  18. package/dist/components/LuInput.vue.d.ts +26 -0
  19. package/dist/components/LuLink.vue.d.ts +23 -0
  20. package/dist/components/LuMenu.vue.d.ts +26 -0
  21. package/dist/components/LuMenuItem.vue.d.ts +20 -0
  22. package/dist/components/LuModal.vue.d.ts +32 -0
  23. package/dist/components/LuPageHeader.vue.d.ts +10 -0
  24. package/dist/components/LuPagination.vue.d.ts +18 -0
  25. package/dist/components/LuProgressBar.vue.d.ts +7 -0
  26. package/dist/components/LuRadio.vue.d.ts +18 -0
  27. package/dist/components/LuRadioGroup.types.d.ts +8 -0
  28. package/dist/components/LuRadioGroup.vue.d.ts +24 -0
  29. package/dist/components/LuSelect.vue.d.ts +18 -0
  30. package/dist/components/LuSkeleton.vue.d.ts +5 -0
  31. package/dist/components/LuSpinner.vue.d.ts +5 -0
  32. package/dist/components/LuSwitch.vue.d.ts +15 -0
  33. package/dist/components/LuTab.vue.d.ts +16 -0
  34. package/dist/components/LuTabList.vue.d.ts +15 -0
  35. package/dist/components/LuTabPanel.vue.d.ts +16 -0
  36. package/dist/components/LuTable.vue.d.ts +15 -0
  37. package/dist/components/LuTableBody.vue.d.ts +15 -0
  38. package/dist/components/LuTableCell.vue.d.ts +15 -0
  39. package/dist/components/LuTableHead.vue.d.ts +15 -0
  40. package/dist/components/LuTableHeadCell.vue.d.ts +15 -0
  41. package/dist/components/LuTableRow.vue.d.ts +15 -0
  42. package/dist/components/LuTabs.vue.d.ts +20 -0
  43. package/dist/components/LuTag.vue.d.ts +20 -0
  44. package/dist/components/LuText.vue.d.ts +16 -0
  45. package/dist/components/LuTextarea.vue.d.ts +14 -0
  46. package/dist/components/LuThemeSelect.vue.d.ts +2 -0
  47. package/dist/components/LuThemeSwitch.vue.d.ts +2 -0
  48. package/dist/components/LuToggleButton.vue.d.ts +16 -0
  49. package/dist/components/LuToggleGroup.vue.d.ts +20 -0
  50. package/dist/components/LuTooltip.vue.d.ts +19 -0
  51. package/dist/components/__tests__/LuForm.test.d.ts +1 -0
  52. package/dist/components/_all.d.ts +3 -0
  53. package/dist/components/index.js +47 -0
  54. package/{src/composables/index.ts → dist/composables/index.d.ts} +1 -1
  55. package/dist/composables/index.js +31 -0
  56. package/dist/composables/useRail.d.ts +6 -0
  57. package/dist/composables/useShiki.d.ts +2 -0
  58. package/dist/composables/useSplit.d.ts +4 -0
  59. package/dist/composables/useTheme.d.ts +7 -0
  60. package/dist/context-CGS7Ou_x.js +36 -0
  61. package/dist/context.d.ts +8 -0
  62. package/{src/index.ts → dist/index.d.ts} +0 -1
  63. package/dist/index.js +166 -0
  64. package/dist/layout/LuDock.vue.d.ts +9 -0
  65. package/dist/layout/LuDockItem.vue.d.ts +16 -0
  66. package/dist/layout/LuFill.vue.d.ts +18 -0
  67. package/dist/layout/LuFixed.vue.d.ts +18 -0
  68. package/dist/layout/LuGrid.vue.d.ts +22 -0
  69. package/dist/layout/LuOverlay.vue.d.ts +15 -0
  70. package/dist/layout/LuScroll.vue.d.ts +15 -0
  71. package/dist/layout/LuSplit.vue.d.ts +16 -0
  72. package/dist/layout/LuSplitPane.vue.d.ts +18 -0
  73. package/dist/layout/LuSplitResizer.vue.d.ts +5 -0
  74. package/dist/layout/LuStack.vue.d.ts +25 -0
  75. package/{src/layout/index.ts → dist/layout/index.d.ts} +1 -14
  76. package/dist/layout/index.js +14 -0
  77. package/dist/plugin.d.ts +6 -0
  78. package/dist/shell/desktop/LuDesktopRailBar.vue.d.ts +17 -0
  79. package/dist/shell/desktop/LuDesktopRailItem.vue.d.ts +18 -0
  80. package/dist/shell/desktop/LuDesktopShell.vue.d.ts +23 -0
  81. package/dist/shell/desktop/LuDesktopSidebar.vue.d.ts +21 -0
  82. package/dist/shell/desktop/LuDesktopStatusBar.vue.d.ts +15 -0
  83. package/dist/shell/desktop/LuDesktopTopBar.vue.d.ts +15 -0
  84. package/dist/shell/embedded/LuEmbeddedShell.vue.d.ts +19 -0
  85. package/dist/shell/embedded/LuEmbeddedStatusBar.vue.d.ts +17 -0
  86. package/dist/shell/embedded/LuEmbeddedTopBar.vue.d.ts +19 -0
  87. package/{src/shell/index.ts → dist/shell/index.d.ts} +0 -1
  88. package/dist/shell/index.js +15 -0
  89. package/dist/shell/mobile/LuMobileHeader.vue.d.ts +19 -0
  90. package/dist/shell/mobile/LuMobileNavBar.vue.d.ts +15 -0
  91. package/dist/shell/mobile/LuMobileShell.vue.d.ts +21 -0
  92. package/dist/skins/components.d.ts +2 -0
  93. package/dist/skins/default.d.ts +2 -0
  94. package/dist/skins/index.js +446 -0
  95. package/dist/skins/layout.d.ts +2 -0
  96. package/dist/skins/shell/desktop.d.ts +2 -0
  97. package/dist/skins/shell/embedded.d.ts +2 -0
  98. package/dist/skins/shell/mobile.d.ts +2 -0
  99. package/dist/tailwind.d.ts +1 -0
  100. package/dist/tailwind.js +13 -0
  101. package/dist/types.d.ts +15 -0
  102. package/dist/useShiki-DPOJfneq.js +30 -0
  103. package/dist/utils.d.ts +10 -0
  104. package/package.json +37 -12
  105. package/src/lumora.css +32 -0
  106. package/src/components/LuAlert.vue +0 -33
  107. package/src/components/LuAvatar.vue +0 -22
  108. package/src/components/LuBadge.vue +0 -15
  109. package/src/components/LuBreadcrumb.vue +0 -63
  110. package/src/components/LuButton.vue +0 -58
  111. package/src/components/LuCard.vue +0 -27
  112. package/src/components/LuCheckbox.vue +0 -94
  113. package/src/components/LuCodeBlock.vue +0 -168
  114. package/src/components/LuCollapsible.vue +0 -34
  115. package/src/components/LuDivider.vue +0 -18
  116. package/src/components/LuForm.types.ts +0 -24
  117. package/src/components/LuForm.vue +0 -121
  118. package/src/components/LuIcon.vue +0 -39
  119. package/src/components/LuInput.vue +0 -82
  120. package/src/components/LuLink.vue +0 -47
  121. package/src/components/LuMenu.vue +0 -86
  122. package/src/components/LuMenuItem.vue +0 -37
  123. package/src/components/LuModal.vue +0 -115
  124. package/src/components/LuPageHeader.vue +0 -24
  125. package/src/components/LuPagination.vue +0 -118
  126. package/src/components/LuProgressBar.vue +0 -21
  127. package/src/components/LuRadio.vue +0 -55
  128. package/src/components/LuRadioGroup.types.ts +0 -10
  129. package/src/components/LuRadioGroup.vue +0 -66
  130. package/src/components/LuSelect.vue +0 -67
  131. package/src/components/LuSkeleton.vue +0 -15
  132. package/src/components/LuSpinner.vue +0 -36
  133. package/src/components/LuSwitch.vue +0 -76
  134. package/src/components/LuTab.vue +0 -26
  135. package/src/components/LuTabList.vue +0 -15
  136. package/src/components/LuTabPanel.vue +0 -19
  137. package/src/components/LuTable.vue +0 -15
  138. package/src/components/LuTableBody.vue +0 -15
  139. package/src/components/LuTableCell.vue +0 -15
  140. package/src/components/LuTableHead.vue +0 -15
  141. package/src/components/LuTableHeadCell.vue +0 -15
  142. package/src/components/LuTableRow.vue +0 -15
  143. package/src/components/LuTabs.vue +0 -30
  144. package/src/components/LuTag.vue +0 -35
  145. package/src/components/LuText.vue +0 -18
  146. package/src/components/LuTextarea.vue +0 -62
  147. package/src/components/LuThemeSelect.vue +0 -26
  148. package/src/components/LuThemeSwitch.vue +0 -22
  149. package/src/components/LuToggleButton.vue +0 -35
  150. package/src/components/LuToggleGroup.vue +0 -27
  151. package/src/components/LuTooltip.vue +0 -36
  152. package/src/components/__tests__/LuForm.test.ts +0 -206
  153. package/src/composables/useRail.ts +0 -24
  154. package/src/composables/useSplit.ts +0 -17
  155. package/src/composables/useTheme.ts +0 -36
  156. package/src/context.ts +0 -39
  157. package/src/layout/LuDock.vue +0 -56
  158. package/src/layout/LuDockItem.vue +0 -20
  159. package/src/layout/LuFill.vue +0 -27
  160. package/src/layout/LuFixed.vue +0 -27
  161. package/src/layout/LuGrid.vue +0 -45
  162. package/src/layout/LuOverlay.vue +0 -17
  163. package/src/layout/LuScroll.vue +0 -19
  164. package/src/layout/LuSplit.vue +0 -23
  165. package/src/layout/LuSplitPane.vue +0 -32
  166. package/src/layout/LuSplitResizer.vue +0 -19
  167. package/src/layout/LuStack.vue +0 -29
  168. package/src/plugin.ts +0 -28
  169. package/src/shell/desktop/LuDesktopRailBar.vue +0 -23
  170. package/src/shell/desktop/LuDesktopRailItem.vue +0 -23
  171. package/src/shell/desktop/LuDesktopShell.vue +0 -25
  172. package/src/shell/desktop/LuDesktopSidebar.vue +0 -36
  173. package/src/shell/desktop/LuDesktopStatusBar.vue +0 -15
  174. package/src/shell/desktop/LuDesktopTopBar.vue +0 -15
  175. package/src/shell/embedded/LuEmbeddedShell.vue +0 -20
  176. package/src/shell/embedded/LuEmbeddedStatusBar.vue +0 -16
  177. package/src/shell/embedded/LuEmbeddedTopBar.vue +0 -17
  178. package/src/shell/mobile/LuMobileHeader.vue +0 -17
  179. package/src/shell/mobile/LuMobileNavBar.vue +0 -15
  180. package/src/shell/mobile/LuMobileShell.vue +0 -21
  181. package/src/skins/default.ts +0 -426
  182. package/src/tailwind.ts +0 -25
  183. package/src/types.ts +0 -18
  184. package/src/utils.ts +0 -95
  185. package/tsconfig.json +0 -10
  186. /package/{src/components/index.ts → dist/components/index.d.ts} +0 -0
  187. /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>
@@ -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>