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.
Files changed (35) hide show
  1. package/dist/lumina-slides.js +21984 -19455
  2. package/dist/lumina-slides.umd.cjs +223 -223
  3. package/dist/style.css +1 -1
  4. package/package.json +3 -1
  5. package/src/components/LandingPage.vue +1 -1
  6. package/src/components/LuminaDeck.vue +237 -232
  7. package/src/components/base/LuminaElement.vue +2 -0
  8. package/src/components/layouts/LayoutFeatures.vue +123 -123
  9. package/src/components/layouts/LayoutFlex.vue +212 -172
  10. package/src/components/layouts/LayoutStatement.vue +5 -2
  11. package/src/components/layouts/LayoutSteps.vue +108 -108
  12. package/src/components/parts/FlexHtml.vue +65 -0
  13. package/src/components/parts/FlexImage.vue +81 -54
  14. package/src/components/site/SiteDocs.vue +3313 -3182
  15. package/src/components/site/SiteExamples.vue +66 -66
  16. package/src/components/studio/EditorLayoutChart.vue +18 -0
  17. package/src/components/studio/EditorLayoutCustom.vue +18 -0
  18. package/src/components/studio/EditorLayoutVideo.vue +18 -0
  19. package/src/components/studio/LuminaStudioEmbed.vue +68 -0
  20. package/src/components/studio/StudioEmbedRoot.vue +19 -0
  21. package/src/components/studio/StudioInspector.vue +1113 -7
  22. package/src/components/studio/StudioSettings.vue +658 -7
  23. package/src/components/studio/StudioToolbar.vue +20 -2
  24. package/src/composables/useElementState.ts +12 -1
  25. package/src/composables/useFlexLayout.ts +128 -122
  26. package/src/core/Lumina.ts +174 -113
  27. package/src/core/animationConfig.ts +10 -0
  28. package/src/core/elementController.ts +18 -0
  29. package/src/core/elementResolver.ts +4 -2
  30. package/src/core/schema.ts +503 -478
  31. package/src/core/store.ts +465 -465
  32. package/src/core/types.ts +59 -14
  33. package/src/index.ts +2 -2
  34. package/src/utils/templateInterpolation.ts +52 -52
  35. package/src/views/DeckView.vue +313 -313
