@jobber/components 8.8.0 → 8.9.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/dist/LightBox/LightBox.d.ts +23 -2
- package/dist/LightBox/LightBox.types.d.ts +41 -0
- package/dist/LightBox-cjs.js +35 -5
- package/dist/LightBox-es.js +35 -5
- package/dist/docs/LightBox/LightBox.md +54 -0
- package/dist/styles.css +65 -35
- package/dist/utils/meta/meta.json +4 -1
- package/package.json +2 -2
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import React from "react";
|
|
2
|
-
import type { LightBoxNavigationProps, LightBoxProps } from "./LightBox.types";
|
|
2
|
+
import type { LightBoxNavigationProps, LightBoxProps, LightBoxThumbnailBarProps, LightBoxThumbnailImageProps, LightBoxThumbnailProps } from "./LightBox.types";
|
|
3
3
|
import { LightBoxProvider } from "./LightBoxContext";
|
|
4
4
|
export declare function LightBoxContent(): React.JSX.Element;
|
|
5
5
|
/**
|
|
@@ -75,7 +75,25 @@ declare function LightBoxCaption(): React.JSX.Element | null;
|
|
|
75
75
|
/**
|
|
76
76
|
* Scrollable thumbnail strip. Only renders when there are two or more images.
|
|
77
77
|
*/
|
|
78
|
-
declare function LightBoxThumbnails(): React.JSX.Element
|
|
78
|
+
declare function LightBoxThumbnails(): React.JSX.Element;
|
|
79
|
+
/**
|
|
80
|
+
* Scrollable container for the thumbnail strip. Owns the scroll chrome and
|
|
81
|
+
* box-sizing, and only renders when there are two or more images.
|
|
82
|
+
*
|
|
83
|
+
* Pass one `LightBox.Thumbnail` per image as `children` to own the thumbnail
|
|
84
|
+
* loop.
|
|
85
|
+
*/
|
|
86
|
+
declare function LightBoxThumbnailBar({ children, className, }: LightBoxThumbnailBarProps): React.JSX.Element | null;
|
|
87
|
+
/**
|
|
88
|
+
* A selectable thumbnail cell identified by its `index`. Owns the selected
|
|
89
|
+
* styling, click-to-navigate behaviour, and renders consumer-provided
|
|
90
|
+
* `children` (typically a `LightBox.ThumbnailImage`).
|
|
91
|
+
*/
|
|
92
|
+
declare function LightBoxThumbnail({ index, children, className, }: LightBoxThumbnailProps): React.JSX.Element;
|
|
93
|
+
/**
|
|
94
|
+
* A thumbnail using our default styling.
|
|
95
|
+
*/
|
|
96
|
+
declare function LightBoxThumbnailImage({ src, alt, className, }: LightBoxThumbnailImageProps): React.JSX.Element;
|
|
79
97
|
/**
|
|
80
98
|
* LightBox displays images in a fullscreen overlay.
|
|
81
99
|
*
|
|
@@ -128,5 +146,8 @@ declare namespace LightBox {
|
|
|
128
146
|
var Navigation: typeof LightBoxNavigation;
|
|
129
147
|
var Caption: typeof LightBoxCaption;
|
|
130
148
|
var Thumbnails: typeof LightBoxThumbnails;
|
|
149
|
+
var ThumbnailBar: typeof LightBoxThumbnailBar;
|
|
150
|
+
var Thumbnail: typeof LightBoxThumbnail;
|
|
151
|
+
var ThumbnailImage: typeof LightBoxThumbnailImage;
|
|
131
152
|
}
|
|
132
153
|
export { LightBox };
|
|
@@ -92,3 +92,44 @@ export interface LightBoxNavigationProps {
|
|
|
92
92
|
*/
|
|
93
93
|
readonly nextButtonClassName?: string;
|
|
94
94
|
}
|
|
95
|
+
export interface LightBoxThumbnailBarProps {
|
|
96
|
+
/**
|
|
97
|
+
* The thumbnails to render inside the scrollable bar, typically one
|
|
98
|
+
* `LightBox.Thumbnail` per image.
|
|
99
|
+
*/
|
|
100
|
+
readonly children: ReactNode;
|
|
101
|
+
/**
|
|
102
|
+
* Additional class name to apply to the thumbnail bar wrapper.
|
|
103
|
+
*/
|
|
104
|
+
readonly className?: string;
|
|
105
|
+
}
|
|
106
|
+
export interface LightBoxThumbnailProps {
|
|
107
|
+
/**
|
|
108
|
+
* The index of the image this thumbnail represents. Used to derive the
|
|
109
|
+
* selected state and to navigate to the image when activated.
|
|
110
|
+
*/
|
|
111
|
+
readonly index: number;
|
|
112
|
+
/**
|
|
113
|
+
* The content rendered inside the selectable thumbnail cell, typically a
|
|
114
|
+
* `LightBox.ThumbnailImage`.
|
|
115
|
+
*/
|
|
116
|
+
readonly children: ReactNode;
|
|
117
|
+
/**
|
|
118
|
+
* Additional class name to apply to the thumbnail cell.
|
|
119
|
+
*/
|
|
120
|
+
readonly className?: string;
|
|
121
|
+
}
|
|
122
|
+
export interface LightBoxThumbnailImageProps {
|
|
123
|
+
/**
|
|
124
|
+
* The image source to render.
|
|
125
|
+
*/
|
|
126
|
+
readonly src: string;
|
|
127
|
+
/**
|
|
128
|
+
* The alternative text for the image.
|
|
129
|
+
*/
|
|
130
|
+
readonly alt: string;
|
|
131
|
+
/**
|
|
132
|
+
* Additional class name to apply to the image.
|
|
133
|
+
*/
|
|
134
|
+
readonly className?: string;
|
|
135
|
+
}
|
package/dist/LightBox-cjs.js
CHANGED
|
@@ -305,13 +305,40 @@ function LightBoxCaption() {
|
|
|
305
305
|
* Scrollable thumbnail strip. Only renders when there are two or more images.
|
|
306
306
|
*/
|
|
307
307
|
function LightBoxThumbnails() {
|
|
308
|
-
const { images
|
|
308
|
+
const { images } = useLightBoxContext();
|
|
309
|
+
return (React.createElement(LightBoxThumbnailBar, null, images.map((image, index) => (React.createElement(LightBoxThumbnail, { key: index, index: index },
|
|
310
|
+
React.createElement(LightBoxThumbnailImage, { src: image.url, alt: image.alt || image.title || "" }))))));
|
|
311
|
+
}
|
|
312
|
+
/**
|
|
313
|
+
* Scrollable container for the thumbnail strip. Owns the scroll chrome and
|
|
314
|
+
* box-sizing, and only renders when there are two or more images.
|
|
315
|
+
*
|
|
316
|
+
* Pass one `LightBox.Thumbnail` per image as `children` to own the thumbnail
|
|
317
|
+
* loop.
|
|
318
|
+
*/
|
|
319
|
+
function LightBoxThumbnailBar({ children, className, }) {
|
|
320
|
+
const { images, boxSizing } = useLightBoxContext();
|
|
309
321
|
if (images.length <= 1)
|
|
310
322
|
return null;
|
|
311
|
-
return (React.createElement("div", { className: styles.thumbnailBar, style: { "--lightbox--box-sizing": boxSizing }, "data-testid": "ATL-Thumbnail-Bar" },
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
323
|
+
return (React.createElement("div", { className: classnames(styles.thumbnailBar, className), style: { "--lightbox--box-sizing": boxSizing }, "data-testid": "ATL-Thumbnail-Bar" }, children));
|
|
324
|
+
}
|
|
325
|
+
/**
|
|
326
|
+
* A selectable thumbnail cell identified by its `index`. Owns the selected
|
|
327
|
+
* styling, click-to-navigate behaviour, and renders consumer-provided
|
|
328
|
+
* `children` (typically a `LightBox.ThumbnailImage`).
|
|
329
|
+
*/
|
|
330
|
+
function LightBoxThumbnail({ index, children, className, }) {
|
|
331
|
+
const { currentImageIndex, selectedThumbnailRef, handleThumbnailClick } = useLightBoxContext();
|
|
332
|
+
const selected = index === currentImageIndex;
|
|
333
|
+
return (React.createElement("div", { className: classnames(styles.thumbnail, className, {
|
|
334
|
+
[styles.selected]: selected,
|
|
335
|
+
}), onClick: () => handleThumbnailClick(index), ref: selected ? selectedThumbnailRef : null }, children));
|
|
336
|
+
}
|
|
337
|
+
/**
|
|
338
|
+
* A thumbnail using our default styling.
|
|
339
|
+
*/
|
|
340
|
+
function LightBoxThumbnailImage({ src, alt, className, }) {
|
|
341
|
+
return (React.createElement("img", { src: src, alt: alt, className: classnames(styles.thumbnailImage, className) }));
|
|
315
342
|
}
|
|
316
343
|
/**
|
|
317
344
|
* LightBox displays images in a fullscreen overlay.
|
|
@@ -367,6 +394,9 @@ LightBox.Slides = LightBoxSlides;
|
|
|
367
394
|
LightBox.Navigation = LightBoxNavigation;
|
|
368
395
|
LightBox.Caption = LightBoxCaption;
|
|
369
396
|
LightBox.Thumbnails = LightBoxThumbnails;
|
|
397
|
+
LightBox.ThumbnailBar = LightBoxThumbnailBar;
|
|
398
|
+
LightBox.Thumbnail = LightBoxThumbnail;
|
|
399
|
+
LightBox.ThumbnailImage = LightBoxThumbnailImage;
|
|
370
400
|
|
|
371
401
|
exports.LightBox = LightBox;
|
|
372
402
|
exports.useLightBoxContext = useLightBoxContext;
|
package/dist/LightBox-es.js
CHANGED
|
@@ -303,13 +303,40 @@ function LightBoxCaption() {
|
|
|
303
303
|
* Scrollable thumbnail strip. Only renders when there are two or more images.
|
|
304
304
|
*/
|
|
305
305
|
function LightBoxThumbnails() {
|
|
306
|
-
const { images
|
|
306
|
+
const { images } = useLightBoxContext();
|
|
307
|
+
return (React__default.createElement(LightBoxThumbnailBar, null, images.map((image, index) => (React__default.createElement(LightBoxThumbnail, { key: index, index: index },
|
|
308
|
+
React__default.createElement(LightBoxThumbnailImage, { src: image.url, alt: image.alt || image.title || "" }))))));
|
|
309
|
+
}
|
|
310
|
+
/**
|
|
311
|
+
* Scrollable container for the thumbnail strip. Owns the scroll chrome and
|
|
312
|
+
* box-sizing, and only renders when there are two or more images.
|
|
313
|
+
*
|
|
314
|
+
* Pass one `LightBox.Thumbnail` per image as `children` to own the thumbnail
|
|
315
|
+
* loop.
|
|
316
|
+
*/
|
|
317
|
+
function LightBoxThumbnailBar({ children, className, }) {
|
|
318
|
+
const { images, boxSizing } = useLightBoxContext();
|
|
307
319
|
if (images.length <= 1)
|
|
308
320
|
return null;
|
|
309
|
-
return (React__default.createElement("div", { className: styles.thumbnailBar, style: { "--lightbox--box-sizing": boxSizing }, "data-testid": "ATL-Thumbnail-Bar" },
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
321
|
+
return (React__default.createElement("div", { className: classnames(styles.thumbnailBar, className), style: { "--lightbox--box-sizing": boxSizing }, "data-testid": "ATL-Thumbnail-Bar" }, children));
|
|
322
|
+
}
|
|
323
|
+
/**
|
|
324
|
+
* A selectable thumbnail cell identified by its `index`. Owns the selected
|
|
325
|
+
* styling, click-to-navigate behaviour, and renders consumer-provided
|
|
326
|
+
* `children` (typically a `LightBox.ThumbnailImage`).
|
|
327
|
+
*/
|
|
328
|
+
function LightBoxThumbnail({ index, children, className, }) {
|
|
329
|
+
const { currentImageIndex, selectedThumbnailRef, handleThumbnailClick } = useLightBoxContext();
|
|
330
|
+
const selected = index === currentImageIndex;
|
|
331
|
+
return (React__default.createElement("div", { className: classnames(styles.thumbnail, className, {
|
|
332
|
+
[styles.selected]: selected,
|
|
333
|
+
}), onClick: () => handleThumbnailClick(index), ref: selected ? selectedThumbnailRef : null }, children));
|
|
334
|
+
}
|
|
335
|
+
/**
|
|
336
|
+
* A thumbnail using our default styling.
|
|
337
|
+
*/
|
|
338
|
+
function LightBoxThumbnailImage({ src, alt, className, }) {
|
|
339
|
+
return (React__default.createElement("img", { src: src, alt: alt, className: classnames(styles.thumbnailImage, className) }));
|
|
313
340
|
}
|
|
314
341
|
/**
|
|
315
342
|
* LightBox displays images in a fullscreen overlay.
|
|
@@ -365,5 +392,8 @@ LightBox.Slides = LightBoxSlides;
|
|
|
365
392
|
LightBox.Navigation = LightBoxNavigation;
|
|
366
393
|
LightBox.Caption = LightBoxCaption;
|
|
367
394
|
LightBox.Thumbnails = LightBoxThumbnails;
|
|
395
|
+
LightBox.ThumbnailBar = LightBoxThumbnailBar;
|
|
396
|
+
LightBox.Thumbnail = LightBoxThumbnail;
|
|
397
|
+
LightBox.ThumbnailImage = LightBoxThumbnailImage;
|
|
368
398
|
|
|
369
399
|
export { LightBox as L, useLightBoxContext as u };
|
|
@@ -43,6 +43,10 @@ LightBox exposes its internal building blocks as subcomponents:
|
|
|
43
43
|
`LightBox.Navigation`, `LightBox.Caption`, and `LightBox.Thumbnails`. This gives
|
|
44
44
|
you more control over the LightBox's appearance and behaviour.
|
|
45
45
|
|
|
46
|
+
The thumbnail strip is itself composed of smaller subcomponents you can use
|
|
47
|
+
directly: `LightBox.ThumbnailBar`, `LightBox.Thumbnail`, and
|
|
48
|
+
`LightBox.ThumbnailImage`. See [Custom thumbnails](#custom-thumbnails) below.
|
|
49
|
+
|
|
46
50
|
Here's a basic example of how the non-composable LightBox is used:
|
|
47
51
|
|
|
48
52
|
```tsx
|
|
@@ -157,6 +161,33 @@ function CustomControls() {
|
|
|
157
161
|
}
|
|
158
162
|
```
|
|
159
163
|
|
|
164
|
+
### Custom thumbnails
|
|
165
|
+
|
|
166
|
+
`LightBox.Thumbnails` renders the default thumbnail strip and requires no
|
|
167
|
+
configuration. When you need to control how each thumbnail renders, compose the
|
|
168
|
+
thumbnail subcomponents yourself:
|
|
169
|
+
|
|
170
|
+
```tsx
|
|
171
|
+
import { LightBox, useLightBoxContext } from "@jobber/components";
|
|
172
|
+
|
|
173
|
+
function CustomThumbnails() {
|
|
174
|
+
const { images } = useLightBoxContext();
|
|
175
|
+
|
|
176
|
+
return (
|
|
177
|
+
<LightBox.ThumbnailBar>
|
|
178
|
+
{images.map((image, index) => (
|
|
179
|
+
<LightBox.Thumbnail key={index} index={index}>
|
|
180
|
+
<LightBox.ThumbnailImage
|
|
181
|
+
src={image.url}
|
|
182
|
+
alt={image.alt ?? image.title ?? ""}
|
|
183
|
+
/>
|
|
184
|
+
</LightBox.Thumbnail>
|
|
185
|
+
))}
|
|
186
|
+
</LightBox.ThumbnailBar>
|
|
187
|
+
);
|
|
188
|
+
}
|
|
189
|
+
```
|
|
190
|
+
|
|
160
191
|
## Testing
|
|
161
192
|
|
|
162
193
|
When using Jest to test LightBox implementations, you will need to include this
|
|
@@ -223,3 +254,26 @@ window.HTMLElement.prototype.scrollIntoView = scrollIntoViewMock;
|
|
|
223
254
|
| Prop | Type | Required | Default | Description |
|
|
224
255
|
|------|------|----------|---------|-------------|
|
|
225
256
|
| `className` | `string` | No | — | |
|
|
257
|
+
|
|
258
|
+
#### LightBox.Thumbnail
|
|
259
|
+
|
|
260
|
+
| Prop | Type | Required | Default | Description |
|
|
261
|
+
|------|------|----------|---------|-------------|
|
|
262
|
+
| `children` | `ReactNode` | Yes | — | The content rendered inside the selectable thumbnail cell, typically a `LightBox.ThumbnailImage`. |
|
|
263
|
+
| `index` | `number` | Yes | — | The index of the image this thumbnail represents. Used to derive the selected state and to navigate to the image when... |
|
|
264
|
+
| `className` | `string` | No | — | Additional class name to apply to the thumbnail cell. |
|
|
265
|
+
|
|
266
|
+
#### LightBox.ThumbnailBar
|
|
267
|
+
|
|
268
|
+
| Prop | Type | Required | Default | Description |
|
|
269
|
+
|------|------|----------|---------|-------------|
|
|
270
|
+
| `children` | `ReactNode` | Yes | — | The thumbnails to render inside the scrollable bar, typically one `LightBox.Thumbnail` per image. |
|
|
271
|
+
| `className` | `string` | No | — | Additional class name to apply to the thumbnail bar wrapper. |
|
|
272
|
+
|
|
273
|
+
#### LightBox.ThumbnailImage
|
|
274
|
+
|
|
275
|
+
| Prop | Type | Required | Default | Description |
|
|
276
|
+
|------|------|----------|---------|-------------|
|
|
277
|
+
| `alt` | `string` | Yes | — | The alternative text for the image. |
|
|
278
|
+
| `src` | `string` | Yes | — | The image source to render. |
|
|
279
|
+
| `className` | `string` | No | — | Additional class name to apply to the image. |
|
package/dist/styles.css
CHANGED
|
@@ -9,6 +9,14 @@
|
|
|
9
9
|
* 3. The active <circle>'s stroke-dasharray expands and contracts so the
|
|
10
10
|
* visible arc length grows and shrinks (Layer 3); stroke-dashoffset
|
|
11
11
|
* slides the arc around the ring across the cycle.
|
|
12
|
+
*
|
|
13
|
+
* Durations are Material's spec scaled by 1.15× for a calmer pace
|
|
14
|
+
* (Material: 1568 / 5332 / 1333). The cycle:arc ratio is held at exactly
|
|
15
|
+
* 4:1 (6132 = 4 × 1533) so the four blooms per rotation stay evenly spaced.
|
|
16
|
+
*
|
|
17
|
+
* The `small` variant uses only Layer 1 — a fixed-length arc spun at a
|
|
18
|
+
* constant speed (~1.8× faster than base) — because the layered
|
|
19
|
+
* expand/rotate motion reads as too busy at the smaller size.
|
|
12
20
|
*/
|
|
13
21
|
|
|
14
22
|
.YST686vLR3c- {
|
|
@@ -43,24 +51,14 @@
|
|
|
43
51
|
height: var(--space-base);
|
|
44
52
|
}
|
|
45
53
|
|
|
46
|
-
/*
|
|
47
|
-
* Layer 1 — continuous linear rotation on the SVG.
|
|
48
|
-
*
|
|
49
|
-
* The three indicator durations (1568ms outer rotation, 5332ms inner
|
|
50
|
-
* 8-phase cycle, 1333ms arc expand/contract) are taken from Material
|
|
51
|
-
* Web's published progress-motion spec. They are tuned against each
|
|
52
|
-
* other to produce the canonical Material rhythm and are intentionally
|
|
53
|
-
* inlined as literals because no other component currently consumes
|
|
54
|
-
* them; promote them to design tokens once a second consumer (e.g. a
|
|
55
|
-
* future `ProgressIndicator`) needs the same values.
|
|
56
|
-
*/
|
|
54
|
+
/* Layer 1 — continuous linear rotation on the SVG. */
|
|
57
55
|
|
|
58
56
|
.Av9z-aLocss- {
|
|
59
57
|
display: block;
|
|
60
58
|
width: 100%;
|
|
61
59
|
height: 100%;
|
|
62
|
-
-webkit-animation: WvHFS--Nm80-
|
|
63
|
-
animation: WvHFS--Nm80-
|
|
60
|
+
-webkit-animation: WvHFS--Nm80- 1803ms linear infinite;
|
|
61
|
+
animation: WvHFS--Nm80- 1803ms linear infinite;
|
|
64
62
|
will-change: transform;
|
|
65
63
|
}
|
|
66
64
|
|
|
@@ -78,14 +76,12 @@
|
|
|
78
76
|
}
|
|
79
77
|
|
|
80
78
|
/*
|
|
81
|
-
* Layer 2 + 3 — the active arc.
|
|
79
|
+
* Layer 2 + 3 — the active arc. The circle has circumference 2π·20 ≈ 125.66
|
|
80
|
+
* (SVG units); the "200" gap exceeds it so only one segment shows at a time.
|
|
81
|
+
* stroke-linecap: round gives the soft pill-shaped tips.
|
|
82
82
|
*
|
|
83
|
-
* The
|
|
84
|
-
*
|
|
85
|
-
* ~95 units, while the dashoffset slides the arc around the ring. The
|
|
86
|
-
* combined cycle is the canonical Material rhythm.
|
|
87
|
-
*
|
|
88
|
-
* stroke-linecap: round produces the soft pill-shaped tips on the arc.
|
|
83
|
+
* The expand animation is delayed by half its period so it starts fully
|
|
84
|
+
* bloomed and its phase is offset from the rotation start.
|
|
89
85
|
*/
|
|
90
86
|
|
|
91
87
|
._9XO0290QNCY- {
|
|
@@ -96,16 +92,35 @@
|
|
|
96
92
|
stroke-linecap: round;
|
|
97
93
|
-webkit-transform-origin: center;
|
|
98
94
|
transform-origin: center;
|
|
99
|
-
-webkit-animation:
|
|
100
|
-
|
|
101
|
-
_0m0Nzc5awnA-
|
|
102
|
-
animation:
|
|
103
|
-
|
|
104
|
-
_0m0Nzc5awnA-
|
|
95
|
+
-webkit-animation: SHHICknKvqA- 6132ms cubic-bezier(0.4, 0, 0.2, 1) infinite
|
|
96
|
+
both,
|
|
97
|
+
_0m0Nzc5awnA- 1533ms linear infinite both;
|
|
98
|
+
animation: SHHICknKvqA- 6132ms cubic-bezier(0.4, 0, 0.2, 1) infinite
|
|
99
|
+
both,
|
|
100
|
+
_0m0Nzc5awnA- 1533ms linear infinite both;
|
|
101
|
+
-webkit-animation-delay: 0s, -766.5ms;
|
|
102
|
+
animation-delay: 0s, -766.5ms;
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
/*
|
|
106
|
+
* Small renders as a simple fixed-length arc spun only by the SVG
|
|
107
|
+
* (Layer 1). The 8-phase rotation (Layer 2) and the tail-chasing expand
|
|
108
|
+
* (Layer 3) read as too busy at this size, so both are disabled and the
|
|
109
|
+
* arc is given a constant length instead. It also spins ~1.8× faster
|
|
110
|
+
* (1803ms ÷ 1.8 ≈ 1000ms) so the simpler single arc still feels lively.
|
|
111
|
+
*/
|
|
112
|
+
|
|
113
|
+
._888S5Y2IeZ8- .Av9z-aLocss- {
|
|
114
|
+
-webkit-animation-duration: 1000ms;
|
|
115
|
+
animation-duration: 1000ms;
|
|
105
116
|
}
|
|
106
117
|
|
|
107
118
|
._888S5Y2IeZ8- ._9XO0290QNCY- {
|
|
108
119
|
stroke-width: 6;
|
|
120
|
+
stroke-dasharray: 40, 200;
|
|
121
|
+
stroke-dashoffset: 0;
|
|
122
|
+
-webkit-animation: none;
|
|
123
|
+
animation: none;
|
|
109
124
|
}
|
|
110
125
|
|
|
111
126
|
@-webkit-keyframes WvHFS--Nm80- {
|
|
@@ -196,38 +211,53 @@
|
|
|
196
211
|
|
|
197
212
|
/*
|
|
198
213
|
* Layer 3 — expand/contract the visible arc length via stroke-dasharray
|
|
199
|
-
* while
|
|
200
|
-
*
|
|
201
|
-
*
|
|
214
|
+
* while sliding it around the ring via stroke-dashoffset.
|
|
215
|
+
*
|
|
216
|
+
* Rhythm (cycle = 4 × arc, so one breath = two rotation phases):
|
|
217
|
+
* - bloom open 0 → 50% (one full rotation phase)
|
|
218
|
+
* - deflate 50 → 80% (tail catches the head)
|
|
219
|
+
* - hold 80 → 100% (a beat before re-blooming)
|
|
220
|
+
*
|
|
221
|
+
* The minimum length stays at 8 (not ~0) so the arc never pinches to a dot,
|
|
222
|
+
* and the 100% keyframe matches 0% with the offset advanced one full
|
|
223
|
+
* circumference (≈125.66) so the loop is seamless — no catch-up blink.
|
|
202
224
|
*/
|
|
203
225
|
|
|
204
226
|
@-webkit-keyframes _0m0Nzc5awnA- {
|
|
205
227
|
0% {
|
|
206
|
-
stroke-dasharray:
|
|
228
|
+
stroke-dasharray: 8, 200;
|
|
207
229
|
stroke-dashoffset: 0;
|
|
208
230
|
}
|
|
209
231
|
50% {
|
|
210
232
|
stroke-dasharray: 90, 200;
|
|
211
233
|
stroke-dashoffset: -35;
|
|
212
234
|
}
|
|
235
|
+
80% {
|
|
236
|
+
stroke-dasharray: 8, 200;
|
|
237
|
+
stroke-dashoffset: -125.66;
|
|
238
|
+
}
|
|
213
239
|
100% {
|
|
214
|
-
stroke-dasharray:
|
|
215
|
-
stroke-dashoffset: -125;
|
|
240
|
+
stroke-dasharray: 8, 200;
|
|
241
|
+
stroke-dashoffset: -125.66;
|
|
216
242
|
}
|
|
217
243
|
}
|
|
218
244
|
|
|
219
245
|
@keyframes _0m0Nzc5awnA- {
|
|
220
246
|
0% {
|
|
221
|
-
stroke-dasharray:
|
|
247
|
+
stroke-dasharray: 8, 200;
|
|
222
248
|
stroke-dashoffset: 0;
|
|
223
249
|
}
|
|
224
250
|
50% {
|
|
225
251
|
stroke-dasharray: 90, 200;
|
|
226
252
|
stroke-dashoffset: -35;
|
|
227
253
|
}
|
|
254
|
+
80% {
|
|
255
|
+
stroke-dasharray: 8, 200;
|
|
256
|
+
stroke-dashoffset: -125.66;
|
|
257
|
+
}
|
|
228
258
|
100% {
|
|
229
|
-
stroke-dasharray:
|
|
230
|
-
stroke-dashoffset: -125;
|
|
259
|
+
stroke-dasharray: 8, 200;
|
|
260
|
+
stroke-dashoffset: -125.66;
|
|
231
261
|
}
|
|
232
262
|
}
|
|
233
263
|
|
|
@@ -138,6 +138,9 @@
|
|
|
138
138
|
"LightBox.Overlay",
|
|
139
139
|
"LightBox.Provider",
|
|
140
140
|
"LightBox.Slides",
|
|
141
|
+
"LightBox.Thumbnail",
|
|
142
|
+
"LightBox.ThumbnailBar",
|
|
143
|
+
"LightBox.ThumbnailImage",
|
|
141
144
|
"LightBox.Thumbnails",
|
|
142
145
|
"LightBox.Toolbar",
|
|
143
146
|
"Link",
|
|
@@ -226,4 +229,4 @@
|
|
|
226
229
|
"Tooltip",
|
|
227
230
|
"Typography"
|
|
228
231
|
]
|
|
229
|
-
}
|
|
232
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@jobber/components",
|
|
3
|
-
"version": "8.
|
|
3
|
+
"version": "8.9.0",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.cjs",
|
|
@@ -556,5 +556,5 @@
|
|
|
556
556
|
"> 1%",
|
|
557
557
|
"IE 10"
|
|
558
558
|
],
|
|
559
|
-
"gitHead": "
|
|
559
|
+
"gitHead": "e38cc8fc9387c2d0152349bfed2b16cfddb31037"
|
|
560
560
|
}
|