meno-interactions 0.1.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/README.md +611 -0
- package/dist/index.d.ts +25 -0
- package/dist/meno-interactions.cjs +458 -0
- package/dist/meno-interactions.css +54 -0
- package/dist/meno-interactions.esm.js +456 -0
- package/dist/meno-interactions.umd.js +456 -0
- package/package.json +40 -0
- package/src/index.js +456 -0
- package/src/styles.css +54 -0
package/README.md
ADDED
|
@@ -0,0 +1,611 @@
|
|
|
1
|
+
# Meno Interactions
|
|
2
|
+
|
|
3
|
+
Attribute-driven JavaScript interactions for Meno projects and static no-code sites.
|
|
4
|
+
|
|
5
|
+
Meno already supports component JavaScript with vanilla DOM code scoped to the component root, and it supports interactive styles through state classes such as `.is-open` or `.is-scrolled`. This package gives no-code builders a reusable script they can add once, then control behavior with custom attributes in the Meno Attributes panel.
|
|
6
|
+
|
|
7
|
+
## Install
|
|
8
|
+
|
|
9
|
+
```bash
|
|
10
|
+
npm install meno-interactions
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
Or use the browser files from `dist/` in a Meno project:
|
|
14
|
+
|
|
15
|
+
```json
|
|
16
|
+
{
|
|
17
|
+
"meta": {
|
|
18
|
+
"libraries": {
|
|
19
|
+
"js": [{ "url": "/libraries/meno-interactions.umd.js", "mode": "defer" }],
|
|
20
|
+
"css": [{ "url": "/libraries/meno-interactions.css" }]
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
## CDN Setup
|
|
27
|
+
|
|
28
|
+
After this package is published to npm, you can load it from a CDN with one CSS file and one deferred script.
|
|
29
|
+
|
|
30
|
+
### Option 1: jsDelivr
|
|
31
|
+
|
|
32
|
+
```html
|
|
33
|
+
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/meno-interactions/dist/meno-interactions.css">
|
|
34
|
+
<script defer src="https://cdn.jsdelivr.net/npm/meno-interactions/dist/meno-interactions.umd.js"></script>
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
### Option 2: unpkg
|
|
38
|
+
|
|
39
|
+
```html
|
|
40
|
+
<link rel="stylesheet" href="https://unpkg.com/meno-interactions/dist/meno-interactions.css">
|
|
41
|
+
<script defer src="https://unpkg.com/meno-interactions/dist/meno-interactions.umd.js"></script>
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
### Option 3: Version-pin the CDN
|
|
45
|
+
|
|
46
|
+
Pinning a version prevents future package updates from changing an already-launched site.
|
|
47
|
+
|
|
48
|
+
```html
|
|
49
|
+
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/meno-interactions@0.1.0/dist/meno-interactions.css">
|
|
50
|
+
<script defer src="https://cdn.jsdelivr.net/npm/meno-interactions@0.1.0/dist/meno-interactions.umd.js"></script>
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
### Add CDN Files in Meno
|
|
54
|
+
|
|
55
|
+
In Meno, add the CDN URLs as page or project libraries. If editing JSON directly, put them in `meta.libraries`:
|
|
56
|
+
|
|
57
|
+
```json
|
|
58
|
+
{
|
|
59
|
+
"meta": {
|
|
60
|
+
"libraries": {
|
|
61
|
+
"css": [
|
|
62
|
+
{ "url": "https://cdn.jsdelivr.net/npm/meno-interactions@0.1.0/dist/meno-interactions.css" }
|
|
63
|
+
],
|
|
64
|
+
"js": [
|
|
65
|
+
{ "url": "https://cdn.jsdelivr.net/npm/meno-interactions@0.1.0/dist/meno-interactions.umd.js", "mode": "defer" }
|
|
66
|
+
]
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
The script auto-initializes on page load. You do not need to write JavaScript for normal use.
|
|
73
|
+
|
|
74
|
+
### Self-hosted CDN-style Setup
|
|
75
|
+
|
|
76
|
+
If you do not want third-party CDN URLs, copy these files into your Meno project's `/libraries/` folder:
|
|
77
|
+
|
|
78
|
+
- `dist/meno-interactions.umd.js`
|
|
79
|
+
- `dist/meno-interactions.css`
|
|
80
|
+
|
|
81
|
+
Then load them like this:
|
|
82
|
+
|
|
83
|
+
```json
|
|
84
|
+
{
|
|
85
|
+
"meta": {
|
|
86
|
+
"libraries": {
|
|
87
|
+
"css": [{ "url": "/libraries/meno-interactions.css" }],
|
|
88
|
+
"js": [{ "url": "/libraries/meno-interactions.umd.js", "mode": "defer" }]
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
## Quick Use
|
|
95
|
+
|
|
96
|
+
Add attributes in Meno's Attributes panel. For example, an accordion only needs a wrapper and trigger attributes:
|
|
97
|
+
|
|
98
|
+
```html
|
|
99
|
+
<div data-meno-accordion data-meno-single="true">
|
|
100
|
+
<button data-meno-accordion-trigger>Question</button>
|
|
101
|
+
<div>Answer</div>
|
|
102
|
+
</div>
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
In Meno JSON, the same idea is represented through `attributes`:
|
|
106
|
+
|
|
107
|
+
```json
|
|
108
|
+
{
|
|
109
|
+
"type": "node",
|
|
110
|
+
"tag": "div",
|
|
111
|
+
"attributes": { "data-meno-accordion": "", "data-meno-single": "true" },
|
|
112
|
+
"children": [
|
|
113
|
+
{
|
|
114
|
+
"type": "node",
|
|
115
|
+
"tag": "button",
|
|
116
|
+
"attributes": { "data-meno-accordion-trigger": "" },
|
|
117
|
+
"children": "Question"
|
|
118
|
+
},
|
|
119
|
+
{ "type": "node", "tag": "div", "children": "Answer" }
|
|
120
|
+
]
|
|
121
|
+
}
|
|
122
|
+
```
|
|
123
|
+
|
|
124
|
+
## Attribute Reference and Examples
|
|
125
|
+
|
|
126
|
+
### Disclosure / Simple Toggle
|
|
127
|
+
|
|
128
|
+
Use this for one button that opens or closes one nearby panel.
|
|
129
|
+
|
|
130
|
+
```html
|
|
131
|
+
<button data-meno-toggle data-meno-target="#details">Show details</button>
|
|
132
|
+
<div id="details" hidden>
|
|
133
|
+
Extra content goes here.
|
|
134
|
+
</div>
|
|
135
|
+
```
|
|
136
|
+
|
|
137
|
+
Attributes:
|
|
138
|
+
|
|
139
|
+
- `data-meno-toggle`: marks the clickable trigger.
|
|
140
|
+
- `data-meno-target="#details"`: optional selector for the panel. If omitted, the next sibling is used.
|
|
141
|
+
|
|
142
|
+
State classes and attributes:
|
|
143
|
+
|
|
144
|
+
- The panel receives `.is-open` when open.
|
|
145
|
+
- The trigger receives `aria-expanded="true"` or `aria-expanded="false"`.
|
|
146
|
+
- The panel `hidden` attribute is toggled.
|
|
147
|
+
|
|
148
|
+
### Accordion
|
|
149
|
+
|
|
150
|
+
Use this for FAQ rows or any stacked expandable content.
|
|
151
|
+
|
|
152
|
+
```html
|
|
153
|
+
<div data-meno-accordion data-meno-single="true">
|
|
154
|
+
<button data-meno-accordion-trigger>What is included?</button>
|
|
155
|
+
<div hidden>Everything needed for the starter setup.</div>
|
|
156
|
+
|
|
157
|
+
<button data-meno-accordion-trigger>Can I open many rows?</button>
|
|
158
|
+
<div hidden>Set data-meno-single="false" on the wrapper.</div>
|
|
159
|
+
</div>
|
|
160
|
+
```
|
|
161
|
+
|
|
162
|
+
Attributes:
|
|
163
|
+
|
|
164
|
+
- `data-meno-accordion`: marks the accordion wrapper.
|
|
165
|
+
- `data-meno-accordion-trigger`: marks each clickable row header.
|
|
166
|
+
- `data-meno-single="true"`: only one panel can be open at a time.
|
|
167
|
+
- `data-meno-single="false"`: multiple panels can stay open.
|
|
168
|
+
|
|
169
|
+
Panel rule:
|
|
170
|
+
|
|
171
|
+
- Each trigger controls its next sibling unless the trigger has `aria-controls="panel-id"`.
|
|
172
|
+
|
|
173
|
+
### Tabs
|
|
174
|
+
|
|
175
|
+
Use this for switching between multiple panels.
|
|
176
|
+
|
|
177
|
+
```html
|
|
178
|
+
<div data-meno-tabs data-meno-initial-tab="overview">
|
|
179
|
+
<div role="tablist">
|
|
180
|
+
<button data-meno-tab="overview">Overview</button>
|
|
181
|
+
<button data-meno-tab="specs">Specs</button>
|
|
182
|
+
<button data-meno-tab="faq">FAQ</button>
|
|
183
|
+
</div>
|
|
184
|
+
|
|
185
|
+
<section data-meno-tab-panel="overview">Overview content.</section>
|
|
186
|
+
<section data-meno-tab-panel="specs">Specs content.</section>
|
|
187
|
+
<section data-meno-tab-panel="faq">FAQ content.</section>
|
|
188
|
+
</div>
|
|
189
|
+
```
|
|
190
|
+
|
|
191
|
+
Attributes:
|
|
192
|
+
|
|
193
|
+
- `data-meno-tabs`: marks the tab set wrapper.
|
|
194
|
+
- `data-meno-tab="id"`: marks a tab button.
|
|
195
|
+
- `data-meno-tab-panel="id"`: marks the matching panel.
|
|
196
|
+
- `data-meno-initial-tab="id"`: optional initial tab. If omitted, the first tab is selected.
|
|
197
|
+
|
|
198
|
+
State:
|
|
199
|
+
|
|
200
|
+
- Active tab and panel receive `.is-active`.
|
|
201
|
+
- Inactive panels receive `hidden`.
|
|
202
|
+
- Buttons receive `aria-selected`.
|
|
203
|
+
|
|
204
|
+
### Dropdown
|
|
205
|
+
|
|
206
|
+
Use this for nav menus or compact option panels.
|
|
207
|
+
|
|
208
|
+
```html
|
|
209
|
+
<nav>
|
|
210
|
+
<button data-meno-dropdown="services">Services</button>
|
|
211
|
+
<div data-meno-dropdown-panel="services">
|
|
212
|
+
<a href="/design">Design</a>
|
|
213
|
+
<a href="/development">Development</a>
|
|
214
|
+
</div>
|
|
215
|
+
</nav>
|
|
216
|
+
```
|
|
217
|
+
|
|
218
|
+
Attributes:
|
|
219
|
+
|
|
220
|
+
- `data-meno-dropdown="services"`: trigger key.
|
|
221
|
+
- `data-meno-dropdown-panel="services"`: matching panel key.
|
|
222
|
+
|
|
223
|
+
State:
|
|
224
|
+
|
|
225
|
+
- The panel receives `.is-open`.
|
|
226
|
+
- The trigger receives `aria-expanded`.
|
|
227
|
+
- Clicking outside the root closes open dropdowns.
|
|
228
|
+
|
|
229
|
+
### Modal
|
|
230
|
+
|
|
231
|
+
Use this for centered overlays, signup prompts, video popups, and confirmations.
|
|
232
|
+
|
|
233
|
+
```html
|
|
234
|
+
<button data-meno-open-modal="signup">Open signup</button>
|
|
235
|
+
|
|
236
|
+
<div data-meno-modal="signup" data-meno-backdrop-close="true">
|
|
237
|
+
<div data-meno-modal-panel>
|
|
238
|
+
<button data-meno-close aria-label="Close">Close</button>
|
|
239
|
+
<h2>Join the list</h2>
|
|
240
|
+
<p>Modal content goes here.</p>
|
|
241
|
+
</div>
|
|
242
|
+
</div>
|
|
243
|
+
```
|
|
244
|
+
|
|
245
|
+
Attributes:
|
|
246
|
+
|
|
247
|
+
- `data-meno-open-modal="signup"`: opens a modal with the same key.
|
|
248
|
+
- `data-meno-modal="signup"`: modal wrapper.
|
|
249
|
+
- `data-meno-close`: closes the nearest modal.
|
|
250
|
+
- `data-meno-backdrop-close="true"`: clicking the backdrop closes the modal.
|
|
251
|
+
- `data-meno-backdrop-close="false"`: disables backdrop close.
|
|
252
|
+
|
|
253
|
+
State:
|
|
254
|
+
|
|
255
|
+
- The modal receives `.is-open`.
|
|
256
|
+
- The modal `hidden` attribute is toggled.
|
|
257
|
+
- Body scrolling is locked while a modal is open.
|
|
258
|
+
- Escape closes open modals.
|
|
259
|
+
|
|
260
|
+
### Drawer / Mobile Nav
|
|
261
|
+
|
|
262
|
+
Use this for side panels, mobile menus, filter panels, or cart drawers.
|
|
263
|
+
|
|
264
|
+
```html
|
|
265
|
+
<button data-meno-open-drawer="menu">Menu</button>
|
|
266
|
+
|
|
267
|
+
<aside data-meno-drawer="menu">
|
|
268
|
+
<button data-meno-close aria-label="Close menu">Close</button>
|
|
269
|
+
<a href="/">Home</a>
|
|
270
|
+
<a href="/about">About</a>
|
|
271
|
+
</aside>
|
|
272
|
+
```
|
|
273
|
+
|
|
274
|
+
Attributes:
|
|
275
|
+
|
|
276
|
+
- `data-meno-open-drawer="menu"`: opens a drawer with the same key.
|
|
277
|
+
- `data-meno-drawer="menu"`: drawer wrapper.
|
|
278
|
+
- `data-meno-close`: closes the drawer.
|
|
279
|
+
|
|
280
|
+
Meno agent compatibility:
|
|
281
|
+
|
|
282
|
+
- `data-action="toggle-mobile-nav"` is also treated as a drawer opener.
|
|
283
|
+
- `data-action="open-drawer"` is also supported.
|
|
284
|
+
|
|
285
|
+
State:
|
|
286
|
+
|
|
287
|
+
- The drawer receives `.is-open`.
|
|
288
|
+
- The drawer `hidden` attribute is toggled.
|
|
289
|
+
- Body scrolling is locked while a drawer is open.
|
|
290
|
+
- Escape closes open drawers.
|
|
291
|
+
|
|
292
|
+
### Carousel
|
|
293
|
+
|
|
294
|
+
Use this for horizontally scrolling cards, logos, images, or testimonials.
|
|
295
|
+
|
|
296
|
+
```html
|
|
297
|
+
<div data-meno-carousel>
|
|
298
|
+
<button data-meno-carousel-prev aria-label="Previous">Previous</button>
|
|
299
|
+
|
|
300
|
+
<div data-meno-carousel-track>
|
|
301
|
+
<article data-meno-carousel-item>Slide 1</article>
|
|
302
|
+
<article data-meno-carousel-item>Slide 2</article>
|
|
303
|
+
<article data-meno-carousel-item>Slide 3</article>
|
|
304
|
+
</div>
|
|
305
|
+
|
|
306
|
+
<button data-meno-carousel-next aria-label="Next">Next</button>
|
|
307
|
+
</div>
|
|
308
|
+
```
|
|
309
|
+
|
|
310
|
+
Attributes:
|
|
311
|
+
|
|
312
|
+
- `data-meno-carousel`: marks the carousel wrapper.
|
|
313
|
+
- `data-meno-carousel-track`: marks the scrollable track.
|
|
314
|
+
- `data-meno-carousel-item`: optional item marker for scroll snapping styles.
|
|
315
|
+
- `data-meno-carousel-prev`: previous button.
|
|
316
|
+
- `data-meno-carousel-next`: next button.
|
|
317
|
+
|
|
318
|
+
Meno agent compatibility:
|
|
319
|
+
|
|
320
|
+
- `data-el="carousel-track"` is also supported.
|
|
321
|
+
- `data-action="carousel-prev"` and `data-action="carousel-next"` are also supported.
|
|
322
|
+
|
|
323
|
+
Behavior:
|
|
324
|
+
|
|
325
|
+
- Prev/next scroll by one item width.
|
|
326
|
+
- The CSS file adds smooth horizontal scroll and scroll snapping.
|
|
327
|
+
|
|
328
|
+
### Sticky Header
|
|
329
|
+
|
|
330
|
+
Use this to add a class after the visitor scrolls.
|
|
331
|
+
|
|
332
|
+
```html
|
|
333
|
+
<header data-meno-sticky data-meno-sticky-threshold="16">
|
|
334
|
+
Site header
|
|
335
|
+
</header>
|
|
336
|
+
```
|
|
337
|
+
|
|
338
|
+
Attributes:
|
|
339
|
+
|
|
340
|
+
- `data-meno-sticky`: watches scroll position.
|
|
341
|
+
- `data-meno-sticky-threshold="16"`: optional pixel threshold. Default is `8`.
|
|
342
|
+
|
|
343
|
+
Meno agent compatibility:
|
|
344
|
+
|
|
345
|
+
- `data-el="site-header"` is also treated as sticky.
|
|
346
|
+
|
|
347
|
+
State:
|
|
348
|
+
|
|
349
|
+
- The header receives `.is-scrolled` after the threshold.
|
|
350
|
+
|
|
351
|
+
### Smooth Scroll
|
|
352
|
+
|
|
353
|
+
Use this for in-page anchor navigation.
|
|
354
|
+
|
|
355
|
+
```html
|
|
356
|
+
<nav data-meno-smooth-scroll>
|
|
357
|
+
<a href="#features">Features</a>
|
|
358
|
+
<a href="#pricing">Pricing</a>
|
|
359
|
+
</nav>
|
|
360
|
+
|
|
361
|
+
<section id="features">Features content</section>
|
|
362
|
+
<section id="pricing">Pricing content</section>
|
|
363
|
+
```
|
|
364
|
+
|
|
365
|
+
Attributes:
|
|
366
|
+
|
|
367
|
+
- `data-meno-smooth-scroll`: put this on a wrapper containing anchor links, or directly on an anchor.
|
|
368
|
+
|
|
369
|
+
Behavior:
|
|
370
|
+
|
|
371
|
+
- Links starting with `#` scroll smoothly to matching element IDs.
|
|
372
|
+
- The URL hash is updated without a full jump.
|
|
373
|
+
|
|
374
|
+
### Copy to Clipboard
|
|
375
|
+
|
|
376
|
+
Use this for copying codes, links, email addresses, or snippets.
|
|
377
|
+
|
|
378
|
+
```html
|
|
379
|
+
<code id="coupon">SAVE20</code>
|
|
380
|
+
<button data-meno-copy="#coupon" data-meno-copied-label="Copied!">Copy code</button>
|
|
381
|
+
```
|
|
382
|
+
|
|
383
|
+
You can also copy a literal value without a source element:
|
|
384
|
+
|
|
385
|
+
```html
|
|
386
|
+
<button data-meno-copy data-meno-copy-text="hello@example.com">Copy email</button>
|
|
387
|
+
```
|
|
388
|
+
|
|
389
|
+
Attributes:
|
|
390
|
+
|
|
391
|
+
- `data-meno-copy="#coupon"`: selector or ID of the source element.
|
|
392
|
+
- `data-meno-copy-text="value"`: fallback literal text to copy.
|
|
393
|
+
- `data-meno-copied-label="Copied!"`: temporary success label.
|
|
394
|
+
- `data-meno-copy-timeout="1500"`: how long the success label stays, in milliseconds.
|
|
395
|
+
|
|
396
|
+
Meno agent compatibility:
|
|
397
|
+
|
|
398
|
+
- `data-action="copy"` and `data-copy-target="coupon"` are also supported.
|
|
399
|
+
|
|
400
|
+
### Form State
|
|
401
|
+
|
|
402
|
+
Use this for simple no-backend validation and success state.
|
|
403
|
+
|
|
404
|
+
```html
|
|
405
|
+
<form data-meno-form data-meno-success="Thanks, we received it.">
|
|
406
|
+
<label>
|
|
407
|
+
Email
|
|
408
|
+
<input name="email" type="email" required data-meno-error="Email is required">
|
|
409
|
+
</label>
|
|
410
|
+
|
|
411
|
+
<button type="submit">Submit</button>
|
|
412
|
+
<p data-meno-form-status></p>
|
|
413
|
+
</form>
|
|
414
|
+
```
|
|
415
|
+
|
|
416
|
+
Attributes:
|
|
417
|
+
|
|
418
|
+
- `data-meno-form`: marks a form for handling.
|
|
419
|
+
- `data-meno-form-status`: element where error/success text appears.
|
|
420
|
+
- `data-meno-success="message"`: success message.
|
|
421
|
+
- `data-meno-reset-on-submit="true"`: reset form after success. Default is `true`.
|
|
422
|
+
- `data-meno-reset-on-submit="false"`: keep form values after success.
|
|
423
|
+
- `data-meno-error="message"`: field-level required error message.
|
|
424
|
+
|
|
425
|
+
Behavior:
|
|
426
|
+
|
|
427
|
+
- The package prevents default submission.
|
|
428
|
+
- Required fields are checked.
|
|
429
|
+
- A `meno:form-submit` event is dispatched with `{ data }`.
|
|
430
|
+
- No network call is made. Wire your own backend by listening for `meno:form-submit`.
|
|
431
|
+
|
|
432
|
+
### Lightbox
|
|
433
|
+
|
|
434
|
+
Use this for image gallery zoom.
|
|
435
|
+
|
|
436
|
+
```html
|
|
437
|
+
<a href="/images/photo-large.webp" data-meno-open-lightbox data-meno-lightbox-alt="Project photo">
|
|
438
|
+
<img src="/images/photo-thumb.webp" alt="Project photo">
|
|
439
|
+
</a>
|
|
440
|
+
|
|
441
|
+
<div data-meno-lightbox hidden>
|
|
442
|
+
<button data-meno-close aria-label="Close">Close</button>
|
|
443
|
+
<img src="" alt="">
|
|
444
|
+
</div>
|
|
445
|
+
```
|
|
446
|
+
|
|
447
|
+
Attributes:
|
|
448
|
+
|
|
449
|
+
- `data-meno-open-lightbox`: opens the lightbox.
|
|
450
|
+
- `data-meno-open-lightbox="/images/photo-large.webp"`: optional explicit image URL.
|
|
451
|
+
- `data-meno-lightbox-alt="Text"`: alt text for the opened image.
|
|
452
|
+
- `data-meno-lightbox`: lightbox wrapper.
|
|
453
|
+
- `data-meno-close`: close button.
|
|
454
|
+
|
|
455
|
+
State:
|
|
456
|
+
|
|
457
|
+
- The lightbox receives `.is-open`.
|
|
458
|
+
- The lightbox `hidden` attribute is toggled.
|
|
459
|
+
|
|
460
|
+
### Generic Class Toggle
|
|
461
|
+
|
|
462
|
+
Use this when you only need to add, remove, or toggle a class.
|
|
463
|
+
|
|
464
|
+
```html
|
|
465
|
+
<button data-meno-class-toggle="is-highlighted" data-meno-target="#card">
|
|
466
|
+
Toggle highlight
|
|
467
|
+
</button>
|
|
468
|
+
|
|
469
|
+
<article id="card">Card content</article>
|
|
470
|
+
```
|
|
471
|
+
|
|
472
|
+
Attributes:
|
|
473
|
+
|
|
474
|
+
- `data-meno-class-toggle="class-name"`: toggles a class.
|
|
475
|
+
- `data-meno-class-add="class-name"`: adds a class.
|
|
476
|
+
- `data-meno-class-remove="class-name"`: removes a class.
|
|
477
|
+
- `data-meno-target="#selector"`: optional target. If omitted, the clicked element is used.
|
|
478
|
+
|
|
479
|
+
Examples:
|
|
480
|
+
|
|
481
|
+
```html
|
|
482
|
+
<button data-meno-class-add="is-open" data-meno-target="#panel">Open</button>
|
|
483
|
+
<button data-meno-class-remove="is-open" data-meno-target="#panel">Close</button>
|
|
484
|
+
<div id="panel">Panel</div>
|
|
485
|
+
```
|
|
486
|
+
|
|
487
|
+
### Custom Event Dispatch
|
|
488
|
+
|
|
489
|
+
Use this to let no-code controls trigger custom JavaScript elsewhere.
|
|
490
|
+
|
|
491
|
+
```html
|
|
492
|
+
<button data-meno-dispatch="pricing:select">Choose plan</button>
|
|
493
|
+
|
|
494
|
+
<script>
|
|
495
|
+
document.addEventListener('pricing:select', function (event) {
|
|
496
|
+
console.log('Selected from', event.detail.source);
|
|
497
|
+
});
|
|
498
|
+
</script>
|
|
499
|
+
```
|
|
500
|
+
|
|
501
|
+
Attributes:
|
|
502
|
+
|
|
503
|
+
- `data-meno-dispatch="event-name"`: dispatches a bubbling custom event from the clicked element.
|
|
504
|
+
|
|
505
|
+
## MenoFilter
|
|
506
|
+
|
|
507
|
+
MenoFilter is built into Meno and already works with attributes such as `data-meno-filter`, `data-meno-list`, `data-meno-search`, `data-meno-sort`, and `data-meno-page`. This package does not replace it; it complements it for UI interactions outside filtering.
|
|
508
|
+
|
|
509
|
+
Common MenoFilter attributes:
|
|
510
|
+
|
|
511
|
+
```html
|
|
512
|
+
<div data-meno-filter="posts" data-meno-url-sync="true" data-meno-per-page="6">
|
|
513
|
+
<input data-meno-search data-meno-search-fields="title,excerpt" placeholder="Search">
|
|
514
|
+
|
|
515
|
+
<button data-meno-filter-field="category" data-meno-filter-value="Design">Design</button>
|
|
516
|
+
<button data-meno-clear>Clear</button>
|
|
517
|
+
|
|
518
|
+
<div data-meno-list>
|
|
519
|
+
<article data-category="Design" data-title="Example post">Example post</article>
|
|
520
|
+
</div>
|
|
521
|
+
|
|
522
|
+
<p><span data-meno-count="results"></span> results</p>
|
|
523
|
+
<div data-meno-empty>No results found.</div>
|
|
524
|
+
</div>
|
|
525
|
+
```
|
|
526
|
+
|
|
527
|
+
## Interactive Styles Pattern
|
|
528
|
+
|
|
529
|
+
Use the package to toggle state classes, then style those states in Meno `interactiveStyles` or component CSS.
|
|
530
|
+
|
|
531
|
+
```json
|
|
532
|
+
{
|
|
533
|
+
"interactiveStyles": [
|
|
534
|
+
{
|
|
535
|
+
"name": "Open panel",
|
|
536
|
+
"prefix": "",
|
|
537
|
+
"postfix": ".is-open",
|
|
538
|
+
"style": { "base": { "display": "block", "opacity": "1" } }
|
|
539
|
+
}
|
|
540
|
+
]
|
|
541
|
+
}
|
|
542
|
+
```
|
|
543
|
+
|
|
544
|
+
For child targets, put the interactive style on the target node and use a parent selector:
|
|
545
|
+
|
|
546
|
+
```json
|
|
547
|
+
{
|
|
548
|
+
"prefix": "[data-el='dropdown']:hover ",
|
|
549
|
+
"postfix": "",
|
|
550
|
+
"style": { "base": { "opacity": "1", "visibility": "visible" } }
|
|
551
|
+
}
|
|
552
|
+
```
|
|
553
|
+
|
|
554
|
+
## Meno Agent Compatibility
|
|
555
|
+
|
|
556
|
+
The script recognizes Meno agent conventions as aliases:
|
|
557
|
+
|
|
558
|
+
| Agent convention | Package behavior |
|
|
559
|
+
| --- | --- |
|
|
560
|
+
| `data-action="toggle-accordion"` | Accordion trigger |
|
|
561
|
+
| `data-action="select-tab"` | Tab trigger |
|
|
562
|
+
| `data-el="tab-panel"` | Tab panel |
|
|
563
|
+
| `data-action="toggle-dropdown"` | Dropdown trigger |
|
|
564
|
+
| `data-el="dropdown-panel"` | Dropdown panel |
|
|
565
|
+
| `data-action="open-modal"` | Modal trigger |
|
|
566
|
+
| `data-action="close-modal"` | Modal close |
|
|
567
|
+
| `data-action="open-drawer"` | Drawer trigger |
|
|
568
|
+
| `data-action="close-drawer"` | Drawer close |
|
|
569
|
+
| `data-action="toggle-mobile-nav"` | Drawer/mobile nav trigger |
|
|
570
|
+
| `data-el="carousel-track"` | Carousel track |
|
|
571
|
+
| `data-action="carousel-prev"` | Carousel previous |
|
|
572
|
+
| `data-action="carousel-next"` | Carousel next |
|
|
573
|
+
| `data-el="site-header"` | Sticky header |
|
|
574
|
+
| `data-action="copy"` | Copy trigger |
|
|
575
|
+
| `data-copy-target="id"` | Copy source |
|
|
576
|
+
| `data-el="form-status"` | Form status element |
|
|
577
|
+
|
|
578
|
+
## JavaScript API
|
|
579
|
+
|
|
580
|
+
```js
|
|
581
|
+
import { init, destroy, register } from 'meno-interactions';
|
|
582
|
+
|
|
583
|
+
const app = init({ root: document });
|
|
584
|
+
app.refresh();
|
|
585
|
+
destroy();
|
|
586
|
+
|
|
587
|
+
register('my-interaction', function (root) {
|
|
588
|
+
const button = root.querySelector('[data-my-button]');
|
|
589
|
+
if (!button) return [];
|
|
590
|
+
const handler = function () {
|
|
591
|
+
console.log('Clicked');
|
|
592
|
+
};
|
|
593
|
+
button.addEventListener('click', handler);
|
|
594
|
+
return [function () { button.removeEventListener('click', handler); }];
|
|
595
|
+
});
|
|
596
|
+
```
|
|
597
|
+
|
|
598
|
+
The browser build exposes `window.MenoInteractions`:
|
|
599
|
+
|
|
600
|
+
```html
|
|
601
|
+
<script>
|
|
602
|
+
window.MenoInteractions.init();
|
|
603
|
+
</script>
|
|
604
|
+
```
|
|
605
|
+
|
|
606
|
+
## Build
|
|
607
|
+
|
|
608
|
+
```bash
|
|
609
|
+
npm run build
|
|
610
|
+
npm test
|
|
611
|
+
```
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
export interface MenoInteractionsOptions {
|
|
2
|
+
root?: Document | Element;
|
|
3
|
+
activeClass?: string;
|
|
4
|
+
openClass?: string;
|
|
5
|
+
scrolledClass?: string;
|
|
6
|
+
hiddenClass?: string;
|
|
7
|
+
reducedMotion?: boolean;
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
export interface MenoInteractionsInstance {
|
|
11
|
+
root: Document | Element | null;
|
|
12
|
+
destroy(): void;
|
|
13
|
+
refresh(): MenoInteractionsInstance;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
export function init(options?: MenoInteractionsOptions): MenoInteractionsInstance;
|
|
17
|
+
export function destroy(root?: Document | Element): void;
|
|
18
|
+
export function register(name: string, initializer: (root: Document | Element, options: MenoInteractionsOptions) => Array<() => void> | void): void;
|
|
19
|
+
|
|
20
|
+
export const MenoInteractions: {
|
|
21
|
+
init: typeof init;
|
|
22
|
+
destroy: typeof destroy;
|
|
23
|
+
register: typeof register;
|
|
24
|
+
version: string;
|
|
25
|
+
};
|