@@ -1,123 +1,123 @@
1
- <template>
2
- <BaseSlide :data="data" :slide-index="slideIndex">
3
- <div :class="[
4
- 'features-root w-full max-w-full flex flex-col justify-center overflow-x-hidden',
5
- data.sizing === 'container' ? 'min-h-full' : 'min-h-screen'
6
- ]">
7
- <!-- Header: wrapper (header) + title and description as separate controllable elements -->
8
- <LuminaElement :id="headerId" :class="[data.class || '', 'text-center lg:text-left max-w-6xl min-w-0']"
9
- :style="{ marginBottom: 'var(--lumina-space-2xl)' }">
10
- <LuminaElement :id="titleId" tag="h2" class="font-bold break-words" :style="{
11
- fontFamily: 'var(--lumina-font-heading)',
12
- fontSize: data.sizing === 'container' ? 'var(--lumina-text-3xl)' : 'var(--lumina-text-5xl)',
13
- marginBottom: 'var(--lumina-space-md)',
14
- letterSpacing: 'var(--lumina-tracking-tighter)',
15
- color: 'var(--lumina-color-text-safe, var(--lumina-color-text))',
16
- textShadow: '0 2px 10px rgba(0,0,0,0.1)'
17
- }">
18
- {{ data.title }}
19
- </LuminaElement>
20
- <LuminaElement v-if="data.description" :id="descriptionId" tag="p" class="break-words" :style="{
21
- color: 'var(--lumina-color-text-safe, var(--lumina-color-text))',
22
- opacity: 0.9,
23
- fontSize: data.sizing === 'container' ? 'var(--lumina-text-sm)' : 'var(--lumina-text-xl)'
24
- }">
25
- {{ data.description }}
26
- </LuminaElement>
27
- </LuminaElement>
28
-
29
- <!-- Grid -->
30
- <div :class="['features-grid', data.sizing !== 'container' ? 'features-grid--multi' : '']">
31
- <LuminaElement v-for="(feature, i) in data.features" :key="i" :id="featureId(i)"
32
- :class="['glass-panel group min-w-0', feature.class || '']" :style="{
33
- borderRadius: 'var(--lumina-card-radius)',
34
- padding: data.sizing === 'container' ? 'var(--lumina-space-lg)' : 'var(--lumina-card-padding)',
35
- borderTop: '1px solid var(--lumina-color-border-subtle)',
36
- transition: 'all var(--lumina-transition-duration) var(--lumina-transition-easing)'
37
- }">
38
- <!-- Icon -->
39
- <div class="flex items-center justify-center group-hover:scale-110 shrink-0" :style="{
40
- color: 'white',
41
- background: 'linear-gradient(135deg, var(--lumina-color-primary) 0%, var(--lumina-color-secondary) 100%)',
42
- width: data.sizing === 'container' ? 'var(--lumina-space-xl)' : 'var(--lumina-space-2xl)',
43
- height: data.sizing === 'container' ? 'var(--lumina-space-xl)' : 'var(--lumina-space-2xl)',
44
- borderRadius: 'var(--lumina-radius-xl)',
45
- marginBottom: data.sizing === 'container' ? 'var(--lumina-space-md)' : 'var(--lumina-space-lg)',
46
- fontSize: 'var(--lumina-text-xl)',
47
- boxShadow: '0 4px 12px rgba(var(--lumina-color-primary-rgb), 0.3)',
48
- transition: 'all var(--lumina-transition-duration) var(--lumina-transition-easing)'
49
- }">
50
- <i
51
- :class="['ph-thin', (feature.icon || 'star').startsWith('ph-') ? feature.icon : `ph-${feature.icon || 'star'}`]"></i>
52
- </div>
53
- <!-- Title -->
54
- <h3 class="font-bold break-words" :style="{
55
- color: 'var(--lumina-surface-text, var(--lumina-color-text))',
56
- fontSize: data.sizing === 'container' ? 'var(--lumina-text-lg)' : 'var(--lumina-text-2xl)',
57
- marginBottom: 'var(--lumina-space-sm)'
58
- }">
59
- {{ feature.title }}
60
- </h3>
61
- <!-- Description (support both desc and description) -->
62
- <p class="break-words" :style="{
63
- color: 'var(--lumina-color-text-secondary)',
64
- fontSize: data.sizing === 'container' ? 'var(--lumina-text-sm)' : 'var(--lumina-text-base)',
65
- lineHeight: 'var(--lumina-leading-relaxed)',
66
- opacity: 0.8
67
- }">
68
- {{ feature.desc || feature.description || '' }}
69
- </p>
70
- </LuminaElement>
71
- </div>
72
- </div>
73
- </BaseSlide>
74
- </template>
75
-
76
- <script setup lang="ts">
77
- import { computed, inject } from 'vue';
78
- import BaseSlide from '../base/BaseSlide.vue';
79
- import { resolveId } from '../../core/elementResolver';
80
- import { StoreKey } from '../../core/store';
81
- import type { SlideFeatures } from '../../core/types';
82
-
83
- const props = defineProps<{
84
- data: SlideFeatures;
85
- slideIndex?: number;
86
- }>();
87
-
88
- const store = inject(StoreKey);
89
- const slideIndex = computed(() => props.slideIndex ?? store?.state.currentIndex ?? 0);
90
-
91
- const headerId = computed(() => resolveId(props.data, slideIndex.value, ['header']));
92
- const titleId = computed(() => resolveId(props.data, slideIndex.value, ['title']));
93
- const descriptionId = computed(() => resolveId(props.data, slideIndex.value, ['description']));
94
- const featureId = (i: number) => resolveId(props.data, slideIndex.value, ['features', i]);
95
- </script>
96
-
97
- <style scoped>
98
- .features-root {
99
- padding: var(--lumina-space-xl) var(--lumina-space-3xl);
100
- }
101
- @media (max-width: 1023px) {
102
- .features-root { padding-left: var(--lumina-space-xl); padding-right: var(--lumina-space-xl); }
103
- }
104
- @media (max-width: 639px) {
105
- .features-root { padding: var(--lumina-space-lg) var(--lumina-space-md); }
106
- }
107
-
108
- .features-grid {
109
- display: grid;
110
- grid-template-columns: 1fr;
111
- gap: var(--lumina-space-md);
112
- }
113
- .features-grid--multi {
114
- grid-template-columns: repeat(auto-fit, minmax(min(100%, 300px), 1fr));
115
- gap: var(--lumina-space-lg);
116
- }
117
- @media (max-width: 639px) {
118
- .features-grid--multi {
119
- grid-template-columns: 1fr;
120
- gap: var(--lumina-space-md);
121
- }
122
- }
123
- </style>
1
+ <template>
2
+ <BaseSlide :data="data" :slide-index="slideIndex">
3
+ <div :class="[
4
+ 'features-root w-full max-w-full flex flex-col justify-center overflow-x-hidden',
5
+ data.sizing === 'container' ? 'min-h-full' : 'min-h-screen'
6
+ ]">
7
+ <!-- Header: wrapper (header) + title and description as separate controllable elements -->
8
+ <LuminaElement :id="headerId" :class="[data.class || '', 'text-center lg:text-left max-w-6xl min-w-0']"
9
+ :style="{ marginBottom: 'var(--lumina-space-2xl)' }">
10
+ <LuminaElement :id="titleId" tag="h2" class="font-bold break-words" :style="{
11
+ fontFamily: 'var(--lumina-font-heading)',
12
+ fontSize: data.sizing === 'container' ? 'var(--lumina-text-3xl)' : 'var(--lumina-text-5xl)',
13
+ marginBottom: 'var(--lumina-space-md)',
14
+ letterSpacing: 'var(--lumina-tracking-tighter)',
15
+ color: 'var(--lumina-color-text-safe, var(--lumina-color-text))',
16
+ textShadow: '0 2px 10px rgba(0,0,0,0.1)'
17
+ }">
18
+ {{ data.title }}
19
+ </LuminaElement>
20
+ <LuminaElement v-if="data.description" :id="descriptionId" tag="p" class="break-words" :style="{
21
+ color: 'var(--lumina-color-text-safe, var(--lumina-color-text))',
22
+ opacity: 0.9,
23
+ fontSize: data.sizing === 'container' ? 'var(--lumina-text-sm)' : 'var(--lumina-text-xl)'
24
+ }">
25
+ {{ data.description }}
26
+ </LuminaElement>
27
+ </LuminaElement>
28
+
29
+ <!-- Grid -->
30
+ <div :class="['features-grid', data.sizing !== 'container' ? 'features-grid--multi' : '']">
31
+ <LuminaElement v-for="(feature, i) in data.features" :key="i" :id="featureId(i)"
32
+ :class="['glass-panel group min-w-0', feature.class || '']" :style="{
33
+ borderRadius: 'var(--lumina-card-radius)',
34
+ padding: data.sizing === 'container' ? 'var(--lumina-space-lg)' : 'var(--lumina-card-padding)',
35
+ borderTop: '1px solid var(--lumina-color-border-subtle)',
36
+ transition: 'all var(--lumina-transition-duration) var(--lumina-transition-easing)'
37
+ }">
38
+ <!-- Icon -->
39
+ <div class="flex items-center justify-center group-hover:scale-110 shrink-0" :style="{
40
+ color: 'white',
41
+ background: 'linear-gradient(135deg, var(--lumina-color-primary) 0%, var(--lumina-color-secondary) 100%)',
42
+ width: data.sizing === 'container' ? 'var(--lumina-space-xl)' : 'var(--lumina-space-2xl)',
43
+ height: data.sizing === 'container' ? 'var(--lumina-space-xl)' : 'var(--lumina-space-2xl)',
44
+ borderRadius: 'var(--lumina-radius-xl)',
45
+ marginBottom: data.sizing === 'container' ? 'var(--lumina-space-md)' : 'var(--lumina-space-lg)',
46
+ fontSize: 'var(--lumina-text-xl)',
47
+ boxShadow: '0 4px 12px rgba(var(--lumina-color-primary-rgb), 0.3)',
48
+ transition: 'all var(--lumina-transition-duration) var(--lumina-transition-easing)'
49
+ }">
50
+ <i
51
+ :class="['ph-thin', (feature.icon || 'star').startsWith('ph-') ? feature.icon : `ph-${feature.icon || 'star'}`]"></i>
52
+ </div>
53
+ <!-- Title -->
54
+ <h3 class="font-bold break-words" :style="{
55
+ color: 'var(--lumina-surface-text, var(--lumina-color-text))',
56
+ fontSize: data.sizing === 'container' ? 'var(--lumina-text-lg)' : 'var(--lumina-text-2xl)',
57
+ marginBottom: 'var(--lumina-space-sm)'
58
+ }">
59
+ {{ feature.title }}
60
+ </h3>
61
+ <!-- Description (support both desc and description) -->
62
+ <p class="break-words" :style="{
63
+ color: 'var(--lumina-color-text-secondary)',
64
+ fontSize: data.sizing === 'container' ? 'var(--lumina-text-sm)' : 'var(--lumina-text-base)',
65
+ lineHeight: 'var(--lumina-leading-relaxed)',
66
+ opacity: 0.8
67
+ }">
68
+ {{ feature.desc || feature.description || '' }}
69
+ </p>
70
+ </LuminaElement>
71
+ </div>
72
+ </div>
73
+ </BaseSlide>
74
+ </template>
75
+
76
+ <script setup lang="ts">
77
+ import { computed, inject } from 'vue';
78
+ import BaseSlide from '../base/BaseSlide.vue';
79
+ import { resolveId } from '../../core/elementResolver';
80
+ import { StoreKey } from '../../core/store';
81
+ import type { SlideFeatures } from '../../core/types';
82
+
83
+ const props = defineProps<{
84
+ data: SlideFeatures;
85
+ slideIndex?: number;
86
+ }>();
87
+
88
+ const store = inject(StoreKey);
89
+ const slideIndex = computed(() => props.slideIndex ?? store?.state.currentIndex ?? 0);
90
+
91
+ const headerId = computed(() => resolveId(props.data, slideIndex.value, ['header']));
92
+ const titleId = computed(() => resolveId(props.data, slideIndex.value, ['title']));
93
+ const descriptionId = computed(() => resolveId(props.data, slideIndex.value, ['description']));
94
+ const featureId = (i: number) => resolveId(props.data, slideIndex.value, ['features', i]);
95
+ </script>
96
+
97
+ <style scoped>
98
+ .features-root {
99
+ padding: var(--lumina-space-xl) var(--lumina-space-3xl);
100
+ }
101
+ @media (max-width: 1023px) {
102
+ .features-root { padding-left: var(--lumina-space-xl); padding-right: var(--lumina-space-xl); }
103
+ }
104
+ @media (max-width: 639px) {
105
+ .features-root { padding: var(--lumina-space-lg) var(--lumina-space-md); }
106
+ }
107
+
108
+ .features-grid {
109
+ display: grid;
110
+ grid-template-columns: 1fr;
111
+ gap: var(--lumina-space-md);
112
+ }
113
+ .features-grid--multi {
114
+ grid-template-columns: repeat(auto-fit, minmax(min(100%, 300px), 1fr));
115
+ gap: var(--lumina-space-lg);
116
+ }
117
+ @media (max-width: 639px) {
118
+ .features-grid--multi {
119
+ grid-template-columns: 1fr;
120
+ gap: var(--lumina-space-md);
121
+ }
122
+ }
123
+ </style>