@inizioevoke/astro-core 2.1.2 → 2.2.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/docs/components/CssBackgroundImage.md +59 -0
- package/docs/components/CssVariables.md +64 -0
- package/docs/components/FlipCard.md +113 -0
- package/docs/components/Modal.md +211 -0
- package/docs/components/ScrollContainer.md +160 -0
- package/docs/components/Tabs.md +102 -0
- package/docs/integrations/prune-build.md +75 -0
- package/docs/integrations/relative-links.md +53 -0
- package/docs/lib/pinch.md +98 -0
- package/docs/lib/swipe.md +147 -0
- package/package.json +2 -1
- package/src/components/CssBackgroundImage.astro +103 -0
- package/src/components/CssVariables.astro +129 -0
- package/src/components/FlipCard/FlipCard.astro +2 -2
- package/src/components/Modal/Modal.ts +4 -4
- package/src/components/ScrollContainer/ScrollContainer.astro +5 -1
- package/src/components/ScrollContainer/ScrollContainer.ts +13 -22
- package/src/components/Tabs/TabItem.astro +1 -2
- package/src/components/Tabs/Tabs.astro +2 -3
- package/src/components/index.ts +2 -0
- package/src/integrations/prune-build.ts +33 -25
- package/src/lib/gestures/pinch.ts +62 -15
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
# CssBackgroundImage
|
|
2
|
+
|
|
3
|
+
The CssBackgroundImage component renders a style element on the page with the given selector and background image. This is useful to quickly set the `background-image` of an element to an imported image url without all the extra inline styles that Astro inserts when using `<style define:vars={{}} />`. This component will also let you use breakpoints to set the `background-image` based on the screen width. If the `selector` parameter is not given the default selector is `body`. This component should be rendered inside your layout. Use a `<slot />` to specify where to inject it.
|
|
4
|
+
|
|
5
|
+
## Image optimization
|
|
6
|
+
|
|
7
|
+
The image will be optimized by default. Optimization options include `format`, `quality`, `width`, `height`. To turn off image optimization, set `optimize={false}`.
|
|
8
|
+
|
|
9
|
+
## Example
|
|
10
|
+
|
|
11
|
+
```html
|
|
12
|
+
<!-- Layout -->
|
|
13
|
+
<html>
|
|
14
|
+
<head>
|
|
15
|
+
<slot name="styles" />
|
|
16
|
+
</head>
|
|
17
|
+
<body>
|
|
18
|
+
<slot />
|
|
19
|
+
</body>
|
|
20
|
+
</html>
|
|
21
|
+
```
|
|
22
|
+
```html
|
|
23
|
+
<!-- Astro Page -->
|
|
24
|
+
---
|
|
25
|
+
import { CssBackgroundImage } from '@inizioevoke/astro-core';
|
|
26
|
+
import Layout from '../layouts/Layout.astro';
|
|
27
|
+
import bgImg_m from '../assets/img/background-m.jpg';
|
|
28
|
+
import bgImg_d from '../assets/img/background-d.jpg';
|
|
29
|
+
---
|
|
30
|
+
<Layout>
|
|
31
|
+
<CssBackgroundImage
|
|
32
|
+
slot="styles"
|
|
33
|
+
selector="body"
|
|
34
|
+
image={bgImg_m}
|
|
35
|
+
breakpoints={[{
|
|
36
|
+
minWidth: 1200,
|
|
37
|
+
image: bgImg_d
|
|
38
|
+
}]}
|
|
39
|
+
/>
|
|
40
|
+
</Layout>
|
|
41
|
+
```
|
|
42
|
+
Output
|
|
43
|
+
```html
|
|
44
|
+
<html>
|
|
45
|
+
<head>
|
|
46
|
+
<style>
|
|
47
|
+
body {
|
|
48
|
+
background-image: url("/[ASSETS]/background-m.jpg");
|
|
49
|
+
@media screen and (min-width: 1200px) {
|
|
50
|
+
background-image: url("/[ASSETS]/background-d.jpg");
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
</style>
|
|
54
|
+
</head>
|
|
55
|
+
<body>
|
|
56
|
+
...
|
|
57
|
+
</body>
|
|
58
|
+
</html>
|
|
59
|
+
```
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
# CssVariables
|
|
2
|
+
|
|
3
|
+
The CssVariables component creates variables in a style element on the page with the given names and values. This is especially useful when you want to set a variable to an imported image url without all the extra inline styles that Astro inserts when using `<style define:vars={{}} />`. This component will also let you use breakpoints to override the variables based on the screen width. If the `selector` parameter is not given the default selector is `:root`. This component should be rendered inside your layout. Use a `<slot />` to specify where to inject it.
|
|
4
|
+
|
|
5
|
+
## Image optimization
|
|
6
|
+
|
|
7
|
+
The image will be optimized by default. Optimization options include `format`, `quality`, `width`, `height`. To turn off image optimization, set `optimize={false}`.
|
|
8
|
+
|
|
9
|
+
## Example
|
|
10
|
+
|
|
11
|
+
```html
|
|
12
|
+
<!-- Layout -->
|
|
13
|
+
<html>
|
|
14
|
+
<head>
|
|
15
|
+
<slot name="cssvars" />
|
|
16
|
+
</head>
|
|
17
|
+
<body>
|
|
18
|
+
<slot />
|
|
19
|
+
</body>
|
|
20
|
+
</html>
|
|
21
|
+
```
|
|
22
|
+
```html
|
|
23
|
+
<!-- Astro Page -->
|
|
24
|
+
---
|
|
25
|
+
import { CssVariables } from '@inizioevoke/astro-core';
|
|
26
|
+
import Layout from '../layouts/Layout.astro';
|
|
27
|
+
import bgImg_m from '../assets/img/background-m.jpg';
|
|
28
|
+
import bgImg_d from '../assets/img/background-d.jpg';
|
|
29
|
+
---
|
|
30
|
+
<Layout>
|
|
31
|
+
<CssVariables
|
|
32
|
+
slot="cssvars"
|
|
33
|
+
selector=":root"
|
|
34
|
+
variables={[{
|
|
35
|
+
name: 'bgImg',
|
|
36
|
+
type: 'url',
|
|
37
|
+
value: bgImg_m,
|
|
38
|
+
breakpoints: [{
|
|
39
|
+
minWidth: 1200,
|
|
40
|
+
value: bgImg_d
|
|
41
|
+
}]
|
|
42
|
+
}]}
|
|
43
|
+
/>
|
|
44
|
+
</Layout>
|
|
45
|
+
```
|
|
46
|
+
Output
|
|
47
|
+
```html
|
|
48
|
+
<html>
|
|
49
|
+
<head>
|
|
50
|
+
<style>
|
|
51
|
+
:root {
|
|
52
|
+
--bgImg: url("/[ASSETS]/background-m.jpg");
|
|
53
|
+
@media screen and (min-width: 1200px) {
|
|
54
|
+
--bgImg: url("/[ASSETS]/background-d.jpg");
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
</style>
|
|
58
|
+
</head>
|
|
59
|
+
<body>
|
|
60
|
+
...
|
|
61
|
+
</body>
|
|
62
|
+
</html>
|
|
63
|
+
|
|
64
|
+
```
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
# FlipCard
|
|
2
|
+
|
|
3
|
+
The FlipCard component renders a 3D flip card with a front and back face. A trigger button (top-right corner of each face) toggles the flip animation. The component is a custom element (`<evo-flip-card>`) with a JavaScript API for programmatic control.
|
|
4
|
+
|
|
5
|
+
## Props
|
|
6
|
+
|
|
7
|
+
| Prop | Type | Default | Description |
|
|
8
|
+
|------|------|---------|-------------|
|
|
9
|
+
| `width` | `number` | `640` | Card width in pixels (sets `--evo-flip-card-width`) |
|
|
10
|
+
| `height` | `number` | `360` | Card height in pixels (sets `--evo-flip-card-height`) |
|
|
11
|
+
| `...rest` | `HTMLAttributes<'div'>` | — | Any additional HTML attributes are passed to the `<evo-flip-card>` element |
|
|
12
|
+
|
|
13
|
+
## Slots
|
|
14
|
+
|
|
15
|
+
| Slot | Description |
|
|
16
|
+
|------|-------------|
|
|
17
|
+
| `front` | Content rendered on the front face |
|
|
18
|
+
| `back` | Content rendered on the back face |
|
|
19
|
+
| `trigger` | Custom trigger button content used on **both** faces (overrides the default ↻ icon) |
|
|
20
|
+
| `front-trigger` | Custom trigger button content for the front face only (takes precedence over `trigger`) |
|
|
21
|
+
| `back-trigger` | Custom trigger button content for the back face only (takes precedence over `trigger`) |
|
|
22
|
+
|
|
23
|
+
## CSS Custom Properties
|
|
24
|
+
|
|
25
|
+
| Property | Default | Description |
|
|
26
|
+
|----------|---------|-------------|
|
|
27
|
+
| `--evo-flip-card-width` | `640px` | Width of the card |
|
|
28
|
+
| `--evo-flip-card-height` | `360px` | Height of the card |
|
|
29
|
+
| `--evo-flip-card-duration` | `0.6s` | Duration of the flip transition |
|
|
30
|
+
|
|
31
|
+
## JavaScript API
|
|
32
|
+
|
|
33
|
+
The underlying `<evo-flip-card>` custom element exposes the following API for programmatic control:
|
|
34
|
+
|
|
35
|
+
| Member | Type | Description |
|
|
36
|
+
|--------|------|-------------|
|
|
37
|
+
| `isFlipped` | `boolean` (get/set) | Current flip state. Setting this toggles the card. |
|
|
38
|
+
| `toggle()` | `method` | Toggles between front and back |
|
|
39
|
+
| `flipFront()` | `method` | Shows the front face |
|
|
40
|
+
| `flipBack()` | `method` | Shows the back face |
|
|
41
|
+
|
|
42
|
+
## Examples
|
|
43
|
+
|
|
44
|
+
### Basic usage
|
|
45
|
+
|
|
46
|
+
```astro
|
|
47
|
+
---
|
|
48
|
+
import { FlipCard } from '@inizioevoke/astro-core';
|
|
49
|
+
---
|
|
50
|
+
<FlipCard width={400} height={300}>
|
|
51
|
+
<div slot="front">
|
|
52
|
+
<h2>Front</h2>
|
|
53
|
+
<p>Click the button to flip.</p>
|
|
54
|
+
</div>
|
|
55
|
+
<div slot="back">
|
|
56
|
+
<h2>Back</h2>
|
|
57
|
+
<p>Click the button to flip back.</p>
|
|
58
|
+
</div>
|
|
59
|
+
</FlipCard>
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
### Custom trigger buttons
|
|
63
|
+
|
|
64
|
+
Use `trigger` to set the same custom button content on both faces, or use `front-trigger` / `back-trigger` to set them independently.
|
|
65
|
+
|
|
66
|
+
```astro
|
|
67
|
+
<FlipCard>
|
|
68
|
+
<span slot="trigger">Flip ↔</span>
|
|
69
|
+
<div slot="front">Front content</div>
|
|
70
|
+
<div slot="back">Back content</div>
|
|
71
|
+
</FlipCard>
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
```astro
|
|
75
|
+
<FlipCard>
|
|
76
|
+
<span slot="front-trigger">See details →</span>
|
|
77
|
+
<span slot="back-trigger">← Go back</span>
|
|
78
|
+
<div slot="front">Front content</div>
|
|
79
|
+
<div slot="back">Back content</div>
|
|
80
|
+
</FlipCard>
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
### Programmatic control
|
|
84
|
+
|
|
85
|
+
Access the custom element directly to control the card from JavaScript.
|
|
86
|
+
|
|
87
|
+
```astro
|
|
88
|
+
<FlipCard id="my-card">
|
|
89
|
+
<div slot="front">Front</div>
|
|
90
|
+
<div slot="back">Back</div>
|
|
91
|
+
</FlipCard>
|
|
92
|
+
|
|
93
|
+
<button id="flip-btn">Flip programmatically</button>
|
|
94
|
+
|
|
95
|
+
<script>
|
|
96
|
+
const card = document.querySelector('#my-card');
|
|
97
|
+
document.querySelector('#flip-btn').addEventListener('click', () => {
|
|
98
|
+
card.toggle();
|
|
99
|
+
});
|
|
100
|
+
</script>
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
### Overriding dimensions via CSS
|
|
104
|
+
|
|
105
|
+
You can also control card dimensions with CSS custom properties directly.
|
|
106
|
+
|
|
107
|
+
```css
|
|
108
|
+
evo-flip-card {
|
|
109
|
+
--evo-flip-card-width: 100%;
|
|
110
|
+
--evo-flip-card-height: 480px;
|
|
111
|
+
--evo-flip-card-duration: 0.4s;
|
|
112
|
+
}
|
|
113
|
+
```
|
|
@@ -0,0 +1,211 @@
|
|
|
1
|
+
# Modal
|
|
2
|
+
|
|
3
|
+
The Modal component system renders a custom element (`<evo-modal>`) that is hidden by default and shown/hidden programmatically or via trigger elements. It ships with three companion components — `ModalTrigger` and `ModalOverlay` — and a JavaScript utility API.
|
|
4
|
+
|
|
5
|
+
When a modal opens it automatically closes any other currently visible modal. Clicking the overlay (or the built-in close button) hides the active modal. An overlay `<div>` is injected automatically into `<body>` on `DOMContentLoaded` if `ModalOverlay` is not present in the page.
|
|
6
|
+
|
|
7
|
+
## Components
|
|
8
|
+
|
|
9
|
+
### `Modal`
|
|
10
|
+
|
|
11
|
+
The modal panel itself.
|
|
12
|
+
|
|
13
|
+
#### Props
|
|
14
|
+
|
|
15
|
+
| Prop | Type | Default | Description |
|
|
16
|
+
|------|------|---------|-------------|
|
|
17
|
+
| `id` | `string` | **required** | Unique id used to target the modal from triggers and the JS API |
|
|
18
|
+
| `closeButton` | `'default' \| 'minimal' \| 'none' \| 'false' \| false` | `'default'` | Controls the built-in close button. `'default'` renders a styled ✕ circle; `'minimal'` renders unstyled; `'none'` / `false` removes it entirely |
|
|
19
|
+
| `closeButtonAtts` | `Record<string, string>` | — | Additional HTML attributes spread onto the close button element |
|
|
20
|
+
| `...rest` | `HTMLAttributes<'div'>` | — | Any additional HTML attributes are passed to the `<evo-modal>` element |
|
|
21
|
+
|
|
22
|
+
#### Slots
|
|
23
|
+
|
|
24
|
+
| Slot | Description |
|
|
25
|
+
|------|-------------|
|
|
26
|
+
| *(default)* | Main modal content, rendered inside the padded `.evo-modal-wrapper` |
|
|
27
|
+
| `close` | Custom label/icon for the close button (default is `X`) |
|
|
28
|
+
| `outer` | Content rendered outside the `.evo-modal-wrapper`, between the close button and the wrapper (useful for full-bleed media) |
|
|
29
|
+
|
|
30
|
+
---
|
|
31
|
+
|
|
32
|
+
### `ModalTrigger`
|
|
33
|
+
|
|
34
|
+
A `<button>` that opens a modal when clicked. Uses `data-evo-modal-show` under the hood, so plain HTML elements with that attribute also work (see [Data attribute triggers](#data-attribute-triggers)).
|
|
35
|
+
|
|
36
|
+
#### Props
|
|
37
|
+
|
|
38
|
+
| Prop | Type | Default | Description |
|
|
39
|
+
|------|------|---------|-------------|
|
|
40
|
+
| `modal` | `string` | **required** | The `id` of the modal to open |
|
|
41
|
+
| `animation` | `'fade' \| 'none'` | `'fade'` | Animation to use when opening |
|
|
42
|
+
| `...rest` | `HTMLAttributes<'button'>` | — | Any additional attributes are spread onto the button |
|
|
43
|
+
|
|
44
|
+
---
|
|
45
|
+
|
|
46
|
+
### `ModalOverlay`
|
|
47
|
+
|
|
48
|
+
An optional backdrop element. If omitted, the script creates one automatically. Include it explicitly when you need to place or style the overlay yourself.
|
|
49
|
+
|
|
50
|
+
#### Props
|
|
51
|
+
|
|
52
|
+
| Prop | Type | Description |
|
|
53
|
+
|------|------|-------------|
|
|
54
|
+
| `class` | `string` | Additional CSS class(es) appended to the overlay element |
|
|
55
|
+
| `...rest` | `HTMLAttributes<'div'>` | Any additional attributes are spread onto the div |
|
|
56
|
+
|
|
57
|
+
---
|
|
58
|
+
|
|
59
|
+
## CSS Custom Properties
|
|
60
|
+
|
|
61
|
+
| Property | Default | Description |
|
|
62
|
+
|----------|---------|-------------|
|
|
63
|
+
| `--evo-modal-width` | `800px` | Width of the modal |
|
|
64
|
+
| `--evo-modal-height` | `450px` | Height of the modal |
|
|
65
|
+
| `--evo-modal-position` | `absolute` | CSS `position` of the modal element |
|
|
66
|
+
| `--evo-modal-viewport-width` | `100vw` | Viewport width used to center the modal |
|
|
67
|
+
| `--evo-modal-viewport-height` | `100vh` | Viewport height used to center the modal |
|
|
68
|
+
| `--evo-modal-animation-duration` | `300ms` | Duration of show/hide animations (also read by JS) |
|
|
69
|
+
| `--evo-modal-z-index` | `99` | `z-index` of the modal; overlay is `z-index - 1` |
|
|
70
|
+
| `--evo-modal-overlay-blur` | `2px` | `backdrop-filter: blur()` value on the overlay |
|
|
71
|
+
|
|
72
|
+
---
|
|
73
|
+
|
|
74
|
+
## JavaScript API
|
|
75
|
+
|
|
76
|
+
### Element methods
|
|
77
|
+
|
|
78
|
+
Access the `<evo-modal>` element directly to call these methods:
|
|
79
|
+
|
|
80
|
+
| Method | Signature | Description |
|
|
81
|
+
|--------|-----------|-------------|
|
|
82
|
+
| `showModal` | `(opts?: { animation?: ModalAnimation }) => Promise<void>` | Shows the modal. Resolves after the animation completes. |
|
|
83
|
+
| `hideModal` | `(opts?: { animation?: ModalAnimation }) => Promise<void>` | Hides the modal. Resolves after the animation completes. |
|
|
84
|
+
|
|
85
|
+
`ModalAnimation` is `'fade' | 'none'`. When omitted, `showModal` defaults to `'fade'` and `hideModal` reuses the animation that was used to show it.
|
|
86
|
+
|
|
87
|
+
### Utility functions
|
|
88
|
+
|
|
89
|
+
Importable from the package entry point for use in client scripts.
|
|
90
|
+
|
|
91
|
+
```ts
|
|
92
|
+
import { showModal, hideModal, hideModals, showOverlay, hideOverlay, bindTriggers } from '@inizioevoke/astro-core';
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
| Function | Signature | Description |
|
|
96
|
+
|----------|-----------|-------------|
|
|
97
|
+
| `showModal` | `(selector: string \| HTMLElement, opts?) => Promise<EvoModalElement \| undefined>` | Shows a modal by id, CSS selector, or element reference. `opts` accepts `animation`, `onShow`, and `onHide` one-time callbacks. |
|
|
98
|
+
| `hideModal` | `(selector: string \| HTMLElement, animation?) => Promise<void>` | Hides a specific modal. |
|
|
99
|
+
| `hideModals` | `(animation?) => Promise<void>` | Hides all currently visible modals. |
|
|
100
|
+
| `showOverlay` | `(animation?) => void` | Shows the overlay independently. |
|
|
101
|
+
| `hideOverlay` | `(opts?) => void` | Hides the overlay independently. |
|
|
102
|
+
| `bindTriggers` | `(container?) => void` | Binds click handlers to `[data-evo-modal-show]` elements. Call this after dynamically inserting trigger elements into the DOM. |
|
|
103
|
+
|
|
104
|
+
### Custom events
|
|
105
|
+
|
|
106
|
+
Both events bubble and are composed (cross shadow DOM). Listen on the `<evo-modal>` element or any ancestor.
|
|
107
|
+
|
|
108
|
+
| Event | Detail | Fires when |
|
|
109
|
+
|-------|--------|------------|
|
|
110
|
+
| `evomodal-visible` | `{ modal: EvoModalElement }` | Modal has finished showing |
|
|
111
|
+
| `evomodal-hidden` | `{ modal: EvoModalElement, replacedBy?: EvoModalElement }` | Modal has finished hiding. `replacedBy` is set when another modal opened in its place. |
|
|
112
|
+
|
|
113
|
+
---
|
|
114
|
+
|
|
115
|
+
## Data attribute triggers
|
|
116
|
+
|
|
117
|
+
Any element with `data-evo-modal-show` will open the target modal on click — no `ModalTrigger` component required. `bindTriggers()` is called automatically on `DOMContentLoaded`; call it manually for dynamically added elements.
|
|
118
|
+
|
|
119
|
+
```html
|
|
120
|
+
<button data-evo-modal-show="my-modal" data-evo-modal-animation="fade">Open</button>
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
| Attribute | Description |
|
|
124
|
+
|-----------|-------------|
|
|
125
|
+
| `data-evo-modal-show` | Id of the modal to open (or a CSS selector prefixed with `#` or `.`) |
|
|
126
|
+
| `data-evo-modal-animation` | Optional animation override (`'fade'` or `'none'`) |
|
|
127
|
+
|
|
128
|
+
Any element with the class `evo-modal-action-hide` inside a modal will close it when clicked (the built-in close button uses this class).
|
|
129
|
+
|
|
130
|
+
---
|
|
131
|
+
|
|
132
|
+
## Examples
|
|
133
|
+
|
|
134
|
+
### Basic modal with trigger
|
|
135
|
+
|
|
136
|
+
```astro
|
|
137
|
+
---
|
|
138
|
+
import { Modal, ModalTrigger } from '@inizioevoke/astro-core';
|
|
139
|
+
---
|
|
140
|
+
<ModalTrigger modal="info-modal">Open modal</ModalTrigger>
|
|
141
|
+
|
|
142
|
+
<Modal id="info-modal">
|
|
143
|
+
<h2>Hello</h2>
|
|
144
|
+
<p>This is the modal content.</p>
|
|
145
|
+
</Modal>
|
|
146
|
+
```
|
|
147
|
+
|
|
148
|
+
### Custom close button label
|
|
149
|
+
|
|
150
|
+
```astro
|
|
151
|
+
<Modal id="info-modal">
|
|
152
|
+
<span slot="close">Close ✕</span>
|
|
153
|
+
<p>Content here.</p>
|
|
154
|
+
</Modal>
|
|
155
|
+
```
|
|
156
|
+
|
|
157
|
+
### No close button
|
|
158
|
+
|
|
159
|
+
```astro
|
|
160
|
+
<Modal id="info-modal" closeButton="none">
|
|
161
|
+
<p>Close me with a trigger inside or via JS.</p>
|
|
162
|
+
<button class="evo-modal-action-hide">Dismiss</button>
|
|
163
|
+
</Modal>
|
|
164
|
+
```
|
|
165
|
+
|
|
166
|
+
### Full-bleed outer slot
|
|
167
|
+
|
|
168
|
+
```astro
|
|
169
|
+
<Modal id="media-modal">
|
|
170
|
+
<img slot="outer" src="/hero.jpg" alt="" style="width:100%;display:block;" />
|
|
171
|
+
<p>Caption below the image.</p>
|
|
172
|
+
</Modal>
|
|
173
|
+
```
|
|
174
|
+
|
|
175
|
+
### Programmatic control with callbacks
|
|
176
|
+
|
|
177
|
+
```astro
|
|
178
|
+
<script>
|
|
179
|
+
import { showModal } from '@inizioevoke/astro-core';
|
|
180
|
+
|
|
181
|
+
document.querySelector('#open-btn').addEventListener('click', () => {
|
|
182
|
+
showModal('info-modal', {
|
|
183
|
+
animation: 'fade',
|
|
184
|
+
onShow: (e) => console.log('modal visible', e.detail.modal),
|
|
185
|
+
onHide: (e) => console.log('modal hidden', e.detail.modal),
|
|
186
|
+
});
|
|
187
|
+
});
|
|
188
|
+
</script>
|
|
189
|
+
```
|
|
190
|
+
|
|
191
|
+
### Binding dynamically added triggers
|
|
192
|
+
|
|
193
|
+
```ts
|
|
194
|
+
import { bindTriggers } from '@inizioevoke/astro-core';
|
|
195
|
+
|
|
196
|
+
// After inserting new trigger elements into the DOM:
|
|
197
|
+
bindTriggers(myContainer);
|
|
198
|
+
```
|
|
199
|
+
|
|
200
|
+
### Explicit overlay with custom styling
|
|
201
|
+
|
|
202
|
+
```astro
|
|
203
|
+
---
|
|
204
|
+
import { Modal, ModalOverlay } from '@inizioevoke/astro-core';
|
|
205
|
+
---
|
|
206
|
+
<ModalOverlay class="my-overlay" />
|
|
207
|
+
|
|
208
|
+
<Modal id="info-modal">
|
|
209
|
+
<p>Content</p>
|
|
210
|
+
</Modal>
|
|
211
|
+
```
|
|
@@ -0,0 +1,160 @@
|
|
|
1
|
+
# ScrollContainer
|
|
2
|
+
|
|
3
|
+
The ScrollContainer component renders a custom element (`<evo-scroll-container>`) that replaces the browser's native scrollbar with a styled, draggable custom scrollbar. It supports vertical, horizontal, or both-axis scrolling.
|
|
4
|
+
|
|
5
|
+
The scrollbar auto-hides when content fits within the container and reappears when content overflows. Thumb size is calculated proportionally to the visible content ratio and automatically updates on window resize, DOM mutation, and intersection visibility changes.
|
|
6
|
+
|
|
7
|
+
## Props
|
|
8
|
+
|
|
9
|
+
| Prop | Type | Default | Description |
|
|
10
|
+
|------|------|---------|-------------|
|
|
11
|
+
| `width` | `string \| number` | — | Container width. Plain numbers are treated as pixels; strings are used as-is (e.g. `'100%'`) |
|
|
12
|
+
| `height` | `string \| number` | — | Container height. Plain numbers are treated as pixels; strings are used as-is |
|
|
13
|
+
| `scrolling` | `'vertical' \| 'horizontal' \| 'both'` | `'vertical'` | Axis or axes to enable scrolling on |
|
|
14
|
+
| `...rest` | `HTMLAttributes<'div'>` | — | Any additional HTML attributes are passed to the `<evo-scroll-container>` element |
|
|
15
|
+
|
|
16
|
+
## Slots
|
|
17
|
+
|
|
18
|
+
| Slot | Description |
|
|
19
|
+
|------|-------------|
|
|
20
|
+
| *(default)* | The scrollable content |
|
|
21
|
+
|
|
22
|
+
## CSS Custom Properties
|
|
23
|
+
|
|
24
|
+
| Property | Default | Description |
|
|
25
|
+
|----------|---------|-------------|
|
|
26
|
+
| `--evo-scroll-container-track-width` | `8px` | Width/height of the scrollbar track |
|
|
27
|
+
| `--evo-scroll-container-track-color` | `#dddddd` | Track background color |
|
|
28
|
+
| `--evo-scroll-container-thumb-color` | `#666666` | Thumb background color |
|
|
29
|
+
| `--evo-scroll-container-thumb-border-width` | `0px` | Border width on the thumb |
|
|
30
|
+
| `--evo-scroll-container-thumb-border-color` | same as track | Border color on the thumb |
|
|
31
|
+
| `--evo-scroll-container-border-radius` | `track-width / 2` | Border radius for track and thumb |
|
|
32
|
+
| `--evo-scroll-container-track-vert-top` | `0px` | Offset from the top of the vertical track |
|
|
33
|
+
| `--evo-scroll-container-track-vert-bottom` | `0px` | Offset from the bottom of the vertical track |
|
|
34
|
+
| `--evo-scroll-container-track-vert-right` | `0px` | Offset from the right edge for the vertical track |
|
|
35
|
+
| `--evo-scroll-container-track-horz-bottom` | `0px` | Offset from the bottom edge for the horizontal track |
|
|
36
|
+
| `--evo-scroll-container-track-horz-left` | `0px` | Left offset of the horizontal track |
|
|
37
|
+
| `--evo-scroll-container-track-horz-right` | `0px` | Right offset of the horizontal track |
|
|
38
|
+
| `--evo-scroll-container-width-offset` | same as `track-width` | Extra horizontal space reserved for the vertical scrollbar |
|
|
39
|
+
| `--evo-scroll-container-height-offset` | same as `track-width` | Extra vertical space reserved for the horizontal scrollbar |
|
|
40
|
+
|
|
41
|
+
## JavaScript API
|
|
42
|
+
|
|
43
|
+
### Element properties and methods
|
|
44
|
+
|
|
45
|
+
Access the `<evo-scroll-container>` element directly to use these members:
|
|
46
|
+
|
|
47
|
+
| Member | Type | Description |
|
|
48
|
+
|--------|------|-------------|
|
|
49
|
+
| `content` | `HTMLElement` (get) | The inner `.evo-scroll-content` element |
|
|
50
|
+
| `scrollLeft` | `number` (get/set) | Horizontal scroll position |
|
|
51
|
+
| `scrollTop` | `number` (get/set) | Vertical scroll position |
|
|
52
|
+
| `scrollWidth` | `number` (get) | Full scrollable width of the content |
|
|
53
|
+
| `scrollHeight` | `number` (get) | Full scrollable height of the content |
|
|
54
|
+
| `scroll(opts?)` | method | Scroll to a position (`ScrollToOptions` or `(x, y)`) |
|
|
55
|
+
| `scrollTo(opts?)` | method | Alias for `scroll()` |
|
|
56
|
+
| `scrollBy(opts?)` | method | Scroll by a delta (`ScrollToOptions` or `(x, y)`) |
|
|
57
|
+
| `getScroll()` | `() => { left, top }` | Returns current scroll position |
|
|
58
|
+
| `resize({ height })` | method | Sets the container height in pixels and refreshes the scrollbar |
|
|
59
|
+
| `configureScrollbar(settings)` | method | Overrides scrollbar appearance. Accepts `{ trackVisible?: boolean, thumbHeight?: number }` |
|
|
60
|
+
| `resetScrollbar()` | method | Resets scrollbar to automatic sizing |
|
|
61
|
+
| `refresh()` | method | Recalculates and repaints thumb sizes. Call after external layout changes. |
|
|
62
|
+
|
|
63
|
+
`scroll`, `scrollTo`, and `scrollBy` proxy directly to the inner content element. `scroll` and `scrollend` events also delegate to the inner content element automatically.
|
|
64
|
+
|
|
65
|
+
### Utility functions
|
|
66
|
+
|
|
67
|
+
Importable from the package entry point for use in client scripts.
|
|
68
|
+
|
|
69
|
+
```ts
|
|
70
|
+
import { resize, refresh, getScroll, scroll, getScrollContainer } from '@inizioevoke/astro-core';
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
| Function | Signature | Description |
|
|
74
|
+
|----------|-----------|-------------|
|
|
75
|
+
| `resize` | `(selector, { height }) => void` | Sets the height of a scroll container by selector or element reference |
|
|
76
|
+
| `refresh` | `(selector?) => void` | Refreshes one container (by selector/element) or all containers if no argument is given |
|
|
77
|
+
| `getScroll` | `(selector) => { left, top } \| undefined` | Returns the current scroll position of a container |
|
|
78
|
+
| `scroll` | `(selector, { left?, top?, behavior? }) => void` | Scrolls a container to a position. Unspecified axes retain their current position. |
|
|
79
|
+
| `getScrollContainer` | `(selector) => IScrollContainer \| undefined` | Returns the `EvoScrollContainerElement` instance for a selector or element |
|
|
80
|
+
|
|
81
|
+
---
|
|
82
|
+
|
|
83
|
+
## Examples
|
|
84
|
+
|
|
85
|
+
### Vertical scroll (default)
|
|
86
|
+
|
|
87
|
+
```astro
|
|
88
|
+
---
|
|
89
|
+
import { ScrollContainer } from '@inizioevoke/astro-core';
|
|
90
|
+
---
|
|
91
|
+
<ScrollContainer height={400}>
|
|
92
|
+
<p>Line 1</p>
|
|
93
|
+
<p>Line 2</p>
|
|
94
|
+
<!-- ... more content ... -->
|
|
95
|
+
</ScrollContainer>
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
### Horizontal scroll
|
|
99
|
+
|
|
100
|
+
```astro
|
|
101
|
+
<ScrollContainer scrolling="horizontal" height={200}>
|
|
102
|
+
<div style="display:flex; gap:1rem; width:max-content;">
|
|
103
|
+
<img src="/a.jpg" />
|
|
104
|
+
<img src="/b.jpg" />
|
|
105
|
+
<img src="/c.jpg" />
|
|
106
|
+
</div>
|
|
107
|
+
</ScrollContainer>
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
### Both axes
|
|
111
|
+
|
|
112
|
+
```astro
|
|
113
|
+
<ScrollContainer scrolling="both" width={600} height={400}>
|
|
114
|
+
<div style="width:1200px;">
|
|
115
|
+
<!-- wide + tall content -->
|
|
116
|
+
</div>
|
|
117
|
+
</ScrollContainer>
|
|
118
|
+
```
|
|
119
|
+
|
|
120
|
+
### Programmatic scroll
|
|
121
|
+
|
|
122
|
+
```astro
|
|
123
|
+
<ScrollContainer id="my-scroll" height={300}>
|
|
124
|
+
<!-- content -->
|
|
125
|
+
</ScrollContainer>
|
|
126
|
+
|
|
127
|
+
<script>
|
|
128
|
+
const sc = document.querySelector('#my-scroll');
|
|
129
|
+
sc.scroll({ top: 200, behavior: 'smooth' });
|
|
130
|
+
</script>
|
|
131
|
+
```
|
|
132
|
+
|
|
133
|
+
### Using utility functions
|
|
134
|
+
|
|
135
|
+
```ts
|
|
136
|
+
import { scroll, refresh } from '@inizioevoke/astro-core';
|
|
137
|
+
|
|
138
|
+
// Smooth-scroll to position
|
|
139
|
+
scroll('#my-scroll', { top: 200, behavior: 'smooth' });
|
|
140
|
+
|
|
141
|
+
// Force refresh after dynamic content insertion
|
|
142
|
+
refresh('#my-scroll');
|
|
143
|
+
```
|
|
144
|
+
|
|
145
|
+
### Custom scrollbar styling
|
|
146
|
+
|
|
147
|
+
```css
|
|
148
|
+
evo-scroll-container {
|
|
149
|
+
--evo-scroll-container-track-width: 12px;
|
|
150
|
+
--evo-scroll-container-track-color: transparent;
|
|
151
|
+
--evo-scroll-container-thumb-color: rgba(0, 0, 0, 0.4);
|
|
152
|
+
}
|
|
153
|
+
```
|
|
154
|
+
|
|
155
|
+
### Force scrollbar visible
|
|
156
|
+
|
|
157
|
+
```ts
|
|
158
|
+
const sc = document.querySelector('#my-scroll');
|
|
159
|
+
sc.configureScrollbar({ trackVisible: true });
|
|
160
|
+
```
|