@mulsense/xnew 0.1.9 → 0.1.10

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/xnew.mjs CHANGED
@@ -1,99 +1,3 @@
1
- //----------------------------------------------------------------------------------------------------
2
- // ticker
3
- //----------------------------------------------------------------------------------------------------
4
- class Ticker {
5
- constructor(callback) {
6
- const self = this;
7
- this.id = null;
8
- let previous = 0;
9
- ticker();
10
- function ticker() {
11
- const time = Date.now();
12
- const interval = 1000 / 60;
13
- if (time - previous > interval * 0.9) {
14
- callback(time);
15
- previous = time;
16
- }
17
- self.id = requestAnimationFrame(ticker);
18
- }
19
- }
20
- clear() {
21
- if (this.id !== null) {
22
- cancelAnimationFrame(this.id);
23
- this.id = null;
24
- }
25
- }
26
- }
27
- //----------------------------------------------------------------------------------------------------
28
- // timer
29
- //----------------------------------------------------------------------------------------------------
30
- class Timer {
31
- constructor(timeout, transition, delay, loop = false) {
32
- var _a;
33
- this.timeout = timeout;
34
- this.transition = transition;
35
- this.delay = delay;
36
- this.loop = loop;
37
- this.id = null;
38
- this.time = 0.0;
39
- this.offset = 0.0;
40
- this.status = 0;
41
- this.ticker = new Ticker((time) => { var _a; return (_a = this.transition) === null || _a === void 0 ? void 0 : _a.call(this, this.elapsed() / this.delay); });
42
- this.visibilitychange = () => document.hidden === false ? this._start() : this._stop();
43
- document.addEventListener('visibilitychange', this.visibilitychange);
44
- if (this.delay > 0.0) {
45
- (_a = this.transition) === null || _a === void 0 ? void 0 : _a.call(this, 0.0);
46
- }
47
- this.start();
48
- }
49
- clear() {
50
- if (this.id !== null) {
51
- clearTimeout(this.id);
52
- this.id = null;
53
- }
54
- document.removeEventListener('visibilitychange', this.visibilitychange);
55
- this.ticker.clear();
56
- }
57
- elapsed() {
58
- return this.offset + (this.id !== null ? (Date.now() - this.time) : 0);
59
- }
60
- start() {
61
- this.status = 1;
62
- this._start();
63
- }
64
- stop() {
65
- this._stop();
66
- this.status = 0;
67
- }
68
- _start() {
69
- if (this.status === 1 && this.id === null) {
70
- this.id = setTimeout(() => {
71
- var _a;
72
- this.timeout();
73
- (_a = this.transition) === null || _a === void 0 ? void 0 : _a.call(this, 1.0);
74
- this.id = null;
75
- this.time = 0.0;
76
- this.offset = 0.0;
77
- if (this.loop) {
78
- this.start();
79
- }
80
- else {
81
- this.clear();
82
- }
83
- }, this.delay - this.offset);
84
- this.time = Date.now();
85
- }
86
- }
87
- _stop() {
88
- if (this.status === 1 && this.id !== null) {
89
- this.offset = this.offset + Date.now() - this.time;
90
- clearTimeout(this.id);
91
- this.id = null;
92
- this.time = 0.0;
93
- }
94
- }
95
- }
96
-
97
1
  //----------------------------------------------------------------------------------------------------
98
2
  // map set
99
3
  //----------------------------------------------------------------------------------------------------
@@ -192,24 +96,117 @@ class MapMap extends Map {
192
96
  }
193
97
 
194
98
  //----------------------------------------------------------------------------------------------------
195
- // utils
99
+ // ticker
196
100
  //----------------------------------------------------------------------------------------------------
