@inizioevoke/astro-core 1.7.0 → 2.0.1
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/package.json +3 -5
- package/src/components/FlipCard/FlipCard.ts +15 -9
- package/src/components/ISI/{RightISI.astro → Right/RightISI.astro} +16 -9
- package/src/components/ISI/Right/RightISI.css +61 -0
- package/src/components/ISI/{RightISI.md → Right/RightISI.md} +0 -1
- package/src/components/ISI/Right/RightISI.ts +78 -0
- package/src/components/ISI/Right/index.ts +1 -0
- package/src/components/ISI/index.ts +5 -0
- package/src/components/Modal/Modal.astro +11 -5
- package/src/components/Modal/Modal.css +49 -39
- package/src/components/Modal/Modal.ts +186 -169
- package/src/components/PdfViewer/PdfViewer.astro +26 -12
- package/src/components/PdfViewer/PdfViewer.css +62 -53
- package/src/components/PdfViewer/PdfViewer.ts +446 -210
- package/src/components/ScrollContainer/ScrollContainer.astro +28 -24
- package/src/components/ScrollContainer/ScrollContainer.css +66 -21
- package/src/components/ScrollContainer/ScrollContainer.ts +170 -67
- package/src/components/index.ts +1 -0
- package/src/lib/index.ts +2 -0
- package/src/components/ISI/RightISI.css +0 -31
- package/src/components/ISI/RightISI.ts +0 -27
- package/src/components/Modal/v2/Modal.astro +0 -42
- package/src/components/Modal/v2/Modal.css +0 -155
- package/src/components/Modal/v2/Modal.ts +0 -219
- package/src/components/Modal/v2/ModalOverlay.astro +0 -14
- package/src/components/Modal/v2/ModalTrigger.astro +0 -29
- package/src/components/Modal/v2/index.ts +0 -1
- package/src/components/ScrollContainer/archive-20260417.ts +0 -150
- package/src/components/v2.ts +0 -3
- package/src/lib/v2.ts +0 -1
|
@@ -1,155 +0,0 @@
|
|
|
1
|
-
|
|
2
|
-
@layer inizioevoke-astro-components {
|
|
3
|
-
:root {
|
|
4
|
-
--evo-modal-viewport-width: 100vw;
|
|
5
|
-
--evo-modal-viewport-height: 100vh;
|
|
6
|
-
--evo-modal-position: absolute;
|
|
7
|
-
--evo-modal-width: 800px;
|
|
8
|
-
--evo-modal-height: 450px;
|
|
9
|
-
--evo-modal-animation-duration: 300ms;
|
|
10
|
-
--evo-modal-z-index: 99;
|
|
11
|
-
--evo-modal-overlay-blur: 2px;
|
|
12
|
-
}
|
|
13
|
-
|
|
14
|
-
.evo-modal-overlay {
|
|
15
|
-
position: fixed;
|
|
16
|
-
left: 0;
|
|
17
|
-
top: 0;
|
|
18
|
-
display: none;
|
|
19
|
-
opacity: 0;
|
|
20
|
-
width: 100%;
|
|
21
|
-
height: 100%;
|
|
22
|
-
backdrop-filter: blur(var(--evo-modal-overlay-blur));
|
|
23
|
-
background-color: rgba(0,0,0,0.66);
|
|
24
|
-
z-index: calc(var(--evo-modal-z-index) - 1);
|
|
25
|
-
animation-duration: var(--evo-modal-animation-duration);
|
|
26
|
-
animation-iteration-count: 1;
|
|
27
|
-
animation-timing-function: linear;
|
|
28
|
-
animation-fill-mode: forwards;
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
evo-modal {
|
|
32
|
-
position: var(--evo-modal-position);
|
|
33
|
-
left: calc((var(--evo-modal-viewport-width) - var(--evo-modal-width)) / 2);
|
|
34
|
-
top: calc((var(--evo-modal-viewport-height) - var(--evo-modal-height)) / 2);
|
|
35
|
-
width: var(--evo-modal-width);
|
|
36
|
-
height: var(--evo-modal-height);
|
|
37
|
-
display: none;
|
|
38
|
-
margin: 0;
|
|
39
|
-
padding: 0;
|
|
40
|
-
opacity: 0;
|
|
41
|
-
color: #000000;
|
|
42
|
-
background-color: #ffffff;
|
|
43
|
-
z-index: var(--evo-modal-z-index);
|
|
44
|
-
box-sizing: border-box;
|
|
45
|
-
animation-duration: var(--evo-modal-animation-duration);
|
|
46
|
-
animation-iteration-count: 1;
|
|
47
|
-
animation-timing-function: linear;
|
|
48
|
-
animation-fill-mode: forwards;
|
|
49
|
-
|
|
50
|
-
.evo-modal-close {
|
|
51
|
-
/* the button click area is larger than the visible button */
|
|
52
|
-
position: absolute;
|
|
53
|
-
right: 0px;
|
|
54
|
-
top: 0px;
|
|
55
|
-
width: 40px;
|
|
56
|
-
height: 40px;
|
|
57
|
-
background-color: transparent;
|
|
58
|
-
border: none;
|
|
59
|
-
cursor: pointer;
|
|
60
|
-
z-index: var(--evo-modal-z-index);
|
|
61
|
-
box-sizing: border-box;
|
|
62
|
-
|
|
63
|
-
&.evo-modal-theme-default {
|
|
64
|
-
.evo-modal-x {
|
|
65
|
-
position: absolute;
|
|
66
|
-
right: 8px;
|
|
67
|
-
top: 8px;
|
|
68
|
-
display: block;
|
|
69
|
-
width: 24px;
|
|
70
|
-
height: 24px;
|
|
71
|
-
background-color: #990000;
|
|
72
|
-
border: none;
|
|
73
|
-
border-radius: 50%;
|
|
74
|
-
text-align: left;
|
|
75
|
-
text-indent: -9999px;
|
|
76
|
-
transform: rotate(45deg);
|
|
77
|
-
|
|
78
|
-
&::before,
|
|
79
|
-
&::after {
|
|
80
|
-
content: "";
|
|
81
|
-
position: absolute;
|
|
82
|
-
background-color: #ffffff;
|
|
83
|
-
}
|
|
84
|
-
&::before {
|
|
85
|
-
left: 5px;
|
|
86
|
-
top: 11px;
|
|
87
|
-
width: 14px;
|
|
88
|
-
height: 2px;
|
|
89
|
-
}
|
|
90
|
-
&::after {
|
|
91
|
-
left: 11px;
|
|
92
|
-
top: 5px;
|
|
93
|
-
width: 2px;
|
|
94
|
-
height: 14px;
|
|
95
|
-
}
|
|
96
|
-
}
|
|
97
|
-
}
|
|
98
|
-
}
|
|
99
|
-
|
|
100
|
-
.evo-modal-wrapper {
|
|
101
|
-
position: relative;
|
|
102
|
-
width: 100%;
|
|
103
|
-
height: 100%;
|
|
104
|
-
padding: 1rem;
|
|
105
|
-
overflow: hidden;
|
|
106
|
-
box-sizing: border-box;
|
|
107
|
-
|
|
108
|
-
h1,h2,h3 {
|
|
109
|
-
&:first-child {
|
|
110
|
-
margin-top: 0;
|
|
111
|
-
}
|
|
112
|
-
}
|
|
113
|
-
}
|
|
114
|
-
}
|
|
115
|
-
|
|
116
|
-
.evo-modal-visible {
|
|
117
|
-
display: block;
|
|
118
|
-
}
|
|
119
|
-
|
|
120
|
-
.evo-modal-hide-none {
|
|
121
|
-
display: none;
|
|
122
|
-
opacity: 0;
|
|
123
|
-
}
|
|
124
|
-
.evo-modal-hide-fade {
|
|
125
|
-
/* display: block; */
|
|
126
|
-
opacity: 0;
|
|
127
|
-
animation-name: evo_modal_hide;
|
|
128
|
-
}
|
|
129
|
-
.evo-modal-show-none {
|
|
130
|
-
display: block;
|
|
131
|
-
opacity: 1;
|
|
132
|
-
}
|
|
133
|
-
.evo-modal-show-fade {
|
|
134
|
-
/* display: block; */
|
|
135
|
-
opacity: 1;
|
|
136
|
-
animation-name: evo_modal_show;
|
|
137
|
-
}
|
|
138
|
-
|
|
139
|
-
@keyframes evo_modal_show {
|
|
140
|
-
0% {
|
|
141
|
-
opacity: 0;
|
|
142
|
-
}
|
|
143
|
-
100% {
|
|
144
|
-
opacity: 1;
|
|
145
|
-
}
|
|
146
|
-
}
|
|
147
|
-
@keyframes evo_modal_hide {
|
|
148
|
-
0% {
|
|
149
|
-
opacity: 1;
|
|
150
|
-
}
|
|
151
|
-
100% {
|
|
152
|
-
opacity: 0;
|
|
153
|
-
}
|
|
154
|
-
}
|
|
155
|
-
}
|
|
@@ -1,219 +0,0 @@
|
|
|
1
|
-
|
|
2
|
-
const TAG_NAME = 'evo-modal';
|
|
3
|
-
const CSS_VISIBLE = 'evo-modal-visible';
|
|
4
|
-
const CSS_PREFIX_SHOW = 'evo-modal-show';
|
|
5
|
-
const CSS_PREFIX_HIDE = 'evo-modal-hide';
|
|
6
|
-
const CSS_OVERLAY = 'evo-modal-overlay';
|
|
7
|
-
|
|
8
|
-
export type ModalAnimation = 'none' | 'fade';
|
|
9
|
-
|
|
10
|
-
export interface ModalEventDetail {
|
|
11
|
-
modal: EvoModalElement;
|
|
12
|
-
replacedBy?: EvoModalElement;
|
|
13
|
-
}
|
|
14
|
-
export type ModalEventCallback = (e: CustomEvent<ModalEventDetail>) => void;
|
|
15
|
-
|
|
16
|
-
declare global {
|
|
17
|
-
interface ElementEventMap {
|
|
18
|
-
'evomodalvisible': CustomEvent<ModalEventDetail>,
|
|
19
|
-
'evomodalhidden': CustomEvent<ModalEventDetail>
|
|
20
|
-
}
|
|
21
|
-
}
|
|
22
|
-
type ModalEventType = 'evomodalvisible' | 'evomodalhidden';
|
|
23
|
-
|
|
24
|
-
export class EvoModalElement extends HTMLElement {
|
|
25
|
-
#animation: ModalAnimation = 'fade';
|
|
26
|
-
|
|
27
|
-
constructor() {
|
|
28
|
-
super();
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
connectedCallback() {
|
|
32
|
-
this.querySelectorAll<HTMLElement>('.evo-modal-action-hide').forEach((trigger) => {
|
|
33
|
-
trigger.addEventListener('click', () => {
|
|
34
|
-
this.hideModal();
|
|
35
|
-
}, { passive: true });
|
|
36
|
-
})
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
showModal({ animation = 'fade' }: { animation?: ModalAnimation } = {}): Promise<void> {
|
|
40
|
-
return new Promise<void>((resolve) => {
|
|
41
|
-
if (!this.classList.contains(CSS_VISIBLE)) {
|
|
42
|
-
[...document.querySelectorAll<EvoModalElement>(`${TAG_NAME}.${CSS_VISIBLE}`)]
|
|
43
|
-
.forEach((modal) => {
|
|
44
|
-
modal.#hideModal({ overlay: false, replacedBy: this });
|
|
45
|
-
});
|
|
46
|
-
this.#animation = animation;
|
|
47
|
-
this.classList.add(CSS_VISIBLE, `${CSS_PREFIX_SHOW}-${animation}`);
|
|
48
|
-
showOverlay(this.#animation);
|
|
49
|
-
|
|
50
|
-
setTimeout(() => {
|
|
51
|
-
this.dispatchEvent(createModalEvent('evomodalvisible', this));
|
|
52
|
-
resolve();
|
|
53
|
-
}, animation !== 'none' ? getAnimationDuration(this) : 0)
|
|
54
|
-
} else {
|
|
55
|
-
resolve();
|
|
56
|
-
}
|
|
57
|
-
});
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
hideModal({ animation }: { animation?: ModalAnimation } = {}): Promise<void> {
|
|
61
|
-
return this.#hideModal({ animation });
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
#hideModal({ animation, overlay = true, replacedBy }: { animation?: ModalAnimation, overlay?: boolean, replacedBy?: EvoModalElement } = {}): Promise<void> {
|
|
65
|
-
return new Promise<void>((resolve) => {
|
|
66
|
-
if (this.classList.contains(CSS_VISIBLE)) {
|
|
67
|
-
if (!animation) {
|
|
68
|
-
animation = this.#animation;
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
const duration = getAnimationDuration(this);
|
|
72
|
-
|
|
73
|
-
this.classList.add(`${CSS_PREFIX_HIDE}-${this.#animation}`);
|
|
74
|
-
this.classList.remove(`${CSS_PREFIX_SHOW}-${this.#animation}`);
|
|
75
|
-
if (overlay) {
|
|
76
|
-
hideOverlay({ modal: this, animation: this.#animation, duration });
|
|
77
|
-
}
|
|
78
|
-
|
|
79
|
-
setTimeout(() => {
|
|
80
|
-
this.classList.remove('evo-modal-visible', `${CSS_PREFIX_HIDE}-${this.#animation}`);
|
|
81
|
-
this.dispatchEvent(createModalEvent('evomodalhidden', this, { replacedBy }));
|
|
82
|
-
resolve();
|
|
83
|
-
}, animation !== 'none' ? duration : 0);
|
|
84
|
-
} else {
|
|
85
|
-
resolve();
|
|
86
|
-
}
|
|
87
|
-
});
|
|
88
|
-
}
|
|
89
|
-
}
|
|
90
|
-
if (!customElements.get(TAG_NAME)) {
|
|
91
|
-
customElements.define(TAG_NAME, EvoModalElement);
|
|
92
|
-
}
|
|
93
|
-
|
|
94
|
-
function createModalEvent(type: ModalEventType, modal: EvoModalElement, { replacedBy }: { replacedBy?: EvoModalElement } = {}) {
|
|
95
|
-
return new CustomEvent(type, {
|
|
96
|
-
detail: { modal, replacedBy },
|
|
97
|
-
bubbles: true,
|
|
98
|
-
composed: true
|
|
99
|
-
});
|
|
100
|
-
}
|
|
101
|
-
|
|
102
|
-
interface ShowModalOpts {
|
|
103
|
-
animation?: ModalAnimation;
|
|
104
|
-
onShow?: ModalEventCallback;
|
|
105
|
-
onHide?: ModalEventCallback;
|
|
106
|
-
}
|
|
107
|
-
|
|
108
|
-
export async function showModal(selector: string | HTMLElement, { animation, onShow, onHide }: ShowModalOpts = {}): Promise<EvoModalElement | undefined> {
|
|
109
|
-
if (typeof selector == 'string' && selector !== TAG_NAME && !/[#\.]/.test(selector)) {
|
|
110
|
-
selector = `#${selector}`; // assume this is an id
|
|
111
|
-
}
|
|
112
|
-
const modal = typeof selector == 'string' ? document.querySelector<EvoModalElement>(selector) : selector;
|
|
113
|
-
if (modal && modal instanceof EvoModalElement) {
|
|
114
|
-
if (typeof onShow == 'function') {
|
|
115
|
-
modal.addEventListener('evomodalvisible', onShow, { once: true });
|
|
116
|
-
}
|
|
117
|
-
if (typeof onHide == 'function') {
|
|
118
|
-
modal.addEventListener('evomodalhidden', onHide, { once: true });
|
|
119
|
-
}
|
|
120
|
-
await modal.showModal({ animation });
|
|
121
|
-
return modal;
|
|
122
|
-
} else {
|
|
123
|
-
return undefined;
|
|
124
|
-
}
|
|
125
|
-
}
|
|
126
|
-
|
|
127
|
-
export async function hideModal(selector: string | HTMLElement, animation?: ModalAnimation) {
|
|
128
|
-
const modal = typeof selector == 'string' ? document.querySelector<EvoModalElement>(selector) : selector;
|
|
129
|
-
if (modal && modal instanceof EvoModalElement) {
|
|
130
|
-
await modal.hideModal({ animation });
|
|
131
|
-
}
|
|
132
|
-
}
|
|
133
|
-
|
|
134
|
-
export async function hideModals(animation?: ModalAnimation) {
|
|
135
|
-
const modals = [...document.querySelectorAll<EvoModalElement>(`${TAG_NAME}.${CSS_VISIBLE}`)];
|
|
136
|
-
await Promise.all(modals.map((m) => { return m.hideModal({ animation })}));
|
|
137
|
-
}
|
|
138
|
-
|
|
139
|
-
export function showOverlay(animation: ModalAnimation = 'fade') {
|
|
140
|
-
const overlay = getOverlay();
|
|
141
|
-
if (overlay && !overlay.classList.contains(CSS_VISIBLE)) {
|
|
142
|
-
overlay.classList.add(CSS_VISIBLE);
|
|
143
|
-
requestAnimationFrame(() => {
|
|
144
|
-
overlay.classList.add(`${CSS_PREFIX_SHOW}-${animation}`);
|
|
145
|
-
});
|
|
146
|
-
}
|
|
147
|
-
}
|
|
148
|
-
export function hideOverlay({ modal, animation = 'fade', duration }: { modal?: EvoModalElement, animation?: ModalAnimation, duration?: number } = {}) {
|
|
149
|
-
const overlay = getOverlay();
|
|
150
|
-
if (overlay && overlay.classList.contains(CSS_VISIBLE)) {
|
|
151
|
-
const cssShow = [...overlay.classList]
|
|
152
|
-
.filter((c) => {
|
|
153
|
-
return c.startsWith(CSS_PREFIX_SHOW);
|
|
154
|
-
});
|
|
155
|
-
const cssHide = [...overlay.classList]
|
|
156
|
-
.filter((c) => {
|
|
157
|
-
return c.startsWith(CSS_PREFIX_HIDE);
|
|
158
|
-
});
|
|
159
|
-
|
|
160
|
-
if (cssShow.length !== 0 && cssHide.length === 0) {
|
|
161
|
-
cssHide.push(`${CSS_PREFIX_HIDE}-${animation}`)
|
|
162
|
-
overlay.classList.add(cssHide[0]);
|
|
163
|
-
overlay.classList.remove(cssShow[0]);
|
|
164
|
-
setTimeout(() => {
|
|
165
|
-
overlay.classList.remove(CSS_VISIBLE, cssHide[0]);
|
|
166
|
-
}, duration ?? getAnimationDuration(modal));
|
|
167
|
-
}
|
|
168
|
-
|
|
169
|
-
}
|
|
170
|
-
}
|
|
171
|
-
|
|
172
|
-
/**
|
|
173
|
-
* Call this function when dynamically adding a trigger to the DOM
|
|
174
|
-
*/
|
|
175
|
-
export function bindTriggers(container = document) {
|
|
176
|
-
container.querySelectorAll<HTMLElement>('[data-evo-modal-show]').forEach((trigger) => {
|
|
177
|
-
if (!trigger.hasAttribute('data-evo-modal-bound')) {
|
|
178
|
-
trigger.setAttribute('data-evo-modal-bound','true');
|
|
179
|
-
trigger.addEventListener('click', async (e) => {
|
|
180
|
-
e.preventDefault();
|
|
181
|
-
const target = (e.currentTarget ?? e.target) as HTMLElement;
|
|
182
|
-
const animation = (target.getAttribute('data-evo-modal-animation') ?? undefined) as ModalAnimation | undefined;
|
|
183
|
-
await showModal(target.getAttribute('data-evo-modal-show') as string, { animation });
|
|
184
|
-
});
|
|
185
|
-
}
|
|
186
|
-
});
|
|
187
|
-
}
|
|
188
|
-
|
|
189
|
-
function getOverlay() {
|
|
190
|
-
return document.querySelector<HTMLElement>(`.${CSS_OVERLAY}`);
|
|
191
|
-
}
|
|
192
|
-
|
|
193
|
-
function getAnimationDuration(element: HTMLElement = document.body) {
|
|
194
|
-
let duration = 300;
|
|
195
|
-
const cssDuration = getComputedStyle(element).getPropertyValue('--evo-modal-animation-duration').trim();
|
|
196
|
-
if (cssDuration) {
|
|
197
|
-
// Match ms or s suffixes
|
|
198
|
-
const match = cssDuration.match(/^(\d+(?:\.\d+)?)(m?s)$/);
|
|
199
|
-
if (match) {
|
|
200
|
-
const value = parseFloat(match[1]);
|
|
201
|
-
const unit = match[2];
|
|
202
|
-
duration = unit === 'ms' ? value : value * 1000;
|
|
203
|
-
}
|
|
204
|
-
}
|
|
205
|
-
return duration;
|
|
206
|
-
}
|
|
207
|
-
|
|
208
|
-
document.addEventListener('DOMContentLoaded', (e) => {
|
|
209
|
-
bindTriggers();
|
|
210
|
-
|
|
211
|
-
if (!getOverlay()) {
|
|
212
|
-
const overlay = document.createElement('div');
|
|
213
|
-
overlay.classList.add(CSS_OVERLAY);
|
|
214
|
-
overlay.addEventListener('click', () => {
|
|
215
|
-
hideModals();
|
|
216
|
-
}, { passive: true });
|
|
217
|
-
document.body.append(overlay);
|
|
218
|
-
}
|
|
219
|
-
}, { passive: true });
|
|
@@ -1,14 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
import type { HTMLAttributes } from "astro/types";
|
|
3
|
-
|
|
4
|
-
interface Props extends HTMLAttributes<'div'> {
|
|
5
|
-
class?: string;
|
|
6
|
-
}
|
|
7
|
-
|
|
8
|
-
const {
|
|
9
|
-
class: cssClass,
|
|
10
|
-
...rest
|
|
11
|
-
} = Astro.props;
|
|
12
|
-
|
|
13
|
-
---
|
|
14
|
-
<div class:list={['evo-modal-overlay', cssClass]} {...rest}><slot /></div>
|
|
@@ -1,29 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
import type { HTMLAttributes } from "astro/types";
|
|
3
|
-
import type { ModalAnimation } from './Modal';
|
|
4
|
-
|
|
5
|
-
interface Props extends HTMLAttributes<'button'> {
|
|
6
|
-
modal: string;
|
|
7
|
-
animation?: ModalAnimation;
|
|
8
|
-
}
|
|
9
|
-
|
|
10
|
-
const {
|
|
11
|
-
modal,
|
|
12
|
-
animation,
|
|
13
|
-
...rest
|
|
14
|
-
} = Astro.props;
|
|
15
|
-
|
|
16
|
-
interface ButtonAttrs extends HTMLAttributes<'button'> {
|
|
17
|
-
'data-evo-modal-show': string;
|
|
18
|
-
'data-evo-modal-animation'?: ModalAnimation
|
|
19
|
-
};
|
|
20
|
-
|
|
21
|
-
const attrs: ButtonAttrs = {...rest, 'data-evo-modal-show': modal};
|
|
22
|
-
if (animation) {
|
|
23
|
-
attrs['data-evo-modal-animation'] = animation;
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
const cssClass = attrs['class'];
|
|
27
|
-
delete attrs['class'];
|
|
28
|
-
---
|
|
29
|
-
<button class:list={['evo-modal-trigger', cssClass]} {...attrs}><slot /></button>
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export * from './Modal';
|
|
@@ -1,150 +0,0 @@
|
|
|
1
|
-
|
|
2
|
-
export interface IScrollContainer {
|
|
3
|
-
container: HTMLElement;
|
|
4
|
-
content: HTMLElement;
|
|
5
|
-
track: HTMLElement;
|
|
6
|
-
thumb: HTMLElement;
|
|
7
|
-
isDragging: boolean;
|
|
8
|
-
startY: number;
|
|
9
|
-
startScrollTop: number;
|
|
10
|
-
}
|
|
11
|
-
|
|
12
|
-
export function resize(scrollContainer: IScrollContainer, { height }: { height?: number }) {
|
|
13
|
-
if (typeof height == 'number') {
|
|
14
|
-
scrollContainer.container.style.height = `${height}px`;
|
|
15
|
-
refresh(scrollContainer);
|
|
16
|
-
}
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
export function refresh(scrollContainer?: IScrollContainer) {
|
|
20
|
-
if (scrollContainer) {
|
|
21
|
-
updateThumbSize(scrollContainer);
|
|
22
|
-
} else {
|
|
23
|
-
[...scrollContainers.values()].forEach((scrollContainer) => {
|
|
24
|
-
updateThumbSize(scrollContainer);
|
|
25
|
-
});
|
|
26
|
-
}
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
export function getScroll(scrollContainer: IScrollContainer): { left: number, top: number } {
|
|
30
|
-
return {
|
|
31
|
-
left: scrollContainer.content.scrollLeft,
|
|
32
|
-
top: scrollContainer.content.scrollTop
|
|
33
|
-
};
|
|
34
|
-
}
|
|
35
|
-
export function scroll(scrollContainer: IScrollContainer, { left, top, behavior = 'auto' }: { left?: number, top?: number, behavior?: 'auto' | 'instant' | 'smooth' } = {}) {
|
|
36
|
-
const current = getScroll(scrollContainer);
|
|
37
|
-
scrollContainer.content.scroll({ left: left ?? current.left, top: top ?? current.top, behavior });
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
export function getScrollContainer(selector: string | HTMLElement): IScrollContainer | undefined {
|
|
41
|
-
const key = typeof selector == 'string' ? document.querySelector<HTMLElement>(selector) : selector;
|
|
42
|
-
return key ? scrollContainers.get(key) : undefined;
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
function thumbMouseDown(scrollContainer: IScrollContainer, e: MouseEvent) {
|
|
46
|
-
scrollContainer.isDragging = true;
|
|
47
|
-
scrollContainer.startY = e.clientY;
|
|
48
|
-
scrollContainer.startScrollTop = scrollContainer.content.scrollTop;
|
|
49
|
-
scrollContainer.thumb.style.cursor = 'grabbing';
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
function updateThumbSize(scrollContainer: IScrollContainer) {
|
|
53
|
-
const { container, content, thumb, track } = scrollContainer;
|
|
54
|
-
const scrollHeight = content.scrollHeight - getPaddingY(content);
|
|
55
|
-
const containerHeight = container.clientHeight - getPaddingY(container);
|
|
56
|
-
const visibleRatio = containerHeight / scrollHeight;
|
|
57
|
-
const thumbHeight = visibleRatio * containerHeight;
|
|
58
|
-
thumb.style.height = `${thumbHeight > 20 ? thumbHeight : 20}px`;
|
|
59
|
-
track.style.display = visibleRatio < 1 ? 'block' : 'none';
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
function scrollContent(scrollContainer: IScrollContainer) {
|
|
63
|
-
const { container, content, thumb, track } = scrollContainer;
|
|
64
|
-
const scrollHeight = content.scrollHeight - getPaddingY(content);
|
|
65
|
-
const containerHeight = container.clientHeight - getPaddingY(container);
|
|
66
|
-
const scrollRatio = content.scrollTop / (scrollHeight - containerHeight);
|
|
67
|
-
const top = scrollRatio * (track.clientHeight - thumb.clientHeight);
|
|
68
|
-
thumb.style.top = `${top}px`;
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
function getPaddingY(content: HTMLElement): number {
|
|
72
|
-
const style = getComputedStyle(content);
|
|
73
|
-
return parseFloat(style.paddingTop) + parseFloat(style.paddingBottom);
|
|
74
|
-
}
|
|
75
|
-
|
|
76
|
-
function getScrollContainerElement(element: HTMLElement) {
|
|
77
|
-
let container = element;
|
|
78
|
-
while (container && !container.classList.contains('scroll-container')) {
|
|
79
|
-
container = container.parentElement as HTMLElement;
|
|
80
|
-
}
|
|
81
|
-
return container;
|
|
82
|
-
}
|
|
83
|
-
|
|
84
|
-
function createScrollContainer(container: HTMLElement): IScrollContainer {
|
|
85
|
-
return {
|
|
86
|
-
container: container,
|
|
87
|
-
content: container.querySelector('.evo-scroll-content') as HTMLElement,
|
|
88
|
-
track: container.querySelector('.evo-scroll-track') as HTMLElement,
|
|
89
|
-
thumb: container.querySelector('.evo-scroll-thumb') as HTMLElement,
|
|
90
|
-
isDragging: false,
|
|
91
|
-
startY: 0,
|
|
92
|
-
startScrollTop: 0
|
|
93
|
-
};
|
|
94
|
-
}
|
|
95
|
-
|
|
96
|
-
const scrollContainers = new Map<HTMLElement, IScrollContainer>();
|
|
97
|
-
|
|
98
|
-
const intersectionObserver = new IntersectionObserver((entries) => {
|
|
99
|
-
entries.forEach((entry) => {
|
|
100
|
-
if (entry.isIntersecting) {
|
|
101
|
-
updateThumbSize(scrollContainers.get(entry.target as HTMLElement) as IScrollContainer);
|
|
102
|
-
}
|
|
103
|
-
});
|
|
104
|
-
},
|
|
105
|
-
{ threshold: 0.1 }
|
|
106
|
-
);
|
|
107
|
-
|
|
108
|
-
const mutationObserver = new MutationObserver((mutations) => {
|
|
109
|
-
const containers: IScrollContainer[] = [];
|
|
110
|
-
mutations.forEach((mutation) => {
|
|
111
|
-
const sc = scrollContainers.get(getScrollContainerElement(mutation.target as HTMLElement));
|
|
112
|
-
if (sc && !containers.includes(sc)) {
|
|
113
|
-
containers.push(sc);
|
|
114
|
-
}
|
|
115
|
-
});
|
|
116
|
-
containers.forEach((container) => {
|
|
117
|
-
updateThumbSize(container);
|
|
118
|
-
});
|
|
119
|
-
});
|
|
120
|
-
|
|
121
|
-
document.querySelectorAll<HTMLElement>('.evo-scroll-container').forEach((container) => {
|
|
122
|
-
const scrollContainer = createScrollContainer(container);
|
|
123
|
-
scrollContainers.set(container, scrollContainer);
|
|
124
|
-
scrollContainer.thumb.addEventListener('mousedown', (e) => { thumbMouseDown(scrollContainer, e); }, { passive: true });
|
|
125
|
-
scrollContainer.content.addEventListener('scroll', (e) => { scrollContent(scrollContainer); }, { passive: true });
|
|
126
|
-
intersectionObserver.observe(container);
|
|
127
|
-
mutationObserver.observe(container, { childList: true, subtree: true });
|
|
128
|
-
});
|
|
129
|
-
document.addEventListener('mousemove', (e) => {
|
|
130
|
-
[...scrollContainers.values()].forEach((scrollContainer) => {
|
|
131
|
-
if (!scrollContainer.isDragging) return;
|
|
132
|
-
const { container, content, thumb } = scrollContainer;
|
|
133
|
-
const deltaY = e.clientY - scrollContainer.startY;
|
|
134
|
-
const scrollRatio =
|
|
135
|
-
(content.scrollHeight - container.clientHeight) /
|
|
136
|
-
(container.clientHeight - thumb.clientHeight);
|
|
137
|
-
scrollContainer.content.scrollTop = scrollContainer.startScrollTop + deltaY * scrollRatio;
|
|
138
|
-
});
|
|
139
|
-
});
|
|
140
|
-
document.addEventListener('mouseup', () => {
|
|
141
|
-
[...scrollContainers.values()].forEach((scrollContainer) => {
|
|
142
|
-
scrollContainer.isDragging = false;
|
|
143
|
-
scrollContainer.thumb.style.cursor = 'grab';
|
|
144
|
-
});
|
|
145
|
-
});
|
|
146
|
-
window.addEventListener('resize', () => {
|
|
147
|
-
[...scrollContainers.values()].forEach((scrollContainer) => {
|
|
148
|
-
updateThumbSize(scrollContainer);
|
|
149
|
-
});
|
|
150
|
-
});
|
package/src/components/v2.ts
DELETED
package/src/lib/v2.ts
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export * as Modal from '../components/Modal/v2/Modal';
|