lumina-slides 9.0.4 → 9.0.6
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/dist/lumina-slides.js +21984 -19455
- package/dist/lumina-slides.umd.cjs +223 -223
- package/dist/style.css +1 -1
- package/package.json +3 -1
- package/src/components/LandingPage.vue +1 -1
- package/src/components/LuminaDeck.vue +237 -232
- package/src/components/base/LuminaElement.vue +2 -0
- package/src/components/layouts/LayoutFeatures.vue +123 -123
- package/src/components/layouts/LayoutFlex.vue +212 -172
- package/src/components/layouts/LayoutStatement.vue +5 -2
- package/src/components/layouts/LayoutSteps.vue +108 -108
- package/src/components/parts/FlexHtml.vue +65 -0
- package/src/components/parts/FlexImage.vue +81 -54
- package/src/components/site/SiteDocs.vue +3313 -3182
- package/src/components/site/SiteExamples.vue +66 -66
- package/src/components/studio/EditorLayoutChart.vue +18 -0
- package/src/components/studio/EditorLayoutCustom.vue +18 -0
- package/src/components/studio/EditorLayoutVideo.vue +18 -0
- package/src/components/studio/LuminaStudioEmbed.vue +68 -0
- package/src/components/studio/StudioEmbedRoot.vue +19 -0
- package/src/components/studio/StudioInspector.vue +1113 -7
- package/src/components/studio/StudioSettings.vue +658 -7
- package/src/components/studio/StudioToolbar.vue +20 -2
- package/src/composables/useElementState.ts +12 -1
- package/src/composables/useFlexLayout.ts +128 -122
- package/src/core/Lumina.ts +174 -113
- package/src/core/animationConfig.ts +10 -0
- package/src/core/elementController.ts +18 -0
- package/src/core/elementResolver.ts +4 -2
- package/src/core/schema.ts +503 -478
- package/src/core/store.ts +465 -465
- package/src/core/types.ts +59 -14
- package/src/index.ts +2 -2
- package/src/utils/templateInterpolation.ts +52 -52
- package/src/views/DeckView.vue +313 -313
|
@@ -1,108 +1,108 @@
|
|
|
1
|
-
<template>
|
|
2
|
-
<BaseSlide :data="data" :slide-index="slideIndex">
|
|
3
|
-
<div :class="['w-full flex flex-col justify-center', data.sizing === 'container' ? 'min-h-full py-12 lg:py-16' : 'min-h-screen']"
|
|
4
|
-
:style="{ padding: 'var(--lumina-space-xl) var(--lumina-space-3xl)' }">
|
|
5
|
-
<!-- Header: wrapper (header) + title and subtitle as separate controllable elements -->
|
|
6
|
-
<LuminaElement :id="headerId" :class="['text-center max-w-4xl mx-auto', data.class || '']"
|
|
7
|
-
:style="{ marginBottom: 'var(--lumina-space-2xl)' }">
|
|
8
|
-
<LuminaElement :id="titleId" tag="h2" class="font-bold" :style="{
|
|
9
|
-
fontFamily: 'var(--lumina-font-heading)',
|
|
10
|
-
fontSize: 'var(--lumina-text-5xl)',
|
|
11
|
-
marginBottom: 'var(--lumina-space-md)',
|
|
12
|
-
letterSpacing: 'var(--lumina-tracking-tighter)',
|
|
13
|
-
color: 'var(--lumina-color-text-safe, var(--lumina-color-text))'
|
|
14
|
-
}">
|
|
15
|
-
{{ data.title }}
|
|
16
|
-
</LuminaElement>
|
|
17
|
-
<LuminaElement v-if="data.subtitle" :id="subtitleId" tag="p" :style="{
|
|
18
|
-
color: 'var(--lumina-color-text-safe, var(--lumina-color-text))',
|
|
19
|
-
opacity: 0.9,
|
|
20
|
-
fontSize: 'var(--lumina-text-xl)'
|
|
21
|
-
}">
|
|
22
|
-
{{ data.subtitle }}
|
|
23
|
-
</LuminaElement>
|
|
24
|
-
</LuminaElement>
|
|
25
|
-
|
|
26
|
-
<!-- Steps Grid -->
|
|
27
|
-
<div :style="{
|
|
28
|
-
display: 'grid',
|
|
29
|
-
gridTemplateColumns: 'repeat(auto-fit, minmax(280px, 1fr))',
|
|
30
|
-
gap: 'var(--lumina-space-xl)',
|
|
31
|
-
maxWidth: '72rem',
|
|
32
|
-
margin: '0 auto',
|
|
33
|
-
width: '100%'
|
|
34
|
-
}">
|
|
35
|
-
<LuminaElement v-for="(step, i) in data.steps" :key="i" :id="stepId(i)"
|
|
36
|
-
:class="['glass-panel group relative overflow-hidden', step.class || '']" :style="{
|
|
37
|
-
borderRadius: 'var(--lumina-card-radius)',
|
|
38
|
-
padding: 'var(--lumina-card-padding)'
|
|
39
|
-
}">
|
|
40
|
-
<!-- Step Number -->
|
|
41
|
-
<div :style="{
|
|
42
|
-
display: 'flex',
|
|
43
|
-
alignItems: 'center',
|
|
44
|
-
gap: 'var(--lumina-space-md)',
|
|
45
|
-
marginBottom: 'var(--lumina-space-md)'
|
|
46
|
-
}">
|
|
47
|
-
<div class="flex items-center justify-center font-bold" :style="{
|
|
48
|
-
width: 'var(--lumina-step-badge-size, 2.5rem)',
|
|
49
|
-
height: 'var(--lumina-step-badge-size, 2.5rem)',
|
|
50
|
-
fontSize: 'var(--lumina-step-font-size, 1rem)',
|
|
51
|
-
background: 'linear-gradient(135deg, var(--lumina-color-primary), var(--lumina-color-secondary))',
|
|
52
|
-
color: 'white',
|
|
53
|
-
borderRadius: 'var(--lumina-radius-xl)',
|
|
54
|
-
boxShadow: '0 4px 12px rgba(var(--lumina-color-primary-rgb), 0.4)'
|
|
55
|
-
}">
|
|
56
|
-
{{ step.step }}
|
|
57
|
-
</div>
|
|
58
|
-
<h3 class="font-bold" :style="{
|
|
59
|
-
fontSize: 'var(--lumina-text-xl)',
|
|
60
|
-
color: 'var(--lumina-surface-text, var(--lumina-color-text))'
|
|
61
|
-
}">
|
|
62
|
-
{{ step.title }}
|
|
63
|
-
</h3>
|
|
64
|
-
</div>
|
|
65
|
-
|
|
66
|
-
<!-- Description -->
|
|
67
|
-
<p v-if="step.description" :style="{
|
|
68
|
-
color: 'var(--lumina-color-text-secondary)',
|
|
69
|
-
lineHeight: 'var(--lumina-leading-relaxed)',
|
|
70
|
-
fontSize: 'var(--lumina-text-base)',
|
|
71
|
-
opacity: 0.8
|
|
72
|
-
}">
|
|
73
|
-
{{ step.description }}
|
|
74
|
-
</p>
|
|
75
|
-
|
|
76
|
-
<!-- Icon (optional) -->
|
|
77
|
-
<div v-if="step.icon" class="absolute top-4 right-4" :style="{
|
|
78
|
-
color: 'var(--lumina-color-primary)',
|
|
79
|
-
opacity: 0.1,
|
|
80
|
-
fontSize: 'var(--lumina-text-4xl)'
|
|
81
|
-
}">
|
|
82
|
-
<i :class="['ph-thin', step.icon.startsWith('ph-') ? step.icon : `ph-${step.icon}`]"></i>
|
|
83
|
-
</div>
|
|
84
|
-
</LuminaElement>
|
|
85
|
-
</div>
|
|
86
|
-
</div>
|
|
87
|
-
</BaseSlide>
|
|
88
|
-
</template>
|
|
89
|
-
|
|
90
|
-
<script setup lang="ts">
|
|
91
|
-
import { computed, inject } from 'vue';
|
|
92
|
-
import BaseSlide from '../base/BaseSlide.vue';
|
|
93
|
-
import { resolveId } from '../../core/elementResolver';
|
|
94
|
-
import { StoreKey } from '../../core/store';
|
|
95
|
-
import type { SlideSteps } from '../../core/types';
|
|
96
|
-
|
|
97
|
-
const props = defineProps<{
|
|
98
|
-
data: SlideSteps;
|
|
99
|
-
slideIndex?: number;
|
|
100
|
-
}>();
|
|
101
|
-
|
|
102
|
-
const store = inject(StoreKey);
|
|
103
|
-
const slideIndex = computed(() => props.slideIndex ?? store?.state.currentIndex ?? 0);
|
|
104
|
-
const headerId = computed(() => resolveId(props.data, slideIndex.value, ['header']));
|
|
105
|
-
const titleId = computed(() => resolveId(props.data, slideIndex.value, ['title']));
|
|
106
|
-
const subtitleId = computed(() => resolveId(props.data, slideIndex.value, ['subtitle']));
|
|
107
|
-
const stepId = (i: number) => resolveId(props.data, slideIndex.value, ['steps', i]);
|
|
108
|
-
</script>
|
|
1
|
+
<template>
|
|
2
|
+
<BaseSlide :data="data" :slide-index="slideIndex">
|
|
3
|
+
<div :class="['w-full flex flex-col justify-center', data.sizing === 'container' ? 'min-h-full py-12 lg:py-16' : 'min-h-screen']"
|
|
4
|
+
:style="{ padding: 'var(--lumina-space-xl) var(--lumina-space-3xl)' }">
|
|
5
|
+
<!-- Header: wrapper (header) + title and subtitle as separate controllable elements -->
|
|
6
|
+
<LuminaElement :id="headerId" :class="['text-center max-w-4xl mx-auto', data.class || '']"
|
|
7
|
+
:style="{ marginBottom: 'var(--lumina-space-2xl)' }">
|
|
8
|
+
<LuminaElement :id="titleId" tag="h2" class="font-bold" :style="{
|
|
9
|
+
fontFamily: 'var(--lumina-font-heading)',
|
|
10
|
+
fontSize: 'var(--lumina-text-5xl)',
|
|
11
|
+
marginBottom: 'var(--lumina-space-md)',
|
|
12
|
+
letterSpacing: 'var(--lumina-tracking-tighter)',
|
|
13
|
+
color: 'var(--lumina-color-text-safe, var(--lumina-color-text))'
|
|
14
|
+
}">
|
|
15
|
+
{{ data.title }}
|
|
16
|
+
</LuminaElement>
|
|
17
|
+
<LuminaElement v-if="data.subtitle" :id="subtitleId" tag="p" :style="{
|
|
18
|
+
color: 'var(--lumina-color-text-safe, var(--lumina-color-text))',
|
|
19
|
+
opacity: 0.9,
|
|
20
|
+
fontSize: 'var(--lumina-text-xl)'
|
|
21
|
+
}">
|
|
22
|
+
{{ data.subtitle }}
|
|
23
|
+
</LuminaElement>
|
|
24
|
+
</LuminaElement>
|
|
25
|
+
|
|
26
|
+
<!-- Steps Grid -->
|
|
27
|
+
<div :style="{
|
|
28
|
+
display: 'grid',
|
|
29
|
+
gridTemplateColumns: 'repeat(auto-fit, minmax(280px, 1fr))',
|
|
30
|
+
gap: 'var(--lumina-space-xl)',
|
|
31
|
+
maxWidth: '72rem',
|
|
32
|
+
margin: '0 auto',
|
|
33
|
+
width: '100%'
|
|
34
|
+
}">
|
|
35
|
+
<LuminaElement v-for="(step, i) in data.steps" :key="i" :id="stepId(i)"
|
|
36
|
+
:class="['glass-panel group relative overflow-hidden', step.class || '']" :style="{
|
|
37
|
+
borderRadius: 'var(--lumina-card-radius)',
|
|
38
|
+
padding: 'var(--lumina-card-padding)'
|
|
39
|
+
}">
|
|
40
|
+
<!-- Step Number -->
|
|
41
|
+
<div :style="{
|
|
42
|
+
display: 'flex',
|
|
43
|
+
alignItems: 'center',
|
|
44
|
+
gap: 'var(--lumina-space-md)',
|
|
45
|
+
marginBottom: 'var(--lumina-space-md)'
|
|
46
|
+
}">
|
|
47
|
+
<div class="flex items-center justify-center font-bold" :style="{
|
|
48
|
+
width: 'var(--lumina-step-badge-size, 2.5rem)',
|
|
49
|
+
height: 'var(--lumina-step-badge-size, 2.5rem)',
|
|
50
|
+
fontSize: 'var(--lumina-step-font-size, 1rem)',
|
|
51
|
+
background: 'linear-gradient(135deg, var(--lumina-color-primary), var(--lumina-color-secondary))',
|
|
52
|
+
color: 'white',
|
|
53
|
+
borderRadius: 'var(--lumina-radius-xl)',
|
|
54
|
+
boxShadow: '0 4px 12px rgba(var(--lumina-color-primary-rgb), 0.4)'
|
|
55
|
+
}">
|
|
56
|
+
{{ step.step }}
|
|
57
|
+
</div>
|
|
58
|
+
<h3 class="font-bold" :style="{
|
|
59
|
+
fontSize: 'var(--lumina-text-xl)',
|
|
60
|
+
color: 'var(--lumina-surface-text, var(--lumina-color-text))'
|
|
61
|
+
}">
|
|
62
|
+
{{ step.title }}
|
|
63
|
+
</h3>
|
|
64
|
+
</div>
|
|
65
|
+
|
|
66
|
+
<!-- Description -->
|
|
67
|
+
<p v-if="step.description" :style="{
|
|
68
|
+
color: 'var(--lumina-color-text-secondary)',
|
|
69
|
+
lineHeight: 'var(--lumina-leading-relaxed)',
|
|
70
|
+
fontSize: 'var(--lumina-text-base)',
|
|
71
|
+
opacity: 0.8
|
|
72
|
+
}">
|
|
73
|
+
{{ step.description }}
|
|
74
|
+
</p>
|
|
75
|
+
|
|
76
|
+
<!-- Icon (optional) -->
|
|
77
|
+
<div v-if="step.icon" class="absolute top-4 right-4" :style="{
|
|
78
|
+
color: 'var(--lumina-color-primary)',
|
|
79
|
+
opacity: 0.1,
|
|
80
|
+
fontSize: 'var(--lumina-text-4xl)'
|
|
81
|
+
}">
|
|
82
|
+
<i :class="['ph-thin', step.icon.startsWith('ph-') ? step.icon : `ph-${step.icon}`]"></i>
|
|
83
|
+
</div>
|
|
84
|
+
</LuminaElement>
|
|
85
|
+
</div>
|
|
86
|
+
</div>
|
|
87
|
+
</BaseSlide>
|
|
88
|
+
</template>
|
|
89
|
+
|
|
90
|
+
<script setup lang="ts">
|
|
91
|
+
import { computed, inject } from 'vue';
|
|
92
|
+
import BaseSlide from '../base/BaseSlide.vue';
|
|
93
|
+
import { resolveId } from '../../core/elementResolver';
|
|
94
|
+
import { StoreKey } from '../../core/store';
|
|
95
|
+
import type { SlideSteps } from '../../core/types';
|
|
96
|
+
|
|
97
|
+
const props = defineProps<{
|
|
98
|
+
data: SlideSteps;
|
|
99
|
+
slideIndex?: number;
|
|
100
|
+
}>();
|
|
101
|
+
|
|
102
|
+
const store = inject(StoreKey);
|
|
103
|
+
const slideIndex = computed(() => props.slideIndex ?? store?.state.currentIndex ?? 0);
|
|
104
|
+
const headerId = computed(() => resolveId(props.data, slideIndex.value, ['header']));
|
|
105
|
+
const titleId = computed(() => resolveId(props.data, slideIndex.value, ['title']));
|
|
106
|
+
const subtitleId = computed(() => resolveId(props.data, slideIndex.value, ['subtitle']));
|
|
107
|
+
const stepId = (i: number) => resolveId(props.data, slideIndex.value, ['steps', i]);
|
|
108
|
+
</script>
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<div
|
|
3
|
+
v-html="html"
|
|
4
|
+
:class="customClass"
|
|
5
|
+
:style="computedStyle"
|
|
6
|
+
></div>
|
|
7
|
+
</template>
|
|
8
|
+
|
|
9
|
+
<script setup lang="ts">
|
|
10
|
+
import { computed } from 'vue';
|
|
11
|
+
|
|
12
|
+
const props = defineProps<{
|
|
13
|
+
html: string;
|
|
14
|
+
class?: string;
|
|
15
|
+
style?: Record<string, string>;
|
|
16
|
+
}>();
|
|
17
|
+
|
|
18
|
+
const customClass = computed(() => props.class || '');
|
|
19
|
+
|
|
20
|
+
const computedStyle = computed(() => {
|
|
21
|
+
return {
|
|
22
|
+
width: '100%',
|
|
23
|
+
...props.style,
|
|
24
|
+
};
|
|
25
|
+
});
|
|
26
|
+
</script>
|
|
27
|
+
|
|
28
|
+
<style scoped>
|
|
29
|
+
/* Ensure HTML content respects container boundaries */
|
|
30
|
+
:deep(*) {
|
|
31
|
+
max-width: 100%;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
/* Style common HTML elements to match Lumina theme */
|
|
35
|
+
:deep(h1), :deep(h2), :deep(h3), :deep(h4), :deep(h5), :deep(h6) {
|
|
36
|
+
color: var(--lumina-color-text);
|
|
37
|
+
font-family: var(--lumina-font-heading);
|
|
38
|
+
margin-top: var(--lumina-space-md);
|
|
39
|
+
margin-bottom: var(--lumina-space-sm);
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
:deep(p) {
|
|
43
|
+
color: var(--lumina-color-text);
|
|
44
|
+
line-height: var(--lumina-leading-relaxed);
|
|
45
|
+
margin-bottom: var(--lumina-space-md);
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
:deep(a) {
|
|
49
|
+
color: var(--lumina-color-primary);
|
|
50
|
+
text-decoration: none;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
:deep(a:hover) {
|
|
54
|
+
text-decoration: underline;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
:deep(ul), :deep(ol) {
|
|
58
|
+
margin-left: var(--lumina-space-lg);
|
|
59
|
+
margin-bottom: var(--lumina-space-md);
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
:deep(li) {
|
|
63
|
+
margin-bottom: var(--lumina-space-xs);
|
|
64
|
+
}
|
|
65
|
+
</style>
|
|
@@ -1,54 +1,81 @@
|
|
|
1
|
-
<template>
|
|
2
|
-
<component :is="href ? 'a' : 'div'" :href="href || undefined" :target="href ? (target || '_blank') : undefined"
|
|
3
|
-
:rel="href ? 'noopener noreferrer' : undefined"
|
|
4
|
-
:class="[containerClass, customClass, href && 'cursor-pointer hover:opacity-90 transition-opacity']"
|
|
5
|
-
:style="containerStyle">
|
|
6
|
-
<img :src="src" :alt="alt || ''" :class="[
|
|
7
|
-
'w-full h-full transition-opacity duration-700',
|
|
8
|
-
|
|
9
|
-
roundedClass,
|
|
10
|
-
isLoaded ? 'opacity-100' : 'opacity-0'
|
|
11
|
-
]" @load="onLoad" @error="onError" />
|
|
12
|
-
</component>
|
|
13
|
-
</template>
|
|
14
|
-
|
|
15
|
-
<script setup lang="ts">
|
|
16
|
-
import { ref, computed } from 'vue';
|
|
17
|
-
|
|
18
|
-
const props = defineProps<{
|
|
19
|
-
src: string;
|
|
20
|
-
alt?: string;
|
|
21
|
-
fill?: boolean;
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
const
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
}
|
|
54
|
-
|
|
1
|
+
<template>
|
|
2
|
+
<component :is="href ? 'a' : 'div'" :href="href || undefined" :target="href ? (target || '_blank') : undefined"
|
|
3
|
+
:rel="href ? 'noopener noreferrer' : undefined"
|
|
4
|
+
:class="[containerClass, customClass, href && 'cursor-pointer hover:opacity-90 transition-opacity']"
|
|
5
|
+
:style="containerStyle">
|
|
6
|
+
<img :src="src" :alt="alt || ''" :class="[
|
|
7
|
+
'w-full h-full transition-opacity duration-700',
|
|
8
|
+
objectFitClass,
|
|
9
|
+
roundedClass,
|
|
10
|
+
isLoaded ? 'opacity-100' : 'opacity-0'
|
|
11
|
+
]" :style="imageStyle" @load="onLoad" @error="onError" />
|
|
12
|
+
</component>
|
|
13
|
+
</template>
|
|
14
|
+
|
|
15
|
+
<script setup lang="ts">
|
|
16
|
+
import { ref, computed } from 'vue';
|
|
17
|
+
|
|
18
|
+
const props = defineProps<{
|
|
19
|
+
src: string;
|
|
20
|
+
alt?: string;
|
|
21
|
+
fill?: boolean;
|
|
22
|
+
fit?: 'cover' | 'contain' | 'fill' | 'none' | 'scale-down';
|
|
23
|
+
position?: string;
|
|
24
|
+
rounded?: string;
|
|
25
|
+
containerClass?: any;
|
|
26
|
+
containerStyle?: any;
|
|
27
|
+
href?: string;
|
|
28
|
+
target?: '_blank' | '_self';
|
|
29
|
+
class?: any;
|
|
30
|
+
style?: Record<string, string>;
|
|
31
|
+
}>();
|
|
32
|
+
|
|
33
|
+
const isLoaded = ref(false);
|
|
34
|
+
const customClass = computed(() => props.class || '');
|
|
35
|
+
|
|
36
|
+
const onLoad = () => {
|
|
37
|
+
isLoaded.value = true;
|
|
38
|
+
};
|
|
39
|
+
|
|
40
|
+
const onError = (e: any) => {
|
|
41
|
+
isLoaded.value = true;
|
|
42
|
+
e.target.src = 'https://placehold.co/800x600/1a1a1a/666?text=Image+Not+Found';
|
|
43
|
+
};
|
|
44
|
+
|
|
45
|
+
const objectFitClass = computed(() => {
|
|
46
|
+
if (props.fit) {
|
|
47
|
+
const fitMap: Record<string, string> = {
|
|
48
|
+
'cover': 'object-cover',
|
|
49
|
+
'contain': 'object-contain',
|
|
50
|
+
'fill': 'object-fill',
|
|
51
|
+
'none': 'object-none',
|
|
52
|
+
'scale-down': 'object-scale-down',
|
|
53
|
+
};
|
|
54
|
+
return fitMap[props.fit] || 'object-cover';
|
|
55
|
+
}
|
|
56
|
+
return props.fill !== false ? 'object-cover' : 'object-contain';
|
|
57
|
+
});
|
|
58
|
+
|
|
59
|
+
const imageStyle = computed(() => {
|
|
60
|
+
const style: Record<string, string> = {
|
|
61
|
+
...props.style,
|
|
62
|
+
};
|
|
63
|
+
if (props.position) {
|
|
64
|
+
style.objectPosition = props.position;
|
|
65
|
+
}
|
|
66
|
+
return style;
|
|
67
|
+
});
|
|
68
|
+
|
|
69
|
+
const roundedClass = computed(() => {
|
|
70
|
+
if (props.fill !== false && !props.rounded) return '';
|
|
71
|
+
const map: Record<string, string> = {
|
|
72
|
+
'none': 'rounded-none',
|
|
73
|
+
'sm': 'rounded-sm',
|
|
74
|
+
'md': 'rounded-md',
|
|
75
|
+
'lg': 'rounded-lg',
|
|
76
|
+
'xl': 'rounded-xl',
|
|
77
|
+
'full': 'rounded-full',
|
|
78
|
+
};
|
|
79
|
+
return map[props.rounded || 'lg'] || 'rounded-lg';
|
|
80
|
+
});
|
|
81
|
+
</script>
|