@inizioevoke/astro-core 1.1.1 → 1.2.0

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 CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@inizioevoke/astro-core",
3
- "version": "1.1.1",
3
+ "version": "1.2.0",
4
4
  "description": "",
5
5
  "license": "ISC",
6
6
  "author": "",
@@ -8,6 +8,8 @@
8
8
  "main": "./index.ts",
9
9
  "exports": {
10
10
  "./components": "./src/components/index.ts",
11
+ "./components/Modal": "./src/components/Modal/index.ts",
12
+ "./components/ScrollContainer": "./src/components/ScrollContainer/index.ts",
11
13
  "./integrations": "./src/integrations/index.ts"
12
14
  },
13
15
  "files": [
@@ -23,9 +25,7 @@
23
25
  "@astrojs/ts-plugin": "^1.10.7",
24
26
  "@types/node": "^25.5.0",
25
27
  "astro": "^6.0.5",
28
+ "pdfjs-dist": "^5.6.205",
26
29
  "typescript": "^5.9.3"
27
- },
28
- "dependencies": {
29
- "pdfjs-dist": "^5.5.207"
30
30
  }
31
31
  }
@@ -0,0 +1,43 @@
1
+ ---
2
+ import type { HTMLTag } from 'astro/types';
3
+ import ScrollContainer, { type Props as ScrollContainerProps } from '../ScrollContainer/ScrollContainer.astro';
4
+ import './RightISI.css';
5
+
6
+ interface Props {
7
+ tag?: HTMLTag;
8
+ scrollContainer?: ScrollContainerProps;
9
+ headerButton?: boolean;
10
+ }
11
+
12
+ const {
13
+ tag: TagName = 'aside',
14
+ scrollContainer,
15
+ headerButton = false
16
+ } = Astro.props;
17
+
18
+ const renderHeaderButton = Astro.slots.has('header-button') || headerButton;
19
+ const renderHeader = Astro.slots.has('header') || renderHeaderButton;
20
+ ---
21
+ <TagName class="evo-isi">
22
+ <div class="evo-isi-wrapper">
23
+
24
+ {renderHeader && <div class="evo-isi-header">
25
+ <slot name="header" />
26
+ {renderHeaderButton &&
27
+ <div class="evo-isi-header-button">
28
+ <slot name="header-button"><button>Expand</button></slot>
29
+ </div>}
30
+ </div>}
31
+ <div class="evo-isi-text">
32
+ <ScrollContainer {...scrollContainer}>
33
+ <slot />
34
+ </ScrollContainer>
35
+ </div>
36
+ {Astro.slots.has('footer') && <div class="evo-isi-footer">
37
+ <slot name="footer" />
38
+ </div>}
39
+ </div>
40
+ </TagName>
41
+ <script>
42
+ import './RightISI';
43
+ </script>
@@ -0,0 +1,31 @@
1
+ :root {
2
+ --evo-isi-width: 25vw;
3
+ --evo-isi-width-expanded: 100vw;
4
+ --evo-isi-height: 100vh;
5
+ --evo-isi-header-height: 0px;
6
+ --evo-isi-footer-height: 0px;
7
+ }
8
+ .evo-isi {
9
+ position: fixed;
10
+ right: 0;
11
+ top: 0;
12
+ display: block;
13
+ width: var(--evo-isi-width);
14
+ height: var(--evo-isi-height);
15
+ overflow: hidden;
16
+ z-index: 99;
17
+ background-color: #ffffff;
18
+
19
+ transform-origin: right top;
20
+ transition-property: width;
21
+ transition-duration: 500ms;
22
+ transition-timing-function: ease-in-out;
23
+
24
+ .evo-isi-wrapper {
25
+ .evo-isi-text {
26
+ .evo-scroll-container {
27
+ /* height: calc(var(--evo-isi-height) - var(--evo-isi-header-height) - var(--evo-isi-footer-height)) */
28
+ }
29
+ }
30
+ }
31
+ }
@@ -0,0 +1,23 @@
1
+ # RightISI
2
+
3
+ ```jsx
4
+ <RightISI
5
+ tag="aside" // optional
6
+ scrollContainer={{ // optional
7
+ /* ScrollContainer props */
8
+ }}
9
+ headerButton={true} // optional
10
+ >
11
+ <!-- optional -->
12
+ <div slot="header">Header Content</div>
13
+
14
+ <!-- optional -->
15
+ <Fragment slot="header-button"><button>My Button</button></Fragment>
16
+
17
+ <!-- ISI content -->
18
+ <h2>Important Safety Information</h2>
19
+ <p>Content</p>
20
+
21
+ <div slot="footer">Footer Content</div>
22
+ </RightISI>
23
+ ```
@@ -0,0 +1,27 @@
1
+ import * as ScrollContainer from '../ScrollContainer/ScrollContainer';
2
+
3
+ const isi = document.querySelector('.evo-isi') as HTMLElement;
4
+ const isiHeader = isi.querySelector<HTMLElement>('.evo-isi-header');
5
+ const isiFooter = isi.querySelector<HTMLElement>('.evo-isi-footer');
6
+ const isiText = isi.querySelector('.evo-isi-text') as HTMLElement;
7
+
8
+ export function resize() {
9
+ if (isi) {
10
+ const isiStyle = getComputedStyle(isi);
11
+ const isiHeight = parseInt(isiStyle.height);
12
+ const headerHeight = isiHeader ? parseInt(getComputedStyle(isiHeader).height) : 0;
13
+ const footerHeight = isiFooter ? parseInt(getComputedStyle(isiFooter).height) : 0;
14
+
15
+ const isiTextStyle = getComputedStyle(isiText);
16
+ const textPadTop = parseInt(isiTextStyle.paddingTop);
17
+ const textPadBot = parseInt(isiTextStyle.paddingBottom);
18
+
19
+ const scrollContainer = ScrollContainer.getScrollContainer(isi.querySelector('.evo-isi-text .evo-scroll-container') as HTMLElement);
20
+ if (scrollContainer) {
21
+ const height = isiHeight - headerHeight - footerHeight - textPadTop - textPadBot;
22
+ ScrollContainer.resize(scrollContainer, { height });
23
+ }
24
+ }
25
+ }
26
+ addEventListener('load', resize, { passive: true });
27
+ window.addEventListener('resize', resize, { passive: true });
@@ -1,18 +1,46 @@
1
1
 
