animot-presenter 0.1.2 → 0.1.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.
@@ -3,20 +3,49 @@ import './styles/presenter.css';
3
3
  declare class AnimotPresenterElement extends HTMLElement {
4
4
  static get observedAttributes(): string[];
5
5
  private _component;
6
+ private _pendingRemount;
7
+ private _src;
6
8
  private _data;
9
+ private _autoplay;
10
+ private _loop;
11
+ private _controls;
12
+ private _arrows;
13
+ private _progress;
14
+ private _keyboard;
15
+ private _duration;
16
+ private _startSlide;
7
17
  private _onslidechange;
8
18
  private _oncomplete;
9
- private _mounted;
10
- private _props;
11
- set data(value: AnimotProject | null);
19
+ get src(): string | null;
20
+ set src(v: string | null);
12
21
  get data(): AnimotProject | null;
22
+ set data(v: AnimotProject | null);
23
+ get autoplay(): boolean;
24
+ set autoplay(v: boolean);
25
+ get loop(): boolean;
26
+ set loop(v: boolean);
27
+ get controls(): boolean;
28
+ set controls(v: boolean);
29
+ get arrows(): boolean;
30
+ set arrows(v: boolean);
31
+ get progress(): boolean;
32
+ set progress(v: boolean);
33
+ get keyboard(): boolean;
34
+ set keyboard(v: boolean);
35
+ get duration(): number | undefined;
36
+ set duration(v: number | undefined);
37
+ get startSlide(): number | undefined;
38
+ set startSlide(v: number | undefined);
39
+ get onslidechange(): ((index: number, total: number) => void) | null;
13
40
  set onslidechange(fn: ((index: number, total: number) => void) | null);
41
+ get oncomplete(): (() => void) | null;
14
42
  set oncomplete(fn: (() => void) | null);
15
43
  connectedCallback(): void;
16
44
  disconnectedCallback(): void;
17
45
  attributeChangedCallback(): void;
18
46
  private _buildProps;
19
- private _updateProps;
47
+ private _cancelPendingRemount;
48
+ private _scheduleRemount;
20
49
  private _mount;
21
50
  private _unmount;
22
51
  next(): void;
@@ -6,60 +6,86 @@ import { mount, unmount } from 'svelte';
6
6
  import AnimotPresenter from './AnimotPresenter.svelte';
7
7
  // Inject floating animation CSS into the document (once)
8
8
  import './styles/presenter.css';
9
- const BOOLEAN_ATTRS = new Set(['autoplay', 'loop', 'controls', 'arrows', 'progress', 'keyboard']);
9
+ const BOOLEAN_PROPS = ['autoplay', 'loop', 'controls', 'arrows', 'progress', 'keyboard'];
10
10
  class AnimotPresenterElement extends HTMLElement {
11
11
  static get observedAttributes() {
12
12
  return ['src', 'autoplay', 'loop', 'controls', 'arrows', 'progress', 'keyboard', 'duration', 'start-slide'];
13
13
  }
14
14
  _component = null;
15
+ _pendingRemount = null;
16
+ // Property backing stores — React 19 sets these as properties, not attributes
17
+ _src = null;
15
18
  _data = null;
19
+ _autoplay = false;
20
+ _loop = false;
21
+ _controls = false;
22
+ _arrows = false;
23
+ _progress = false;
24
+ _keyboard = false;
25
+ _duration = undefined;
26
+ _startSlide = undefined;
16
27
  _onslidechange = null;
17
28
  _oncomplete = null;
18
- _mounted = false;
19
- // Reactive props object that Svelte reads from
20
- _props = $state({});
21
- set data(value) {
22
- this._data = value;
23
- this._updateProps();
24
- }
25
- get data() {
26
- return this._data;
27
- }
29
+ // --- Property getters/setters (React 19 sets these directly) ---
30
+ get src() { return this._src ?? this.getAttribute('src'); }
31
+ set src(v) { this._src = v; this._scheduleRemount(); }
32
+ get data() { return this._data; }
33
+ set data(v) { this._data = v; this._scheduleRemount(); }
34
+ get autoplay() { return this._autoplay || this.hasAttribute('autoplay'); }
35
+ set autoplay(v) { this._autoplay = !!v; this._scheduleRemount(); }
36
+ get loop() { return this._loop || this.hasAttribute('loop'); }
37
+ set loop(v) { this._loop = !!v; this._scheduleRemount(); }
38
+ get controls() { return this._controls || this.hasAttribute('controls'); }
39
+ set controls(v) { this._controls = !!v; this._scheduleRemount(); }
40
+ get arrows() { return this._arrows || this.hasAttribute('arrows'); }
41
+ set arrows(v) { this._arrows = !!v; this._scheduleRemount(); }
42
+ get progress() { return this._progress || this.hasAttribute('progress'); }
43
+ set progress(v) { this._progress = !!v; this._scheduleRemount(); }
44
+ get keyboard() { return this._keyboard || this.hasAttribute('keyboard'); }
45
+ set keyboard(v) { this._keyboard = !!v; this._scheduleRemount(); }
46
+ get duration() { return this._duration; }
47
+ set duration(v) { this._duration = v; this._scheduleRemount(); }
48
+ get startSlide() { return this._startSlide; }
49
+ set startSlide(v) { this._startSlide = v; this._scheduleRemount(); }
50
+ get onslidechange() { return this._onslidechange; }
28
51
  set onslidechange(fn) {
29
52
  this._onslidechange = fn;
30
- this._updateProps();
53
+ this._scheduleRemount();
31
54
  }
55
+ get oncomplete() { return this._oncomplete; }
32
56
  set oncomplete(fn) {
33
57
  this._oncomplete = fn;
34
- this._updateProps();
58
+ this._scheduleRemount();
35
59
  }
36
60
  connectedCallback() {
37
- this._mounted = true;
38
61
  this._mount();
39
62
  }
40
63
  disconnectedCallback() {
41
- this._mounted = false;
64
+ this._cancelPendingRemount();
42
65
  this._unmount();
43
66
  }
44
67
  attributeChangedCallback() {
45
- // Only update props if already mounted don't remount
46
- if (this._mounted && this._component) {
47
- this._updateProps();
68
+ if (this.isConnected && this._component) {
69
+ this._scheduleRemount();
48
70
  }
49
71
  }
50
72
  _buildProps() {
51
73
  const props = {};
52
- const src = this.getAttribute('src');
74
+ // Read from property first (React 19), fall back to attribute (vanilla HTML)
75
+ const src = this._src ?? this.getAttribute('src');
53
76
  if (src)
54
77
  props.src = src;
55
- for (const attr of BOOLEAN_ATTRS) {
56
- props[attr] = this.hasAttribute(attr);
57
- }
58
- const duration = this.getAttribute('duration');
59
- if (duration)
78
+ props.autoplay = this.autoplay;
79
+ props.loop = this.loop;
80
+ props.controls = this.controls;
81
+ props.arrows = this.arrows;
82
+ props.progress = this.progress;
83
+ props.keyboard = this.keyboard;
84
+ const duration = this._duration ?? this.getAttribute('duration');
85
+ if (duration != null)
60
86
  props.duration = Number(duration);
61
- const startSlide = this.getAttribute('start-slide');
62
- if (startSlide)
87
+ const startSlide = this._startSlide ?? this.getAttribute('start-slide');
88
+ if (startSlide != null)
63
89
  props.startSlide = Number(startSlide);
64
90
  if (this._data)
65
91
  props.data = this._data;
@@ -81,30 +107,41 @@ class AnimotPresenterElement extends HTMLElement {
81
107
  }
82
108
  return props;
83
109
  }
84
- _updateProps() {
85
- const newProps = this._buildProps();
86
- // Update the reactive props object in place so Svelte picks up changes
87
- for (const key of Object.keys(newProps)) {
88
- this._props[key] = newProps[key];
110
+ _cancelPendingRemount() {
111
+ if (this._pendingRemount) {
112
+ clearTimeout(this._pendingRemount);
113
+ this._pendingRemount = null;
89
114
  }
90
115
  }
116
+ _scheduleRemount() {
117
+ if (!this.isConnected)
118
+ return;
119
+ this._cancelPendingRemount();
120
+ this._pendingRemount = setTimeout(() => {
121
+ this._pendingRemount = null;
122
+ this._unmount();
123
+ this._mount();
124
+ }, 0);
125
+ }
91
126
  _mount() {
92
127
  if (this._component)
93
128
  return;
94
129
  if (!this.style.display) {
95
130
  this.style.display = 'block';
96
131
  }
97
- // Build initial props
98
- Object.assign(this._props, this._buildProps());
132
+ if (!this.style.height && !this.getAttribute('style')?.includes('height')) {
133
+ this.style.height = '100%';
134
+ }
99
135
  this._component = mount(AnimotPresenter, {
100
136
  target: this,
101
- props: this._props
137
+ props: this._buildProps()
102
138
  });
103
139
  }
104
140
  _unmount() {
105
141
  if (this._component) {
106
142
  unmount(this._component);
107
143
  this._component = null;
144
+ this.innerHTML = '';
108
145
  }
109
146
  }
110
147
  next() {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "animot-presenter",
3
- "version": "0.1.2",
3
+ "version": "0.1.3",
4
4
  "description": "Embed animated presentations anywhere. Works with vanilla JS, React, Vue, Angular, Svelte, and any frontend framework. Morphing animations, code highlighting, charts, particles, and more.",
5
5
  "type": "module",
6
6
  "svelte": "./dist/index.js",