@plaidev/karte-action-sdk 1.1.188 → 1.1.189
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/hydrate/index.es.js +238 -227
- package/dist/index.es.js +231 -231
- package/package.json +1 -1
package/dist/hydrate/index.es.js
CHANGED
|
@@ -25,6 +25,233 @@ const ALL_ACTION_SHORTEN_ID = 'KARTE_ALL_ACTION_SHORTEN_ID';
|
|
|
25
25
|
*/
|
|
26
26
|
const KARTE_MODAL_ROOT = 'karte-modal-root';
|
|
27
27
|
|
|
28
|
+
/** @internal */
|
|
29
|
+
const NOOP = (_args) => { }; // eslint-disable-line @typescript-eslint/no-unused-vars
|
|
30
|
+
/** @internal */
|
|
31
|
+
const isPreview = () => {
|
|
32
|
+
return true;
|
|
33
|
+
};
|
|
34
|
+
/** @internal */
|
|
35
|
+
const setPreviousFocus = () => {
|
|
36
|
+
const previously_focused = typeof document !== 'undefined' && document.activeElement;
|
|
37
|
+
if (previously_focused) {
|
|
38
|
+
previously_focused?.focus();
|
|
39
|
+
}
|
|
40
|
+
};
|
|
41
|
+
/** @internal */
|
|
42
|
+
const handleKeydown = (handlers) => (e) => {
|
|
43
|
+
if (handlers[e.key]) {
|
|
44
|
+
handlers[e.key](e);
|
|
45
|
+
}
|
|
46
|
+
};
|
|
47
|
+
const POSITION_STYLES = {
|
|
48
|
+
'top-center': 'top: 0; right: 50%; transform: translate(+50%, 0%);',
|
|
49
|
+
'top-left': 'top: 0; left: 0; transform: translate(0%, 0%);',
|
|
50
|
+
'top-right': 'top: 0; right: 0; transform: translate(0%, 0%);',
|
|
51
|
+
'center-left': 'top: 50%; left: 0; transform: translate(0%, -50%);',
|
|
52
|
+
center: 'top: 50%; left: 50%; transform: translate(-50%, -50%);',
|
|
53
|
+
'center-right': 'top: 50%; right: 0; transform: translate(0%, -50%);',
|
|
54
|
+
'bottom-left': 'bottom: 0; left: 0; transform: translate(0%, 0%);',
|
|
55
|
+
'bottom-center': 'bottom: 0; left: 50%; transform: translate(-50%, 0%);',
|
|
56
|
+
'bottom-right': 'bottom: 0; right: 0; transform: translate(0%, 0);',
|
|
57
|
+
none: 'top: 0; bottom: 0; right: 0; left: 0;',
|
|
58
|
+
};
|
|
59
|
+
const TRANSFORM = {
|
|
60
|
+
'top-center': [50, 0],
|
|
61
|
+
'top-left': [0, 0],
|
|
62
|
+
'top-right': [0, 0],
|
|
63
|
+
'center-left': [0, -50],
|
|
64
|
+
center: [-50, -50],
|
|
65
|
+
'center-right': [0, -50],
|
|
66
|
+
'bottom-left': [0, 0],
|
|
67
|
+
'bottom-center': [-50, 0],
|
|
68
|
+
'bottom-right': [0, 0],
|
|
69
|
+
none: [0, 0],
|
|
70
|
+
};
|
|
71
|
+
/** @internal */
|
|
72
|
+
const getPositionStyle = (position) => {
|
|
73
|
+
const style = POSITION_STYLES[position];
|
|
74
|
+
if (style != null) {
|
|
75
|
+
return style;
|
|
76
|
+
}
|
|
77
|
+
else {
|
|
78
|
+
console.warn(`[action-sdk] invalid '${position}', so we use 'center' instead`);
|
|
79
|
+
return POSITION_STYLES['center'];
|
|
80
|
+
}
|
|
81
|
+
};
|
|
82
|
+
/** @internal */
|
|
83
|
+
const getTransform = (position) => {
|
|
84
|
+
const transform = TRANSFORM[position];
|
|
85
|
+
if (transform != null) {
|
|
86
|
+
return transform;
|
|
87
|
+
}
|
|
88
|
+
else {
|
|
89
|
+
console.warn(`[action-sdk] invalid '${position}', so we use 'center' instead`);
|
|
90
|
+
return TRANSFORM['center'];
|
|
91
|
+
}
|
|
92
|
+
};
|
|
93
|
+
/** @internal */
|
|
94
|
+
const getMarginStyle = (margin) => {
|
|
95
|
+
return `margin: ${margin?.top ?? 0} ${margin?.right ?? 0} ${margin?.bottom ?? 0} ${margin?.left ?? 0};`;
|
|
96
|
+
};
|
|
97
|
+
/** @internal */
|
|
98
|
+
const parseStyle = (style) => {
|
|
99
|
+
return Object.fromEntries(style.split(';').map(attr => attr.split(':').map(str => str.trim())));
|
|
100
|
+
};
|
|
101
|
+
/** @internal */
|
|
102
|
+
const stringifyStyleObj = (styleObj) => {
|
|
103
|
+
return Object.entries(styleObj)
|
|
104
|
+
.map(([key, value]) => `${key}:${value}`)
|
|
105
|
+
.join(';');
|
|
106
|
+
};
|
|
107
|
+
/**
|
|
108
|
+
* スクロール率が達したときに呼び出すコールバックを登録します
|
|
109
|
+
*
|
|
110
|
+
* @param rate - スクロール率。この値は viewport でのスクロールのパーセンテージ
|
|
111
|
+
* @param fn - スクロール率が達したときに呼び出されるコールバック関数
|
|
112
|
+
*
|
|
113
|
+
* @returns スクロール率によって呼び出されるコールバックを停止する関数を返します
|
|
114
|
+
*
|
|
115
|
+
* @public
|
|
116
|
+
*/
|
|
117
|
+
function onScroll(rate, fn) {
|
|
118
|
+
const rates = Array.isArray(rate) ? rate : [rate];
|
|
119
|
+
const body = window.document.body;
|
|
120
|
+
const html = window.document.documentElement;
|
|
121
|
+
const contexts = new Map();
|
|
122
|
+
rates.forEach(rate => {
|
|
123
|
+
contexts.set(rate, {
|
|
124
|
+
rate,
|
|
125
|
+
repeat: false,
|
|
126
|
+
zone: 'out',
|
|
127
|
+
previousRate: 0,
|
|
128
|
+
deltaRate: 0,
|
|
129
|
+
scrollRate: 0,
|
|
130
|
+
scrollTop: html.scrollTop || body.scrollTop,
|
|
131
|
+
});
|
|
132
|
+
});
|
|
133
|
+
const _fn = fn;
|
|
134
|
+
const direction = (ctx) => ctx.deltaRate > 0 ? 'down' : 'up';
|
|
135
|
+
const updateStates = (ctx, repeat) => {
|
|
136
|
+
ctx.repeat = repeat;
|
|
137
|
+
// prettier-ignore
|
|
138
|
+
ctx.zone =
|
|
139
|
+
// case: the scroll rate cannot detect the rate when scrolling to the top
|
|
140
|
+
ctx.scrollTop === 0 && ctx.scrollRate >= ctx.rate
|
|
141
|
+
? 'out'
|
|
142
|
+
: ctx.scrollRate >= ctx.rate
|
|
143
|
+
? 'in'
|
|
144
|
+
: 'out';
|
|
145
|
+
// console.log('updateStates', ctx.zone);
|
|
146
|
+
};
|
|
147
|
+
// prettier-ignore
|
|
148
|
+
const canCall = ({ zone, scrollRate, rate, scrollTop, repeat }) => zone === 'out'
|
|
149
|
+
? scrollRate >= rate
|
|
150
|
+
: repeat
|
|
151
|
+
// case: the scroll rate cannot detect the rate when scrolling to the top
|
|
152
|
+
? scrollRate < rate || (scrollTop === 0 && scrollRate >= rate)
|
|
153
|
+
: false;
|
|
154
|
+
/*
|
|
155
|
+
// NOTE: same logic the above (code size optimiazation)
|
|
156
|
+
const canCall = (ctx: OnScrollInternalContext): boolean => {
|
|
157
|
+
// console.log('repeat', ctx.repeat, 'rate', ctx.rate, 'scrollRate', ctx.scrollRate, '1 - rate', 1 - ctx.rate, '1 - scrollRate', 1 - ctx.scrollRate, 'scrollRate >= rate', ctx.scrollRate >= ctx.rate, '1 - scrollRate >= 1 - rate', 1 - ctx.scrollRate >= 1 - ctx.rate);
|
|
158
|
+
// console.log(ctx.rate, 'deltaRate', ctx.deltaRate, 'reviousRate', ctx.previousRate)
|
|
159
|
+
if (ctx.zone === 'out') {
|
|
160
|
+
return ctx.scrollRate >= ctx.rate;
|
|
161
|
+
} else {
|
|
162
|
+
// 'in'
|
|
163
|
+
if (ctx.repeat) {
|
|
164
|
+
return ctx.scrollRate < ctx.rate || (ctx.scrollTop === 0 && ctx.scrollRate >= ctx.rate);
|
|
165
|
+
} else {
|
|
166
|
+
return false;
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
};
|
|
170
|
+
//*/
|
|
171
|
+
const onScroll = () => {
|
|
172
|
+
const scrollTop = html.scrollTop || body.scrollTop;
|
|
173
|
+
const pageHeight = Math.max(...[body.clientHeight, body.scrollHeight, html.scrollHeight, html.clientHeight]);
|
|
174
|
+
const viewHeight = Math.min(...[html.clientHeight, body.clientHeight]);
|
|
175
|
+
const scrollRate = (scrollTop + viewHeight) / pageHeight;
|
|
176
|
+
// console.log('scrollRate ->', scrollRate, 'scrollTop ->', scrollTop);
|
|
177
|
+
contexts.forEach(ctx => {
|
|
178
|
+
ctx.scrollRate = scrollRate;
|
|
179
|
+
ctx.deltaRate = ctx.scrollRate - ctx.previousRate;
|
|
180
|
+
ctx.previousRate = ctx.scrollRate;
|
|
181
|
+
ctx.scrollTop = scrollTop;
|
|
182
|
+
if (canCall(ctx)) {
|
|
183
|
+
const repeat = !!_fn(Object.assign({ direction: direction(ctx) }, ctx));
|
|
184
|
+
updateStates(ctx, repeat);
|
|
185
|
+
}
|
|
186
|
+
});
|
|
187
|
+
};
|
|
188
|
+
// register scorll event
|
|
189
|
+
window.addEventListener('scroll', onScroll);
|
|
190
|
+
// return disposing (finalizing/releasing) function
|
|
191
|
+
return () => {
|
|
192
|
+
window.removeEventListener('scroll', onScroll);
|
|
193
|
+
};
|
|
194
|
+
}
|
|
195
|
+
/**
|
|
196
|
+
* 指定した時間の経過後に呼び出すコールバックを登録します
|
|
197
|
+
*
|
|
198
|
+
* @param time - コールバックを呼び出すまでの時間。単位はミリセカンド(ms)
|
|
199
|
+
* @param fn - 指定した時間が経過後に呼び出されるコールバック関数
|
|
200
|
+
*
|
|
201
|
+
* @returns コールバックを呼び出すためのタイマーを停止する関数を返します
|
|
202
|
+
*
|
|
203
|
+
* @public
|
|
204
|
+
*/
|
|
205
|
+
function onTime(time, fn) {
|
|
206
|
+
const timeoutHandler = setTimeout(fn, time);
|
|
207
|
+
return () => timeoutHandler && clearTimeout(timeoutHandler);
|
|
208
|
+
}
|
|
209
|
+
/** @internal */
|
|
210
|
+
function hasSuffix(value, suffix) {
|
|
211
|
+
return new RegExp(`[0-9]${suffix}$`).test(value);
|
|
212
|
+
}
|
|
213
|
+
/**
|
|
214
|
+
* Goolge Fonts用のURLを生成
|
|
215
|
+
*
|
|
216
|
+
* @param fonts - フォント名の配列
|
|
217
|
+
* @param texts - 使用するテキストの配列
|
|
218
|
+
*
|
|
219
|
+
* @remarks
|
|
220
|
+
* textsを指定した場合フォントサイズが削減される
|
|
221
|
+
*
|
|
222
|
+
* @internal
|
|
223
|
+
*/
|
|
224
|
+
function makeGoogleFontUrl(fonts, texts) {
|
|
225
|
+
const params = [];
|
|
226
|
+
params.push('display=swap');
|
|
227
|
+
if (texts) {
|
|
228
|
+
texts.forEach(text => params.push(`text=${text}`));
|
|
229
|
+
}
|
|
230
|
+
fonts.forEach(font => params.push(`family=${font.replace(/['"]/g, '').replace(/ /g, '+')}`));
|
|
231
|
+
return `https://fonts.googleapis.com/css2?${params.join('&')}`;
|
|
232
|
+
}
|
|
233
|
+
/**
|
|
234
|
+
* HTML要素を生成
|
|
235
|
+
*
|
|
236
|
+
* @internal
|
|
237
|
+
*/
|
|
238
|
+
const h = (type, props, ...children) => {
|
|
239
|
+
const el = document.createElement(type);
|
|
240
|
+
for (const key of Object.keys(props)) {
|
|
241
|
+
const v = props[key];
|
|
242
|
+
if (key === 'style') {
|
|
243
|
+
Object.assign(el.style, v);
|
|
244
|
+
}
|
|
245
|
+
else {
|
|
246
|
+
el.setAttribute(key, v);
|
|
247
|
+
}
|
|
248
|
+
}
|
|
249
|
+
for (const child of children) {
|
|
250
|
+
el.appendChild(child);
|
|
251
|
+
}
|
|
252
|
+
return el;
|
|
253
|
+
};
|
|
254
|
+
|
|
28
255
|
/**
|
|
29
256
|
* ポップアップ(モーダル)のコンポーネントで利用するPropの定義
|
|
30
257
|
*/
|
|
@@ -444,6 +671,8 @@ const state = writable('/');
|
|
|
444
671
|
* @public
|
|
445
672
|
*/
|
|
446
673
|
function setState$1(stateId, options) {
|
|
674
|
+
if (options?.disableInPreview)
|
|
675
|
+
return;
|
|
447
676
|
state.set(stateId);
|
|
448
677
|
}
|
|
449
678
|
/**
|
|
@@ -739,233 +968,6 @@ function resetVariables() {
|
|
|
739
968
|
*/
|
|
740
969
|
const formData = writable({});
|
|
741
970
|
|
|
742
|
-
/** @internal */
|
|
743
|
-
const NOOP = (_args) => { }; // eslint-disable-line @typescript-eslint/no-unused-vars
|
|
744
|
-
/** @internal */
|
|
745
|
-
const isPreview = () => {
|
|
746
|
-
return true;
|
|
747
|
-
};
|
|
748
|
-
/** @internal */
|
|
749
|
-
const setPreviousFocus = () => {
|
|
750
|
-
const previously_focused = typeof document !== 'undefined' && document.activeElement;
|
|
751
|
-
if (previously_focused) {
|
|
752
|
-
previously_focused?.focus();
|
|
753
|
-
}
|
|
754
|
-
};
|
|
755
|
-
/** @internal */
|
|
756
|
-
const handleKeydown = (handlers) => (e) => {
|
|
757
|
-
if (handlers[e.key]) {
|
|
758
|
-
handlers[e.key](e);
|
|
759
|
-
}
|
|
760
|
-
};
|
|
761
|
-
const POSITION_STYLES = {
|
|
762
|
-
'top-center': 'top: 0; right: 50%; transform: translate(+50%, 0%);',
|
|
763
|
-
'top-left': 'top: 0; left: 0; transform: translate(0%, 0%);',
|
|
764
|
-
'top-right': 'top: 0; right: 0; transform: translate(0%, 0%);',
|
|
765
|
-
'center-left': 'top: 50%; left: 0; transform: translate(0%, -50%);',
|
|
766
|
-
center: 'top: 50%; left: 50%; transform: translate(-50%, -50%);',
|
|
767
|
-
'center-right': 'top: 50%; right: 0; transform: translate(0%, -50%);',
|
|
768
|
-
'bottom-left': 'bottom: 0; left: 0; transform: translate(0%, 0%);',
|
|
769
|
-
'bottom-center': 'bottom: 0; left: 50%; transform: translate(-50%, 0%);',
|
|
770
|
-
'bottom-right': 'bottom: 0; right: 0; transform: translate(0%, 0);',
|
|
771
|
-
none: 'top: 0; bottom: 0; right: 0; left: 0;',
|
|
772
|
-
};
|
|
773
|
-
const TRANSFORM = {
|
|
774
|
-
'top-center': [50, 0],
|
|
775
|
-
'top-left': [0, 0],
|
|
776
|
-
'top-right': [0, 0],
|
|
777
|
-
'center-left': [0, -50],
|
|
778
|
-
center: [-50, -50],
|
|
779
|
-
'center-right': [0, -50],
|
|
780
|
-
'bottom-left': [0, 0],
|
|
781
|
-
'bottom-center': [-50, 0],
|
|
782
|
-
'bottom-right': [0, 0],
|
|
783
|
-
none: [0, 0],
|
|
784
|
-
};
|
|
785
|
-
/** @internal */
|
|
786
|
-
const getPositionStyle = (position) => {
|
|
787
|
-
const style = POSITION_STYLES[position];
|
|
788
|
-
if (style != null) {
|
|
789
|
-
return style;
|
|
790
|
-
}
|
|
791
|
-
else {
|
|
792
|
-
console.warn(`[action-sdk] invalid '${position}', so we use 'center' instead`);
|
|
793
|
-
return POSITION_STYLES['center'];
|
|
794
|
-
}
|
|
795
|
-
};
|
|
796
|
-
/** @internal */
|
|
797
|
-
const getTransform = (position) => {
|
|
798
|
-
const transform = TRANSFORM[position];
|
|
799
|
-
if (transform != null) {
|
|
800
|
-
return transform;
|
|
801
|
-
}
|
|
802
|
-
else {
|
|
803
|
-
console.warn(`[action-sdk] invalid '${position}', so we use 'center' instead`);
|
|
804
|
-
return TRANSFORM['center'];
|
|
805
|
-
}
|
|
806
|
-
};
|
|
807
|
-
/** @internal */
|
|
808
|
-
const getMarginStyle = (margin) => {
|
|
809
|
-
return `margin: ${margin?.top ?? 0} ${margin?.right ?? 0} ${margin?.bottom ?? 0} ${margin?.left ?? 0};`;
|
|
810
|
-
};
|
|
811
|
-
/** @internal */
|
|
812
|
-
const parseStyle = (style) => {
|
|
813
|
-
return Object.fromEntries(style.split(';').map(attr => attr.split(':').map(str => str.trim())));
|
|
814
|
-
};
|
|
815
|
-
/** @internal */
|
|
816
|
-
const stringifyStyleObj = (styleObj) => {
|
|
817
|
-
return Object.entries(styleObj)
|
|
818
|
-
.map(([key, value]) => `${key}:${value}`)
|
|
819
|
-
.join(';');
|
|
820
|
-
};
|
|
821
|
-
/**
|
|
822
|
-
* スクロール率が達したときに呼び出すコールバックを登録します
|
|
823
|
-
*
|
|
824
|
-
* @param rate - スクロール率。この値は viewport でのスクロールのパーセンテージ
|
|
825
|
-
* @param fn - スクロール率が達したときに呼び出されるコールバック関数
|
|
826
|
-
*
|
|
827
|
-
* @returns スクロール率によって呼び出されるコールバックを停止する関数を返します
|
|
828
|
-
*
|
|
829
|
-
* @public
|
|
830
|
-
*/
|
|
831
|
-
function onScroll(rate, fn) {
|
|
832
|
-
const rates = Array.isArray(rate) ? rate : [rate];
|
|
833
|
-
const body = window.document.body;
|
|
834
|
-
const html = window.document.documentElement;
|
|
835
|
-
const contexts = new Map();
|
|
836
|
-
rates.forEach(rate => {
|
|
837
|
-
contexts.set(rate, {
|
|
838
|
-
rate,
|
|
839
|
-
repeat: false,
|
|
840
|
-
zone: 'out',
|
|
841
|
-
previousRate: 0,
|
|
842
|
-
deltaRate: 0,
|
|
843
|
-
scrollRate: 0,
|
|
844
|
-
scrollTop: html.scrollTop || body.scrollTop,
|
|
845
|
-
});
|
|
846
|
-
});
|
|
847
|
-
const _fn = fn;
|
|
848
|
-
const direction = (ctx) => ctx.deltaRate > 0 ? 'down' : 'up';
|
|
849
|
-
const updateStates = (ctx, repeat) => {
|
|
850
|
-
ctx.repeat = repeat;
|
|
851
|
-
// prettier-ignore
|
|
852
|
-
ctx.zone =
|
|
853
|
-
// case: the scroll rate cannot detect the rate when scrolling to the top
|
|
854
|
-
ctx.scrollTop === 0 && ctx.scrollRate >= ctx.rate
|
|
855
|
-
? 'out'
|
|
856
|
-
: ctx.scrollRate >= ctx.rate
|
|
857
|
-
? 'in'
|
|
858
|
-
: 'out';
|
|
859
|
-
// console.log('updateStates', ctx.zone);
|
|
860
|
-
};
|
|
861
|
-
// prettier-ignore
|
|
862
|
-
const canCall = ({ zone, scrollRate, rate, scrollTop, repeat }) => zone === 'out'
|
|
863
|
-
? scrollRate >= rate
|
|
864
|
-
: repeat
|
|
865
|
-
// case: the scroll rate cannot detect the rate when scrolling to the top
|
|
866
|
-
? scrollRate < rate || (scrollTop === 0 && scrollRate >= rate)
|
|
867
|
-
: false;
|
|
868
|
-
/*
|
|
869
|
-
// NOTE: same logic the above (code size optimiazation)
|
|
870
|
-
const canCall = (ctx: OnScrollInternalContext): boolean => {
|
|
871
|
-
// console.log('repeat', ctx.repeat, 'rate', ctx.rate, 'scrollRate', ctx.scrollRate, '1 - rate', 1 - ctx.rate, '1 - scrollRate', 1 - ctx.scrollRate, 'scrollRate >= rate', ctx.scrollRate >= ctx.rate, '1 - scrollRate >= 1 - rate', 1 - ctx.scrollRate >= 1 - ctx.rate);
|
|
872
|
-
// console.log(ctx.rate, 'deltaRate', ctx.deltaRate, 'reviousRate', ctx.previousRate)
|
|
873
|
-
if (ctx.zone === 'out') {
|
|
874
|
-
return ctx.scrollRate >= ctx.rate;
|
|
875
|
-
} else {
|
|
876
|
-
// 'in'
|
|
877
|
-
if (ctx.repeat) {
|
|
878
|
-
return ctx.scrollRate < ctx.rate || (ctx.scrollTop === 0 && ctx.scrollRate >= ctx.rate);
|
|
879
|
-
} else {
|
|
880
|
-
return false;
|
|
881
|
-
}
|
|
882
|
-
}
|
|
883
|
-
};
|
|
884
|
-
//*/
|
|
885
|
-
const onScroll = () => {
|
|
886
|
-
const scrollTop = html.scrollTop || body.scrollTop;
|
|
887
|
-
const pageHeight = Math.max(...[body.clientHeight, body.scrollHeight, html.scrollHeight, html.clientHeight]);
|
|
888
|
-
const viewHeight = Math.min(...[html.clientHeight, body.clientHeight]);
|
|
889
|
-
const scrollRate = (scrollTop + viewHeight) / pageHeight;
|
|
890
|
-
// console.log('scrollRate ->', scrollRate, 'scrollTop ->', scrollTop);
|
|
891
|
-
contexts.forEach(ctx => {
|
|
892
|
-
ctx.scrollRate = scrollRate;
|
|
893
|
-
ctx.deltaRate = ctx.scrollRate - ctx.previousRate;
|
|
894
|
-
ctx.previousRate = ctx.scrollRate;
|
|
895
|
-
ctx.scrollTop = scrollTop;
|
|
896
|
-
if (canCall(ctx)) {
|
|
897
|
-
const repeat = !!_fn(Object.assign({ direction: direction(ctx) }, ctx));
|
|
898
|
-
updateStates(ctx, repeat);
|
|
899
|
-
}
|
|
900
|
-
});
|
|
901
|
-
};
|
|
902
|
-
// register scorll event
|
|
903
|
-
window.addEventListener('scroll', onScroll);
|
|
904
|
-
// return disposing (finalizing/releasing) function
|
|
905
|
-
return () => {
|
|
906
|
-
window.removeEventListener('scroll', onScroll);
|
|
907
|
-
};
|
|
908
|
-
}
|
|
909
|
-
/**
|
|
910
|
-
* 指定した時間の経過後に呼び出すコールバックを登録します
|
|
911
|
-
*
|
|
912
|
-
* @param time - コールバックを呼び出すまでの時間。単位はミリセカンド(ms)
|
|
913
|
-
* @param fn - 指定した時間が経過後に呼び出されるコールバック関数
|
|
914
|
-
*
|
|
915
|
-
* @returns コールバックを呼び出すためのタイマーを停止する関数を返します
|
|
916
|
-
*
|
|
917
|
-
* @public
|
|
918
|
-
*/
|
|
919
|
-
function onTime(time, fn) {
|
|
920
|
-
const timeoutHandler = setTimeout(fn, time);
|
|
921
|
-
return () => timeoutHandler && clearTimeout(timeoutHandler);
|
|
922
|
-
}
|
|
923
|
-
/** @internal */
|
|
924
|
-
function hasSuffix(value, suffix) {
|
|
925
|
-
return new RegExp(`[0-9]${suffix}$`).test(value);
|
|
926
|
-
}
|
|
927
|
-
/**
|
|
928
|
-
* Goolge Fonts用のURLを生成
|
|
929
|
-
*
|
|
930
|
-
* @param fonts - フォント名の配列
|
|
931
|
-
* @param texts - 使用するテキストの配列
|
|
932
|
-
*
|
|
933
|
-
* @remarks
|
|
934
|
-
* textsを指定した場合フォントサイズが削減される
|
|
935
|
-
*
|
|
936
|
-
* @internal
|
|
937
|
-
*/
|
|
938
|
-
function makeGoogleFontUrl(fonts, texts) {
|
|
939
|
-
const params = [];
|
|
940
|
-
params.push('display=swap');
|
|
941
|
-
if (texts) {
|
|
942
|
-
texts.forEach(text => params.push(`text=${text}`));
|
|
943
|
-
}
|
|
944
|
-
fonts.forEach(font => params.push(`family=${font.replace(/['"]/g, '').replace(/ /g, '+')}`));
|
|
945
|
-
return `https://fonts.googleapis.com/css2?${params.join('&')}`;
|
|
946
|
-
}
|
|
947
|
-
/**
|
|
948
|
-
* HTML要素を生成
|
|
949
|
-
*
|
|
950
|
-
* @internal
|
|
951
|
-
*/
|
|
952
|
-
const h = (type, props, ...children) => {
|
|
953
|
-
const el = document.createElement(type);
|
|
954
|
-
for (const key of Object.keys(props)) {
|
|
955
|
-
const v = props[key];
|
|
956
|
-
if (key === 'style') {
|
|
957
|
-
Object.assign(el.style, v);
|
|
958
|
-
}
|
|
959
|
-
else {
|
|
960
|
-
el.setAttribute(key, v);
|
|
961
|
-
}
|
|
962
|
-
}
|
|
963
|
-
for (const child of children) {
|
|
964
|
-
el.appendChild(child);
|
|
965
|
-
}
|
|
966
|
-
return el;
|
|
967
|
-
};
|
|
968
|
-
|
|
969
971
|
/**
|
|
970
972
|
* アクションのログの記録の管理
|
|
971
973
|
*/
|
|
@@ -1593,6 +1595,9 @@ function createModal(App, options = {
|
|
|
1593
1595
|
if (app) {
|
|
1594
1596
|
return;
|
|
1595
1597
|
}
|
|
1598
|
+
if (trigger === 'custom') {
|
|
1599
|
+
return;
|
|
1600
|
+
}
|
|
1596
1601
|
if (trigger === 'custom' && (options.props.show_on_scroll || options.props.show_on_time)) {
|
|
1597
1602
|
return;
|
|
1598
1603
|
}
|
|
@@ -1650,6 +1655,9 @@ function createModal(App, options = {
|
|
|
1650
1655
|
const trigger = event?.detail?.trigger ? event.detail.trigger : 'none';
|
|
1651
1656
|
show(trigger);
|
|
1652
1657
|
};
|
|
1658
|
+
const autoShow = () => {
|
|
1659
|
+
return show('auto');
|
|
1660
|
+
};
|
|
1653
1661
|
// ここからメインの処理
|
|
1654
1662
|
initialize({ send: options.send, initialState: data.initial_state });
|
|
1655
1663
|
// ActionTable APIへの非同期リクエスト
|
|
@@ -1663,6 +1671,9 @@ function createModal(App, options = {
|
|
|
1663
1671
|
window.addEventListener(ACTION_CHANGE_STATE_EVENT, handleState);
|
|
1664
1672
|
let showTriggerCleanups = [];
|
|
1665
1673
|
let closeTriggerCleanups = [];
|
|
1674
|
+
{
|
|
1675
|
+
autoShow();
|
|
1676
|
+
}
|
|
1666
1677
|
// 旧Widget API IFの処理
|
|
1667
1678
|
const { onCreateHandlers } = getInternalHandlers();
|
|
1668
1679
|
if (onCreateHandlers) {
|
package/dist/index.es.js
CHANGED
|
@@ -25,6 +25,237 @@ const ALL_ACTION_SHORTEN_ID = 'KARTE_ALL_ACTION_SHORTEN_ID';
|
|
|
25
25
|
*/
|
|
26
26
|
const KARTE_MODAL_ROOT = 'karte-modal-root';
|
|
27
27
|
|
|
28
|
+
/** @internal */
|
|
29
|
+
const NOOP = (_args) => { }; // eslint-disable-line @typescript-eslint/no-unused-vars
|
|
30
|
+
/** @internal */
|
|
31
|
+
const isPreview = () => {
|
|
32
|
+
return false;
|
|
33
|
+
};
|
|
34
|
+
/** @internal */
|
|
35
|
+
const setPreviousFocus = () => {
|
|
36
|
+
const previously_focused = typeof document !== 'undefined' && document.activeElement;
|
|
37
|
+
if (previously_focused) {
|
|
38
|
+
previously_focused?.focus();
|
|
39
|
+
}
|
|
40
|
+
};
|
|
41
|
+
/** @internal */
|
|
42
|
+
const handleKeydown = (handlers) => (e) => {
|
|
43
|
+
if (handlers[e.key]) {
|
|
44
|
+
handlers[e.key](e);
|
|
45
|
+
}
|
|
46
|
+
};
|
|
47
|
+
const POSITION_STYLES = {
|
|
48
|
+
'top-center': 'top: 0; right: 50%; transform: translate(+50%, 0%);',
|
|
49
|
+
'top-left': 'top: 0; left: 0; transform: translate(0%, 0%);',
|
|
50
|
+
'top-right': 'top: 0; right: 0; transform: translate(0%, 0%);',
|
|
51
|
+
'center-left': 'top: 50%; left: 0; transform: translate(0%, -50%);',
|
|
52
|
+
center: 'top: 50%; left: 50%; transform: translate(-50%, -50%);',
|
|
53
|
+
'center-right': 'top: 50%; right: 0; transform: translate(0%, -50%);',
|
|
54
|
+
'bottom-left': 'bottom: 0; left: 0; transform: translate(0%, 0%);',
|
|
55
|
+
'bottom-center': 'bottom: 0; left: 50%; transform: translate(-50%, 0%);',
|
|
56
|
+
'bottom-right': 'bottom: 0; right: 0; transform: translate(0%, 0);',
|
|
57
|
+
none: 'top: 0; bottom: 0; right: 0; left: 0;',
|
|
58
|
+
};
|
|
59
|
+
const TRANSFORM = {
|
|
60
|
+
'top-center': [50, 0],
|
|
61
|
+
'top-left': [0, 0],
|
|
62
|
+
'top-right': [0, 0],
|
|
63
|
+
'center-left': [0, -50],
|
|
64
|
+
center: [-50, -50],
|
|
65
|
+
'center-right': [0, -50],
|
|
66
|
+
'bottom-left': [0, 0],
|
|
67
|
+
'bottom-center': [-50, 0],
|
|
68
|
+
'bottom-right': [0, 0],
|
|
69
|
+
none: [0, 0],
|
|
70
|
+
};
|
|
71
|
+
/** @internal */
|
|
72
|
+
const getPositionStyle = (position) => {
|
|
73
|
+
const style = POSITION_STYLES[position];
|
|
74
|
+
if (style != null) {
|
|
75
|
+
return style;
|
|
76
|
+
}
|
|
77
|
+
else {
|
|
78
|
+
console.warn(`[action-sdk] invalid '${position}', so we use 'center' instead`);
|
|
79
|
+
return POSITION_STYLES['center'];
|
|
80
|
+
}
|
|
81
|
+
};
|
|
82
|
+
/** @internal */
|
|
83
|
+
const getTransform = (position) => {
|
|
84
|
+
const transform = TRANSFORM[position];
|
|
85
|
+
if (transform != null) {
|
|
86
|
+
return transform;
|
|
87
|
+
}
|
|
88
|
+
else {
|
|
89
|
+
console.warn(`[action-sdk] invalid '${position}', so we use 'center' instead`);
|
|
90
|
+
return TRANSFORM['center'];
|
|
91
|
+
}
|
|
92
|
+
};
|
|
93
|
+
/** @internal */
|
|
94
|
+
const getMarginStyle = (margin) => {
|
|
95
|
+
return `margin: ${margin?.top ?? 0} ${margin?.right ?? 0} ${margin?.bottom ?? 0} ${margin?.left ?? 0};`;
|
|
96
|
+
};
|
|
97
|
+
/** @internal */
|
|
98
|
+
const parseStyle = (style) => {
|
|
99
|
+
return Object.fromEntries(style.split(';').map(attr => attr.split(':').map(str => str.trim())));
|
|
100
|
+
};
|
|
101
|
+
/** @internal */
|
|
102
|
+
const stringifyStyleObj = (styleObj) => {
|
|
103
|
+
return Object.entries(styleObj)
|
|
104
|
+
.map(([key, value]) => `${key}:${value}`)
|
|
105
|
+
.join(';');
|
|
106
|
+
};
|
|
107
|
+
/**
|
|
108
|
+
* スクロール率が達したときに呼び出すコールバックを登録します
|
|
109
|
+
*
|
|
110
|
+
* @param rate - スクロール率。この値は viewport でのスクロールのパーセンテージ
|
|
111
|
+
* @param fn - スクロール率が達したときに呼び出されるコールバック関数
|
|
112
|
+
*
|
|
113
|
+
* @returns スクロール率によって呼び出されるコールバックを停止する関数を返します
|
|
114
|
+
*
|
|
115
|
+
* @public
|
|
116
|
+
*/
|
|
117
|
+
function onScroll(rate, fn) {
|
|
118
|
+
const rates = Array.isArray(rate) ? rate : [rate];
|
|
119
|
+
const body = window.document.body;
|
|
120
|
+
const html = window.document.documentElement;
|
|
121
|
+
const contexts = new Map();
|
|
122
|
+
rates.forEach(rate => {
|
|
123
|
+
contexts.set(rate, {
|
|
124
|
+
rate,
|
|
125
|
+
repeat: false,
|
|
126
|
+
zone: 'out',
|
|
127
|
+
previousRate: 0,
|
|
128
|
+
deltaRate: 0,
|
|
129
|
+
scrollRate: 0,
|
|
130
|
+
scrollTop: html.scrollTop || body.scrollTop,
|
|
131
|
+
});
|
|
132
|
+
});
|
|
133
|
+
const _fn = fn;
|
|
134
|
+
const direction = (ctx) => ctx.deltaRate > 0 ? 'down' : 'up';
|
|
135
|
+
const updateStates = (ctx, repeat) => {
|
|
136
|
+
ctx.repeat = repeat;
|
|
137
|
+
// prettier-ignore
|
|
138
|
+
ctx.zone =
|
|
139
|
+
// case: the scroll rate cannot detect the rate when scrolling to the top
|
|
140
|
+
ctx.scrollTop === 0 && ctx.scrollRate >= ctx.rate
|
|
141
|
+
? 'out'
|
|
142
|
+
: ctx.scrollRate >= ctx.rate
|
|
143
|
+
? 'in'
|
|
144
|
+
: 'out';
|
|
145
|
+
// console.log('updateStates', ctx.zone);
|
|
146
|
+
};
|
|
147
|
+
// prettier-ignore
|
|
148
|
+
const canCall = ({ zone, scrollRate, rate, scrollTop, repeat }) => zone === 'out'
|
|
149
|
+
? scrollRate >= rate
|
|
150
|
+
: repeat
|
|
151
|
+
// case: the scroll rate cannot detect the rate when scrolling to the top
|
|
152
|
+
? scrollRate < rate || (scrollTop === 0 && scrollRate >= rate)
|
|
153
|
+
: false;
|
|
154
|
+
/*
|
|
155
|
+
// NOTE: same logic the above (code size optimiazation)
|
|
156
|
+
const canCall = (ctx: OnScrollInternalContext): boolean => {
|
|
157
|
+
// console.log('repeat', ctx.repeat, 'rate', ctx.rate, 'scrollRate', ctx.scrollRate, '1 - rate', 1 - ctx.rate, '1 - scrollRate', 1 - ctx.scrollRate, 'scrollRate >= rate', ctx.scrollRate >= ctx.rate, '1 - scrollRate >= 1 - rate', 1 - ctx.scrollRate >= 1 - ctx.rate);
|
|
158
|
+
// console.log(ctx.rate, 'deltaRate', ctx.deltaRate, 'reviousRate', ctx.previousRate)
|
|
159
|
+
if (ctx.zone === 'out') {
|
|
160
|
+
return ctx.scrollRate >= ctx.rate;
|
|
161
|
+
} else {
|
|
162
|
+
// 'in'
|
|
163
|
+
if (ctx.repeat) {
|
|
164
|
+
return ctx.scrollRate < ctx.rate || (ctx.scrollTop === 0 && ctx.scrollRate >= ctx.rate);
|
|
165
|
+
} else {
|
|
166
|
+
return false;
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
};
|
|
170
|
+
//*/
|
|
171
|
+
const onScroll = () => {
|
|
172
|
+
const scrollTop = html.scrollTop || body.scrollTop;
|
|
173
|
+
const pageHeight = Math.max(...[body.clientHeight, body.scrollHeight, html.scrollHeight, html.clientHeight]);
|
|
174
|
+
const viewHeight = Math.min(...[html.clientHeight, body.clientHeight]);
|
|
175
|
+
const scrollRate = (scrollTop + viewHeight) / pageHeight;
|
|
176
|
+
// console.log('scrollRate ->', scrollRate, 'scrollTop ->', scrollTop);
|
|
177
|
+
contexts.forEach(ctx => {
|
|
178
|
+
ctx.scrollRate = scrollRate;
|
|
179
|
+
ctx.deltaRate = ctx.scrollRate - ctx.previousRate;
|
|
180
|
+
ctx.previousRate = ctx.scrollRate;
|
|
181
|
+
ctx.scrollTop = scrollTop;
|
|
182
|
+
if (canCall(ctx)) {
|
|
183
|
+
const repeat = !!_fn(Object.assign({ direction: direction(ctx) }, ctx));
|
|
184
|
+
updateStates(ctx, repeat);
|
|
185
|
+
}
|
|
186
|
+
});
|
|
187
|
+
};
|
|
188
|
+
// register scorll event
|
|
189
|
+
window.addEventListener('scroll', onScroll);
|
|
190
|
+
// return disposing (finalizing/releasing) function
|
|
191
|
+
return () => {
|
|
192
|
+
window.removeEventListener('scroll', onScroll);
|
|
193
|
+
};
|
|
194
|
+
}
|
|
195
|
+
/**
|
|
196
|
+
* 指定した時間の経過後に呼び出すコールバックを登録します
|
|
197
|
+
*
|
|
198
|
+
* @param time - コールバックを呼び出すまでの時間。単位はミリセカンド(ms)
|
|
199
|
+
* @param fn - 指定した時間が経過後に呼び出されるコールバック関数
|
|
200
|
+
*
|
|
201
|
+
* @returns コールバックを呼び出すためのタイマーを停止する関数を返します
|
|
202
|
+
*
|
|
203
|
+
* @public
|
|
204
|
+
*/
|
|
205
|
+
function onTime(time, fn) {
|
|
206
|
+
const timeoutHandler = setTimeout(fn, time);
|
|
207
|
+
return () => timeoutHandler && clearTimeout(timeoutHandler);
|
|
208
|
+
}
|
|
209
|
+
/** @internal */
|
|
210
|
+
function hasSuffix(value, suffix) {
|
|
211
|
+
return new RegExp(`[0-9]${suffix}$`).test(value);
|
|
212
|
+
}
|
|
213
|
+
/** @internal */
|
|
214
|
+
function randStr(digit = 8) {
|
|
215
|
+
return Math.random().toString(32).substring(digit);
|
|
216
|
+
}
|
|
217
|
+
/**
|
|
218
|
+
* Goolge Fonts用のURLを生成
|
|
219
|
+
*
|
|
220
|
+
* @param fonts - フォント名の配列
|
|
221
|
+
* @param texts - 使用するテキストの配列
|
|
222
|
+
*
|
|
223
|
+
* @remarks
|
|
224
|
+
* textsを指定した場合フォントサイズが削減される
|
|
225
|
+
*
|
|
226
|
+
* @internal
|
|
227
|
+
*/
|
|
228
|
+
function makeGoogleFontUrl(fonts, texts) {
|
|
229
|
+
const params = [];
|
|
230
|
+
params.push('display=swap');
|
|
231
|
+
if (texts) {
|
|
232
|
+
texts.forEach(text => params.push(`text=${text}`));
|
|
233
|
+
}
|
|
234
|
+
fonts.forEach(font => params.push(`family=${font.replace(/['"]/g, '').replace(/ /g, '+')}`));
|
|
235
|
+
return `https://fonts.googleapis.com/css2?${params.join('&')}`;
|
|
236
|
+
}
|
|
237
|
+
/**
|
|
238
|
+
* HTML要素を生成
|
|
239
|
+
*
|
|
240
|
+
* @internal
|
|
241
|
+
*/
|
|
242
|
+
const h = (type, props, ...children) => {
|
|
243
|
+
const el = document.createElement(type);
|
|
244
|
+
for (const key of Object.keys(props)) {
|
|
245
|
+
const v = props[key];
|
|
246
|
+
if (key === 'style') {
|
|
247
|
+
Object.assign(el.style, v);
|
|
248
|
+
}
|
|
249
|
+
else {
|
|
250
|
+
el.setAttribute(key, v);
|
|
251
|
+
}
|
|
252
|
+
}
|
|
253
|
+
for (const child of children) {
|
|
254
|
+
el.appendChild(child);
|
|
255
|
+
}
|
|
256
|
+
return el;
|
|
257
|
+
};
|
|
258
|
+
|
|
28
259
|
/**
|
|
29
260
|
* ポップアップ(モーダル)のコンポーネントで利用するPropの定義
|
|
30
261
|
*/
|
|
@@ -739,237 +970,6 @@ function resetVariables() {
|
|
|
739
970
|
*/
|
|
740
971
|
const formData = writable({});
|
|
741
972
|
|
|
742
|
-
/** @internal */
|
|
743
|
-
const NOOP = (_args) => { }; // eslint-disable-line @typescript-eslint/no-unused-vars
|
|
744
|
-
/** @internal */
|
|
745
|
-
const isPreview = () => {
|
|
746
|
-
return false;
|
|
747
|
-
};
|
|
748
|
-
/** @internal */
|
|
749
|
-
const setPreviousFocus = () => {
|
|
750
|
-
const previously_focused = typeof document !== 'undefined' && document.activeElement;
|
|
751
|
-
if (previously_focused) {
|
|
752
|
-
previously_focused?.focus();
|
|
753
|
-
}
|
|
754
|
-
};
|
|
755
|
-
/** @internal */
|
|
756
|
-
const handleKeydown = (handlers) => (e) => {
|
|
757
|
-
if (handlers[e.key]) {
|
|
758
|
-
handlers[e.key](e);
|
|
759
|
-
}
|
|
760
|
-
};
|
|
761
|
-
const POSITION_STYLES = {
|
|
762
|
-
'top-center': 'top: 0; right: 50%; transform: translate(+50%, 0%);',
|
|
763
|
-
'top-left': 'top: 0; left: 0; transform: translate(0%, 0%);',
|
|
764
|
-
'top-right': 'top: 0; right: 0; transform: translate(0%, 0%);',
|
|
765
|
-
'center-left': 'top: 50%; left: 0; transform: translate(0%, -50%);',
|
|
766
|
-
center: 'top: 50%; left: 50%; transform: translate(-50%, -50%);',
|
|
767
|
-
'center-right': 'top: 50%; right: 0; transform: translate(0%, -50%);',
|
|
768
|
-
'bottom-left': 'bottom: 0; left: 0; transform: translate(0%, 0%);',
|
|
769
|
-
'bottom-center': 'bottom: 0; left: 50%; transform: translate(-50%, 0%);',
|
|
770
|
-
'bottom-right': 'bottom: 0; right: 0; transform: translate(0%, 0);',
|
|
771
|
-
none: 'top: 0; bottom: 0; right: 0; left: 0;',
|
|
772
|
-
};
|
|
773
|
-
const TRANSFORM = {
|
|
774
|
-
'top-center': [50, 0],
|
|
775
|
-
'top-left': [0, 0],
|
|
776
|
-
'top-right': [0, 0],
|
|
777
|
-
'center-left': [0, -50],
|
|
778
|
-
center: [-50, -50],
|
|
779
|
-
'center-right': [0, -50],
|
|
780
|
-
'bottom-left': [0, 0],
|
|
781
|
-
'bottom-center': [-50, 0],
|
|
782
|
-
'bottom-right': [0, 0],
|
|
783
|
-
none: [0, 0],
|
|
784
|
-
};
|
|
785
|
-
/** @internal */
|
|
786
|
-
const getPositionStyle = (position) => {
|
|
787
|
-
const style = POSITION_STYLES[position];
|
|
788
|
-
if (style != null) {
|
|
789
|
-
return style;
|
|
790
|
-
}
|
|
791
|
-
else {
|
|
792
|
-
console.warn(`[action-sdk] invalid '${position}', so we use 'center' instead`);
|
|
793
|
-
return POSITION_STYLES['center'];
|
|
794
|
-
}
|
|
795
|
-
};
|
|
796
|
-
/** @internal */
|
|
797
|
-
const getTransform = (position) => {
|
|
798
|
-
const transform = TRANSFORM[position];
|
|
799
|
-
if (transform != null) {
|
|
800
|
-
return transform;
|
|
801
|
-
}
|
|
802
|
-
else {
|
|
803
|
-
console.warn(`[action-sdk] invalid '${position}', so we use 'center' instead`);
|
|
804
|
-
return TRANSFORM['center'];
|
|
805
|
-
}
|
|
806
|
-
};
|
|
807
|
-
/** @internal */
|
|
808
|
-
const getMarginStyle = (margin) => {
|
|
809
|
-
return `margin: ${margin?.top ?? 0} ${margin?.right ?? 0} ${margin?.bottom ?? 0} ${margin?.left ?? 0};`;
|
|
810
|
-
};
|
|
811
|
-
/** @internal */
|
|
812
|
-
const parseStyle = (style) => {
|
|
813
|
-
return Object.fromEntries(style.split(';').map(attr => attr.split(':').map(str => str.trim())));
|
|
814
|
-
};
|
|
815
|
-
/** @internal */
|
|
816
|
-
const stringifyStyleObj = (styleObj) => {
|
|
817
|
-
return Object.entries(styleObj)
|
|
818
|
-
.map(([key, value]) => `${key}:${value}`)
|
|
819
|
-
.join(';');
|
|
820
|
-
};
|
|
821
|
-
/**
|
|
822
|
-
* スクロール率が達したときに呼び出すコールバックを登録します
|
|
823
|
-
*
|
|
824
|
-
* @param rate - スクロール率。この値は viewport でのスクロールのパーセンテージ
|
|
825
|
-
* @param fn - スクロール率が達したときに呼び出されるコールバック関数
|
|
826
|
-
*
|
|
827
|
-
* @returns スクロール率によって呼び出されるコールバックを停止する関数を返します
|
|
828
|
-
*
|
|
829
|
-
* @public
|
|
830
|
-
*/
|
|
831
|
-
function onScroll(rate, fn) {
|
|
832
|
-
const rates = Array.isArray(rate) ? rate : [rate];
|
|
833
|
-
const body = window.document.body;
|
|
834
|
-
const html = window.document.documentElement;
|
|
835
|
-
const contexts = new Map();
|
|
836
|
-
rates.forEach(rate => {
|
|
837
|
-
contexts.set(rate, {
|
|
838
|
-
rate,
|
|
839
|
-
repeat: false,
|
|
840
|
-
zone: 'out',
|
|
841
|
-
previousRate: 0,
|
|
842
|
-
deltaRate: 0,
|
|
843
|
-
scrollRate: 0,
|
|
844
|
-
scrollTop: html.scrollTop || body.scrollTop,
|
|
845
|
-
});
|
|
846
|
-
});
|
|
847
|
-
const _fn = fn;
|
|
848
|
-
const direction = (ctx) => ctx.deltaRate > 0 ? 'down' : 'up';
|
|
849
|
-
const updateStates = (ctx, repeat) => {
|
|
850
|
-
ctx.repeat = repeat;
|
|
851
|
-
// prettier-ignore
|
|
852
|
-
ctx.zone =
|
|
853
|
-
// case: the scroll rate cannot detect the rate when scrolling to the top
|
|
854
|
-
ctx.scrollTop === 0 && ctx.scrollRate >= ctx.rate
|
|
855
|
-
? 'out'
|
|
856
|
-
: ctx.scrollRate >= ctx.rate
|
|
857
|
-
? 'in'
|
|
858
|
-
: 'out';
|
|
859
|
-
// console.log('updateStates', ctx.zone);
|
|
860
|
-
};
|
|
861
|
-
// prettier-ignore
|
|
862
|
-
const canCall = ({ zone, scrollRate, rate, scrollTop, repeat }) => zone === 'out'
|
|
863
|
-
? scrollRate >= rate
|
|
864
|
-
: repeat
|
|
865
|
-
// case: the scroll rate cannot detect the rate when scrolling to the top
|
|
866
|
-
? scrollRate < rate || (scrollTop === 0 && scrollRate >= rate)
|
|
867
|
-
: false;
|
|
868
|
-
/*
|
|
869
|
-
// NOTE: same logic the above (code size optimiazation)
|
|
870
|
-
const canCall = (ctx: OnScrollInternalContext): boolean => {
|
|
871
|
-
// console.log('repeat', ctx.repeat, 'rate', ctx.rate, 'scrollRate', ctx.scrollRate, '1 - rate', 1 - ctx.rate, '1 - scrollRate', 1 - ctx.scrollRate, 'scrollRate >= rate', ctx.scrollRate >= ctx.rate, '1 - scrollRate >= 1 - rate', 1 - ctx.scrollRate >= 1 - ctx.rate);
|
|
872
|
-
// console.log(ctx.rate, 'deltaRate', ctx.deltaRate, 'reviousRate', ctx.previousRate)
|
|
873
|
-
if (ctx.zone === 'out') {
|
|
874
|
-
return ctx.scrollRate >= ctx.rate;
|
|
875
|
-
} else {
|
|
876
|
-
// 'in'
|
|
877
|
-
if (ctx.repeat) {
|
|
878
|
-
return ctx.scrollRate < ctx.rate || (ctx.scrollTop === 0 && ctx.scrollRate >= ctx.rate);
|
|
879
|
-
} else {
|
|
880
|
-
return false;
|
|
881
|
-
}
|
|
882
|
-
}
|
|
883
|
-
};
|
|
884
|
-
//*/
|
|
885
|
-
const onScroll = () => {
|
|
886
|
-
const scrollTop = html.scrollTop || body.scrollTop;
|
|
887
|
-
const pageHeight = Math.max(...[body.clientHeight, body.scrollHeight, html.scrollHeight, html.clientHeight]);
|
|
888
|
-
const viewHeight = Math.min(...[html.clientHeight, body.clientHeight]);
|
|
889
|
-
const scrollRate = (scrollTop + viewHeight) / pageHeight;
|
|
890
|
-
// console.log('scrollRate ->', scrollRate, 'scrollTop ->', scrollTop);
|
|
891
|
-
contexts.forEach(ctx => {
|
|
892
|
-
ctx.scrollRate = scrollRate;
|
|
893
|
-
ctx.deltaRate = ctx.scrollRate - ctx.previousRate;
|
|
894
|
-
ctx.previousRate = ctx.scrollRate;
|
|
895
|
-
ctx.scrollTop = scrollTop;
|
|
896
|
-
if (canCall(ctx)) {
|
|
897
|
-
const repeat = !!_fn(Object.assign({ direction: direction(ctx) }, ctx));
|
|
898
|
-
updateStates(ctx, repeat);
|
|
899
|
-
}
|
|
900
|
-
});
|
|
901
|
-
};
|
|
902
|
-
// register scorll event
|
|
903
|
-
window.addEventListener('scroll', onScroll);
|
|
904
|
-
// return disposing (finalizing/releasing) function
|
|
905
|
-
return () => {
|
|
906
|
-
window.removeEventListener('scroll', onScroll);
|
|
907
|
-
};
|
|
908
|
-
}
|
|
909
|
-
/**
|
|
910
|
-
* 指定した時間の経過後に呼び出すコールバックを登録します
|
|
911
|
-
*
|
|
912
|
-
* @param time - コールバックを呼び出すまでの時間。単位はミリセカンド(ms)
|
|
913
|
-
* @param fn - 指定した時間が経過後に呼び出されるコールバック関数
|
|
914
|
-
*
|
|
915
|
-
* @returns コールバックを呼び出すためのタイマーを停止する関数を返します
|
|
916
|
-
*
|
|
917
|
-
* @public
|
|
918
|
-
*/
|
|
919
|
-
function onTime(time, fn) {
|
|
920
|
-
const timeoutHandler = setTimeout(fn, time);
|
|
921
|
-
return () => timeoutHandler && clearTimeout(timeoutHandler);
|
|
922
|
-
}
|
|
923
|
-
/** @internal */
|
|
924
|
-
function hasSuffix(value, suffix) {
|
|
925
|
-
return new RegExp(`[0-9]${suffix}$`).test(value);
|
|
926
|
-
}
|
|
927
|
-
/** @internal */
|
|
928
|
-
function randStr(digit = 8) {
|
|
929
|
-
return Math.random().toString(32).substring(digit);
|
|
930
|
-
}
|
|
931
|
-
/**
|
|
932
|
-
* Goolge Fonts用のURLを生成
|
|
933
|
-
*
|
|
934
|
-
* @param fonts - フォント名の配列
|
|
935
|
-
* @param texts - 使用するテキストの配列
|
|
936
|
-
*
|
|
937
|
-
* @remarks
|
|
938
|
-
* textsを指定した場合フォントサイズが削減される
|
|
939
|
-
*
|
|
940
|
-
* @internal
|
|
941
|
-
*/
|
|
942
|
-
function makeGoogleFontUrl(fonts, texts) {
|
|
943
|
-
const params = [];
|
|
944
|
-
params.push('display=swap');
|
|
945
|
-
if (texts) {
|
|
946
|
-
texts.forEach(text => params.push(`text=${text}`));
|
|
947
|
-
}
|
|
948
|
-
fonts.forEach(font => params.push(`family=${font.replace(/['"]/g, '').replace(/ /g, '+')}`));
|
|
949
|
-
return `https://fonts.googleapis.com/css2?${params.join('&')}`;
|
|
950
|
-
}
|
|
951
|
-
/**
|
|
952
|
-
* HTML要素を生成
|
|
953
|
-
*
|
|
954
|
-
* @internal
|
|
955
|
-
*/
|
|
956
|
-
const h = (type, props, ...children) => {
|
|
957
|
-
const el = document.createElement(type);
|
|
958
|
-
for (const key of Object.keys(props)) {
|
|
959
|
-
const v = props[key];
|
|
960
|
-
if (key === 'style') {
|
|
961
|
-
Object.assign(el.style, v);
|
|
962
|
-
}
|
|
963
|
-
else {
|
|
964
|
-
el.setAttribute(key, v);
|
|
965
|
-
}
|
|
966
|
-
}
|
|
967
|
-
for (const child of children) {
|
|
968
|
-
el.appendChild(child);
|
|
969
|
-
}
|
|
970
|
-
return el;
|
|
971
|
-
};
|
|
972
|
-
|
|
973
973
|
/**
|
|
974
974
|
* アクションのログの記録の管理
|
|
975
975
|
*/
|