@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.
Files changed (179) hide show
  1. package/CHANGELOG.md +141 -137
  2. package/dist/LuCodeBlock.vue_vue_type_script_setup_true_lang-BjwcjuXF.js +1623 -0
  3. package/dist/LuEmbeddedStatusBar.vue_vue_type_script_setup_true_lang-CIksvebU.js +218 -0
  4. package/dist/LuOverlay.vue_vue_type_script_setup_true_lang-DZch4Vrw.js +226 -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 +21 -0
  11. package/dist/components/LuCheckbox.vue.d.ts +27 -0
  12. package/dist/components/LuCodeBlock.vue.d.ts +29 -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/index.js +47 -0
  53. package/{src/composables/index.ts → dist/composables/index.d.ts} +0 -1
  54. package/dist/composables/index.js +30 -0
  55. package/dist/composables/useRail.d.ts +6 -0
  56. package/dist/composables/useSplit.d.ts +4 -0
  57. package/dist/composables/useTheme.d.ts +7 -0
  58. package/dist/context-0gENwESP.js +62 -0
  59. package/dist/context.d.ts +8 -0
  60. package/{src/index.ts → dist/index.d.ts} +0 -1
  61. package/dist/index.js +94 -0
  62. package/dist/layout/LuDock.vue.d.ts +9 -0
  63. package/dist/layout/LuDockItem.vue.d.ts +16 -0
  64. package/dist/layout/LuFill.vue.d.ts +21 -0
  65. package/dist/layout/LuFixed.vue.d.ts +21 -0
  66. package/dist/layout/LuGrid.vue.d.ts +26 -0
  67. package/dist/layout/LuOverlay.vue.d.ts +15 -0
  68. package/dist/layout/LuScroll.vue.d.ts +15 -0
  69. package/dist/layout/LuSplit.vue.d.ts +16 -0
  70. package/dist/layout/LuSplitPane.vue.d.ts +18 -0
  71. package/dist/layout/LuSplitResizer.vue.d.ts +5 -0
  72. package/dist/layout/LuStack.vue.d.ts +23 -0
  73. package/{src/layout/index.ts → dist/layout/index.d.ts} +1 -14
  74. package/dist/layout/index.js +14 -0
  75. package/dist/plugin.d.ts +6 -0
  76. package/dist/shell/desktop/LuDesktopRailBar.vue.d.ts +17 -0
  77. package/dist/shell/desktop/LuDesktopRailItem.vue.d.ts +18 -0
  78. package/dist/shell/desktop/LuDesktopShell.vue.d.ts +23 -0
  79. package/dist/shell/desktop/LuDesktopSidebar.vue.d.ts +21 -0
  80. package/dist/shell/desktop/LuDesktopStatusBar.vue.d.ts +15 -0
  81. package/dist/shell/desktop/LuDesktopTopBar.vue.d.ts +15 -0
  82. package/dist/shell/embedded/LuEmbeddedShell.vue.d.ts +19 -0
  83. package/dist/shell/embedded/LuEmbeddedStatusBar.vue.d.ts +17 -0
  84. package/dist/shell/embedded/LuEmbeddedTopBar.vue.d.ts +19 -0
  85. package/{src/shell/index.ts → dist/shell/index.d.ts} +0 -1
  86. package/dist/shell/index.js +15 -0
  87. package/dist/shell/mobile/LuMobileHeader.vue.d.ts +19 -0
  88. package/dist/shell/mobile/LuMobileNavBar.vue.d.ts +15 -0
  89. package/dist/shell/mobile/LuMobileShell.vue.d.ts +21 -0
  90. package/dist/skins/default.d.ts +2 -0
  91. package/{src/skins/default.ts → dist/skins/index.js} +119 -129
  92. package/dist/tailwind.d.ts +1 -0
  93. package/dist/tailwind.js +13 -0
  94. package/dist/types.d.ts +15 -0
  95. package/dist/useTheme-Cd4wVaLs.js +21 -0
  96. package/dist/utils.d.ts +21 -0
  97. package/package.json +94 -69
  98. package/src/lumora.css +16 -16
  99. package/src/components/LuAlert.vue +0 -33
  100. package/src/components/LuAvatar.vue +0 -22
  101. package/src/components/LuBadge.vue +0 -15
  102. package/src/components/LuBreadcrumb.vue +0 -63
  103. package/src/components/LuButton.vue +0 -58
  104. package/src/components/LuCard.vue +0 -27
  105. package/src/components/LuCheckbox.vue +0 -94
  106. package/src/components/LuCodeBlock.vue +0 -168
  107. package/src/components/LuCollapsible.vue +0 -34
  108. package/src/components/LuDivider.vue +0 -18
  109. package/src/components/LuForm.types.ts +0 -24
  110. package/src/components/LuForm.vue +0 -121
  111. package/src/components/LuIcon.vue +0 -39
  112. package/src/components/LuInput.vue +0 -82
  113. package/src/components/LuLink.vue +0 -47
  114. package/src/components/LuMenu.vue +0 -86
  115. package/src/components/LuMenuItem.vue +0 -37
  116. package/src/components/LuModal.vue +0 -115
  117. package/src/components/LuPageHeader.vue +0 -24
  118. package/src/components/LuPagination.vue +0 -118
  119. package/src/components/LuProgressBar.vue +0 -21
  120. package/src/components/LuRadio.vue +0 -55
  121. package/src/components/LuRadioGroup.types.ts +0 -10
  122. package/src/components/LuRadioGroup.vue +0 -66
  123. package/src/components/LuSelect.vue +0 -67
  124. package/src/components/LuSkeleton.vue +0 -15
  125. package/src/components/LuSpinner.vue +0 -36
  126. package/src/components/LuSwitch.vue +0 -76
  127. package/src/components/LuTab.vue +0 -26
  128. package/src/components/LuTabList.vue +0 -15
  129. package/src/components/LuTabPanel.vue +0 -19
  130. package/src/components/LuTable.vue +0 -15
  131. package/src/components/LuTableBody.vue +0 -15
  132. package/src/components/LuTableCell.vue +0 -15
  133. package/src/components/LuTableHead.vue +0 -15
  134. package/src/components/LuTableHeadCell.vue +0 -15
  135. package/src/components/LuTableRow.vue +0 -15
  136. package/src/components/LuTabs.vue +0 -30
  137. package/src/components/LuTag.vue +0 -35
  138. package/src/components/LuText.vue +0 -18
  139. package/src/components/LuTextarea.vue +0 -62
  140. package/src/components/LuThemeSelect.vue +0 -26
  141. package/src/components/LuThemeSwitch.vue +0 -22
  142. package/src/components/LuToggleButton.vue +0 -35
  143. package/src/components/LuToggleGroup.vue +0 -27
  144. package/src/components/LuTooltip.vue +0 -36
  145. package/src/components/__tests__/LuForm.test.ts +0 -206
  146. package/src/composables/useRail.ts +0 -24
  147. package/src/composables/useSplit.ts +0 -17
  148. package/src/composables/useTheme.ts +0 -36
  149. package/src/context.ts +0 -39
  150. package/src/layout/LuDock.vue +0 -56
  151. package/src/layout/LuDockItem.vue +0 -20
  152. package/src/layout/LuFill.vue +0 -27
  153. package/src/layout/LuFixed.vue +0 -27
  154. package/src/layout/LuGrid.vue +0 -45
  155. package/src/layout/LuOverlay.vue +0 -17
  156. package/src/layout/LuScroll.vue +0 -19
  157. package/src/layout/LuSplit.vue +0 -23
  158. package/src/layout/LuSplitPane.vue +0 -32
  159. package/src/layout/LuSplitResizer.vue +0 -19
  160. package/src/layout/LuStack.vue +0 -29
  161. package/src/plugin.ts +0 -28
  162. package/src/shell/desktop/LuDesktopRailBar.vue +0 -23
  163. package/src/shell/desktop/LuDesktopRailItem.vue +0 -23
  164. package/src/shell/desktop/LuDesktopShell.vue +0 -25
  165. package/src/shell/desktop/LuDesktopSidebar.vue +0 -36
  166. package/src/shell/desktop/LuDesktopStatusBar.vue +0 -15
  167. package/src/shell/desktop/LuDesktopTopBar.vue +0 -15
  168. package/src/shell/embedded/LuEmbeddedShell.vue +0 -20
  169. package/src/shell/embedded/LuEmbeddedStatusBar.vue +0 -16
  170. package/src/shell/embedded/LuEmbeddedTopBar.vue +0 -17
  171. package/src/shell/mobile/LuMobileHeader.vue +0 -17
  172. package/src/shell/mobile/LuMobileNavBar.vue +0 -15
  173. package/src/shell/mobile/LuMobileShell.vue +0 -21
  174. package/src/tailwind.ts +0 -25
  175. package/src/types.ts +0 -18
  176. package/src/utils.ts +0 -95
  177. package/tsconfig.json +0 -10
  178. /package/{src/components/index.ts → dist/components/index.d.ts} +0 -0
  179. /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>