2
2
  export type ModalAnimation = 'none' | 'fade';
3
+ export type ModalEventCallback = (modal: HTMLElement | HTMLElement[]) => void;
4
+ interface ModalEventCallbackItem {
5
+ once?: boolean;
6
+ callback: ModalEventCallback;
7
+ }
8
+
9
+ type ModalEventType = 'show' | 'hide';
10
+ type ModalEventTypeCallbacks = Record<ModalEventType, Set<ModalEventCallbackItem>>;
11
+ const callbacks = new Map<HTMLElement, ModalEventTypeCallbacks>();
3
12
 
4
13
  interface ModalOptions {
5
- animation?: ModalAnimation;
14
+ animation?: ModalAnimation;
6
15
  }
7
- export function show(selector: string | HTMLElement, { animation = 'fade' }: ModalOptions = {}) {
16
+ interface ModalShowOptions extends ModalOptions {
17
+ on?: {
18
+ show?: ModalEventCallback,
19
+ hide?: ModalEventCallback
20
+ }
21
+ }
22
+ export function show(selector: string | HTMLElement, { animation = 'fade', on }: ModalShowOptions = {}) {
8
23
  return new Promise<void>(async (resolve) => {
9
24
  let modal = typeof selector == 'string' ? document.querySelector<HTMLElement>(/^[\.#]/.test(selector) ? selector : `#${selector}`) : selector;
10
25
  if (modal) {
26
+ if (on?.hide) {
27
+ onEvent('hide', modal, { once: true, callback: on.hide });
28
+ }
11
29
  await hide(null, { animation, hideOverlay: false });
12
30
  __showOverlay(animation);
13
31
 
14
32
  modal.classList.add('evo-modal-visible', `evo-modal-show-${animation}`);
15
- setTimeout(resolve, animation !== 'none' ? animationDuration : 0);
33
+ setTimeout(() => {
34
+ triggerEventCallbacks(modal, 'show');
35
+ if (on?.show) {
36
+ try {
37
+ on.show(modal);
38
+ } catch (err) {
39
+ console.log(err);
40
+ }
41
+ }
42
+ resolve();
43
+ }, animation !== 'none' ? animationDuration : 0);
16
44
  }
17
45
  });
18
46
  }
@@ -22,11 +50,17 @@ function __showOverlay(animation: ModalAnimation) {
22
50
  overlay.classList.add('evo-modal-visible', `evo-modal-show-${animation}`);
23
51
  }
24
52
  }
53
+ export function onShow(selector: string | HTMLElement, callback: ModalEventCallback, { once }: { once?: boolean } = {}) {
54
+ onEvent('show', selector, { once, callback });
55
+ }
25
56
 
26
57
  interface HideModalOptions extends ModalOptions {
27
58
  hideOverlay?: boolean;
59
+ on?: {
60
+ hide?: ModalEventCallback
61
+ }
28
62
  }
29
- export function hide(selector?: string | HTMLElement | (string | HTMLElement)[] | null, { animation, hideOverlay = true }: HideModalOptions = {}) {
63
+ export function hide(selector?: string | HTMLElement | (string | HTMLElement)[] | null, { animation, hideOverlay = true, on }: HideModalOptions = {}) {
30
64
  return new Promise<void>(async (resolve) => {
31
65
  const modals: HTMLElement[] = (selector ? Array.isArray(selector) ? selector : [selector] : [...document.querySelectorAll<HTMLElement>('.evo-modal.evo-modal-visible')])
32
66
  .map((m) => {
@@ -49,6 +83,13 @@ export function hide(selector?: string | HTMLElement | (string | HTMLElement)[]
49
83
  hides.push(__hide(overlay, animation));
50
84
  }
51
85
  await Promise.all(hides);
86
+ if (on?.hide) {
87
+ try {
88
+ on.hide(modals);
89
+ } catch (err) {
90
+ console.log(err);
91
+ }
92
+ }
52
93
  resolve();
53
94
  });
54
95
  }
@@ -59,10 +100,14 @@ function __hide(modal: HTMLElement, animation: ModalAnimation) {
59
100
  modal.classList.remove(showClass);
60
101
  setTimeout(() => {
61
102
  modal.classList.remove('evo-modal-visible', `evo-modal-hide-${animation}`);
103
+ triggerEventCallbacks(modal, 'hide');
62
104
  resolve();
63
105
  }, animation !== 'none' ? animationDuration : 0);
64
106
  });
65
107
  }
108
+ export function onHide(selector: string | HTMLElement, callback: ModalEventCallback, { once }: { once?: boolean } = {}) {
109
+ onEvent('hide', selector, { once, callback });
110
+ }
66
111
 
67
112
  /**
68
113
  * Moves the overlay element by appending it to an element
@@ -75,6 +120,40 @@ export function appendOverlay(selector: string | HTMLElement) {
75
120
  }
76
121
  }
77
122
 
123
+ function onEvent(type: ModalEventType, selector: string | HTMLElement, callbackItem: ModalEventCallbackItem) {
124
+ let modal = typeof selector == 'string' ? document.querySelector<HTMLElement>(/^[\.#]/.test(selector) ? selector : `#${selector}`) : selector;
125
+ if (modal) {
126
+ const modalCallbacks = callbacks.get(modal) ?? {} as ModalEventTypeCallbacks;
127
+ if (!modalCallbacks[type]) {
128
+ modalCallbacks[type] = new Set();
129
+ }
130
+ modalCallbacks[type].add(callbackItem);
131
+ callbacks.set(modal, modalCallbacks);
132
+ }
133
+ }
134
+
135
+ function triggerEventCallbacks(modal: HTMLElement, eventType: 'show' | 'hide') {
136
+ if (modal) {
137
+ const modalCallbacks = callbacks.get(modal);
138
+ if (modalCallbacks && modalCallbacks[eventType]) {
139
+ const items = [...modalCallbacks[eventType]];
140
+ const keep: ModalEventCallbackItem[] = [];
141
+ for (const item of items) {
142
+ try {
143
+ item.callback(modal);
144
+ } catch (err) {
145
+ console.log(err);
146
+ } finally {
147
+ if (!item.once) {
148
+ keep.push(item);
149
+ }
150
+ }
151
+ }
152
+ callbacks.set(modal, {...modalCallbacks, [eventType]: new Set(keep)});
153
+ }
154
+ }
155
+ }
156
+
78
157
  const overlay: HTMLElement = document.querySelector<HTMLElement>('.evo-modal-overlay') ?? (() => {
79
158
  // create the overlay
80
159
  const div = document.createElement('div');
@@ -0,0 +1,2 @@
1
+ export { default as Modal } from './Modal.astro';
2
+ export * from './Modal';
@@ -1,4 +1,4 @@
1
- import * as pdfjs from './pdf.mjs';
1
+ import * as pdfjs from './pdf.min.mjs';
2
2
  import type { PDFDocumentProxy } from 'pdfjs-dist';
3
3
  import * as ScrollContainer from '../ScrollContainer/ScrollContainer';
4
4