197
- const SYSTEM_EVENTS = ['start', 'update', 'stop', 'finalize'];
198
- class UnitPromise {
199
- constructor(promise) { this.promise = promise; }
200
- then(callback) {
201
- this.promise = this.promise.then(Unit.wrap(Unit.current, callback));
202
- return this;
101
+ class Ticker {
102
+ constructor(callback) {
103
+ const self = this;
104
+ this.id = null;
105
+ let previous = 0;
106
+ ticker();
107
+ function ticker() {
108
+ const time = Date.now();
109
+ const interval = 1000 / 60;
110
+ if (time - previous > interval * 0.9) {
111
+ callback(time);
112
+ previous = time;
113
+ }
114
+ self.id = requestAnimationFrame(ticker);
115
+ }
203
116
  }
204
- catch(callback) {
205
- this.promise = this.promise.catch(Unit.wrap(Unit.current, callback));
206
- return this;
117
+ clear() {
118
+ if (this.id !== null) {
119
+ cancelAnimationFrame(this.id);
120
+ this.id = null;
121
+ }
207
122
  }
208
- finally(callback) {
209
- this.promise = this.promise.finally(Unit.wrap(Unit.current, callback));
210
- return this;
123
+ }
124
+ //----------------------------------------------------------------------------------------------------
125
+ // timer
126
+ //----------------------------------------------------------------------------------------------------
127
+ class Timer {
128
+ constructor(transition, timeout, interval, { loop = false, easing = 'linear' } = {}) {
129
+ var _a;
130
+ this.transition = transition;
131
+ this.timeout = timeout;
132
+ this.interval = interval !== null && interval !== void 0 ? interval : 0;
133
+ this.loop = loop;
134
+ this.easing = easing;
135
+ this.id = null;
136
+ this.time = 0.0;
137
+ this.offset = 0.0;
138
+ this.status = 0;
139
+ this.ticker = new Ticker((time) => {
140
+ var _a;
141
+ let p = Math.min(this.elapsed() / this.interval, 1.0);
142
+ if (easing === 'ease-out') {
143
+ p = Math.pow((1.0 - Math.pow((1.0 - p), 2.0)), 0.5);
144
+ }
145
+ else if (easing === 'ease-in') {
146
+ p = Math.pow((1.0 - Math.pow((1.0 - p), 0.5)), 2.0);
147
+ }
148
+ else if (easing === 'ease') {
149
+ p = (1.0 - Math.cos(p * Math.PI)) / 2.0;
150
+ }
151
+ else if (easing === 'ease-in-out') {
152
+ p = (1.0 - Math.cos(p * Math.PI)) / 2.0;
153
+ }
154
+ (_a = this.transition) === null || _a === void 0 ? void 0 : _a.call(this, p);
155
+ });
156
+ this.visibilitychange = () => document.hidden === false ? this._start() : this._stop();
157
+ document.addEventListener('visibilitychange', this.visibilitychange);
158
+ if (this.interval > 0.0) {
159
+ (_a = this.transition) === null || _a === void 0 ? void 0 : _a.call(this, 0.0);
160
+ }
161
+ this.start();
162
+ }
163
+ clear() {
164
+ if (this.id !== null) {
165
+ clearTimeout(this.id);
166
+ this.id = null;
167
+ }
168
+ document.removeEventListener('visibilitychange', this.visibilitychange);
169
+ this.ticker.clear();
170
+ }
171
+ elapsed() {
172
+ return this.offset + (this.id !== null ? (Date.now() - this.time) : 0);
173
+ }
174
+ start() {
175
+ this.status = 1;
176
+ this._start();
177
+ }
178
+ stop() {
179
+ this._stop();
180
+ this.status = 0;
181
+ }
182
+ _start() {
183
+ if (this.status === 1 && this.id === null) {
184
+ this.id = setTimeout(() => {
185
+ var _a, _b;
186
+ (_a = this.timeout) === null || _a === void 0 ? void 0 : _a.call(this);
187
+ (_b = this.transition) === null || _b === void 0 ? void 0 : _b.call(this, 1.0);
188
+ this.id = null;
189
+ this.time = 0.0;
190
+ this.offset = 0.0;
191
+ this.loop ? this.start() : this.clear();
192
+ }, this.interval - this.offset);
193
+ this.time = Date.now();
194
+ }
195
+ }
196
+ _stop() {
197
+ if (this.status === 1 && this.id !== null) {
198
+ this.offset = this.offset + Date.now() - this.time;
199
+ clearTimeout(this.id);
200
+ this.id = null;
201
+ this.time = 0.0;
202
+ }
211
203
  }
212
204
  }
205
+
206
+ //----------------------------------------------------------------------------------------------------
207
+ // utils
208
+ //----------------------------------------------------------------------------------------------------
209
+ const SYSTEM_EVENTS = ['start', 'update', 'stop', 'finalize'];
213
210
  //----------------------------------------------------------------------------------------------------
214
211
  // unit
215
212
  //----------------------------------------------------------------------------------------------------
@@ -549,6 +546,76 @@ Unit.component2units = new MapSet();
549
546
  // event
550
547
  //----------------------------------------------------------------------------------------------------
551
548
  Unit.type2units = new MapSet();
549
+ //----------------------------------------------------------------------------------------------------
550
+ // unit promise
551
+ //----------------------------------------------------------------------------------------------------
552
+ class UnitPromise {
553
+ constructor(promise) { this.promise = promise; }
554
+ then(callback) {
555
+ this.promise = this.promise.then(Unit.wrap(Unit.current, callback));
556
+ return this;
557
+ }
558
+ catch(callback) {
559
+ this.promise = this.promise.catch(Unit.wrap(Unit.current, callback));
560
+ return this;
561
+ }
562
+ finally(callback) {
563
+ this.promise = this.promise.finally(Unit.wrap(Unit.current, callback));
564
+ return this;
565
+ }
566
+ }
567
+ //----------------------------------------------------------------------------------------------------
568
+ // unit timer
569
+ //----------------------------------------------------------------------------------------------------
570
+ class UnitTimer {
571
+ constructor({ transition, timeout, interval, easing, loop }) {
572
+ this.stack = [];
573
+ this.unit = new Unit(Unit.current, UnitTimer.Component, { snapshot: Unit.snapshot(Unit.current), transition, timeout, interval, easing, loop });
574
+ }
575
+ clear() {
576
+ this.unit.off();
577
+ this.unit.finalize();
578
+ }
579
+ timeout(timeout, interval = 0) {
580
+ UnitTimer.execute(this, { timeout, interval });
581
+ return this;
582
+ }
583
+ transition(transition, interval = 0, easing = 'linear') {
584
+ UnitTimer.execute(this, { transition, interval, easing });
585
+ return this;
586
+ }
587
+ static execute(timer, { transition, timeout, interval, easing, loop }) {
588
+ if (timer.unit._.state === 'finalized') {
589
+ timer.unit = new Unit(Unit.current, UnitTimer.Component, { snapshot: Unit.snapshot(Unit.current), transition, timeout, interval, easing, loop });
590
+ }
591
+ else if (timer.stack.length === 0) {
592
+ timer.stack.push({ snapshot: Unit.snapshot(Unit.current), transition, timeout, interval, easing, loop });
593
+ timer.unit.on('finalize', () => { UnitTimer.next(timer); });
594
+ }
595
+ else {
596
+ timer.stack.push({ snapshot: Unit.snapshot(Unit.current), transition, timeout, interval, easing, loop });
597
+ }
598
+ }
599
+ static next(timer) {
600
+ if (timer.stack.length > 0) {
601
+ timer.unit = new Unit(Unit.current, UnitTimer.Component, timer.stack.shift());
602
+ timer.unit.on('finalize', () => { UnitTimer.next(timer); });
603
+ }
604
+ }
605
+ static Component(unit, { snapshot, transition, timeout, interval, loop, easing }) {
606
+ const timer = new Timer((x) => {
607
+ if (transition !== undefined)
608
+ Unit.scope(snapshot, transition, x);
609
+ }, () => {
610
+ if (transition !== undefined)
611
+ Unit.scope(snapshot, transition, 1.0);
612
+ if (timeout !== undefined)
613
+ Unit.scope(snapshot, timeout);
614
+ unit.finalize();
615
+ }, interval, { loop, easing });
616
+ unit.on('finalize', () => timer.clear());
617
+ }
618
+ }
552
619
 
553
620
  const xnew$1 = Object.assign(function (...args) {
554
621
  if (Unit.root === undefined) {
@@ -729,42 +796,27 @@ const xnew$1 = Object.assign(function (...args) {
729
796
  },
730
797
  /**
731
798
  * Executes a callback once after a delay, managed by component lifecycle
732
- * @param callback - Function to execute after delay
733
- * @param delay - Delay in milliseconds
799
+ * @param timeout - Function to execute after Interval
800
+ * @param interval - Interval duration in milliseconds
734
801
  * @returns Object with clear() method to cancel the timeout
735
802
  * @example
736
803
  * const timer = xnew.timeout(() => console.log('Delayed'), 1000)
737
804
  * // Cancel if needed: timer.clear()
738
805
  */
739
- timeout(callback, delay = 0) {
740
- const snapshot = Unit.snapshot(Unit.current);
741
- const unit = xnew$1((self) => {
742
- const timer = new Timer(() => {
743
- Unit.scope(snapshot, callback);
744
- self.finalize();
745
- }, null, delay, false);
746
- self.on('finalize', () => timer.clear());
747
- });
748
- return { clear: () => unit.finalize() };
806
+ timeout(timeout, interval = 0) {
807
+ return new UnitTimer({ timeout, interval });
749
808
  },
750
809
  /**
751
810
  * Executes a callback repeatedly at specified intervals, managed by component lifecycle
752
- * @param callback - Function to execute at each interval
753
- * @param delay - Interval duration in milliseconds
811
+ * @param timeout - Function to execute at each interval
812
+ * @param interval - Interval duration in milliseconds
754
813
  * @returns Object with clear() method to stop the interval
755
814
  * @example
756
815
  * const timer = xnew.interval(() => console.log('Tick'), 1000)
757
816
  * // Stop when needed: timer.clear()
758
817
  */
759
- interval(callback, delay) {
760
- const snapshot = Unit.snapshot(Unit.current);
761
- const unit = xnew$1((self) => {
762
- const timer = new Timer(() => {
763
- Unit.scope(snapshot, callback);
764
- }, null, delay, true);
765
- self.on('finalize', () => timer.clear());
766
- });
767
- return { clear: () => unit.finalize() };
818
+ interval(timeout, interval) {
819
+ return new UnitTimer({ timeout, interval, loop: true });
768
820
  },
769
821
  /**
770
822
  * Creates a transition animation with easing, executing callback with progress values
@@ -773,61 +825,14 @@ const xnew$1 = Object.assign(function (...args) {
773
825
  * @param easing - Easing function: 'linear', 'ease', 'ease-in', 'ease-out', 'ease-in-out' (default: 'linear')
774
826
  * @returns Object with clear() and next() methods for controlling transitions
775
827
  * @example
776
- * xnew.transition(progress => {
777
- * element.style.opacity = progress
778
- * }, 500, 'ease-out').next(progress => {
779
- * element.style.transform = `scale(${progress})`
828
+ * xnew.transition(p => {
829
+ * element.style.opacity = p
830
+ * }, 500, 'ease-out').transition(p => {
831
+ * element.style.transform = `scale(${p})`
780
832
  * }, 300)
781
833
  */
782
- transition(callback, interval, easing = 'linear') {
783
- const snapshot = Unit.snapshot(Unit.current);
784
- let stacks = [];
785
- let unit = xnew$1(Local, { callback, interval, easing });
786
- let isRunning = true;
787
- const timer = { clear, next };
788
- return timer;
789
- function execute() {
790
- if (isRunning === false && stacks.length > 0) {
791
- unit = xnew$1(Local, stacks.shift());
792
- isRunning = true;
793
- }
794
- }
795
- function clear() {
796
- stacks = [];
797
- unit.finalize();
798
- }
799
- function next(callback, interval = 0, easing = 'linear') {
800
- stacks.push({ callback, interval, easing });
801
- execute();
802
- return timer;
803
- }
804
- function Local(self, { callback, interval, easing }) {
805
- const timer = new Timer(() => {
806
- Unit.scope(snapshot, callback, 1.0);
807
- self.finalize();
808
- }, (x) => {
809
- if (x < 1.0) {
810
- if (easing === 'ease-out') {
811
- x = Math.pow((1.0 - Math.pow((1.0 - x), 2.0)), 0.5);
812
- }
813
- else if (easing === 'ease-in') {
814
- x = Math.pow((1.0 - Math.pow((1.0 - x), 0.5)), 2.0);
815
- }
816
- else if (easing === 'ease') {
817
- x = (1.0 - Math.cos(x * Math.PI)) / 2.0;
818
- }
819
- else if (easing === 'ease-in-out') {
820
- x = (1.0 - Math.cos(x * Math.PI)) / 2.0;
821
- }
822
- Unit.scope(snapshot, callback, x);
823
- }
824
- }, interval);
825
- self.on('finalize', () => {
826
- timer.clear();
827
- isRunning = false;
828
- execute();
829
- });
830
- }
834
+ transition(transition, interval = 0, easing = 'linear') {
835
+ return new UnitTimer({ transition, interval, easing });
831
836
  },
832
837
  /**
833
838
  * Creates an event listener manager for a target element with automatic cleanup
@@ -862,6 +867,84 @@ const xnew$1 = Object.assign(function (...args) {
862
867
  },
863
868
  });
864
869
 
870
+ function AccordionFrame(frame, { open = false, duration = 200, easing = 'ease' } = {}) {
871
+ const internal = xnew$1((internal) => {
872
+ return { frame, open, rate: 0.0, };
873
+ });
874
+ xnew$1.context('xnew.accordionframe', internal);
875
+ internal.on('-transition', ({ rate }) => internal.rate = rate);
876
+ internal.emit('-transition', { rate: open ? 1.0 : 0.0 });
877
+ return {
878
+ toggle() {
879
+ if (internal.rate === 1.0) {
880
+ frame.close();
881
+ }
882
+ else if (internal.rate === 0.0) {
883
+ frame.open();
884
+ }
885
+ },
886
+ open() {
887
+ if (internal.rate === 0.0) {
888
+ xnew$1.transition((x) => internal.emit('-transition', { rate: x }), duration, easing);
889
+ }
890
+ },
891
+ close() {
892
+ if (internal.rate === 1.0) {
893
+ xnew$1.transition((x) => internal.emit('-transition', { rate: 1.0 - x }), duration, easing);
894
+ }
895
+ }
896
+ };
897
+ }
898
+ function AccordionHeader(header, {} = {}) {
899
+ const internal = xnew$1.context('xnew.accordionframe');
900
+ xnew$1.nest('<button style="display: flex; align-items: center; margin: 0; padding: 0; width: 100%; text-align: left; border: none; font: inherit; color: inherit; background: none; cursor: pointer;">');
901
+ header.on('click', () => internal.frame.toggle());
902
+ }
903
+ function AccordionBullet(bullet, { type = 'arrow' } = {}) {
904
+ const internal = xnew$1.context('xnew.accordionframe');
905
+ xnew$1.nest('<div style="display:inline-block; position: relative; width: 0.55em; margin: 0 0.3em;">');
906
+ if (type === 'arrow') {
907
+ const arrow = xnew$1(`<div style="width: 100%; height: 0.55em; border-right: 0.12em solid currentColor; border-bottom: 0.12em solid currentColor; box-sizing: border-box; transform-origin: center;">`);
908
+ arrow.element.style.transform = `rotate(${internal.rate * 90 - 45}deg)`;
909
+ internal.on('-transition', ({ rate }) => {
910
+ arrow.element.style.transform = `rotate(${rate * 90 - 45}deg)`;
911
+ });
912
+ }
913
+ else if (type === 'plusminus') {
914
+ const line1 = xnew$1(`<div style="position: absolute; width: 100%; border-top: 0.06em solid currentColor; border-bottom: 0.06em solid currentColor; box-sizing: border-box; transform-origin: center;">`);
915
+ const line2 = xnew$1(`<div style="position: absolute; width: 100%; border-top: 0.06em solid currentColor; border-bottom: 0.06em solid currentColor; box-sizing: border-box; transform-origin: center;">`);
916
+ line2.element.style.transform = `rotate(90deg)`;
917
+ line2.element.style.opacity = `${1.0 - internal.rate}`;
918
+ internal.on('-transition', ({ rate }) => {
919
+ line1.element.style.transform = `rotate(${90 + rate * 90}deg)`;
920
+ line2.element.style.transform = `rotate(${rate * 180}deg)`;
921
+ });
922
+ }
923
+ }
924
+ function AccordionContent(content, {} = {}) {
925
+ const internal = xnew$1.context('xnew.accordionframe');
926
+ xnew$1.nest(`<div style="display: ${internal.open ? 'block' : 'none'};">`);
927
+ xnew$1.nest('<div style="padding: 0; display: flex; flex-direction: column; box-sizing: border-box;">');
928
+ internal.on('-transition', ({ rate }) => {
929
+ content.transition({ element: content.element, rate });
930
+ });
931
+ return {
932
+ transition({ element, rate }) {
933
+ const wrapper = element.parentElement;
934
+ wrapper.style.display = 'block';
935
+ if (rate === 0.0) {
936
+ wrapper.style.display = 'none';
937
+ }
938
+ else if (rate < 1.0) {
939
+ Object.assign(wrapper.style, { height: element.offsetHeight * rate + 'px', overflow: 'hidden', opacity: rate });
940
+ }
941
+ else {
942
+ Object.assign(wrapper.style, { height: 'auto', overflow: 'visible', opacity: 1.0 });
943
+ }
944
+ }
945
+ };
946
+ }
947
+
865
948
  function ResizeEvent(resize) {
866
949
  const observer = new ResizeObserver((entries) => {
867
950
  for (const entry of entries) {
@@ -878,7 +961,29 @@ function ResizeEvent(resize) {
878
961
  }
879
962
  });
880
963
  }
881
-
964
+ function KeyboardEvent(unit) {
965
+ const state = {};
966
+ xnew$1.listener(window).on('keydown', (event) => {
967
+ state[event.code] = 1;
968
+ unit.emit('-keydown', { event, type: '-keydown', code: event.code });
969
+ });
970
+ xnew$1.listener(window).on('keyup', (event) => {
971
+ state[event.code] = 0;
972
+ unit.emit('-keyup', { event, type: '-keyup', code: event.code });
973
+ });
974
+ xnew$1.listener(window).on('keydown', (event) => {
975
+ unit.emit('-arrowkeydown', { event, type: '-arrowkeydown', code: event.code, vector: getVector() });
976
+ });
977
+ xnew$1.listener(window).on('keyup', (event) => {
978
+ unit.emit('-arrowkeyup', { event, type: '-arrowkeyup', code: event.code, vector: getVector() });
979
+ });
980
+ function getVector() {
981
+ return {
982
+ x: (state['ArrowLeft'] ? -1 : 0) + (state['ArrowRight'] ? +1 : 0),
983
+ y: (state['ArrowUp'] ? -1 : 0) + (state['ArrowDown'] ? +1 : 0)
984
+ };
985
+ }
986
+ }
882
987
  function PointerEvent(unit) {
883
988
  const internal = xnew$1();
884
989
  internal.on('pointerdown', (event) => unit.emit('-pointerdown', { event, position: getPosition(unit.element, event) }));
@@ -995,30 +1100,6 @@ function getPosition(element, event) {
995
1100
  return { x: event.clientX - rect.left, y: event.clientY - rect.top };
996
1101
  }
997
1102
 
998
- function KeyboardEvent(unit) {
999
- const state = {};
1000
- xnew$1.listener(window).on('keydown', (event) => {
1001
- state[event.code] = 1;
1002
- unit.emit('-keydown', { event, type: '-keydown', code: event.code });
1003
- });
1004
- xnew$1.listener(window).on('keyup', (event) => {
1005
- state[event.code] = 0;
1006
- unit.emit('-keyup', { event, type: '-keyup', code: event.code });
1007
- });
1008
- xnew$1.listener(window).on('keydown', (event) => {
1009
- unit.emit('-arrowkeydown', { event, type: '-arrowkeydown', code: event.code, vector: getVector() });
1010
- });
1011
- xnew$1.listener(window).on('keyup', (event) => {
1012
- unit.emit('-arrowkeyup', { event, type: '-arrowkeyup', code: event.code, vector: getVector() });
1013
- });
1014
- function getVector() {
1015
- return {
1016
- x: (state['ArrowLeft'] ? -1 : 0) + (state['ArrowRight'] ? +1 : 0),
1017
- y: (state['ArrowUp'] ? -1 : 0) + (state['ArrowDown'] ? +1 : 0)
1018
- };
1019
- }
1020
- }
1021
-
1022
1103
  function Screen(screen, { width = 640, height = 480, fit = 'contain' } = {}) {
1023
1104
  const size = { width, height };
1024
1105
  const wrapper = xnew$1.nest('<div style="position: relative; width: 100%; height: 100%; overflow: hidden;">');
@@ -1175,84 +1256,6 @@ function TabContent(content, { key } = {}) {
1175
1256
  };
1176
1257
  }
1177
1258
 
1178
- function AccordionFrame(frame, { open = false, duration = 200, easing = 'ease' } = {}) {
1179
- const internal = xnew$1((internal) => {
1180
- return { frame, open, rate: 0.0, };
1181
- });
1182
- xnew$1.context('xnew.accordionframe', internal);
1183
- internal.on('-transition', ({ rate }) => internal.rate = rate);
1184
- internal.emit('-transition', { rate: open ? 1.0 : 0.0 });
1185
- return {
1186
- toggle() {
1187
- if (internal.rate === 1.0) {
1188
- frame.close();
1189
- }
1190
- else if (internal.rate === 0.0) {
1191
- frame.open();
1192
- }
1193
- },
1194
- open() {
1195
- if (internal.rate === 0.0) {
1196
- xnew$1.transition((x) => internal.emit('-transition', { rate: x }), duration, easing);
1197
- }
1198
- },
1199
- close() {
1200
- if (internal.rate === 1.0) {
1201
- xnew$1.transition((x) => internal.emit('-transition', { rate: 1.0 - x }), duration, easing);
1202
- }
1203
- }
1204
- };
1205
- }
1206
- function AccordionHeader(header, {} = {}) {
1207
- const internal = xnew$1.context('xnew.accordionframe');
1208
- xnew$1.nest('<button style="display: flex; align-items: center; margin: 0; padding: 0; width: 100%; text-align: left; border: none; font: inherit; color: inherit; background: none; cursor: pointer;">');
1209
- header.on('click', () => internal.frame.toggle());
1210
- }
1211
- function AccordionBullet(bullet, { type = 'arrow' } = {}) {
1212
- const internal = xnew$1.context('xnew.accordionframe');
1213
- xnew$1.nest('<div style="display:inline-block; position: relative; width: 0.55em; margin: 0 0.3em;">');
1214
- if (type === 'arrow') {
1215
- const arrow = xnew$1(`<div style="width: 100%; height: 0.55em; border-right: 0.12em solid currentColor; border-bottom: 0.12em solid currentColor; box-sizing: border-box; transform-origin: center;">`);
1216
- arrow.element.style.transform = `rotate(${internal.rate * 90 - 45}deg)`;
1217
- internal.on('-transition', ({ rate }) => {
1218
- arrow.element.style.transform = `rotate(${rate * 90 - 45}deg)`;
1219
- });
1220
- }
1221
- else if (type === 'plusminus') {
1222
- const line1 = xnew$1(`<div style="position: absolute; width: 100%; border-top: 0.06em solid currentColor; border-bottom: 0.06em solid currentColor; box-sizing: border-box; transform-origin: center;">`);
1223
- const line2 = xnew$1(`<div style="position: absolute; width: 100%; border-top: 0.06em solid currentColor; border-bottom: 0.06em solid currentColor; box-sizing: border-box; transform-origin: center;">`);
1224
- line2.element.style.transform = `rotate(90deg)`;
1225
- line2.element.style.opacity = `${1.0 - internal.rate}`;
1226
- internal.on('-transition', ({ rate }) => {
1227
- line1.element.style.transform = `rotate(${90 + rate * 90}deg)`;
1228
- line2.element.style.transform = `rotate(${rate * 180}deg)`;
1229
- });
1230
- }
1231
- }
1232
- function AccordionContent(content, {} = {}) {
1233
- const internal = xnew$1.context('xnew.accordionframe');
1234
- xnew$1.nest(`<div style="display: ${internal.open ? 'block' : 'none'};">`);
1235
- xnew$1.nest('<div style="padding: 0; display: flex; flex-direction: column; box-sizing: border-box;">');
1236
- internal.on('-transition', ({ rate }) => {
1237
- content.transition({ element: content.element, rate });
1238
- });
1239
- return {
1240
- transition({ element, rate }) {
1241
- const wrapper = element.parentElement;
1242
- wrapper.style.display = 'block';
1243
- if (rate === 0.0) {
1244
- wrapper.style.display = 'none';
1245
- }
1246
- else if (rate < 1.0) {
1247
- Object.assign(wrapper.style, { height: element.offsetHeight * rate + 'px', overflow: 'hidden', opacity: rate });
1248
- }
1249
- else {
1250
- Object.assign(wrapper.style, { height: 'auto', overflow: 'visible', opacity: 1.0 });
1251
- }
1252
- }
1253
- };
1254
- }
1255
-
1256
1259
  function DragFrame(frame, { x = 0, y = 0 } = {}) {
1257
1260
  const absolute = xnew$1.nest(`<div style="position: absolute; top: ${y}px; left: ${x}px;">`);
1258
1261
  xnew$1.context('xnew.dragframe', { frame, absolute });
@@ -1290,11 +1293,11 @@ function DragTarget(target, {} = {}) {
1290
1293
  // controller
1291
1294
  //----------------------------------------------------------------------------------------------------
1292
1295
  function SVGTemplate(self, { fill = null, fillOpacity = 0.8, stroke = null, strokeOpacity = 0.8, strokeWidth = 2, strokeLinejoin = 'round' }) {
1293
- xnew$1.nest(`<svg
1294
- viewBox="0 0 100 100"
1295
- style="position: absolute; width: 100%; height: 100%; pointer-select: none;
1296
- ${fill ? `fill: ${fill}; fill-opacity: ${fillOpacity};` : ''}
1297
- ${stroke ? `stroke: ${stroke}; stroke-opacity: ${strokeOpacity}; stroke-width: ${strokeWidth}; stroke-linejoin: ${strokeLinejoin};` : ''}
1296
+ xnew$1.nest(`<svg
1297
+ viewBox="0 0 100 100"
1298
+ style="position: absolute; width: 100%; height: 100%; pointer-select: none;
1299
+ ${fill ? `fill: ${fill}; fill-opacity: ${fillOpacity};` : ''}
1300
+ ${stroke ? `stroke: ${stroke}; stroke-opacity: ${strokeOpacity}; stroke-width: ${strokeWidth}; stroke-linejoin: ${strokeLinejoin};` : ''}
1298
1301
  ">`);
1299
1302
  }
1300
1303
  function AnalogStick(self, { size, fill = '#FFF', fillOpacity = 0.8, stroke = '#000', strokeOpacity = 0.8, strokeWidth = 2, strokeLinejoin = 'round' } = {}) {