@getvitops/generator 5.0.0 → 6.0.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/CHANGELOG.md +58 -0
- package/assets/bricks/elements/carousel.php +55 -9
- package/assets/css/global.css +24 -0
- package/assets/css/patterns/carousel.css +602 -179
- package/assets/js/elements.js +4 -4
- package/dist/index.d.mts.map +1 -1
- package/dist/index.mjs +10 -3
- package/dist/index.mjs.map +1 -1
- package/package.json +3 -3
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,63 @@
|
|
|
1
1
|
# @getvitops/generator
|
|
2
2
|
|
|
3
|
+
## 6.0.0
|
|
4
|
+
|
|
5
|
+
### Major Changes
|
|
6
|
+
|
|
7
|
+
- Carousel rework: a scroll strip that is operable and discoverable with no JS in every engine, and
|
|
8
|
+
real controls where the scroll-marker pseudo-elements are missing.
|
|
9
|
+
|
|
10
|
+
`::scroll-button()`, `::scroll-marker` and `::scroll-marker-group` are still Chromium-only, and
|
|
11
|
+
there is no usable polyfill (the one prototype targets the superseded syntax and only re-parses
|
|
12
|
+
inline `<style>` elements). So the carousel no longer assumes them: `<wc-carousel>` builds real
|
|
13
|
+
prev/next `<button>`s and a real dot nav where they are absent, styled from the same declarations
|
|
14
|
+
as the native ones. Which branch is live is decided **by the stylesheet** — one `@supports` sets
|
|
15
|
+
`--carousel-native-nav: 1` and the element reads it back — so the condition is written once and
|
|
16
|
+
the two cannot disagree.
|
|
17
|
+
|
|
18
|
+
**Breaking — `.carousel` is now a shell and `.carousel__track` is the scroller** (all formats). The
|
|
19
|
+
hint and the controls need a home outside the scrollport, and absolute positioning against the
|
|
20
|
+
shell replaces `position: fixed` + `anchor-name`/`position-area`, which pinned controls to a
|
|
21
|
+
viewport corner in any engine without anchor positioning. The 5.x single-element form is still
|
|
22
|
+
styled via `:not(:has(> .carousel__track))` and is promoted by the element at runtime, but it is
|
|
23
|
+
deprecated: wrap your slides in `<ul class="carousel__track">`.
|
|
24
|
+
|
|
25
|
+
**Breaking — looping is opt-in.** `<wc-carousel loop>` clones the slides; the default no longer
|
|
26
|
+
does. Cloning triples the markup, duplicates every image element and makes the scrollbar report 3×
|
|
27
|
+
the real content. `autoplay` implies `loop`. Migration: add `loop`.
|
|
28
|
+
|
|
29
|
+
**Breaking — `[part='autoplay']` is now `.carousel__autoplay`** (aliased for one release; `part`
|
|
30
|
+
only crosses a shadow boundary and this element is light DOM, so it was never a part). The button
|
|
31
|
+
is also a child of the shell rather than the track, where it used to occupy a slide-width column.
|
|
32
|
+
|
|
33
|
+
**Breaking — the host role is `group`, not `region`.** `region` is a landmark, so every carousel
|
|
34
|
+
grew an entry in the landmark list. Pass `landmark` to `<Carousel />` where it really is one.
|
|
35
|
+
|
|
36
|
+
**Changed (visual)** — the scrollbar is visible by default (`scrollbar-width: thin`, was `none`)
|
|
37
|
+
and a "Scroll for more" hint renders above the strip; both dim once the visitor scrolls, via a
|
|
38
|
+
scroll-progress timeline where available and a `data-scrolled` attribute otherwise. Opt out with
|
|
39
|
+
`.carousel--no-scrollbar` and `hint={false}`. `@getvitops/core`'s `global.css` also gains a narrow
|
|
40
|
+
media reset (`max-inline-size: 100%` on replaced elements, `block-size: auto` on `img`/`video`) —
|
|
41
|
+
deliberately without `display: block`, which would change inline images in prose.
|
|
42
|
+
|
|
43
|
+
**Added** — `@getvitops/astro/components/Carousel.astro`, a tier-3 wrapper emitting semantic
|
|
44
|
+
`<ul>`/`<li>`/`<figure>` markup with the right per-slide image priorities: the first slide eager
|
|
45
|
+
and high (the LCP candidate), the rest `lazy`/`low`/`async`. `loading="lazy"` is honoured for
|
|
46
|
+
images clipped by a horizontal scroll container, so off-screen slides defer with no JavaScript at
|
|
47
|
+
all. Also new: `carousel--markers-below` and `carousel--no-scrollbar`, and
|
|
48
|
+
`--carousel-slide-aspect`, which keeps slide heights equal whatever each image's aspect ratio is.
|
|
49
|
+
|
|
50
|
+
**Fixed** — `::scroll-button()` glyphs sat off-centre in their circles (`global.css`'s `*` reset
|
|
51
|
+
does not reach a pseudo-element, so the button was `content-box` with the UA's `padding: 1px 6px`
|
|
52
|
+
and `inline-size` + `aspect-ratio` sized an ellipse); the hover state was a no-op (it set the same
|
|
53
|
+
token as the base rule); slide heights varied with each image's aspect ratio; navigation used
|
|
54
|
+
physical `left`/`right` and so put "previous" on the wrong side in RTL; cloned slides duplicated
|
|
55
|
+
their `id`s; and `scrollBy(clientWidth)` overshot whenever `--carousel-slide-size` was not `100%`.
|
|
56
|
+
|
|
57
|
+
### Patch Changes
|
|
58
|
+
|
|
59
|
+
- @getvitops/utils@6.0.0
|
|
60
|
+
|
|
3
61
|
## 5.0.0
|
|
4
62
|
|
|
5
63
|
### Major Changes
|
|
@@ -2,14 +2,24 @@
|
|
|
2
2
|
/**
|
|
3
3
|
* Vitops — Carousel element (Bricks Builder).
|
|
4
4
|
*
|
|
5
|
-
* Renders the <wc-carousel> Lit component (src/web-components/WCCarousel.ts)
|
|
6
|
-
*
|
|
7
|
-
*
|
|
8
|
-
*
|
|
5
|
+
* Renders the <wc-carousel> Lit component (src/web-components/WCCarousel.ts) around a
|
|
6
|
+
* `.carousel__track` scroll container. Each direct child of the element is a slide.
|
|
7
|
+
*
|
|
8
|
+
* Without JS the `.carousel` classes still yield a working scroll-snap carousel with a
|
|
9
|
+
* visible scrollbar, a "scroll for more" hint and — in Chromium — native prev/next
|
|
10
|
+
* buttons and dot navigation, so the builder canvas stays functional. Where those
|
|
11
|
+
* pseudo-elements are missing (Firefox, older Safari) the component builds real
|
|
12
|
+
* buttons and dots styled to match.
|
|
9
13
|
*
|
|
10
14
|
* The `.carousel` base rides on the built-in "CSS classes" setting (defaulted below) so
|
|
11
15
|
* it applies in the canvas and the frontend. Add modifier classes there:
|
|
12
|
-
* `carousel--scroll-buttons`, `carousel--scroll-markers`, `carousel--auto-pages
|
|
16
|
+
* `carousel--scroll-buttons`, `carousel--scroll-markers`, `carousel--auto-pages`,
|
|
17
|
+
* `carousel--inert`, `carousel--force-stop`, `carousel--no-scrollbar`,
|
|
18
|
+
* `carousel--markers-below`.
|
|
19
|
+
*
|
|
20
|
+
* Note the slide track here is a <div>, not a <ul>: Bricks children are blocks, so the
|
|
21
|
+
* list semantics the Astro component emits are not available on this platform. The CSS
|
|
22
|
+
* targets `> *`, so everything else is identical.
|
|
13
23
|
*
|
|
14
24
|
* Owned by the framework repo (vitops: bricks/elements/); copied into the theme's
|
|
15
25
|
* dist/bricks/ on build — do not hand-edit in the theme.
|
|
@@ -41,7 +51,14 @@ class Vitops_Element_Carousel extends \Bricks\Element {
|
|
|
41
51
|
'label' => esc_html__( 'Autoplay interval (ms)', 'bricks' ),
|
|
42
52
|
'type' => 'number',
|
|
43
53
|
'placeholder' => '0',
|
|
44
|
-
'description' => esc_html__( 'Milliseconds between slides. Leave empty / 0 to disable.', 'bricks' ),
|
|
54
|
+
'description' => esc_html__( 'Milliseconds between slides. Leave empty / 0 to disable. Autoplay implies looping.', 'bricks' ),
|
|
55
|
+
);
|
|
56
|
+
|
|
57
|
+
$this->controls['loop'] = array(
|
|
58
|
+
'tab' => 'content',
|
|
59
|
+
'label' => esc_html__( 'Loop', 'bricks' ),
|
|
60
|
+
'type' => 'checkbox',
|
|
61
|
+
'description' => esc_html__( 'Clone the slides at both ends for a seamless infinite strip. Off by default: it triples the markup and duplicates every image.', 'bricks' ),
|
|
45
62
|
);
|
|
46
63
|
|
|
47
64
|
$this->controls['label'] = array(
|
|
@@ -50,14 +67,30 @@ class Vitops_Element_Carousel extends \Bricks\Element {
|
|
|
50
67
|
'type' => 'text',
|
|
51
68
|
);
|
|
52
69
|
|
|
70
|
+
$this->controls['aspect'] = array(
|
|
71
|
+
'tab' => 'content',
|
|
72
|
+
'label' => esc_html__( 'Slide media aspect ratio', 'bricks' ),
|
|
73
|
+
'type' => 'text',
|
|
74
|
+
'placeholder' => '16 / 9',
|
|
75
|
+
'description' => esc_html__( 'Sets --carousel-slide-aspect, the ratio each slide\'s media box takes. Keeps slide heights equal whatever the image.', 'bricks' ),
|
|
76
|
+
);
|
|
77
|
+
|
|
78
|
+
$this->controls['hint'] = array(
|
|
79
|
+
'tab' => 'content',
|
|
80
|
+
'label' => esc_html__( 'Scroll hint', 'bricks' ),
|
|
81
|
+
'type' => 'text',
|
|
82
|
+
'placeholder' => 'Scroll for more',
|
|
83
|
+
'description' => esc_html__( 'Shown beside the strip and dimmed once the visitor scrolls. Clear to omit it.', 'bricks' ),
|
|
84
|
+
);
|
|
85
|
+
|
|
53
86
|
$this->controls['modifiersInfo'] = array(
|
|
54
87
|
'tab' => 'content',
|
|
55
88
|
'type' => 'info',
|
|
56
|
-
'content' => esc_html__( 'Add modifier classes in "CSS classes": carousel--scroll-buttons, carousel--scroll-markers, carousel--auto-pages. Each direct child is a slide.', 'bricks' ),
|
|
89
|
+
'content' => esc_html__( 'Add modifier classes in "CSS classes": carousel--scroll-buttons, carousel--scroll-markers, carousel--auto-pages, carousel--inert, carousel--force-stop, carousel--no-scrollbar, carousel--markers-below. Each direct child is a slide.', 'bricks' ),
|
|
57
90
|
);
|
|
58
91
|
|
|
59
92
|
// Base carousel class defaulted onto the built-in "CSS classes" setting.
|
|
60
|
-
$this->controls['_cssClasses']['default'] = 'carousel';
|
|
93
|
+
$this->controls['_cssClasses']['default'] = 'carousel carousel--scroll-buttons carousel--scroll-markers';
|
|
61
94
|
}
|
|
62
95
|
|
|
63
96
|
// Seed three empty slides — the author fills each.
|
|
@@ -72,18 +105,31 @@ class Vitops_Element_Carousel extends \Bricks\Element {
|
|
|
72
105
|
public function render() {
|
|
73
106
|
$s = $this->settings;
|
|
74
107
|
$attrs = array();
|
|
108
|
+
$style = '';
|
|
75
109
|
|
|
76
110
|
if ( isset( $s['autoplay'] ) && '' !== $s['autoplay'] && (int) $s['autoplay'] > 0 ) {
|
|
77
111
|
$attrs[] = 'autoplay="' . esc_attr( $s['autoplay'] ) . '"';
|
|
78
112
|
}
|
|
113
|
+
if ( ! empty( $s['loop'] ) ) {
|
|
114
|
+
$attrs[] = 'loop';
|
|
115
|
+
}
|
|
79
116
|
if ( ! empty( $s['label'] ) ) {
|
|
80
117
|
$attrs[] = 'aria-label="' . esc_attr( $s['label'] ) . '"';
|
|
81
118
|
}
|
|
119
|
+
if ( ! empty( $s['aspect'] ) ) {
|
|
120
|
+
$style = ' style="--carousel-slide-aspect:' . esc_attr( $s['aspect'] ) . '"';
|
|
121
|
+
}
|
|
82
122
|
|
|
83
123
|
$attr_str = implode( ' ', $attrs );
|
|
124
|
+
$hint = isset( $s['hint'] ) ? $s['hint'] : esc_html__( 'Scroll for more', 'bricks' );
|
|
84
125
|
|
|
85
|
-
echo "<wc-carousel {$attr_str} {$this->render_attributes( '_root' )}>";
|
|
126
|
+
echo "<wc-carousel {$attr_str} {$this->render_attributes( '_root' )}{$style}>";
|
|
127
|
+
echo '<div class="carousel__track" tabindex="0">';
|
|
86
128
|
echo \Bricks\Frontend::render_children( $this );
|
|
129
|
+
echo '</div>';
|
|
130
|
+
if ( '' !== $hint ) {
|
|
131
|
+
echo '<p class="carousel__hint font-footnote" aria-hidden="true">' . esc_html( $hint ) . '</p>';
|
|
132
|
+
}
|
|
87
133
|
echo '</wc-carousel>';
|
|
88
134
|
}
|
|
89
135
|
}
|
package/assets/css/global.css
CHANGED
|
@@ -26,6 +26,30 @@
|
|
|
26
26
|
box-sizing: border-box;
|
|
27
27
|
}
|
|
28
28
|
|
|
29
|
+
/* Media never overflows its container. `:where()` so it carries zero specificity
|
|
30
|
+
and this file's layer (`vitops.base`) so it loses to everything, including a
|
|
31
|
+
consumer's unlayered rule.
|
|
32
|
+
|
|
33
|
+
Deliberately NOT the classic `img { display: block }` half of this reset. That
|
|
34
|
+
is the part that breaks things here: inline images in prose lose baseline
|
|
35
|
+
alignment, `patterns/icon.css`'s `.icon > img` and marquee logo runs break onto
|
|
36
|
+
their own lines, and `layout.css`'s
|
|
37
|
+
`.rhythm > :where(p, h1…h6, ul, ol) + :where(figure, img, picture, video)`
|
|
38
|
+
rules start spacing images that were previously inline. Every framework pattern
|
|
39
|
+
that wants a block image already declares it (media.css, subgrid.css,
|
|
40
|
+
carousel.css), which is the right place for it.
|
|
41
|
+
|
|
42
|
+
`svg` is excluded from `block-size: auto` because `patterns/svg.css` ships a
|
|
43
|
+
bare `svg` rule and SVGs commonly size from presentation attributes;
|
|
44
|
+
`max-inline-size` alone is safe there. */
|
|
45
|
+
:where(img, svg, video, canvas, iframe, embed, object) {
|
|
46
|
+
max-inline-size: 100%;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
:where(img, video) {
|
|
50
|
+
block-size: auto;
|
|
51
|
+
}
|
|
52
|
+
|
|
29
53
|
/* Drop the UA's 8px body margin. The framework owns page gutters via `.centered`
|
|
30
54
|
(--gutter), so the UA default just offsets every full-bleed surface — sticky
|
|
31
55
|
headers and `bg-*` bands end up inset by 8px with a sliver of canvas showing
|