sliderpro-agentic-skills-etch 0.1.0 → 0.1.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
CHANGED
|
@@ -444,19 +444,28 @@ handler inside `ready()`: the slider mounted before your code ran, so it has alr
|
|
|
444
444
|
Before configuring an unfamiliar slider, check whether it is a premade template. If it is, use
|
|
445
445
|
that template's documented knobs rather than inventing new CSS.
|
|
446
446
|
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
|
451
|
-
|
|
|
452
|
-
| Slider
|
|
453
|
-
| Slider
|
|
454
|
-
| Slider
|
|
455
|
-
|
|
|
456
|
-
|
|
|
457
|
-
|
|
|
458
|
-
|
|
459
|
-
|
|
447
|
+
Every template names its Wrapper, so one class on the Wrapper identifies all nine. Check that
|
|
448
|
+
first; the second column is confirmation.
|
|
449
|
+
|
|
450
|
+
| Template | Wrapper class | Also present | Script | Guide |
|
|
451
|
+
| --- | --- | --- | --- | --- |
|
|
452
|
+
| Slider Zeon | `.slider-zeon-wrapper` | `.slider-zeon__bg-thumb`, `.main-slider-zeon__content` | no | `https://design-with-cracka.gitbook.io/etchsliderpro/premade-templates` |
|
|
453
|
+
| Slider Chronos | `.slider-chronos-wrapper` | `.slider-chronos__slide`, `.slider-chronos__year` | no | `https://design-with-cracka.gitbook.io/etchsliderpro/premade-templates` |
|
|
454
|
+
| Slider Flow | `.slider-flow-wrapper` | `.slider-flow__slide`, `.slider-flow__slide-bg-media` | no | `https://design-with-cracka.gitbook.io/etchsliderpro/premade-templates` |
|
|
455
|
+
| Slider Team | `.slider-team-wrapper` | `.slider-team__grid`, `.slider-team__sync` | no | `https://design-with-cracka.gitbook.io/etchsliderpro/premade-templates` |
|
|
456
|
+
| Slider Stack | `.slider-stack-wrapper` | `.slider-stack__card`, `.slider-stack__card-lift` | no | `https://design-with-cracka.gitbook.io/etchsliderpro/card-stack-templates` |
|
|
457
|
+
| Slider Marquee | `.slider-marquee-wrapper` | two rows, Infinite Scroll on, Edge Fade on the Wrapper | no | `https://design-with-cracka.gitbook.io/etchsliderpro/premade-templates` |
|
|
458
|
+
| Deck Featured | `.slider-wrapper-deck-featured` | `.deck-stack-featured`, `.deck-card-featured` | yes | `https://design-with-cracka.gitbook.io/etchsliderpro/card-stack-templates` |
|
|
459
|
+
| Deck Testimonial | `.slider-wrapper-deck-testimonial` | `.deck-stack-testimonial`, `.deck-card-testimonial` | yes | `https://design-with-cracka.gitbook.io/etchsliderpro/card-stack-templates` |
|
|
460
|
+
| Fall | `.slider-wrapper-fall` | `.fall-stack`, `.fall-card` | yes | `https://design-with-cracka.gitbook.io/etchsliderpro/card-stack-templates` |
|
|
461
|
+
|
|
462
|
+
Note the two naming schemes: the six slider templates suffix the name (`.slider-flow-wrapper`),
|
|
463
|
+
the three card stacks infix it (`.slider-wrapper-fall`).
|
|
464
|
+
|
|
465
|
+
Five of the nine sync elements outside the track, and they do not all use the same prop. Team and
|
|
466
|
+
Stack set `sliderSetup.syncCustomElement` on the Slider; the three card stacks set
|
|
467
|
+
`sliderlessSync.customElement` on the Wrapper. Zeon pairs sliders by `sliderSetup.sliderRole`
|
|
468
|
+
instead, and Chronos, Flow and Marquee sync nothing.
|
|
460
469
|
|
|
461
470
|
The three that carry a script expose named constants at the top of it. On the two Deck templates,
|
|
462
471
|
`MAX_TIERS` is the deepest ring the CSS defines and `NAV_RINGS` is how many rings stay clickable.
|
|
@@ -147,20 +147,57 @@ await etch.saveAsync()
|
|
|
147
147
|
|
|
148
148
|
### Component instances are the unit of work
|
|
149
149
|
|
|
150
|
-
A Slider Pro build is a tree of `etch/component` blocks, each
|
|
151
|
-
|
|
150
|
+
A Slider Pro build is a tree of `etch/component` blocks, each naming a component and carrying a
|
|
151
|
+
flat `attributes` map of prop values. **Two different shapes describe the same tree, and mixing
|
|
152
|
+
them up is the first thing that goes wrong in a session.**
|
|
153
|
+
|
|
154
|
+
**The live shape**, which `etch.blocks.getTree()` returns and `etch.blocks.create()` accepts:
|
|
152
155
|
|
|
153
156
|
```json
|
|
154
157
|
{
|
|
155
|
-
"
|
|
156
|
-
"
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
}
|
|
158
|
+
"type": "etch/component",
|
|
159
|
+
"version": 1,
|
|
160
|
+
"context": {},
|
|
161
|
+
"children": [],
|
|
162
|
+
"componentId": 6455,
|
|
163
|
+
"attributes": { "wrapperHeight": "350px", "spaceBetweenSliders": "50px" }
|
|
161
164
|
}
|
|
162
165
|
```
|
|
163
166
|
|
|
167
|
+
`version`, `context` and `children` are required. Block ids are strings (`"ot2wnef"`), not numbers.
|
|
168
|
+
|
|
169
|
+
**The export shape**, which you only ever see inside a premade template `.json` file, uses
|
|
170
|
+
`blockName`, nests under `attrs`, and calls the component id `ref`:
|
|
171
|
+
|
|
172
|
+
```json
|
|
173
|
+
{ "blockName": "etch/component", "attrs": { "ref": 6455, "attributes": {} }, "innerBlocks": [] }
|
|
174
|
+
```
|
|
175
|
+
|
|
176
|
+
Never pass the export shape to `create()`. It is rejected with
|
|
177
|
+
`Invalid block JSON: expected string, received undefined` at `path: ["type"]`. To put a template on
|
|
178
|
+
the page, hand its whole `gutenbergBlock` to `etch.blocks.pasteAsync()` instead.
|
|
179
|
+
|
|
180
|
+
### Children go in a slot, never directly on the component
|
|
181
|
+
|
|
182
|
+
A component's children must be wrapped in an `etch/slot-content` node naming the slot they fill.
|
|
183
|
+
Putting a Slider straight inside a Wrapper's `children` renders nothing.
|
|
184
|
+
|
|
185
|
+
```json
|
|
186
|
+
{ "type": "etch/slot-content", "version": 1, "context": {}, "children": [], "slotName": "Slides" }
|
|
187
|
+
```
|
|
188
|
+
|
|
189
|
+
| Component | Slots |
|
|
190
|
+
| --- | --- |
|
|
191
|
+
| DWC Slider Wrapper | `Sliders_and_Controls` |
|
|
192
|
+
| DWC Slider | `Top__Controls`, `Slides`, `Bottom__Controls` |
|
|
193
|
+
| DWC Slide | `Content` |
|
|
194
|
+
| DWC Slider Pagination | `PaginationButtons` |
|
|
195
|
+
| DWC Slider Nav Button | `Nav_Btn_Content` |
|
|
196
|
+
| DWC Slider Progress, DWC Slider Play-Pause | none |
|
|
197
|
+
|
|
198
|
+
Controls are siblings of the Slider inside `Sliders_and_Controls`, or children of the Slider's own
|
|
199
|
+
`Top__Controls` / `Bottom__Controls`. Both work, because controls find their own slider.
|
|
200
|
+
|
|
164
201
|
### Group props and the one-extra-brace rule
|
|
165
202
|
|
|
166
203
|
Most Slider props live in groups (`layout`, `motion`, `slides`, `autoplay`, ...). A group is stored
|
|
@@ -305,9 +342,9 @@ unit. `props.pauseSlidersOnHover` on the Wrapper pauses both rows together.
|
|
|
305
342
|
|
|
306
343
|
Infinite Scroll needs the Auto-Scroll extension enabled in admin settings, which is the default.
|
|
307
344
|
|
|
308
|
-
### Synced elements (
|
|
345
|
+
### Synced elements (Team, Stack)
|
|
309
346
|
|
|
310
|
-
|
|
347
|
+
Driving arbitrary elements on the page from the slider is one prop.
|
|
311
348
|
|
|
312
349
|
```js
|
|
313
350
|
setGroup(sliderId, 'sliderSetup', { syncCustomElement: '.timeline-node',
|
|
@@ -319,8 +356,23 @@ moves, and with nav on, clicking one jumps the slider to it. **You write the CSS
|
|
|
319
356
|
states.** The elements do not need to be inside the slider and do not need to match the slide
|
|
320
357
|
count.
|
|
321
358
|
|
|
359
|
+
The selector takes a comma-separated list, so one slider can drive several groups at once. Team
|
|
360
|
+
uses `'.slider-team__sync, .slider-team__sync-heading'` to move a portrait and a heading together.
|
|
361
|
+
|
|
322
362
|
Grep `## 3. Sync Custom Element` in the reference for multiple selectors and the overlap caveat.
|
|
323
363
|
|
|
364
|
+
### Main and thumbnails in one wrapper (Zeon)
|
|
365
|
+
|
|
366
|
+
A full-bleed hero with a thumbnail strip needs no sync prop at all, just roles:
|
|
367
|
+
|
|
368
|
+
```js
|
|
369
|
+
setGroup(mainId, 'sliderSetup', { sliderRole: 'main', transitionType: 'Fade' });
|
|
370
|
+
setGroup(thumbId, 'sliderSetup', { sliderRole: 'thumbnails', transitionType: 'Loop' });
|
|
371
|
+
```
|
|
372
|
+
|
|
373
|
+
Both inside the same Wrapper and they pair automatically. A Wrapper can hold more than one
|
|
374
|
+
thumbnail slider, which is how Zeon runs a background layer and a strip off the same main.
|
|
375
|
+
|
|
324
376
|
### Carousel on mobile, grid on desktop
|
|
325
377
|
|
|
326
378
|
```js
|
|
@@ -345,23 +397,51 @@ setGroup(wrapperId, 'sliderlessSync', {
|
|
|
345
397
|
|
|
346
398
|
CSS handles the front card and its two neighbours from `is-active` / `is-prev` / `is-next`. What
|
|
347
399
|
CSS cannot do is know that a given card is *three* back, so the rows behind, the z-index ladder and
|
|
348
|
-
the click targets need a script. That is case 1 of the native-first gate.
|
|
349
|
-
|
|
400
|
+
the click targets need a script. That is case 1 of the native-first gate.
|
|
401
|
+
|
|
402
|
+
The contract between that script and the CSS is one attribute, **`data-pos`**, which the script
|
|
403
|
+
derives from `is-active` and writes on every card. It is a **signed** offset from the active card,
|
|
404
|
+
so the CSS can fan the left and right sides in opposite directions:
|
|
405
|
+
|
|
406
|
+
```css
|
|
407
|
+
.deck-stack-featured &:is([data-pos='2'], [data-pos='-2']) { /* ring 2, both sides */ }
|
|
408
|
+
```
|
|
409
|
+
|
|
410
|
+
The stack container carries **`data-tiers`**, the number of rings the CSS defines, which lets the
|
|
411
|
+
same CSS serve a three-ring fan and a one-ring stack.
|
|
412
|
+
|
|
413
|
+
Writing an unsigned rank, or naming the attribute anything else, produces a flat pile: the rules
|
|
414
|
+
above simply never match. The script does three things:
|
|
350
415
|
|
|
351
416
|
```js
|
|
352
417
|
// 1. make a custom property interpolable, so a blur can animate (case 2)
|
|
353
418
|
CSS.registerProperty({ name: '--stack-focus', syntax: '<number>',
|
|
354
419
|
inherits: true, initialValue: '0' });
|
|
355
420
|
|
|
356
|
-
// 2. per card:
|
|
357
|
-
var
|
|
358
|
-
card.setAttribute('data-
|
|
421
|
+
// 2. per card: SIGNED offset from the active card, clamped to the deepest ring
|
|
422
|
+
var signed = index - activeIndex;
|
|
423
|
+
card.setAttribute('data-pos', String(Math.max(-MAX_TIERS, Math.min(MAX_TIERS, signed))));
|
|
359
424
|
|
|
360
|
-
// 3. hit-testing: stack order by
|
|
425
|
+
// 3. hit-testing: stack order by distance, and clicks off beyond the clickable rings
|
|
426
|
+
var rank = Math.abs(signed);
|
|
361
427
|
card.style.zIndex = String(total - rank);
|
|
362
428
|
lift.style.pointerEvents = rank <= NAV_RINGS ? 'auto' : 'none';
|
|
363
429
|
```
|
|
364
430
|
|
|
431
|
+
Recompute on every change: watch the stack with a `MutationObserver` filtered to `class`, since
|
|
432
|
+
`is-active` moving is the only signal you get.
|
|
433
|
+
|
|
434
|
+
### Where a script goes
|
|
435
|
+
|
|
436
|
+
There is no script block type. Add a `script` element inside the wrapper:
|
|
437
|
+
|
|
438
|
+
```js
|
|
439
|
+
el('script', {}, [ text(SOURCE) ])
|
|
440
|
+
```
|
|
441
|
+
|
|
442
|
+
Component `<script>` elements are left alone on Sync Without Slider wrappers, which is why a deck
|
|
443
|
+
script keeps working. Do not add one to a wrapper that contains a real slider and expect the same.
|
|
444
|
+
|
|
365
445
|
Step 3 is not optional. Stacked cards are coplanar, so the browser hit-tests them by DOM order and
|
|
366
446
|
a click near the front card can land on one three positions away.
|
|
367
447
|
|
|
@@ -392,19 +472,30 @@ function setGroup(id, key, patch) {
|
|
|
392
472
|
etch.blocks.setAttribute(id, key, '{' + JSON.stringify(next) + '}');
|
|
393
473
|
}
|
|
394
474
|
|
|
395
|
-
function
|
|
396
|
-
return {
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
475
|
+
function node(extra, children) {
|
|
476
|
+
return Object.assign({ version: 1, context: {}, children: children || [] }, extra);
|
|
477
|
+
}
|
|
478
|
+
|
|
479
|
+
function component(componentId, attributes, children) {
|
|
480
|
+
return node({ type: 'etch/component', componentId: componentId,
|
|
481
|
+
attributes: attributes || {} }, children);
|
|
482
|
+
}
|
|
483
|
+
|
|
484
|
+
function slot(slotName, children) {
|
|
485
|
+
return node({ type: 'etch/slot-content', slotName: slotName }, children);
|
|
401
486
|
}
|
|
402
487
|
|
|
403
|
-
function
|
|
488
|
+
function el(tag, attributes, children) {
|
|
489
|
+
return node({ type: 'etch/element', tag: tag, attributes: attributes || {} }, children);
|
|
490
|
+
}
|
|
491
|
+
|
|
492
|
+
function text(t) { return node({ type: 'etch/text', text: t }); }
|
|
493
|
+
|
|
494
|
+
function findByRef(nodes, componentId, out) {
|
|
404
495
|
out = out || [];
|
|
405
496
|
for (const n of nodes || []) {
|
|
406
|
-
if (n.componentId ===
|
|
407
|
-
findByRef(n.children
|
|
497
|
+
if (n.componentId === componentId) out.push(n);
|
|
498
|
+
findByRef(n.children, componentId, out);
|
|
408
499
|
}
|
|
409
500
|
return out;
|
|
410
501
|
}
|
|
@@ -415,18 +506,27 @@ function findByRef(nodes, ref, out) {
|
|
|
415
506
|
```js
|
|
416
507
|
const C = comps();
|
|
417
508
|
const slides = [];
|
|
418
|
-
for (let i = 0; i < 5; i++)
|
|
509
|
+
for (let i = 0; i < 5; i++) {
|
|
510
|
+
slides.push(component(C['DWC Slide'], {}, [
|
|
511
|
+
slot('Content', [ el('div', {}, [ text('Slide ' + (i + 1)) ]) ])
|
|
512
|
+
]));
|
|
513
|
+
}
|
|
419
514
|
|
|
420
515
|
const id = etch.blocks.create(
|
|
421
516
|
component(C['DWC Slider Wrapper'], {}, [
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
517
|
+
slot('Sliders_and_Controls', [
|
|
518
|
+
component(C['DWC Slider'], {}, [ slot('Slides', slides) ]),
|
|
519
|
+
component(C['DWC Slider Nav Button'], {}),
|
|
520
|
+
component(C['DWC Slider Pagination'], {})
|
|
521
|
+
])
|
|
425
522
|
])
|
|
426
523
|
);
|
|
427
524
|
return id;
|
|
428
525
|
```
|
|
429
526
|
|
|
527
|
+
An empty Slide has no content and so no height. Give slides something to size before wondering why
|
|
528
|
+
the slider is a flat line.
|
|
529
|
+
|
|
430
530
|
Build **one** first, screenshot it, then scale to the full count. Do not generate twenty slides
|
|
431
531
|
before you have seen one render.
|
|
432
532
|
|