@rcaferati/react-awesome-slider 5.0.0 → 5.0.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/README.md CHANGED
@@ -5,10 +5,10 @@
5
5
  - **`AwesomeSlider`** — animated media/children slider
6
6
  - **`withAutoplay`** — autoplay wrapper
7
7
  - **`withCaptionedImages`** — caption overlay wrapper
8
- - **`withAnimatedLettering`** — “screens → <p> lines” wrapper
8
+ - **`withAnimatedLettering`** — “screens → `<p>` lines” wrapper
9
9
  - **Navigation utilities** — `Provider`, `Link`, `withNavigationContext`, `withNavigationHandlers`
10
10
 
11
- This README is updated for the current v5+ patterns (functional core + CSS variables + optional CSS Modules).
11
+ This README is updated for the current v5 patterns (functional core + CSS variables + optional CSS Modules support).
12
12
 
13
13
  ---
14
14
 
@@ -18,7 +18,7 @@ This README is updated for the current v5+ patterns (functional core + CSS varia
18
18
  npm install @rcaferati/react-awesome-slider
19
19
  ```
20
20
 
21
- Peer deps:
21
+ Peer dependencies:
22
22
 
23
23
  - `react >= 18`
24
24
  - `react-dom >= 18`
@@ -105,7 +105,66 @@ export default function Example() {
105
105
  }
106
106
  ```
107
107
 
108
- > Tip: When `animation="sideAnimation"` you typically omit `animation` entirely (core defaults).
108
+ > Tip: when using the default side animation, omit the `animation` prop entirely.
109
+
110
+ ### Importing animation module objects
111
+
112
+ This package also exports animation subpaths such as:
113
+
114
+ - `@rcaferati/react-awesome-slider/custom-animations/cube-animation`
115
+ - `@rcaferati/react-awesome-slider/custom-animations/fall-animation`
116
+
117
+ Those module exports are useful for `cssModule` setups because they provide the class-name mapping object.
118
+
119
+ **Important:** in current consumer setups such as Vite, the JS/MJS animation import alone should not be treated as enough to load the stylesheet into the page. You should still import the public CSS file as a side effect.
120
+
121
+ #### Plain CSS users
122
+
123
+ Use only the public CSS file:
124
+
125
+ ```js
126
+ import '@rcaferati/react-awesome-slider/custom-animations/cube-animation.css';
127
+ ```
128
+
129
+ #### `cssModule` users
130
+
131
+ Import both:
132
+
133
+ 1. the public CSS file so the rules are actually injected
134
+ 2. the JS module export so you can pass the mapping object into `cssModule`
135
+
136
+ ```jsx
137
+ import React from 'react';
138
+ import AwesomeSlider from '@rcaferati/react-awesome-slider';
139
+ import sliderStylesRaw from '@rcaferati/react-awesome-slider/styles';
140
+
141
+ import '@rcaferati/react-awesome-slider/styles.css';
142
+
143
+ import '@rcaferati/react-awesome-slider/custom-animations/cube-animation.css';
144
+ import cubeAnimationRaw from '@rcaferati/react-awesome-slider/custom-animations/cube-animation';
145
+
146
+ const sliderStyles = sliderStylesRaw?.default ?? sliderStylesRaw;
147
+ const cubeAnimation = cubeAnimationRaw?.default ?? cubeAnimationRaw;
148
+
149
+ export default function Example() {
150
+ return (
151
+ <AwesomeSlider
152
+ animation="cubeAnimation"
153
+ cssModule={[sliderStyles, cubeAnimation]}
154
+ >
155
+ <div data-src="https://picsum.photos/id/1018/1200/600" />
156
+ <div data-src="https://picsum.photos/id/1015/1200/600" />
157
+ </AwesomeSlider>
158
+ );
159
+ }
160
+ ```
161
+
162
+ In other words:
163
+
164
+ - `.css` import → injects the stylesheet
165
+ - JS/MJS import → provides the module mapping for `cssModule`
166
+
167
+ For the widest compatibility, prefer the public CSS files whenever possible.
109
168
 
110
169
  ---
111
170
 
@@ -113,37 +172,89 @@ export default function Example() {
113
172
 
114
173
  ### CSS variables (recommended)
115
174
 
116
- The core stylesheet exposes CSS variables on the slider root element (default `awssld`).
175
+ The core stylesheet exposes CSS variables on the slider root element (default root key: `awssld`).
117
176
  You can override them per instance using `style`:
118
177
 
119
178
  ```jsx
120
- <AwesomeSlider
121
- style={{
122
- // arrows
123
- '--organic-arrow-color': 'rgba(255,255,255,0.9)',
124
- '--organic-arrow-height': '44px',
125
- '--organic-arrow-thickness': '4px',
126
-
127
- // bullets
128
- '--control-bullet-color': 'rgba(255,255,255,0.35)',
129
- '--control-bullet-active-color': 'rgba(255,255,255,0.9)',
130
-
131
- // content
132
- '--content-background-color': '#10131a',
133
- }}
134
- />
179
+ import React from 'react';
180
+ import AwesomeSlider from '@rcaferati/react-awesome-slider';
181
+ import '@rcaferati/react-awesome-slider/styles.css';
182
+
183
+ export default function Example() {
184
+ return (
185
+ <AwesomeSlider
186
+ style={{
187
+ // arrows
188
+ '--organic-arrow-color': 'rgba(255,255,255,0.9)',
189
+ '--organic-arrow-height': '44px',
190
+ '--organic-arrow-thickness': '4px',
191
+
192
+ // bullets
193
+ '--control-bullet-color': 'rgba(255,255,255,0.35)',
194
+ '--control-bullet-active-color': 'rgba(255,255,255,0.9)',
195
+
196
+ // content
197
+ '--content-background-color': '#10131a',
198
+ }}
199
+ media={[
200
+ { source: 'https://picsum.photos/id/1018/1200/600' },
201
+ { source: 'https://picsum.photos/id/1015/1200/600' },
202
+ ]}
203
+ />
204
+ );
205
+ }
135
206
  ```
136
207
 
137
208
  ### CSS Modules (`cssModule`)
138
209
 
139
210
  If your bundler emits CSS module maps, you can pass module objects via `cssModule`.
140
- Many setups export the module object as `default` — this pattern is safe:
211
+
212
+ The package exports a `styles` entry:
213
+
214
+ ```jsx
215
+ import React from 'react';
216
+ import AwesomeSlider from '@rcaferati/react-awesome-slider';
217
+ import sliderStylesRaw from '@rcaferati/react-awesome-slider/styles';
218
+ import '@rcaferati/react-awesome-slider/styles.css';
219
+
220
+ const styles = sliderStylesRaw?.default ?? sliderStylesRaw;
221
+
222
+ export default function Example() {
223
+ return (
224
+ <AwesomeSlider cssModule={styles}>
225
+ <div data-src="https://picsum.photos/id/1018/1200/600" />
226
+ <div data-src="https://picsum.photos/id/1015/1200/600" />
227
+ </AwesomeSlider>
228
+ );
229
+ }
230
+ ```
231
+
232
+ If you are also using a custom animation module export, combine them as an array and still import the corresponding CSS file:
141
233
 
142
234
  ```jsx
143
- import AwsSliderStyles from '@rcaferati/react-awesome-slider/dist/styles.css?inline'; // (example — depends on bundler)
235
+ import React from 'react';
236
+ import AwesomeSlider from '@rcaferati/react-awesome-slider';
237
+ import sliderStylesRaw from '@rcaferati/react-awesome-slider/styles';
238
+
239
+ import '@rcaferati/react-awesome-slider/styles.css';
240
+
241
+ import '@rcaferati/react-awesome-slider/custom-animations/cube-animation.css';
242
+ import cubeAnimationRaw from '@rcaferati/react-awesome-slider/custom-animations/cube-animation';
243
+
244
+ const core = sliderStylesRaw?.default ?? sliderStylesRaw;
245
+ const cube = cubeAnimationRaw?.default ?? cubeAnimationRaw;
246
+
247
+ export default function Example() {
248
+ return (
249
+ <AwesomeSlider animation="cubeAnimation" cssModule={[core, cube]}>
250
+ <div data-src="https://picsum.photos/id/1018/1200/600" />
251
+ <div data-src="https://picsum.photos/id/1015/1200/600" />
252
+ </AwesomeSlider>
253
+ );
254
+ }
144
255
  ```
145
256
 
146
- In this repository’s Storybook setup, `*.scss` imports resolve to CSS module maps. In consumer apps, you’ll typically import prebuilt CSS files (`styles.css`, `captioned.css`, `lettering.css`, and `custom-animations/*.css`) unless you have a CSS-module pipeline configured.
257
+ In most consumer apps, plain CSS imports are simpler and more portable than CSS-module object imports.
147
258
 
148
259
  ---
149
260
 
@@ -151,28 +262,44 @@ In this repository’s Storybook setup, `*.scss` imports resolve to CSS module m
151
262
 
152
263
  ### Common usage patterns
153
264
 
154
- #### Children mode (HTML slides)
265
+ #### Children mode
155
266
 
156
267
  ```jsx
157
- <AwesomeSlider>
158
- <div style={{ background: '#0b0f18', height: '100%' }}>
159
- <h2 style={{ color: 'white' }}>Slide A</h2>
160
- </div>
161
- <div style={{ background: '#f4f6fb', height: '100%' }}>
162
- <h2 style={{ color: '#111' }}>Slide B</h2>
163
- </div>
164
- </AwesomeSlider>
268
+ import React from 'react';
269
+ import AwesomeSlider from '@rcaferati/react-awesome-slider';
270
+ import '@rcaferati/react-awesome-slider/styles.css';
271
+
272
+ export default function Example() {
273
+ return (
274
+ <AwesomeSlider>
275
+ <div style={{ background: '#0b0f18', height: '100%' }}>
276
+ <h2 style={{ color: 'white' }}>Slide A</h2>
277
+ </div>
278
+ <div style={{ background: '#f4f6fb', height: '100%' }}>
279
+ <h2 style={{ color: '#111' }}>Slide B</h2>
280
+ </div>
281
+ </AwesomeSlider>
282
+ );
283
+ }
165
284
  ```
166
285
 
167
- #### Media mode (images/videos)
286
+ #### Media mode
168
287
 
169
288
  ```jsx
170
- <AwesomeSlider
171
- media={[
172
- { source: '/img/0.jpg', slug: 'a' },
173
- { source: '/img/1.jpg', slug: 'b' },
174
- ]}
175
- />
289
+ import React from 'react';
290
+ import AwesomeSlider from '@rcaferati/react-awesome-slider';
291
+ import '@rcaferati/react-awesome-slider/styles.css';
292
+
293
+ export default function Example() {
294
+ return (
295
+ <AwesomeSlider
296
+ media={[
297
+ { source: '/img/0.jpg', slug: 'a' },
298
+ { source: '/img/1.jpg', slug: 'b' },
299
+ ]}
300
+ />
301
+ );
302
+ }
176
303
  ```
177
304
 
178
305
  ---
@@ -192,24 +319,24 @@ In this repository’s Storybook setup, `*.scss` imports resolve to CSS module m
192
319
  | `infinite` | `boolean` | `true` | Wrap-around navigation. |
193
320
  | `fillParent` | `boolean` | `false` | Fill parent bounds (fullscreen layouts). |
194
321
  | `startupScreen` | `ReactNode` | `null` | Optional startup screen shown before first slide. |
195
- | `startup` | `boolean` | `true` | If `startupScreen` is set, whether to auto-start into first slide. |
322
+ | `startup` | `boolean` | `true` | If `startupScreen` is set, whether to auto-start into the first slide. |
196
323
  | `startupDelay` | `number` | `0` | Delay before auto-start. |
197
324
  | `transitionDelay` | `number` | `0` | Delay before starting transition animation (ms). |
198
- | `controlsReturnDelay` | `number` | `0` | Delay to remove “controls active” class after transitions (ms). |
325
+ | `controlsReturnDelay` | `number` | `0` | Delay to remove the “controls active” class after transitions (ms). |
199
326
  | `mobileTouch` | `boolean` | `true` | Enables touch/swipe navigation. |
200
327
  | `cssModule` | `object \| object[] \| null` | `null` | CSS module map(s) used to map class names. |
201
- | `className` | `string \| null` | `null` | Extra className(s) added to root element. |
202
- | `style` | `React.CSSProperties` | `{}` | Inline styles (also used for CSS variables). |
328
+ | `className` | `string \| null` | `null` | Extra className(s) added to the root element. |
329
+ | `style` | `React.CSSProperties` | `{}` | Inline styles, including CSS variable overrides. |
203
330
  | `onFirstMount` | `(info) => void` | `null` | Called once after mount with `getInfo()` payload. |
204
331
  | `onTransitionStart` | `(info) => void` | `null` | Called on transition start. |
205
332
  | `onTransitionEnd` | `(info) => void` | `null` | Called on transition end. |
206
- | `onTransitionRequest` | `(info) => void` | `null` | Called when user requests a transition (next/prev/bullet). |
207
- | `onTransitionReject` | `(info) => void` | `null` | Called when a transition is rejected (e.g., busy/loading). |
333
+ | `onTransitionRequest` | `(info) => void` | `null` | Called when the user requests a transition (next/prev/bullet). |
334
+ | `onTransitionReject` | `(info) => void` | `null` | Called when a transition is rejected (for example, busy/loading). |
208
335
  | `onLoadStart` | `(payload) => void` | `null` | Optional custom preload hook. Call `payload.next()` when ready. |
209
336
 
210
337
  ### `getInfo()` payload (high level)
211
338
 
212
- `getInfo()` is used by the event callbacks and includes (best-effort):
339
+ `getInfo()` is used by the event callbacks and includes, best-effort:
213
340
 
214
341
  - `slides` — slide count
215
342
  - `currentIndex` — current index
@@ -312,11 +439,16 @@ export default function Example() {
312
439
  }
313
440
  ```
314
441
 
315
- ### Adaptive Controls (optional HOC)
442
+ ### Adaptive Controls
443
+
444
+ Adaptive Controls is currently part of the repository work and Storybook examples, but it is not listed as a public package export in the current package `exports` map.
316
445
 
317
- If your build includes `hoc/adaptive-controls`, it can compute a theme (light/dark) and apply CSS variables for arrows/bullets based on the active slide background.
446
+ That means:
318
447
 
319
- > This HOC is intentionally CSS-modules-safe and applies variables to the real slider root.
448
+ - it is available in the source repository
449
+ - it is not currently documented here as a stable public import path from the npm package
450
+
451
+ If and when it becomes a public export, it should be documented with its exact import path.
320
452
 
321
453
  ---
322
454
 
@@ -358,9 +490,10 @@ export default function Nav() {
358
490
 
359
491
  ### `withNavigationHandlers`
360
492
 
361
- Wrap a slider so URL ↔ slider selection stays aligned (supports popstate, retries on rejects, and mismatch correction).
493
+ Wrap a slider so URL ↔ slider selection stays aligned.
362
494
 
363
495
  ```jsx
496
+ import React from 'react';
364
497
  import AwesomeSlider from '@rcaferati/react-awesome-slider';
365
498
  import { withNavigationHandlers } from '@rcaferati/react-awesome-slider/navigation';
366
499
 
@@ -371,6 +504,22 @@ export default function Page() {
371
504
  }
372
505
  ```
373
506
 
507
+ ### `withNavigationContext`
508
+
509
+ If you need raw navigation state + setter injected into a component:
510
+
511
+ ```jsx
512
+ import React from 'react';
513
+ import { withNavigationContext } from '@rcaferati/react-awesome-slider/navigation';
514
+
515
+ function Status(props) {
516
+ const { fullpage } = props;
517
+ return <pre>{JSON.stringify(fullpage.navigation, null, 2)}</pre>;
518
+ }
519
+
520
+ export default withNavigationContext(Status);
521
+ ```
522
+
374
523
  ---
375
524
 
376
525
  ## Recommended patterns (current)
@@ -383,10 +532,22 @@ If you use slugs + navigation handlers, keep `media` entries stable and include
383
532
 
384
533
  - Always load `styles.css`
385
534
  - Load one extra animation CSS only when that animation is selected
535
+ - If you use animation module objects with `cssModule`, still import the matching `.css` file
386
536
 
387
537
  ### ✅ Customize via CSS variables first
388
538
 
389
- Theme/contrast/polish is usually easiest via the exposed custom properties.
539
+ Theme, contrast, and visual polish are usually easiest via the exposed custom properties.
540
+
541
+ ### ✅ Use CSS module exports only when your bundler supports them
542
+
543
+ For the widest compatibility:
544
+
545
+ - use `styles.css`
546
+ - use `captioned.css`
547
+ - use `lettering.css`
548
+ - use `custom-animations/*.css`
549
+
550
+ Use `@rcaferati/react-awesome-slider/styles` or `@rcaferati/react-awesome-slider/custom-animations/*` module exports only when your bundler setup expects JS style-module entries, and pair them with the corresponding CSS file imports.
390
551
 
391
552
  ---
392
553
 
@@ -0,0 +1,3 @@
1
+ declare const Styles: { readonly [key: string]: string };
2
+
3
+ export default Styles;
@@ -0,0 +1,3 @@
1
+ declare const Styles: { readonly [key: string]: string };
2
+
3
+ export default Styles;
@@ -0,0 +1,12 @@
1
+ 'use strict';
2
+
3
+ const Styles = {
4
+ "awssld--cubeAnimation": "awssld--cubeAnimation",
5
+ "awssld__container": "awssld__container",
6
+ "awssld--moveRight": "awssld--moveRight",
7
+ "awssld--moveLeft": "awssld--moveLeft",
8
+ "awssld--exit": "awssld--exit"
9
+ };
10
+
11
+ module.exports = Styles;
12
+ module.exports.default = Styles;
@@ -0,0 +1,9 @@
1
+ const Styles = {
2
+ "awssld--cubeAnimation": "awssld--cubeAnimation",
3
+ "awssld__container": "awssld__container",
4
+ "awssld--moveRight": "awssld--moveRight",
5
+ "awssld--moveLeft": "awssld--moveLeft",
6
+ "awssld--exit": "awssld--exit"
7
+ };
8
+
9
+ export default Styles;
@@ -0,0 +1,3 @@
1
+ declare const Styles: { readonly [key: string]: string };
2
+
3
+ export default Styles;
@@ -0,0 +1,3 @@
1
+ declare const Styles: { readonly [key: string]: string };
2
+
3
+ export default Styles;
@@ -0,0 +1,11 @@
1
+ 'use strict';
2
+
3
+ const Styles = {
4
+ "awssld--fallAnimation": "awssld--fallAnimation",
5
+ "awssld--moveRight": "awssld--moveRight",
6
+ "awssld--moveLeft": "awssld--moveLeft",
7
+ "awssld--exit": "awssld--exit"
8
+ };
9
+
10
+ module.exports = Styles;
11
+ module.exports.default = Styles;
@@ -0,0 +1,8 @@
1
+ const Styles = {
2
+ "awssld--fallAnimation": "awssld--fallAnimation",
3
+ "awssld--moveRight": "awssld--moveRight",
4
+ "awssld--moveLeft": "awssld--moveLeft",
5
+ "awssld--exit": "awssld--exit"
6
+ };
7
+
8
+ export default Styles;
@@ -0,0 +1,3 @@
1
+ declare const Styles: { readonly [key: string]: string };
2
+
3
+ export default Styles;
@@ -0,0 +1,3 @@
1
+ declare const Styles: { readonly [key: string]: string };
2
+
3
+ export default Styles;
@@ -0,0 +1,12 @@
1
+ 'use strict';
2
+
3
+ const Styles = {
4
+ "awssld--foldOutAnimation": "awssld--foldOutAnimation",
5
+ "awssld__container": "awssld__container",
6
+ "awssld--exit": "awssld--exit",
7
+ "awssld--moveLeft": "awssld--moveLeft",
8
+ "awssld--moveRight": "awssld--moveRight"
9
+ };
10
+
11
+ module.exports = Styles;
12
+ module.exports.default = Styles;
@@ -0,0 +1,9 @@
1
+ const Styles = {
2
+ "awssld--foldOutAnimation": "awssld--foldOutAnimation",
3
+ "awssld__container": "awssld__container",
4
+ "awssld--exit": "awssld--exit",
5
+ "awssld--moveLeft": "awssld--moveLeft",
6
+ "awssld--moveRight": "awssld--moveRight"
7
+ };
8
+
9
+ export default Styles;
@@ -0,0 +1,3 @@
1
+ declare const Styles: { readonly [key: string]: string };
2
+
3
+ export default Styles;
@@ -0,0 +1,3 @@
1
+ declare const Styles: { readonly [key: string]: string };
2
+
3
+ export default Styles;
@@ -0,0 +1,12 @@
1
+ 'use strict';
2
+
3
+ const Styles = {
4
+ "awssld--openAnimation": "awssld--openAnimation",
5
+ "awssld__container": "awssld__container",
6
+ "awssld--moveLeft": "awssld--moveLeft",
7
+ "awssld--moveRight": "awssld--moveRight",
8
+ "awssld--exit": "awssld--exit"
9
+ };
10
+
11
+ module.exports = Styles;
12
+ module.exports.default = Styles;
@@ -0,0 +1,9 @@
1
+ const Styles = {
2
+ "awssld--openAnimation": "awssld--openAnimation",
3
+ "awssld__container": "awssld__container",
4
+ "awssld--moveLeft": "awssld--moveLeft",
5
+ "awssld--moveRight": "awssld--moveRight",
6
+ "awssld--exit": "awssld--exit"
7
+ };
8
+
9
+ export default Styles;
@@ -0,0 +1,3 @@
1
+ declare const Styles: { readonly [key: string]: string };
2
+
3
+ export default Styles;
@@ -0,0 +1,3 @@
1
+ declare const Styles: { readonly [key: string]: string };
2
+
3
+ export default Styles;
@@ -0,0 +1,11 @@
1
+ 'use strict';
2
+
3
+ const Styles = {
4
+ "awssld--scaleOutAnimation": "awssld--scaleOutAnimation",
5
+ "awssld--exit": "awssld--exit",
6
+ "awssld--moveRight": "awssld--moveRight",
7
+ "awssld--moveLeft": "awssld--moveLeft"
8
+ };
9
+
10
+ module.exports = Styles;
11
+ module.exports.default = Styles;
@@ -0,0 +1,8 @@
1
+ const Styles = {
2
+ "awssld--scaleOutAnimation": "awssld--scaleOutAnimation",
3
+ "awssld--exit": "awssld--exit",
4
+ "awssld--moveRight": "awssld--moveRight",
5
+ "awssld--moveLeft": "awssld--moveLeft"
6
+ };
7
+
8
+ export default Styles;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@rcaferati/react-awesome-slider",
3
- "version": "5.0.0",
3
+ "version": "5.0.1",
4
4
  "description": "React Awesome Slider is a 60fps performant, extendable, highly customisable, production ready React Component that renders a media (image/video) gallery slider carousel.",
5
5
  "author": "Rafael Caferati",
6
6
  "license": "MIT",
@@ -59,7 +59,13 @@
59
59
  "./styles.css": "./dist/styles.css",
60
60
  "./captioned.css": "./dist/captioned.css",
61
61
  "./lettering.css": "./dist/lettering.css",
62
- "./custom-animations/*": "./dist/custom-animations/*.css",
62
+ "./custom-animations/*": {
63
+ "types": "./dist/custom-animations/*.d.ts",
64
+ "import": "./dist/custom-animations/*.mjs",
65
+ "require": "./dist/custom-animations/*.js",
66
+ "default": "./dist/custom-animations/*.mjs"
67
+ },
68
+ "./custom-animations/*.css": "./dist/custom-animations/*.css",
63
69
  "./dist/*": "./dist/*",
64
70
  "./package.json": "./package.json"
65
71
  },
@@ -79,6 +85,9 @@
79
85
  ],
80
86
  "navigation": [
81
87
  "dist/navigation.d.ts"
88
+ ],
89
+ "custom-animations/*": [
90
+ "dist/custom-animations/*.d.ts"
82
91
  ]
83
92
  }
84
93
  },
@@ -97,8 +106,9 @@
97
106
  "build:css": "sass --no-source-map --silence-deprecation=import src/core/styles.scss dist/styles.css && sass --no-source-map --silence-deprecation=import src/hoc/animated-lettering/styles.scss dist/lettering.css && sass --no-source-map --silence-deprecation=import src/hoc/captioned-images/styles.scss dist/captioned.css",
98
107
  "build:animations": "node scripts/build-animations.mjs",
99
108
  "prepare": "npm run build",
109
+ "start": "npm run storybook",
100
110
  "storybook": "storybook dev -p 6006",
101
- "build-storybook": "storybook build",
111
+ "build-storybook": "storybook build -o storybook-static",
102
112
  "test": "vitest",
103
113
  "test:run": "vitest run",
104
114
  "test:watch": "vitest --watch",