@mulsense/xnew 0.1.5 → 0.1.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.
@@ -1,5 +1,9 @@
1
1
  import { xnew } from '../core/xnew';
2
- export declare function AccordionFrame(frame: xnew.Unit, {}?: {}): {
2
+ export declare function AccordionFrame(frame: xnew.Unit, { open, duration, easing }?: {
3
+ open?: boolean;
4
+ duration?: number;
5
+ easing?: string;
6
+ }): {
3
7
  toggle(): void;
4
8
  open(): void;
5
9
  close(): void;
@@ -7,14 +11,10 @@ export declare function AccordionFrame(frame: xnew.Unit, {}?: {}): {
7
11
  export declare function AccordionHeader(header: xnew.Unit, {}?: {}): void;
8
12
  export declare function AccordionBullet(bullet: xnew.Unit, { type }?: {
9
13
  type?: string;
10
- }): {
11
- transition(status: number): void;
12
- } | undefined;
13
- export declare function AccordionContent(content: xnew.Unit, { open, duration, easing }?: {
14
- open?: boolean;
15
- duration?: number;
16
- easing?: string;
17
- }): {
18
- readonly status: number;
19
- transition(status: number): void;
14
+ }): void;
15
+ export declare function AccordionContent(content: xnew.Unit, {}?: {}): {
16
+ transition({ element, rate }: {
17
+ element: HTMLElement;
18
+ rate: number;
19
+ }): void;
20
20
  };
@@ -1,9 +1,15 @@
1
1
  import { xnew } from '../core/xnew';
2
- export declare function ModalFrame(frame: xnew.Unit, {}?: {}): {
3
- close(): void;
4
- };
5
- export declare function ModalContent(content: xnew.Unit, { duration, easing, background }?: {
2
+ export declare function ModalFrame(frame: xnew.Unit, { duration, easing }?: {
6
3
  duration?: number;
7
4
  easing?: string;
5
+ }): {
6
+ close(): void;
7
+ };
8
+ export declare function ModalContent(content: xnew.Unit, { background }?: {
8
9
  background?: string;
9
- }): void;
10
+ }): {
11
+ transition({ element, rate }: {
12
+ element: HTMLElement;
13
+ rate: number;
14
+ }): void;
15
+ };
@@ -1,12 +1,24 @@
1
1
  import { xnew } from '../core/xnew';
2
- export declare function TabFrame(frame: xnew.Unit, { select }?: {
3
- select?: number | undefined;
2
+ export declare function TabFrame(frame: xnew.Unit, { key }?: {
3
+ key?: string;
4
4
  }): void;
5
- export declare function TabButton(button: xnew.Unit, {}?: {}): {
6
- select(): void;
7
- deselect(): void;
5
+ export declare function TabButton(button: xnew.Unit, { key }?: {
6
+ key?: string;
7
+ }): {
8
+ select({ element }: {
9
+ element: HTMLElement;
10
+ }): void;
11
+ deselect({ element }: {
12
+ element: HTMLElement;
13
+ }): void;
8
14
  };
9
- export declare function TabContent(self: xnew.Unit, {}?: {}): {
10
- select(): void;
11
- deselect(): void;
15
+ export declare function TabContent(content: xnew.Unit, { key }?: {
16
+ key?: string;
17
+ }): {
18
+ select({ element }: {
19
+ element: HTMLElement;
20
+ }): void;
21
+ deselect({ element }: {
22
+ element: HTMLElement;
23
+ }): void;
12
24
  };
package/dist/xnew.d.ts CHANGED
@@ -117,28 +117,50 @@ declare function Screen(screen: xnew$1.Unit, { width, height, fit }?: {
117
117
 
118
118
  declare function InputFrame(frame: xnew$1.Unit, {}?: {}): void;
119
119
 
120
- declare function ModalFrame(frame: xnew$1.Unit, {}?: {}): {
121
- close(): void;
122
- };
123
- declare function ModalContent(content: xnew$1.Unit, { duration, easing, background }?: {
120
+ declare function ModalFrame(frame: xnew$1.Unit, { duration, easing }?: {
124
121
  duration?: number;
125
122
  easing?: string;
123
+ }): {
124
+ close(): void;
125
+ };
126
+ declare function ModalContent(content: xnew$1.Unit, { background }?: {
126
127
  background?: string;
127
- }): void;
128
+ }): {
129
+ transition({ element, rate }: {
130
+ element: HTMLElement;
131
+ rate: number;
132
+ }): void;
133
+ };
128
134
 
129
- declare function TabFrame(frame: xnew$1.Unit, { select }?: {
130
- select?: number | undefined;
135
+ declare function TabFrame(frame: xnew$1.Unit, { key }?: {
136
+ key?: string;
131
137
  }): void;
132
- declare function TabButton(button: xnew$1.Unit, {}?: {}): {
133
- select(): void;
134
- deselect(): void;
138
+ declare function TabButton(button: xnew$1.Unit, { key }?: {
139
+ key?: string;
140
+ }): {
141
+ select({ element }: {
142
+ element: HTMLElement;
143
+ }): void;
144
+ deselect({ element }: {
145
+ element: HTMLElement;
146
+ }): void;
135
147
  };
136
- declare function TabContent(self: xnew$1.Unit, {}?: {}): {
137
- select(): void;
138
- deselect(): void;
148
+ declare function TabContent(content: xnew$1.Unit, { key }?: {
149
+ key?: string;
150
+ }): {
151
+ select({ element }: {
152
+ element: HTMLElement;
153
+ }): void;
154
+ deselect({ element }: {
155
+ element: HTMLElement;
156
+ }): void;
139
157
  };
140
158
 
141
- declare function AccordionFrame(frame: xnew$1.Unit, {}?: {}): {
159
+ declare function AccordionFrame(frame: xnew$1.Unit, { open, duration, easing }?: {
160
+ open?: boolean;
161
+ duration?: number;
162
+ easing?: string;
163
+ }): {
142
164
  toggle(): void;
143
165
  open(): void;
144
166
  close(): void;
@@ -146,16 +168,12 @@ declare function AccordionFrame(frame: xnew$1.Unit, {}?: {}): {
146
168
  declare function AccordionHeader(header: xnew$1.Unit, {}?: {}): void;
147
169
  declare function AccordionBullet(bullet: xnew$1.Unit, { type }?: {
148
170
  type?: string;
149
- }): {
150
- transition(status: number): void;
151
- } | undefined;
152
- declare function AccordionContent(content: xnew$1.Unit, { open, duration, easing }?: {
153
- open?: boolean;
154
- duration?: number;
155
- easing?: string;
156
- }): {
157
- readonly status: number;
158
- transition(status: number): void;
171
+ }): void;
172
+ declare function AccordionContent(content: xnew$1.Unit, {}?: {}): {
173
+ transition({ element, rate }: {
174
+ element: HTMLElement;
175
+ rate: number;
176
+ }): void;
159
177
  };
160
178
 
161
179
  declare function DragFrame(frame: xnew$1.Unit, { x, y }?: {
package/dist/xnew.js CHANGED
@@ -992,7 +992,9 @@
992
992
 
993
993
  function InputFrame(frame, {} = {}) {
994
994
  xnew$1.nest('<div>');
995
- xnew$1.capture((unit) => unit.element.tagName.toLowerCase() === 'input', (unit) => {
995
+ xnew$1.capture((unit) => {
996
+ return unit.element.tagName.toLowerCase() === 'input';
997
+ }, (unit) => {
996
998
  const element = unit.element;
997
999
  xnew$1.listener(element).on('input', (event) => {
998
1000
  frame.emit('-input', { event });
@@ -1006,177 +1008,171 @@
1006
1008
  });
1007
1009
  }
1008
1010
 
1009
- function ModalFrame(frame, {} = {}) {
1010
- xnew$1.context('xnew.modalframe', frame);
1011
- xnew$1.nest('<div style="position: fixed; inset: 0; z-index: 1000;">');
1012
- xnew$1.capture((unit) => unit.components.includes(ModalContent), (unit) => {
1011
+ function ModalFrame(frame, { duration = 200, easing = 'ease' } = {}) {
1012
+ const internal = xnew$1((internal) => {
1013
+ return {};
1013
1014
  });
1014
- xnew$1().on('click', (event) => frame === null || frame === void 0 ? void 0 : frame.close());
1015
+ xnew$1.context('xnew.modalframe', internal);
1016
+ xnew$1.nest('<div style="position: fixed; inset: 0; z-index: 1000;">');
1017
+ xnew$1().on('click', (event) => frame.close());
1018
+ xnew$1.transition((x) => internal.emit('-transition', { rate: x }), duration, easing);
1015
1019
  return {
1016
1020
  close() {
1017
- frame.emit('-close');
1021
+ xnew$1.transition((x) => internal.emit('-transition', { rate: 1.0 - x }), duration, easing)
1022
+ .next(() => frame.finalize());
1018
1023
  }
1019
1024
  };
1020
1025
  }
1021
- function ModalContent(content, { duration = 200, easing = 'ease', background = 'rgba(0, 0, 0, 0.1)' } = {}) {
1022
- const frame = xnew$1.context('xnew.modalframe');
1023
- const div = xnew$1.nest('<div style="width: 100%; height: 100%; opacity: 0;">');
1024
- div.style.background = background;
1026
+ function ModalContent(content, { background = 'rgba(0, 0, 0, 0.1)' } = {}) {
1027
+ const internal = xnew$1.context('xnew.modalframe');
1028
+ xnew$1.nest(`<div style="width: 100%; height: 100%; opacity: 0; background: ${background}">`);
1025
1029
  xnew$1.nest('<div style="position: absolute; inset: 0; margin: auto; width: max-content; height: max-content;">');
1026
1030
  xnew$1().on('click', (event) => event.stopPropagation());
1027
- xnew$1.timeout(() => frame.emit('-open'));
1028
- frame.on('-open', () => {
1029
- xnew$1.transition((x) => {
1030
- div.style.opacity = x.toString();
1031
- }, duration, easing);
1032
- });
1033
- frame.on('-close', () => {
1034
- xnew$1.transition((x) => {
1035
- div.style.opacity = (1.0 - x).toString();
1036
- }, duration, easing).next(() => frame.finalize());
1031
+ internal.on('-transition', ({ rate }) => {
1032
+ content.transition({ element: content.element, rate });
1037
1033
  });
1034
+ return {
1035
+ transition({ element, rate }) {
1036
+ const wrapper = element.parentElement;
1037
+ wrapper.style.opacity = rate.toString();
1038
+ }
1039
+ };
1038
1040
  }
1039
1041
 
1040
- function TabFrame(frame, { select = 0 } = {}) {
1041
- xnew$1.context('xnew.tabframe', frame);
1042
- const buttons = [];
1043
- const contents = [];
1044
- xnew$1.capture((unit) => unit.components.includes(TabButton), (unit) => {
1045
- buttons.push(unit);
1042
+ function TabFrame(frame, { key } = {}) {
1043
+ const internal = xnew$1((internal) => {
1044
+ const buttons = new Map();
1045
+ const contents = new Map();
1046
+ return { frame, buttons, contents };
1046
1047
  });
1047
- xnew$1.capture((unit) => unit.components.includes(TabContent), (unit) => {
1048
- contents.push(unit);
1049
- });
1050
- frame.on('-click', ({ unit }) => execute(buttons.indexOf(unit)));
1051
- const timeout = xnew$1.timeout(() => execute(select));
1052
- function execute(index) {
1053
- timeout.clear();
1054
- const button = buttons[index];
1055
- const content = contents[index];
1056
- buttons.filter((item) => item !== button).forEach((item) => item.deselect());
1057
- contents.filter((item) => item !== content).forEach((item) => item.deselect());
1058
- button.select();
1059
- content.select();
1060
- }
1048
+ xnew$1.context('xnew.tabframe', internal);
1049
+ xnew$1.timeout(() => internal.emit('-select', { key: key !== null && key !== void 0 ? key : [...internal.buttons.keys()][0] }));
1061
1050
  }
1062
- function TabButton(button, {} = {}) {
1063
- const frame = xnew$1.context('xnew.tabframe');
1064
- xnew$1.nest('<div>');
1065
- button.on('click', () => frame.emit('-click', { unit: button }));
1051
+ function TabButton(button, { key } = {}) {
1052
+ const internal = xnew$1.context('xnew.tabframe');
1053
+ const div = xnew$1.nest('<div>');
1054
+ key = key !== null && key !== void 0 ? key : (internal.buttons.size).toString();
1055
+ internal.buttons.set(key, button);
1056
+ button.on('click', () => {
1057
+ internal.emit('-select', { key });
1058
+ });
1059
+ internal.on('-select', ({ key }) => {
1060
+ const select = internal.buttons.get(key);
1061
+ if (select === button) {
1062
+ button.select({ element: div });
1063
+ }
1064
+ else {
1065
+ button.deselect({ element: div });
1066
+ }
1067
+ });
1066
1068
  return {
1067
- select() {
1068
- Object.assign(button.element.style, { opacity: 1.0, cursor: 'text' });
1069
+ select({ element }) {
1070
+ Object.assign(element.style, { opacity: 1.0, cursor: 'text' });
1069
1071
  },
1070
- deselect() {
1071
- Object.assign(button.element.style, { opacity: 0.6, cursor: 'pointer' });
1072
+ deselect({ element }) {
1073
+ Object.assign(element.style, { opacity: 0.6, cursor: 'pointer' });
1072
1074
  }
1073
1075
  };
1074
1076
  }
1075
- function TabContent(self, {} = {}) {
1076
- xnew$1.context('xnew.tabframe');
1077
- xnew$1.nest('<div>');
1077
+ function TabContent(content, { key } = {}) {
1078
+ const internal = xnew$1.context('xnew.tabframe');
1079
+ const div = xnew$1.nest('<div style="display: none;">');
1080
+ key = key !== null && key !== void 0 ? key : (internal.contents.size).toString();
1081
+ internal.contents.set(key, content);
1082
+ internal.on('-select', ({ key }) => {
1083
+ const select = internal.contents.get(key);
1084
+ if (select === content) {
1085
+ content.select({ element: div });
1086
+ }
1087
+ else {
1088
+ content.deselect({ element: div });
1089
+ }
1090
+ });
1078
1091
  return {
1079
- select() {
1080
- Object.assign(self.element.style, { display: 'block' });
1092
+ select({ element }) {
1093
+ Object.assign(element.style, { display: 'block' });
1081
1094
  },
1082
- deselect() {
1083
- Object.assign(self.element.style, { display: 'none' });
1095
+ deselect({ element }) {
1096
+ Object.assign(element.style, { display: 'none' });
1084
1097
  }
1085
1098
  };
1086
1099
  }
1087
1100
 
1088
- function AccordionFrame(frame, {} = {}) {
1089
- xnew$1.context('xnew.accordionframe', frame);
1090
- let content = null;
1091
- xnew$1.capture((unit) => unit.components.includes(AccordionContent), (unit) => {
1092
- content = unit;
1101
+ function AccordionFrame(frame, { open = false, duration = 200, easing = 'ease' } = {}) {
1102
+ const internal = xnew$1((internal) => {
1103
+ return { frame, open, rate: 0.0, };
1093
1104
  });
1105
+ xnew$1.context('xnew.accordionframe', internal);
1106
+ internal.on('-transition', ({ rate }) => internal.rate = rate);
1107
+ internal.emit('-transition', { rate: open ? 1.0 : 0.0 });
1094
1108
  return {
1095
1109
  toggle() {
1096
- if ((content === null || content === void 0 ? void 0 : content.status) === 1.0) {
1097
- frame.emit('-close');
1110
+ if (internal.rate === 1.0) {
1111
+ frame.close();
1098
1112
  }
1099
- else if ((content === null || content === void 0 ? void 0 : content.status) === 0.0) {
1100
- frame.emit('-open');
1113
+ else if (internal.rate === 0.0) {
1114
+ frame.open();
1101
1115
  }
1102
1116
  },
1103
1117
  open() {
1104
- if ((content === null || content === void 0 ? void 0 : content.status) === 0.0) {
1105
- frame.emit('-open');
1118
+ if (internal.rate === 0.0) {
1119
+ xnew$1.transition((x) => internal.emit('-transition', { rate: x }), duration, easing);
1106
1120
  }
1107
1121
  },
1108
1122
  close() {
1109
- if ((content === null || content === void 0 ? void 0 : content.status) === 1.0) {
1110
- frame.emit('-close');
1123
+ if (internal.rate === 1.0) {
1124
+ xnew$1.transition((x) => internal.emit('-transition', { rate: 1.0 - x }), duration, easing);
1111
1125
  }
1112
1126
  }
1113
1127
  };
1114
1128
  }
1115
1129
  function AccordionHeader(header, {} = {}) {
1116
- const frame = xnew$1.context('xnew.accordionframe');
1130
+ const internal = xnew$1.context('xnew.accordionframe');
1117
1131
  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;">');
1118
- header.on('click', () => frame.toggle());
1132
+ header.on('click', () => internal.frame.toggle());
1119
1133
  }
1120
1134
  function AccordionBullet(bullet, { type = 'arrow' } = {}) {
1121
- const frame = xnew$1.context('xnew.accordionframe');
1122
- xnew$1.nest('<div style="display:inline-block; position: relative; width: 0.5em; margin: 0 0.3em;">');
1123
- frame.on('-transition', ({ status }) => { var _a; return (_a = bullet.transition) === null || _a === void 0 ? void 0 : _a.call(bullet, status); });
1135
+ const internal = xnew$1.context('xnew.accordionframe');
1136
+ xnew$1.nest('<div style="display:inline-block; position: relative; width: 0.55em; margin: 0 0.3em;">');
1124
1137
  if (type === 'arrow') {
1125
- const arrow = xnew$1(`<div style="width: 100%; height: 0.5em; border-right: 0.12em solid currentColor; border-bottom: 0.12em solid currentColor; box-sizing: border-box; transform-origin: center center;">`);
1126
- return {
1127
- transition(status) {
1128
- arrow.element.style.transform = `rotate(${status * 90 - 45}deg)`;
1129
- }
1130
- };
1138
+ 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;">`);
1139
+ arrow.element.style.transform = `rotate(${internal.rate * 90 - 45}deg)`;
1140
+ internal.on('-transition', ({ rate }) => {
1141
+ arrow.element.style.transform = `rotate(${rate * 90 - 45}deg)`;
1142
+ });
1131
1143
  }
1132
1144
  else if (type === 'plusminus') {
1133
- 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 center;">`);
1134
- 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 center;">`);
1145
+ 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;">`);
1146
+ 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;">`);
1135
1147
  line2.element.style.transform = `rotate(90deg)`;
1136
- return {
1137
- transition(status) {
1138
- line2.element.style.opacity = `${1.0 - status}`;
1139
- }
1140
- };
1148
+ line2.element.style.opacity = `${1.0 - internal.rate}`;
1149
+ internal.on('-transition', ({ rate }) => {
1150
+ line1.element.style.transform = `rotate(${90 + rate * 90}deg)`;
1151
+ line2.element.style.transform = `rotate(${rate * 180}deg)`;
1152
+ });
1141
1153
  }
1142
1154
  }
1143
- function AccordionContent(content, { open = false, duration = 200, easing = 'ease' } = {}) {
1144
- const frame = xnew$1.context('xnew.accordionframe');
1145
- const outer = xnew$1.nest('<div>');
1146
- const inner = xnew$1.nest('<div style="padding: 0; display: flex; flex-direction: column; box-sizing: border-box;">');
1147
- let status = open ? 1.0 : 0.0;
1148
- outer.style.display = status ? 'block' : 'none';
1149
- frame.emit('-transition', { status });
1150
- frame.on('-open', () => {
1151
- xnew$1.transition((x) => {
1152
- status = x;
1153
- frame.emit('-transition', { status });
1154
- content.transition(status);
1155
- }, duration, easing);
1156
- });
1157
- frame.on('-close', () => {
1158
- xnew$1.transition((x) => {
1159
- status = 1.0 - x;
1160
- frame.emit('-transition', { status });
1161
- content.transition(status);
1162
- }, duration, easing);
1155
+ function AccordionContent(content, {} = {}) {
1156
+ const internal = xnew$1.context('xnew.accordionframe');
1157
+ xnew$1.nest(`<div style="display: ${internal.open ? 'block' : 'none'};">`);
1158
+ xnew$1.nest('<div style="padding: 0; display: flex; flex-direction: column; box-sizing: border-box;">');
1159
+ internal.on('-transition', ({ rate }) => {
1160
+ content.transition({ element: content.element, rate });
1163
1161
  });
1164
1162
  return {
1165
- get status() {
1166
- return status;
1167
- },
1168
- transition(status) {
1169
- outer.style.display = 'block';
1170
- if (status === 0.0) {
1171
- outer.style.display = 'none';
1163
+ transition({ element, rate }) {
1164
+ const wrapper = element.parentElement;
1165
+ wrapper.style.display = 'block';
1166
+ if (rate === 0.0) {
1167
+ wrapper.style.display = 'none';
1172
1168
  }
1173
- else if (status < 1.0) {
1174
- Object.assign(outer.style, { height: inner.offsetHeight * status + 'px', overflow: 'hidden', opacity: status });
1169
+ else if (rate < 1.0) {
1170
+ Object.assign(wrapper.style, { height: element.offsetHeight * rate + 'px', overflow: 'hidden', opacity: rate });
1175
1171
  }
1176
1172
  else {
1177
- Object.assign(outer.style, { height: 'auto', overflow: 'visible', opacity: 1.0 });
1173
+ Object.assign(wrapper.style, { height: 'auto', overflow: 'visible', opacity: 1.0 });
1178
1174
  }
1179
- },
1175
+ }
1180
1176
  };
1181
1177
  }
1182
1178
 
package/dist/xnew.mjs CHANGED
@@ -986,7 +986,9 @@ function Screen(screen, { width = 640, height = 480, fit = 'contain' } = {}) {
986
986
 
987
987
  function InputFrame(frame, {} = {}) {
988
988
  xnew$1.nest('<div>');
989
- xnew$1.capture((unit) => unit.element.tagName.toLowerCase() === 'input', (unit) => {
989
+ xnew$1.capture((unit) => {
990
+ return unit.element.tagName.toLowerCase() === 'input';
991
+ }, (unit) => {
990
992
  const element = unit.element;
991
993
  xnew$1.listener(element).on('input', (event) => {
992
994
  frame.emit('-input', { event });
@@ -1000,177 +1002,171 @@ function InputFrame(frame, {} = {}) {
1000
1002
  });
1001
1003
  }
1002
1004
 
1003
- function ModalFrame(frame, {} = {}) {
1004
- xnew$1.context('xnew.modalframe', frame);
1005
- xnew$1.nest('<div style="position: fixed; inset: 0; z-index: 1000;">');
1006
- xnew$1.capture((unit) => unit.components.includes(ModalContent), (unit) => {
1005
+ function ModalFrame(frame, { duration = 200, easing = 'ease' } = {}) {
1006
+ const internal = xnew$1((internal) => {
1007
+ return {};
1007
1008
  });
1008
- xnew$1().on('click', (event) => frame === null || frame === void 0 ? void 0 : frame.close());
1009
+ xnew$1.context('xnew.modalframe', internal);
1010
+ xnew$1.nest('<div style="position: fixed; inset: 0; z-index: 1000;">');
1011
+ xnew$1().on('click', (event) => frame.close());
1012
+ xnew$1.transition((x) => internal.emit('-transition', { rate: x }), duration, easing);
1009
1013
  return {
1010
1014
  close() {
1011
- frame.emit('-close');
1015
+ xnew$1.transition((x) => internal.emit('-transition', { rate: 1.0 - x }), duration, easing)
1016
+ .next(() => frame.finalize());
1012
1017
  }
1013
1018
  };
1014
1019
  }
1015
- function ModalContent(content, { duration = 200, easing = 'ease', background = 'rgba(0, 0, 0, 0.1)' } = {}) {
1016
- const frame = xnew$1.context('xnew.modalframe');
1017
- const div = xnew$1.nest('<div style="width: 100%; height: 100%; opacity: 0;">');
1018
- div.style.background = background;
1020
+ function ModalContent(content, { background = 'rgba(0, 0, 0, 0.1)' } = {}) {
1021
+ const internal = xnew$1.context('xnew.modalframe');
1022
+ xnew$1.nest(`<div style="width: 100%; height: 100%; opacity: 0; background: ${background}">`);
1019
1023
  xnew$1.nest('<div style="position: absolute; inset: 0; margin: auto; width: max-content; height: max-content;">');
1020
1024
  xnew$1().on('click', (event) => event.stopPropagation());
1021
- xnew$1.timeout(() => frame.emit('-open'));
1022
- frame.on('-open', () => {
1023
- xnew$1.transition((x) => {
1024
- div.style.opacity = x.toString();
1025
- }, duration, easing);
1026
- });
1027
- frame.on('-close', () => {
1028
- xnew$1.transition((x) => {
1029
- div.style.opacity = (1.0 - x).toString();
1030
- }, duration, easing).next(() => frame.finalize());
1025
+ internal.on('-transition', ({ rate }) => {
1026
+ content.transition({ element: content.element, rate });
1031
1027
  });
1028
+ return {
1029
+ transition({ element, rate }) {
1030
+ const wrapper = element.parentElement;
1031
+ wrapper.style.opacity = rate.toString();
1032
+ }
1033
+ };
1032
1034
  }
1033
1035
 
1034
- function TabFrame(frame, { select = 0 } = {}) {
1035
- xnew$1.context('xnew.tabframe', frame);
1036
- const buttons = [];
1037
- const contents = [];
1038
- xnew$1.capture((unit) => unit.components.includes(TabButton), (unit) => {
1039
- buttons.push(unit);
1036
+ function TabFrame(frame, { key } = {}) {
1037
+ const internal = xnew$1((internal) => {
1038
+ const buttons = new Map();
1039
+ const contents = new Map();
1040
+ return { frame, buttons, contents };
1040
1041
  });
1041
- xnew$1.capture((unit) => unit.components.includes(TabContent), (unit) => {
1042
- contents.push(unit);
1043
- });
1044
- frame.on('-click', ({ unit }) => execute(buttons.indexOf(unit)));
1045
- const timeout = xnew$1.timeout(() => execute(select));
1046
- function execute(index) {
1047
- timeout.clear();
1048
- const button = buttons[index];
1049
- const content = contents[index];
1050
- buttons.filter((item) => item !== button).forEach((item) => item.deselect());
1051
- contents.filter((item) => item !== content).forEach((item) => item.deselect());
1052
- button.select();
1053
- content.select();
1054
- }
1042
+ xnew$1.context('xnew.tabframe', internal);
1043
+ xnew$1.timeout(() => internal.emit('-select', { key: key !== null && key !== void 0 ? key : [...internal.buttons.keys()][0] }));
1055
1044
  }
1056
- function TabButton(button, {} = {}) {
1057
- const frame = xnew$1.context('xnew.tabframe');
1058
- xnew$1.nest('<div>');
1059
- button.on('click', () => frame.emit('-click', { unit: button }));
1045
+ function TabButton(button, { key } = {}) {
1046
+ const internal = xnew$1.context('xnew.tabframe');
1047
+ const div = xnew$1.nest('<div>');
1048
+ key = key !== null && key !== void 0 ? key : (internal.buttons.size).toString();
1049
+ internal.buttons.set(key, button);
1050
+ button.on('click', () => {
1051
+ internal.emit('-select', { key });
1052
+ });
1053
+ internal.on('-select', ({ key }) => {
1054
+ const select = internal.buttons.get(key);
1055
+ if (select === button) {
1056
+ button.select({ element: div });
1057
+ }
1058
+ else {
1059
+ button.deselect({ element: div });
1060
+ }
1061
+ });
1060
1062
  return {
1061
- select() {
1062
- Object.assign(button.element.style, { opacity: 1.0, cursor: 'text' });
1063
+ select({ element }) {
1064
+ Object.assign(element.style, { opacity: 1.0, cursor: 'text' });
1063
1065
  },
1064
- deselect() {
1065
- Object.assign(button.element.style, { opacity: 0.6, cursor: 'pointer' });
1066
+ deselect({ element }) {
1067
+ Object.assign(element.style, { opacity: 0.6, cursor: 'pointer' });
1066
1068
  }
1067
1069
  };
1068
1070
  }
1069
- function TabContent(self, {} = {}) {
1070
- xnew$1.context('xnew.tabframe');
1071
- xnew$1.nest('<div>');
1071
+ function TabContent(content, { key } = {}) {
1072
+ const internal = xnew$1.context('xnew.tabframe');
1073
+ const div = xnew$1.nest('<div style="display: none;">');
1074
+ key = key !== null && key !== void 0 ? key : (internal.contents.size).toString();
1075
+ internal.contents.set(key, content);
1076
+ internal.on('-select', ({ key }) => {
1077
+ const select = internal.contents.get(key);
1078
+ if (select === content) {
1079
+ content.select({ element: div });
1080
+ }
1081
+ else {
1082
+ content.deselect({ element: div });
1083
+ }
1084
+ });
1072
1085
  return {
1073
- select() {
1074
- Object.assign(self.element.style, { display: 'block' });
1086
+ select({ element }) {
1087
+ Object.assign(element.style, { display: 'block' });
1075
1088
  },
1076
- deselect() {
1077
- Object.assign(self.element.style, { display: 'none' });
1089
+ deselect({ element }) {
1090
+ Object.assign(element.style, { display: 'none' });
1078
1091
  }
1079
1092
  };
1080
1093
  }
1081
1094
 
1082
- function AccordionFrame(frame, {} = {}) {
1083
- xnew$1.context('xnew.accordionframe', frame);
1084
- let content = null;
1085
- xnew$1.capture((unit) => unit.components.includes(AccordionContent), (unit) => {
1086
- content = unit;
1095
+ function AccordionFrame(frame, { open = false, duration = 200, easing = 'ease' } = {}) {
1096
+ const internal = xnew$1((internal) => {
1097
+ return { frame, open, rate: 0.0, };
1087
1098
  });
1099
+ xnew$1.context('xnew.accordionframe', internal);
1100
+ internal.on('-transition', ({ rate }) => internal.rate = rate);
1101
+ internal.emit('-transition', { rate: open ? 1.0 : 0.0 });
1088
1102
  return {
1089
1103
  toggle() {
1090
- if ((content === null || content === void 0 ? void 0 : content.status) === 1.0) {
1091
- frame.emit('-close');
1104
+ if (internal.rate === 1.0) {
1105
+ frame.close();
1092
1106
  }
1093
- else if ((content === null || content === void 0 ? void 0 : content.status) === 0.0) {
1094
- frame.emit('-open');
1107
+ else if (internal.rate === 0.0) {
1108
+ frame.open();
1095
1109
  }
1096
1110
  },
1097
1111
  open() {
1098
- if ((content === null || content === void 0 ? void 0 : content.status) === 0.0) {
1099
- frame.emit('-open');
1112
+ if (internal.rate === 0.0) {
1113
+ xnew$1.transition((x) => internal.emit('-transition', { rate: x }), duration, easing);
1100
1114
  }
1101
1115
  },
1102
1116
  close() {
1103
- if ((content === null || content === void 0 ? void 0 : content.status) === 1.0) {
1104
- frame.emit('-close');
1117
+ if (internal.rate === 1.0) {
1118
+ xnew$1.transition((x) => internal.emit('-transition', { rate: 1.0 - x }), duration, easing);
1105
1119
  }
1106
1120
  }
1107
1121
  };
1108
1122
  }
1109
1123
  function AccordionHeader(header, {} = {}) {
1110
- const frame = xnew$1.context('xnew.accordionframe');
1124
+ const internal = xnew$1.context('xnew.accordionframe');
1111
1125
  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;">');
1112
- header.on('click', () => frame.toggle());
1126
+ header.on('click', () => internal.frame.toggle());
1113
1127
  }
1114
1128
  function AccordionBullet(bullet, { type = 'arrow' } = {}) {
1115
- const frame = xnew$1.context('xnew.accordionframe');
1116
- xnew$1.nest('<div style="display:inline-block; position: relative; width: 0.5em; margin: 0 0.3em;">');
1117
- frame.on('-transition', ({ status }) => { var _a; return (_a = bullet.transition) === null || _a === void 0 ? void 0 : _a.call(bullet, status); });
1129
+ const internal = xnew$1.context('xnew.accordionframe');
1130
+ xnew$1.nest('<div style="display:inline-block; position: relative; width: 0.55em; margin: 0 0.3em;">');
1118
1131
  if (type === 'arrow') {
1119
- const arrow = xnew$1(`<div style="width: 100%; height: 0.5em; border-right: 0.12em solid currentColor; border-bottom: 0.12em solid currentColor; box-sizing: border-box; transform-origin: center center;">`);
1120
- return {
1121
- transition(status) {
1122
- arrow.element.style.transform = `rotate(${status * 90 - 45}deg)`;
1123
- }
1124
- };
1132
+ 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;">`);
1133
+ arrow.element.style.transform = `rotate(${internal.rate * 90 - 45}deg)`;
1134
+ internal.on('-transition', ({ rate }) => {
1135
+ arrow.element.style.transform = `rotate(${rate * 90 - 45}deg)`;
1136
+ });
1125
1137
  }
1126
1138
  else if (type === 'plusminus') {
1127
- 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 center;">`);
1128
- 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 center;">`);
1139
+ 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;">`);
1140
+ 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;">`);
1129
1141
  line2.element.style.transform = `rotate(90deg)`;
1130
- return {
1131
- transition(status) {
1132
- line2.element.style.opacity = `${1.0 - status}`;
1133
- }
1134
- };
1142
+ line2.element.style.opacity = `${1.0 - internal.rate}`;
1143
+ internal.on('-transition', ({ rate }) => {
1144
+ line1.element.style.transform = `rotate(${90 + rate * 90}deg)`;
1145
+ line2.element.style.transform = `rotate(${rate * 180}deg)`;
1146
+ });
1135
1147
  }
1136
1148
  }
1137
- function AccordionContent(content, { open = false, duration = 200, easing = 'ease' } = {}) {
1138
- const frame = xnew$1.context('xnew.accordionframe');
1139
- const outer = xnew$1.nest('<div>');
1140
- const inner = xnew$1.nest('<div style="padding: 0; display: flex; flex-direction: column; box-sizing: border-box;">');
1141
- let status = open ? 1.0 : 0.0;
1142
- outer.style.display = status ? 'block' : 'none';
1143
- frame.emit('-transition', { status });
1144
- frame.on('-open', () => {
1145
- xnew$1.transition((x) => {
1146
- status = x;
1147
- frame.emit('-transition', { status });
1148
- content.transition(status);
1149
- }, duration, easing);
1150
- });
1151
- frame.on('-close', () => {
1152
- xnew$1.transition((x) => {
1153
- status = 1.0 - x;
1154
- frame.emit('-transition', { status });
1155
- content.transition(status);
1156
- }, duration, easing);
1149
+ function AccordionContent(content, {} = {}) {
1150
+ const internal = xnew$1.context('xnew.accordionframe');
1151
+ xnew$1.nest(`<div style="display: ${internal.open ? 'block' : 'none'};">`);
1152
+ xnew$1.nest('<div style="padding: 0; display: flex; flex-direction: column; box-sizing: border-box;">');
1153
+ internal.on('-transition', ({ rate }) => {
1154
+ content.transition({ element: content.element, rate });
1157
1155
  });
1158
1156
  return {
1159
- get status() {
1160
- return status;
1161
- },
1162
- transition(status) {
1163
- outer.style.display = 'block';
1164
- if (status === 0.0) {
1165
- outer.style.display = 'none';
1157
+ transition({ element, rate }) {
1158
+ const wrapper = element.parentElement;
1159
+ wrapper.style.display = 'block';
1160
+ if (rate === 0.0) {
1161
+ wrapper.style.display = 'none';
1166
1162
  }
1167
- else if (status < 1.0) {
1168
- Object.assign(outer.style, { height: inner.offsetHeight * status + 'px', overflow: 'hidden', opacity: status });
1163
+ else if (rate < 1.0) {
1164
+ Object.assign(wrapper.style, { height: element.offsetHeight * rate + 'px', overflow: 'hidden', opacity: rate });
1169
1165
  }
1170
1166
  else {
1171
- Object.assign(outer.style, { height: 'auto', overflow: 'visible', opacity: 1.0 });
1167
+ Object.assign(wrapper.style, { height: 'auto', overflow: 'visible', opacity: 1.0 });
1172
1168
  }
1173
- },
1169
+ }
1174
1170
  };
1175
1171
  }
1176
1172
 
package/package.json CHANGED
@@ -4,7 +4,7 @@
4
4
  "keywords": [
5
5
  "Component-Oriented Programming"
6
6
  ],
7
- "version": "0.1.5",
7
+ "version": "0.1.6",
8
8
  "main": "dist/xnew.js",
9
9
  "module": "dist/xnew.mjs",
10
10
  "types": "dist/xnew.d.ts",