@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.
Files changed (30) hide show
  1. package/package.json +3 -5
  2. package/src/components/FlipCard/FlipCard.ts +15 -9
  3. package/src/components/ISI/{RightISI.astro → Right/RightISI.astro} +16 -9
  4. package/src/components/ISI/Right/RightISI.css +61 -0
  5. package/src/components/ISI/{RightISI.md → Right/RightISI.md} +0 -1
  6. package/src/components/ISI/Right/RightISI.ts +78 -0
  7. package/src/components/ISI/Right/index.ts +1 -0
  8. package/src/components/ISI/index.ts +5 -0
  9. package/src/components/Modal/Modal.astro +11 -5
  10. package/src/components/Modal/Modal.css +49 -39
  11. package/src/components/Modal/Modal.ts +186 -169
  12. package/src/components/PdfViewer/PdfViewer.astro +26 -12
  13. package/src/components/PdfViewer/PdfViewer.css +62 -53
  14. package/src/components/PdfViewer/PdfViewer.ts +446 -210
  15. package/src/components/ScrollContainer/ScrollContainer.astro +28 -24
  16. package/src/components/ScrollContainer/ScrollContainer.css +66 -21
  17. package/src/components/ScrollContainer/ScrollContainer.ts +170 -67
  18. package/src/components/index.ts +1 -0
  19. package/src/lib/index.ts +2 -0
  20. package/src/components/ISI/RightISI.css +0 -31
  21. package/src/components/ISI/RightISI.ts +0 -27
  22. package/src/components/Modal/v2/Modal.astro +0 -42
  23. package/src/components/Modal/v2/Modal.css +0 -155
  24. package/src/components/Modal/v2/Modal.ts +0 -219
  25. package/src/components/Modal/v2/ModalOverlay.astro +0 -14
  26. package/src/components/Modal/v2/ModalTrigger.astro +0 -29
  27. package/src/components/Modal/v2/index.ts +0 -1
  28. package/src/components/ScrollContainer/archive-20260417.ts +0 -150
  29. package/src/components/v2.ts +0 -3
  30. package/src/lib/v2.ts +0 -1
@@ -1,206 +1,223 @@
1
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
+
2
8
  export type ModalAnimation = 'none' | 'fade';
