lumina-slides 9.0.1 → 9.0.3

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.
@@ -54,6 +54,29 @@
54
54
  class="px-3 py-1.5 rounded bg-blue-600 text-white text-sm font-medium hover:bg-blue-500 disabled:opacity-50 disabled:cursor-not-allowed"
55
55
  @click="onTimelinePlay">Play</button>
56
56
  </div>
57
+
58
+ <!-- Template Tags: edit engine.data and see slides update (layout-template-tags example) -->
59
+ <div v-if="showTemplateTagsUI" class="fixed bottom-0 left-0 right-0 z-[90] flex items-center gap-4 px-4 py-3 bg-black/90 border-t border-white/10 backdrop-blur flex-wrap">
60
+ <span class="text-white/50 text-xs uppercase tracking-wider">engine.data</span>
61
+ <label class="flex items-center gap-2 text-sm text-white/80">
62
+ Product
63
+ <input v-model="templateProduct" type="text" placeholder="product"
64
+ class="w-28 px-2 py-1 rounded bg-white/10 border border-white/20 text-white text-sm focus:border-blue-500 focus:outline-none"
65
+ @input="onTemplateDataInput('product', ($event.target as HTMLInputElement).value)" />
66
+ </label>
67
+ <label class="flex items-center gap-2 text-sm text-white/80">
68
+ Version
69
+ <input v-model="templateVersion" type="text" placeholder="version"
70
+ class="w-24 px-2 py-1 rounded bg-white/10 border border-white/20 text-white text-sm focus:border-blue-500 focus:outline-none"
71
+ @input="onTemplateDataInput('version', ($event.target as HTMLInputElement).value)" />
72
+ </label>
73
+ <label class="flex items-center gap-2 text-sm text-white/80">
74
+ User
75
+ <input v-model="templateUser" type="text" placeholder="user"
76
+ class="w-28 px-2 py-1 rounded bg-white/10 border border-white/20 text-white text-sm focus:border-blue-500 focus:outline-none"
77
+ @input="onTemplateDataInput('user', ($event.target as HTMLInputElement).value)" />
78
+ </label>
79
+ </div>
57
80
  </div>
58
81
  </template>
59
82
 
@@ -85,16 +108,33 @@ const timelineCancelRef = ref<(() => void) | null>(null);
85
108
  const timelineIntervalRef = ref<ReturnType<typeof setInterval> | null>(null);
86
109
 
87
110
  const showTimelineUI = computed(() => {
88
- const id = route.params.id as string;
111
+ const p = route.params.id;
112
+ const id = typeof p === 'string' ? p : (Array.isArray(p) && p[0] ? p[0] : '');
89
113
  if (id !== 'animation-timeline') return false;
90
- const slide = loadedDeck.value?.slides[currentSlideIndex.value] as { timelineTracks?: unknown } | undefined;
114
+ const slide = loadedDeck.value?.slides[currentSlideIndex.value];
91
115
  return !!slide?.timelineTracks;
92
116
  });
93
117
 
118
+ // Template Tags example: edit engine.data and see slides update
119
+ const templateProduct = ref('Lumina');
120
+ const templateVersion = ref('2.0');
121
+ const templateUser = ref('World');
122
+ const showTemplateTagsUI = computed(() => {
123
+ const p = route.params.id;
124
+ const id = typeof p === 'string' ? p : (Array.isArray(p) && p[0] ? p[0] : '');
125
+ return id === 'layout-template-tags';
126
+ });
127
+ function onTemplateDataInput(key: string, value: string) {
128
+ engineRef.value?.data.set(key, value);
129
+ }
130
+
94
131
  function onTimelineInput(e: Event) {
95
- const v = parseFloat((e.target as HTMLInputElement).value);
96
- timelineProgress.value = v;
97
- engineRef.value?.seekTo(v / 100);
132
+ const t = e.target;
133
+ if (t instanceof HTMLInputElement) {
134
+ const v = parseFloat(t.value);
135
+ timelineProgress.value = v;
136
+ engineRef.value?.seekTo(v / 100);
137
+ }
98
138
  }
99
139
 
100
140
  function onTimelinePlay() {
@@ -163,7 +203,7 @@ async function onLoginAndDuplicate() {
163
203
  await loginWithGoogle();
164
204
  showLoginModal.value = false;
165
205
  await duplicateAndEdit();
166
- } catch (e: unknown) {
206
+ } catch (e) {
167
207
  const msg = e instanceof Error ? e.message : 'Sign-in failed. Please try again.';
168
208
  loginError.value = msg;
169
209
  } finally {
@@ -176,7 +216,8 @@ onMounted(async () => {
176
216
  initFirebase();
177
217
  } catch (e) { }
178
218
 
179
- const deckId = route.params.id as string;
219
+ const p = route.params.id;
220
+ const deckId = typeof p === 'string' ? p : (Array.isArray(p) && p[0] ? p[0] : '');
180
221
  if (!deckId) return;
181
222
 
182
223
  try {
@@ -208,7 +249,7 @@ onMounted(async () => {
208
249
  showControls: true,
209
250
  showProgressBar: true
210
251
  },
211
- theme: (deckData as Deck & { theme?: string }).theme || 'default'
252
+ theme: deckData.theme || 'default'
212
253
  });
213
254
  engineRef.value = engine;
214
255
 
@@ -227,29 +268,6 @@ onMounted(async () => {
227
268
  });
228
269
  }
229
270
 
230
- if (deckId === 'animation-presets') {
231
- const presets = ['fadeUp', 'scaleIn', 'spring'] as const;
232
- engine.on('ready', () => engine?.revealInSequence(0, { preset: presets[0], delayMs: 450 }));
233
- engine.on('slideChange', ({ index }) => {
234
- engine?.revealInSequence(index, { preset: presets[index] ?? 'fadeUp', delayMs: 450 });
235
- });
236
- }
237
-
238
- if (deckId === 'animation-stagger') {
239
- const modes = ['center-out', 'wave', 'random'] as const;
240
- engine.on('ready', () =>
241
- engine?.revealInSequence(0, { preset: 'scaleIn', staggerMode: modes[0], delayMs: 380 })
242
- );
243
- engine.on('slideChange', ({ index }) => {
244
- engine?.revealInSequence(index, {
245
- preset: 'scaleIn',
246
- staggerMode: modes[index] ?? 'sequential',
247
- randomSeed: index,
248
- delayMs: 380
249
- });
250
- });
251
- }
252
-
253
271
  if (deckId === 'animation-timeline') {
254
272
  engine.on('ready', () => {
255
273
  engine?.seekTo(0);
@@ -270,6 +288,12 @@ onMounted(async () => {
270
288
  });
271
289
  }
272
290
 
291
+ if (deckId === 'layout-template-tags') {
292
+ engine.data.set('product', templateProduct.value);
293
+ engine.data.set('version', templateVersion.value);
294
+ engine.data.set('user', templateUser.value);
295
+ }
296
+
273
297
  engine.load(deckData);
274
298
  } catch (error) {
275
299
  console.error("Failed to load deck:", error);