lumina-slides 9.0.2 → 9.0.4
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 +4692 -4632
- package/dist/lumina-slides.umd.cjs +120 -120
- package/dist/style.css +1 -1
- package/package.json +1 -1
- package/src/components/layouts/LayoutFeatures.vue +7 -5
- package/src/components/layouts/LayoutSteps.vue +7 -5
- package/src/components/site/SiteDocs.vue +140 -95
- package/src/core/Lumina.ts +30 -8
- package/src/core/elementResolver.ts +40 -8
- package/src/core/types.ts +3 -2
- package/src/index.ts +1 -1
package/src/core/Lumina.ts
CHANGED
|
@@ -433,28 +433,50 @@ export class Lumina {
|
|
|
433
433
|
return createElementController(this.store, this, idOrSlide);
|
|
434
434
|
}
|
|
435
435
|
|
|
436
|
+
/**
|
|
437
|
+
* Returns the element at the given path on the current slide. Shorthand for
|
|
438
|
+
* engine.element(engine.currentSlideIndex, path). Use when you don't need the slide index.
|
|
439
|
+
*
|
|
440
|
+
* @param path - Logical path (e.g. "title", "features.0", ["elements", 0, "elements", 1]).
|
|
441
|
+
* @returns ElementController for that element.
|
|
442
|
+
*
|
|
443
|
+
* @example
|
|
444
|
+
* engine.elementInCurrent("title").show();
|
|
445
|
+
* engine.elementInCurrent("features.0").animate({ from: { opacity: 0 }, to: { opacity: 1 }, duration: 0.5 });
|
|
446
|
+
*
|
|
447
|
+
* @see element
|
|
448
|
+
* @see elements
|
|
449
|
+
*/
|
|
450
|
+
public elementInCurrent(path: string | ElementPath): ElementController {
|
|
451
|
+
const i = this.store.state.currentIndex ?? 0;
|
|
452
|
+
return this.element(i, path);
|
|
453
|
+
}
|
|
454
|
+
|
|
436
455
|
/**
|
|
437
456
|
* Returns all element ids for a slide. Use to discover which ids exist (e.g. for
|
|
438
457
|
* meta.initialElementState, or to iterate and control elements). Each id can be passed to
|
|
439
458
|
* engine.element(id). Uses the same path→id logic as element(slideIndex, path); ids follow
|
|
440
|
-
* resolveId (explicit id, slide.ids, or elemId(slideIndex, ...path)).
|
|
459
|
+
* resolveId (explicit id, slide.ids, or slide.id / elemId(slideIndex, ...path) as fallback).
|
|
441
460
|
*
|
|
442
|
-
* @param slideIndex - Zero-based slide index. If out of range or deck not loaded, returns [].
|
|
443
|
-
* @returns Array of id strings (e.g. ["s0-slide","s0-tag","s0-title","s0-subtitle"]
|
|
461
|
+
* @param slideIndex - Zero-based slide index. Omit to use the current slide. If out of range or deck not loaded, returns [].
|
|
462
|
+
* @returns Array of id strings (e.g. ["s0-slide","s0-tag","s0-title","s0-subtitle"] or ["intro-slide","intro-tag",...] when slide.id is set).
|
|
444
463
|
*
|
|
445
464
|
* @example
|
|
446
|
-
*
|
|
447
|
-
*
|
|
465
|
+
* engine.elements(); // current slide
|
|
466
|
+
* engine.elements(0);
|
|
467
|
+
* engine.elements().forEach(id => { if (id.endsWith('-title')) engine.element(id).hide(); });
|
|
448
468
|
*
|
|
449
469
|
* @see element
|
|
470
|
+
* @see elementInCurrent
|
|
450
471
|
* @see getElementIds
|
|
451
472
|
* @see resolveId
|
|
452
473
|
* @see DeckMeta.initialElementState
|
|
453
474
|
*/
|
|
454
|
-
public elements(slideIndex
|
|
455
|
-
const
|
|
475
|
+
public elements(slideIndex?: number): string[] {
|
|
476
|
+
const i = slideIndex ?? this.store.state.currentIndex ?? 0;
|
|
477
|
+
const slide = this.store.state.deck?.slides[i];
|
|
456
478
|
if (!slide) return [];
|
|
457
|
-
return getElementIds(slide,
|
|
479
|
+
return getElementIds(slide, i);
|
|
458
480
|
}
|
|
459
481
|
|
|
460
482
|
/**
|
|
@@ -71,7 +71,8 @@ export function parsePath(input: string | ElementPath): ElementPath {
|
|
|
71
71
|
* 1. Path [] or ['slide'] → slide.id or elemId(slideIndex, 'slide').
|
|
72
72
|
* 2. If the value at path is an object with string `id` → use it (e.g. feature.id, node.id).
|
|
73
73
|
* 3. If slide.ids[pathToKey(path)] exists → use it (supports compound keys: 'tag', 'features.0', 'elements.0.elements.1').
|
|
74
|
-
* 4. Otherwise →
|
|
74
|
+
* 4. Otherwise → if slide.id is set, "{slide.id}-{path}"; else elemId(slideIndex, ...path)
|
|
75
|
+
* (e.g. "intro-tag" with slide.id "intro", or "s0-tag" when no slide.id).
|
|
75
76
|
*
|
|
76
77
|
* @param slide - The slide data.
|
|
77
78
|
* @param slideIndex - Zero-based slide index (for elemId fallback).
|
|
@@ -99,6 +100,11 @@ export function resolveId(
|
|
|
99
100
|
if (key && slideAny?.ids?.[key]) {
|
|
100
101
|
return slideAny.ids[key];
|
|
101
102
|
}
|
|
103
|
+
// Fallback: use slide.id as namespace when present, so IDs stay stable when slides are
|
|
104
|
+
// inserted, removed or reordered. Otherwise s{N}-{path} (same as before).
|
|
105
|
+
if (slideAny?.id != null && slideAny.id !== '') {
|
|
106
|
+
return `${slideAny.id}-${path.map(String).join('-')}`;
|
|
107
|
+
}
|
|
102
108
|
return elemId(slideIndex, ...path);
|
|
103
109
|
}
|
|
104
110
|
|
|
@@ -107,22 +113,38 @@ export type PathGenerator = (slide: Readonly<BaseSlideData>) => ElementPath[];
|
|
|
107
113
|
|
|
108
114
|
/** Map of slide.type → path generator. Extend to support new layouts. */
|
|
109
115
|
const PATH_GENERATORS: Record<string, PathGenerator> = {
|
|
110
|
-
statement: () =>
|
|
116
|
+
statement: (s) => {
|
|
117
|
+
const paths: ElementPath[] = [['title']];
|
|
118
|
+
if (getValueAt(s, ['tag'])) paths.unshift(['tag']);
|
|
119
|
+
if (getValueAt(s, ['subtitle'])) paths.push(['subtitle']);
|
|
120
|
+
return paths;
|
|
121
|
+
},
|
|
111
122
|
features: (s) => {
|
|
112
123
|
const arr = getValueAt(s, ['features']);
|
|
113
124
|
const list = Array.isArray(arr) ? arr : [];
|
|
114
|
-
|
|
125
|
+
const paths: ElementPath[] = [['header'], ['title']];
|
|
126
|
+
if (getValueAt(s, ['description'])) paths.push(['description']);
|
|
127
|
+
return [...paths, ...list.map((_: unknown, i: number) => ['features', i] as ElementPath)];
|
|
128
|
+
},
|
|
129
|
+
half: (s) => {
|
|
130
|
+
const paths: ElementPath[] = [['media'], ['title'], ['paragraphs']];
|
|
131
|
+
if (getValueAt(s, ['tag'])) paths.splice(1, 0, ['tag']); // after media, before title
|
|
132
|
+
if (getValueAt(s, ['cta'])) paths.push(['cta']);
|
|
133
|
+
return paths;
|
|
115
134
|
},
|
|
116
|
-
half: () => [['media'], ['tag'], ['title'], ['paragraphs'], ['cta']],
|
|
117
135
|
timeline: (s) => {
|
|
118
136
|
const arr = getValueAt(s, ['timeline']);
|
|
119
137
|
const list = Array.isArray(arr) ? arr : [];
|
|
120
|
-
|
|
138
|
+
const paths: ElementPath[] = [['title']];
|
|
139
|
+
if (getValueAt(s, ['subtitle'])) paths.push(['subtitle']);
|
|
140
|
+
return [...paths, ...list.map((_: unknown, i: number) => ['timeline', i] as ElementPath)];
|
|
121
141
|
},
|
|
122
142
|
steps: (s) => {
|
|
123
143
|
const arr = getValueAt(s, ['steps']);
|
|
124
144
|
const list = Array.isArray(arr) ? arr : [];
|
|
125
|
-
|
|
145
|
+
const paths: ElementPath[] = [['header'], ['title']];
|
|
146
|
+
if (getValueAt(s, ['subtitle'])) paths.push(['subtitle']);
|
|
147
|
+
return [...paths, ...list.map((_: unknown, i: number) => ['steps', i] as ElementPath)];
|
|
126
148
|
},
|
|
127
149
|
flex: (s) => {
|
|
128
150
|
const paths: ElementPath[] = [];
|
|
@@ -137,7 +159,13 @@ const PATH_GENERATORS: Record<string, PathGenerator> = {
|
|
|
137
159
|
});
|
|
138
160
|
return paths;
|
|
139
161
|
},
|
|
140
|
-
chart: () =>
|
|
162
|
+
chart: (s) => {
|
|
163
|
+
const paths: ElementPath[] = [];
|
|
164
|
+
if (getValueAt(s, ['title'])) paths.push(['title']);
|
|
165
|
+
if (getValueAt(s, ['subtitle'])) paths.push(['subtitle']);
|
|
166
|
+
paths.push(['chart']);
|
|
167
|
+
return paths;
|
|
168
|
+
},
|
|
141
169
|
diagram: (s) => {
|
|
142
170
|
const p: ElementPath[] = [];
|
|
143
171
|
const nodes = getValueAt(s, ['nodes']);
|
|
@@ -147,7 +175,11 @@ const PATH_GENERATORS: Record<string, PathGenerator> = {
|
|
|
147
175
|
return p;
|
|
148
176
|
},
|
|
149
177
|
custom: () => [],
|
|
150
|
-
video: () =>
|
|
178
|
+
video: (s) => {
|
|
179
|
+
const paths: ElementPath[] = [['video']];
|
|
180
|
+
if (getValueAt(s, ['title'])) paths.push(['title']);
|
|
181
|
+
return paths;
|
|
182
|
+
},
|
|
151
183
|
free: (s) => {
|
|
152
184
|
const arr = getValueAt(s, ['elements']);
|
|
153
185
|
const list = Array.isArray(arr) ? arr : [];
|
package/src/core/types.ts
CHANGED
|
@@ -448,8 +448,8 @@ export type TimelineKeyframes = Record<string, TimelineKeyframeState>;
|
|
|
448
448
|
export type TimelineTracks = Record<string, TimelineKeyframes>;
|
|
449
449
|
|
|
450
450
|
/**
|
|
451
|
-
* Fluent API to control one slide element in real time. Returned by `engine.element(id)
|
|
452
|
-
*
|
|
451
|
+
* Fluent API to control one slide element in real time. Returned by `engine.element(id)`,
|
|
452
|
+
* `engine.element(slideIndex, path)`, and `engine.elementInCurrent(path)`. All methods return `this` for chaining.
|
|
453
453
|
*
|
|
454
454
|
* Use for: starting with an empty slide and revealing items in order, hiding highlights,
|
|
455
455
|
* animating entrances on demand, or syncing with voice/agent.
|
|
@@ -462,6 +462,7 @@ export type TimelineTracks = Record<string, TimelineKeyframes>;
|
|
|
462
462
|
* engine.element(0, 'subtitle').show();
|
|
463
463
|
*
|
|
464
464
|
* @see Lumina.element
|
|
465
|
+
* @see Lumina.elementInCurrent
|
|
465
466
|
* @see Lumina.elements
|
|
466
467
|
* @see ElementState
|
|
467
468
|
* @see AnimateOptions
|
package/src/index.ts
CHANGED
|
@@ -10,7 +10,7 @@
|
|
|
10
10
|
* **Deck:** `{ meta: { title, initialElementState?, elementControl?, effects? }, slides: [...] }`
|
|
11
11
|
* Slide types: statement, features, half, timeline, steps, flex, chart, diagram, custom, video.
|
|
12
12
|
*
|
|
13
|
-
* **Element control:** `engine.element(id)
|
|
13
|
+
* **Element control:** `engine.element(id)`, `engine.element(slideIndex, path)`, or `engine.elementInCurrent(path)` → ElementController:
|
|
14
14
|
* `.show()`, `.hide()`, `.toggle()`, `.opacity(n)`, `.transform(s)`, `.animate({ preset?, from?, to?, duration?, ease? })`.
|
|
15
15
|
* Presets: fadeUp, fadeIn, scaleIn, slideLeft, slideRight, zoomIn, blurIn, spring, drop, fadeOut. `to` optional when using preset.
|
|
16
16
|
* Ids: `engine.elements(slideIndex)` or `s{N}-{path}` (e.g. s0-tag, s1-features-0). `meta.initialElementState`:
|