3
- export type ModalEventCallback = (modal: HTMLElement | HTMLElement[]) => void;
4
- interface ModalEventCallbackItem {
5
- once?: boolean;
6
- callback: ModalEventCallback;
7
- }
8
- interface ModalEventCallbackArgs {
9
- once?: boolean
9
+
10
+ export interface ModalEventDetail {
11
+ modal: EvoModalElement;
12
+ replacedBy?: EvoModalElement;
10
13
  }
14
+ export type ModalEventCallback = (e: CustomEvent<ModalEventDetail>) => void;
11
15
 
12
- type ModalEventType = 'show' | 'hide' | 'overlay';
13
- type ModalEventTypeCallbacks = Record<ModalEventType, Set<ModalEventCallbackItem>>;
14
- const callbacks = new Map<HTMLElement, ModalEventTypeCallbacks>();
16
+ declare global {
17
+ interface ElementEventMap {
18
+ 'evomodal-visible': CustomEvent<ModalEventDetail>,
19
+ 'evomodal-hidden': CustomEvent<ModalEventDetail>
20
+ }
21
+ }
22
+ type ModalEventType = 'evomodal-visible' | 'evomodal-hidden';
15
23
 
16
- interface ModalOptions {
17
- animation?: ModalAnimation;
24
+ export interface IEvoModalElement {
25
+ showModal(opts?: { animation?: ModalAnimation }): Promise<void>;
26
+ hideModal(opts?: { animation?: ModalAnimation }): Promise<void>;
18
27
  }
19
- interface ModalShowOptions extends ModalOptions {
20
- on?: {
21
- show?: ModalEventCallback,
22
- hide?: ModalEventCallback
28
+ export class EvoModalElement extends HTMLElement implements IEvoModalElement {
29
+ #animation: ModalAnimation = 'fade';
30
+
31
+ constructor() {
32
+ super();
23
33
  }
24
- }
25
- export function show(selector: string | HTMLElement, { animation = 'fade', on }: ModalShowOptions = {}) {
26
- return new Promise<void>(async (resolve) => {
27
- let modal = typeof selector == 'string' ? document.querySelector<HTMLElement>(/^[\.#]/.test(selector) ? selector : `#${selector}`) : selector;
28
- if (modal) {
29
- if (on?.hide) {
30
- onEvent('hide', modal, { once: true, callback: on.hide });
34
+
35
+ connectedCallback() {
36
+ this.querySelectorAll<HTMLElement>('.evo-modal-action-hide').forEach((trigger) => {
37
+ trigger.addEventListener('click', () => {
38
+ this.hideModal();
39
+ }, { passive: true });
40
+ })
41
+ }
42
+
43
+ showModal({ animation = 'fade' }: { animation?: ModalAnimation } = {}): Promise<void> {
44
+ return new Promise<void>((resolve) => {
45
+ if (!this.classList.contains(CSS_VISIBLE)) {
46
+ [...document.querySelectorAll<EvoModalElement>(`${TAG_NAME}.${CSS_VISIBLE}`)]
47
+ .forEach((modal) => {
48
+ modal.#hideModal({ overlay: false, replacedBy: this });
49
+ });
50
+ this.#animation = animation;
51
+ this.classList.add(CSS_VISIBLE, `${CSS_PREFIX_SHOW}-${animation}`);
52
+ showOverlay(this.#animation);
53
+
54
+ setTimeout(() => {
55
+ this.dispatchEvent(createModalEvent('evomodal-visible', this));
56
+ resolve();
57
+ }, animation !== 'none' ? getAnimationDuration(this) : 0)
58
+ } else {
59
+ resolve();
31
60
  }
32
- await hide(null, { animation, hideOverlay: false });
33
- __showOverlay(animation);
61
+ });
62
+ }
34
63
 
35
- modal.classList.add('evo-modal-visible', `evo-modal-show-${animation}`);
36
- setTimeout(() => {
37
- triggerEventCallbacks(modal, 'show');
38
- if (on?.show) {
39
- try {
40
- on.show(modal);
41
- } catch (err) {
42
- console.log(err);
43
- }
64
+ hideModal({ animation }: { animation?: ModalAnimation } = {}): Promise<void> {
65
+ return this.#hideModal({ animation });
66
+ }
67
+
68
+ #hideModal({ animation, overlay = true, replacedBy }: { animation?: ModalAnimation, overlay?: boolean, replacedBy?: EvoModalElement } = {}): Promise<void> {
69
+ return new Promise<void>((resolve) => {
70
+ if (this.classList.contains(CSS_VISIBLE)) {
71
+ if (!animation) {
72
+ animation = this.#animation;
73
+ }
74
+
75
+ const duration = getAnimationDuration(this);
76
+
77
+ this.classList.add(`${CSS_PREFIX_HIDE}-${this.#animation}`);
78
+ this.classList.remove(`${CSS_PREFIX_SHOW}-${this.#animation}`);
79
+ if (overlay) {
80
+ hideOverlay({ modal: this, animation: this.#animation, duration });
44
81
  }
82
+
83
+ setTimeout(() => {
84
+ this.classList.remove('evo-modal-visible', `${CSS_PREFIX_HIDE}-${this.#animation}`);
85
+ this.dispatchEvent(createModalEvent('evomodal-hidden', this, { replacedBy }));
86
+ resolve();
87
+ }, animation !== 'none' ? duration : 0);
88
+ } else {
45
89
  resolve();
46
- }, animation !== 'none' ? getAnimationDuration(modal) : 0);
47
- }
48
- });
49
- }
50
- function __showOverlay(animation: ModalAnimation) {
51
- if (!overlay.classList.contains('evo-modal-visible')) {
52
- overlay.setAttribute('data-evo-modal-animation', animation);
53
- overlay.classList.add('evo-modal-visible', `evo-modal-show-${animation}`);
90
+ }
91
+ });
54
92
  }
55
93
  }
56
- export function onShow(selector: string | HTMLElement, callback: ModalEventCallback, { once }: ModalEventCallbackArgs = {}) {
57
- onEvent('show', selector, { once, callback });
94
+ if (!customElements.get(TAG_NAME)) {
95
+ customElements.define(TAG_NAME, EvoModalElement);
58
96
  }
59
97
 
60
- interface HideModalOptions extends ModalOptions {
61
- hideOverlay?: boolean;
62
- on?: {
63
- hide?: ModalEventCallback
64
- }
65
- }
66
- export function hide(selector?: string | HTMLElement | (string | HTMLElement)[] | null, { animation, hideOverlay = true, on }: HideModalOptions = {}) {
67
- return new Promise<void>(async (resolve) => {
68
- const modals: HTMLElement[] = (selector ? Array.isArray(selector) ? selector : [selector] : [...document.querySelectorAll<HTMLElement>('.evo-modal.evo-modal-visible')])
69
- .map((m) => {
70
- return typeof m == 'string' ? document.querySelector<HTMLElement>(/^[\.#]/.test(m) ? m : `#${m}`) : m;
71
- })
72
- .filter(m => m !== undefined && m !== null);
73
-
74
- const hides = [];
75
- if (!animation) {
76
- if (modals.length) {
77
- animation = ([...modals[0].classList.values()].find((c) => { return c.startsWith('evo-modal-show'); }) ?? 'evo-modal-show-fade').substring(15) as ModalAnimation;
78
- } else {
79
- animation = 'fade';
80
- }
81
- }
82
- for (let modal of modals) {
83
- hides.push(__hide(modal, animation));
84
- }
85
- if (hideOverlay) {
86
- hides.push(__hide(overlay, animation));
87
- }
88
- await Promise.all(hides);
89
- if (on?.hide) {
90
- try {
91
- on.hide(modals);
92
- } catch (err) {
93
- console.log(err);
94
- }
95
- }
96
- resolve();
98
+ function createModalEvent(type: ModalEventType, modal: EvoModalElement, { replacedBy }: { replacedBy?: EvoModalElement } = {}) {
99
+ return new CustomEvent(type, {
100
+ detail: { modal, replacedBy },
101
+ bubbles: true,
102
+ composed: true
97
103
  });
98
104
  }
99
- function __hide(modal: HTMLElement, animation: ModalAnimation) {
100
- return new Promise<void>((resolve) => {
101
- const showClass = [...modal.classList.values()].find((c) => { return c.startsWith('evo-modal-show'); }) ?? 'evo-modal-show-fade';
102
- modal.classList.add(`evo-modal-hide-${animation}`);
103
- modal.classList.remove(showClass);
104
- setTimeout(() => {
105
- modal.classList.remove('evo-modal-visible', `evo-modal-hide-${animation}`);
106
- triggerEventCallbacks(modal, 'hide');
107
- resolve();
108
- }, animation !== 'none' ? getAnimationDuration(modal) : 0);
109
- });
105
+
106
+ interface ShowModalOpts {
107
+ animation?: ModalAnimation;
108
+ onShow?: ModalEventCallback;
109
+ onHide?: ModalEventCallback;
110
110
  }
111
- export function onHide(selector: string | HTMLElement, callback: ModalEventCallback, { once }: ModalEventCallbackArgs = {}) {
112
- onEvent('hide', selector, { once, callback });
111
+
112
+ export async function showModal(selector: string | HTMLElement, { animation, onShow, onHide }: ShowModalOpts = {}): Promise<EvoModalElement | undefined> {
113
+ if (typeof selector == 'string' && selector !== TAG_NAME && !/[#\.]/.test(selector)) {
114
+ selector = `#${selector}`; // assume this is an id
115
+ }
116
+ const modal = typeof selector == 'string' ? document.querySelector<EvoModalElement>(selector) : selector;
117
+ if (modal && modal instanceof EvoModalElement) {
118
+ if (typeof onShow == 'function') {
119
+ modal.addEventListener('evomodal-visible', onShow, { once: true });
120
+ }
121
+ if (typeof onHide == 'function') {
122
+ modal.addEventListener('evomodal-hidden', onHide, { once: true });
123
+ }
124
+ await modal.showModal({ animation });
125
+ return modal;
126
+ } else {
127
+ return undefined;
128
+ }
113
129
  }
114
130
 
115
- /**
116
- * Moves the overlay element by appending it to an element
117
- * @param selector
118
- */
119
- export function appendOverlay(selector: string | HTMLElement) {
120
- const container = typeof selector == 'string' ? document.querySelector(selector) : selector;
121
- if (container) {
122
- container.appendChild(overlay);
131
+ export async function hideModal(selector: string | HTMLElement, animation?: ModalAnimation) {
132
+ const modal = typeof selector == 'string' ? document.querySelector<EvoModalElement>(selector) : selector;
133
+ if (modal && modal instanceof EvoModalElement) {
134
+ await modal.hideModal({ animation });
123
135
  }
124
136
  }
125
137
 
126
- export function onOverlayClick(callback: ModalEventCallback, { once }: ModalEventCallbackArgs = {}) {
127
- onEvent('overlay', overlay, { once, callback });
138
+ export async function hideModals(animation?: ModalAnimation) {
139
+ const modals = [...document.querySelectorAll<EvoModalElement>(`${TAG_NAME}.${CSS_VISIBLE}`)];
140
+ await Promise.all(modals.map((m) => { return m.hideModal({ animation })}));
128
141
  }
129
142
 
130
- function onEvent(type: ModalEventType, selector: string | HTMLElement, callbackItem: ModalEventCallbackItem) {
131
- let modal = typeof selector == 'string' ? document.querySelector<HTMLElement>(/^[\.#]/.test(selector) ? selector : `#${selector}`) : selector;
132
- if (modal) {
133
- const modalCallbacks = callbacks.get(modal) ?? {} as ModalEventTypeCallbacks;
134
- if (!modalCallbacks[type]) {
135
- modalCallbacks[type] = new Set();
136
- }
137
- modalCallbacks[type].add(callbackItem);
138
- callbacks.set(modal, modalCallbacks);
143
+ export function showOverlay(animation: ModalAnimation = 'fade') {
144
+ const overlay = getOverlay();
145
+ if (overlay && !overlay.classList.contains(CSS_VISIBLE)) {
146
+ overlay.classList.add(CSS_VISIBLE);
147
+ requestAnimationFrame(() => {
148
+ overlay.classList.add(`${CSS_PREFIX_SHOW}-${animation}`);
149
+ });
139
150
  }
140
151
  }
152
+ export function hideOverlay({ modal, animation = 'fade', duration }: { modal?: EvoModalElement, animation?: ModalAnimation, duration?: number } = {}) {
153
+ const overlay = getOverlay();
154
+ if (overlay && overlay.classList.contains(CSS_VISIBLE)) {
155
+ const cssShow = [...overlay.classList]
156
+ .filter((c) => {
157
+ return c.startsWith(CSS_PREFIX_SHOW);
158
+ });
159
+ const cssHide = [...overlay.classList]
160
+ .filter((c) => {
161
+ return c.startsWith(CSS_PREFIX_HIDE);
162
+ });
141
163
 
142
- function triggerEventCallbacks(element: HTMLElement, eventType: ModalEventType) {
143
- if (element) {
144
- const eventCallbacks = callbacks.get(element);
145
- if (eventCallbacks && eventCallbacks[eventType]) {
146
- const items = [...eventCallbacks[eventType]];
147
- const keep: ModalEventCallbackItem[] = [];
148
- for (const item of items) {
149
- try {
150
- item.callback(element);
151
- } catch (err) {
152
- console.log(err);
153
- } finally {
154
- if (!item.once) {
155
- keep.push(item);
156
- }
157
- }
158
- }
159
- callbacks.set(element, {...eventCallbacks, [eventType]: new Set(keep)});
164
+ if (cssShow.length !== 0 && cssHide.length === 0) {
165
+ cssHide.push(`${CSS_PREFIX_HIDE}-${animation}`)
166
+ overlay.classList.add(cssHide[0]);
167
+ overlay.classList.remove(cssShow[0]);
168
+ setTimeout(() => {
169
+ overlay.classList.remove(CSS_VISIBLE, cssHide[0]);
170
+ }, duration ?? getAnimationDuration(modal));
160
171
  }
172
+
161
173
  }
162
174
  }
163
175
 
164
- const overlay: HTMLElement = document.querySelector<HTMLElement>('.evo-modal-overlay') ?? (() => {
165
- // create the overlay
166
- const div = document.createElement('div');
167
- div.classList.add('evo-modal-overlay');
168
- document.body.append(div);
169
- return div;
170
- })();
171
- overlay.addEventListener('click', () => {
172
- hide();
173
- triggerEventCallbacks(overlay, 'overlay');
174
- });
176
+ /**
177
+ * Call this function when dynamically adding a trigger to the DOM
178
+ */
179
+ export function bindTriggers(container = document) {
180
+ container.querySelectorAll<HTMLElement>('[data-evo-modal-show]').forEach((trigger) => {
181
+ if (!trigger.hasAttribute('data-evo-modal-bound')) {
182
+ trigger.setAttribute('data-evo-modal-bound','true');
183
+ trigger.addEventListener('click', async (e) => {
184
+ e.preventDefault();
185
+ const target = (e.currentTarget ?? e.target) as HTMLElement;
186
+ const animation = (target.getAttribute('data-evo-modal-animation') ?? undefined) as ModalAnimation | undefined;
187
+ await showModal(target.getAttribute('data-evo-modal-show') as string, { animation });
188
+ });
189
+ }
190
+ });
191
+ }
192
+
193
+ function getOverlay() {
194
+ return document.querySelector<HTMLElement>(`.${CSS_OVERLAY}`);
195
+ }
175
196
 
176
197
  function getAnimationDuration(element: HTMLElement = document.body) {
177
- let duration = 0;
178
- const cssDuration = getComputedStyle(element).getPropertyValue('--evo-modal-animation-duration').trim();
179
- if (cssDuration) {
180
- // Match ms or s suffixes
181
- const match = cssDuration.match(/^(\d+(?:\.\d+)?)(m?s)$/);
182
- if (match) {
183
- const value = parseFloat(match[1]);
184
- const unit = match[2];
185
- duration = unit === 'ms' ? value : value * 1000;
198
+ let duration = 300;
199
+ const cssDuration = getComputedStyle(element).getPropertyValue('--evo-modal-animation-duration').trim();
200
+ if (cssDuration) {
201
+ // Match ms or s suffixes
202
+ const match = cssDuration.match(/^(\d+(?:\.\d+)?)(m?s)$/);
203
+ if (match) {
204
+ const value = parseFloat(match[1]);
205
+ const unit = match[2];
206
+ duration = unit === 'ms' ? value : value * 1000;
207
+ }
186
208
  }
209
+ return duration;
187
210
  }
188
- return duration;
189
- };
190
211
 
191
- document.querySelectorAll<HTMLElement>('.evo-modal').forEach((modal) => {
192
- modal.querySelectorAll<HTMLElement>('.evo-modal-action-hide').forEach((btn) => {
193
- btn.addEventListener('click', async () => {
194
- hide(modal);
195
- });
196
- });
197
- });
198
-
199
- document.querySelectorAll<HTMLElement>('[data-evo-modal-show]').forEach((trigger) => {
200
- trigger.addEventListener('click', async (e) => {
201
- e.preventDefault();
202
- const target = (e.currentTarget ?? e.target) as HTMLElement;
203
- const animation = (target.getAttribute('data-evo-modal-animation') ?? undefined) as ModalAnimation | undefined;
204
- await show(target.getAttribute('data-evo-modal-show') as string, { animation });
205
- });
206
- });
212
+ document.addEventListener('DOMContentLoaded', (e) => {
213
+ bindTriggers();
214
+
215
+ if (!getOverlay()) {
216
+ const overlay = document.createElement('div');
217
+ overlay.classList.add(CSS_OVERLAY);
218
+ overlay.addEventListener('click', () => {
219
+ hideModals();
220
+ }, { passive: true });
221
+ document.body.append(overlay);
222
+ }
223
+ }, { passive: true });
@@ -1,5 +1,7 @@
1
1
  ---
2
2
  import ScrollContainer from '../ScrollContainer/ScrollContainer.astro';
3
+ import type { Layout } from './PdfViewer';
4
+ import type { Scrolling } from '../ScrollContainer/ScrollContainer';
3
5
  import './PdfViewer.css';
4
6
 
5
7
  interface Props {
@@ -11,8 +13,9 @@ interface Props {
11
13
  zoom?: 50 | 60 | 70 | 80 | 90 | 100 | 110 | 120 | 130 | 140 | 150;
12
14
  page?: number;
13
15
  pages?: string;
14
- // bookmarks?: Record<string, number>;
15
- // bookmarkText?: string;
16
+ layout?: Layout;
17
+ fit?: 'width' | 'height' | `${string}%` | number;
18
+ quality?: number;
16
19
  toolbar?: {
17
20
  nav?: boolean;
18
21
  page?: boolean;
@@ -21,7 +24,7 @@ interface Props {
21
24
  placeholder?: string;
22
25
  items: Record<string, number>;
23
26
  }
24
- }
27
+ } | false;
25
28
  }
26
29
  const {
27
30
  id,
@@ -31,6 +34,9 @@ const {
31
34
  pdf,
32
35
  zoom,
33
36
  page = 1,
37
+ layout = 'vertical',
38
+ fit = '100%',
39
+ quality = 2,
34
40
  toolbar,
35
41
  ...rest
36
42
  } = Astro.props;
@@ -39,13 +45,18 @@ const attrs: Record<string, string> = {...rest};
39
45
  if (height) {
40
46
  attrs.style = `${attrs.style ? `${attrs.style}${attrs.style.endsWith(';') ? '' : ';'}` : ''}--evo-pdf-viewer-height:${typeof height == 'number' ? `${height}px` : height};`;
41
47
  }
48
+
49
+ const scrollContainerScrolling: Scrolling = toolbar === undefined || (toolbar && toolbar?.zoom !== false) ? 'both' : layout as Scrolling;
42
50
  ---
43
- <div
51
+ <evo-pdf-viewer
44
52
  id={id}
45
- class:list={['evo-pdf-viewer', cssClass, theme ? `evo-pdf-viewer-theme-${theme}` : null]}
53
+ class:list={['evo-pdf-viewer', `evo-pdf-viewer-layout-${layout}`, cssClass, theme ? `evo-pdf-viewer-theme-${theme}` : null, toolbar === false ? 'evo-pdf-viewer-toolbar-hidden' : null]}
46
54
  data-pdf={pdf}
47
55
  data-page={page}
48
56
  data-zoom={zoom}
57
+ data-layout={layout}
58
+ data-fit={fit}
59
+ data-quality={quality}
49
60
  {...attrs}
50
61
  >
51
62
  <div class="evo-pdf-viewer-toolbar">
@@ -53,7 +64,7 @@ if (height) {
53
64
  <slot name="toolbar-start" />
54
65
  </div>
55
66
  <div class="evo-pdf-viewer-toolbar-controls">
56
- <div class:list={["evo-pdf-viewer-toolbar-arrows", toolbar?.nav === false ? 'evo-hidden' : null]}>
67
+ <div class:list={["evo-pdf-viewer-toolbar-arrows", toolbar && toolbar.nav === false ? 'evo-hidden' : null]}>
57
68
  <button class="evo-pdf-viewer-toolbar-prev" title="Previous">
58
69
  <slot name="toolbar-prev">
59
70
  <svg class="evo-pdf-viewer-toolbar-icon" width="20px" height="20px" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
@@ -69,10 +80,10 @@ if (height) {
69
80
  </slot>
70
81
  </button>
71
82
  </div>
72
- <div class:list={['evo-pdf-viewer-nav-page', toolbar?.page === false ? 'evo-hidden' : null]}>
83
+ <div class:list={['evo-pdf-viewer-nav-page', toolbar && toolbar.page === false ? 'evo-hidden' : null]}>
73
84
  <select><option value="1">1</option></select> of <span class="evo-pdf-viewer-nav-page-count">1</span>
74
85
  </div>
75
- <div class:list={['evo-pdf-viewer-toolbar-zoom', toolbar?.zoom === false ? 'evo-hidden' : null]}>
86
+ <div class:list={['evo-pdf-viewer-toolbar-zoom', toolbar && toolbar.zoom === false ? 'evo-hidden' : null]}>
76
87
  <button class="evo-pdf-viewer-toolbar-zoom-out" title="Zoom out">
77
88
  <slot name="toolbar-zoom-out">
78
89
  <svg class="evo-pdf-viewer-toolbar-icon" width="16px" height="16px" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
@@ -94,10 +105,10 @@ if (height) {
94
105
  </slot>
95
106
  </button>
96
107
  </div>
97
- {toolbar?.bookmarks && Object.keys(toolbar.bookmarks.items).length > 0 &&
108
+ {toolbar && toolbar.bookmarks && Object.keys(toolbar.bookmarks.items).length > 0 &&
98
109
  <div class="evo-pdf-viewer-toolbar-bookmarks">
99
110
  <select>
100
- <option value="" disabled selected hidden>{toolbar.bookmarks.placeholder ?? 'Jump To'}</option>
111
+ <option value="" disabled selected hidden>{toolbar.bookmarks.placeholder ?? ''}</option>
101
112
  {Object.entries(toolbar.bookmarks.items).map((b) => (
102
113
  <option value={b[1]}>{b[0]}</option>
103
114
  ))}
@@ -109,7 +120,7 @@ if (height) {
109
120
  </div>
110
121
  </div>
111
122
  <div class="evo-pdf-viewer-container">
112
- <ScrollContainer>
123
+ <ScrollContainer scrolling={scrollContainerScrolling}>
113
124
  <!-- <div class="evo-pdf-viewer-page">
114
125
 
115
126
  </div>
@@ -118,4 +129,7 @@ if (height) {
118
129
  </div> -->
119
130
  </ScrollContainer>
120
131
  </div>
121
- </div>
132
+ </evo-pdf-viewer>
133
+ <script>
134
+ import './PdfViewer';
135
+ </script>
@@ -1,11 +1,17 @@
1
- .evo-pdf-viewer {
2
- --evo-pdf-viewer-height: 100%;
1
+ evo-pdf-viewer {
2
+ --evo-pdf-viewer-height: 100vh;
3
3
  --evo-pdf-viewer-toolbar-height: 44px;
4
4
  --evo-pdf-viewer-toolbar-align: center;
5
5
  --evo-pdf-viewer-scale: 1;
6
+ --evo-pdf-viewer-padding-top: 0px;
7
+ --evo-pdf-viewer-padding-right: 8px;
8
+ --evo-pdf-viewer-padding-bottom: 8px;
9
+ --evo-pdf-viewer-padding-left: calc(8px + var(--evo-scroll-container-track-width) + var(--evo-scroll-container-width-offset));
6
10
 
7
11
  position: relative;
12
+ display: block;
8
13
  height: var(--evo-pdf-viewer-height);
14
+ padding: var(--evo-pdf-viewer-padding-top) var(--evo-pdf-viewer-padding-right) var(--evo-pdf-viewer-padding-bottom) var(--evo-pdf-viewer-padding-left);
9
15
  background-color: #f0f0f0;
10
16
  box-sizing: border-box;
11
17
 
@@ -104,56 +110,27 @@
104
110
  }
105
111
  }
106
112
  }
107
- /*.evo-pdf-viewer-nav {
108
- position: absolute;
109
- left: calc(50% - 80px);
110
- top: var(--evo-pdf-viewer-toolbar-height);
111
- display: flex;
112
- justify-content: space-between;
113
- width: 160px;
114
- padding: 6px 12px;
115
- border-radius: 0 0 12px 12px;
116
- background-color: rgba(51, 51, 51, 0.9);
117
- backdrop-filter: blur(2px);
118
- z-index: 1;
119
- box-sizing: border-box;
120
-
121
- button {
122
- all: unset;
123
- display: block;
124
- cursor: pointer;
125
- &.evo-pdf-viewer-nav-arrow {
126
- width: 24px;
127
- height: 24px;
128
- }
129
- &.evo-pdf-viewer-nav-page {
130
- color: white;
131
- font-family: sans-serif;
132
- font-size: 18px;
133
- line-height: 18px;
134
- }
135
- }
136
- }*/
137
113
  .evo-pdf-viewer-container {
138
- height: calc(var(--evo-pdf-viewer-height) - var(--evo-pdf-viewer-toolbar-height));
139
- padding: 0 9px 9px var(--evo-scroll-container-content-padding-right);
114
+ --evo-pdf-viewer-container-height: calc(var(--evo-pdf-viewer-height) - var(--evo-pdf-viewer-padding-top) - var(--evo-pdf-viewer-toolbar-height) - var(--evo-pdf-viewer-padding-bottom));
115
+ height: var(--evo-pdf-viewer-container-height);
140
116
  box-sizing: border-box;
141
117
 
142
- .evo-scroll-container {
118
+ evo-scroll-container {
143
119
  --evo-scroll-container-track-color: #cccccc;
120
+ /* height: 100%; */
121
+ height: var(--evo-pdf-viewer-container-height);
144
122
  .evo-scroll-content {
145
- overflow-x: hidden;
123
+ display: flex;
124
+ flex-direction: column;
125
+ align-items: flex-start;
126
+ gap: 16px;
127
+
146
128
  .evo-pdf-viewer-page-wrapper {
147
129
  display: block;
148
- margin: 18px auto;
130
+ flex-shrink: 0;
131
+ margin-left: auto;
132
+ margin-right: auto;
149
133
  background-color: white;
150
-
151
- &:first-child {
152
- margin-top: 0;
153
- }
154
- &:last-child {
155
- margin-bottom: 0;
156
- }
157
134
  }
158
135
 
159
136
  canvas {
@@ -164,7 +141,7 @@
164
141
 
165
142
  .evo-pdf-viewer-link-overlay {
166
143
  pointer-events: auto;
167
- z-index: 1;
144
+ z-index: 0;
168
145
  -webkit-tap-highlight-color: transparent;
169
146
  user-select: none;
170
147
  touch-action: manipulation;
@@ -177,18 +154,50 @@
177
154
  }
178
155
  }
179
156
 
180
- /* &.evo-pdf-viewer-theme-modern {
157
+ &.evo-pdf-viewer-toolbar-hidden {
181
158
  .evo-pdf-viewer-toolbar {
182
- button {
183
- background-color: transparent;
184
- border: none;
185
- border-radius: 0;
186
- &:hover {
187
- background-color: rgba(0,0,0,0.05);
159
+ display: none;
160
+ }
161
+ .evo-pdf-viewer-container {
162
+ --evo-pdf-viewer-container-height: calc(var(--evo-pdf-viewer-height) - var(--evo-pdf-viewer-padding-top) - var(--evo-pdf-viewer-padding-bottom));
163
+ }
164
+
165
+ &.evo-pdf-viewer-layout-horizontal {
166
+ --evo-pdf-viewer-padding-left: var(--evo-pdf-viewer-padding-right);
167
+ }
168
+ &.evo-pdf-viewer-layout-vertical {
169
+ --evo-pdf-viewer-padding-top: 8px
170
+ }
171
+ }
172
+
173
+ &.evo-pdf-viewer-layout-horizontal {
174
+ .evo-pdf-viewer-toolbar {
175
+ .evo-pdf-viewer-toolbar-arrows {
176
+ .evo-pdf-viewer-toolbar-prev {
177
+ transform: rotate(-90deg);
178
+ }
179
+ .evo-pdf-viewer-toolbar-next {
180
+ transform: rotate(-90deg);
181
+ }
182
+ }
183
+ }
184
+ .evo-pdf-viewer-container {
185
+ evo-scroll-container {
186
+ .evo-scroll-content {
187
+ display: flex;
188
+ flex-direction: row;
189
+ align-items: flex-start;
190
+
191
+ .evo-pdf-viewer-page-wrapper {
192
+ display: block;
193
+ margin-top: auto;
194
+ margin-bottom: auto;
195
+ flex-shrink: 0;
196
+ }
188
197
  }
189
198
  }
190
199
  }
191
- } */
200
+ }
192
201
  &.evo-pdf-viewer-theme-dark {
193
202
  background-color: #555555;
194
203
  .evo-pdf-viewer-toolbar {