@ldelia/react-media 0.8.8 → 0.10.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/components/reproduction-widget/models/Player/YouTubePlayer.d.ts +0 -1
- package/dist/components/reproduction-widget/models/Reproduction.d.ts +16 -4
- package/dist/components/reproduction-widget/models/Reproduction.js +96 -11
- package/dist/stories/reproduction-widget.stories.d.ts +6 -5
- package/dist/stories/reproduction-widget.stories.js +21 -7
- package/dist/stories/timeline.stories.d.ts +8 -7
- package/dist/stories/timeline.stories.js +1 -1
- package/package.json +10 -10
|
@@ -2,6 +2,13 @@ import { ReproductionBuilder } from './ReproductionBuilder';
|
|
|
2
2
|
import { PlayAlongPlayer } from './Player/PlayAlongPlayer';
|
|
3
3
|
import { YouTubePlayer } from './Player/YouTubePlayer';
|
|
4
4
|
type Player = PlayAlongPlayer | YouTubePlayer;
|
|
5
|
+
export declare const REPRODUCTION_STATES: {
|
|
6
|
+
STOPPED: number;
|
|
7
|
+
COUNTING_IN: number;
|
|
8
|
+
PLAYING: number;
|
|
9
|
+
PAUSED: number;
|
|
10
|
+
};
|
|
11
|
+
type ReproductionState = (typeof REPRODUCTION_STATES)[keyof typeof REPRODUCTION_STATES];
|
|
5
12
|
type Handler = (args: object) => void;
|
|
6
13
|
declare const dispatchOnReadyHandlers: unique symbol;
|
|
7
14
|
declare const dispatchOnSongStartHandlers: unique symbol;
|
|
@@ -12,11 +19,13 @@ declare const dispatchOnPausedHandlers: unique symbol;
|
|
|
12
19
|
declare const dispatchOnFinishHandlers: unique symbol;
|
|
13
20
|
declare const dispatchOnErrorHandlers: unique symbol;
|
|
14
21
|
export declare class Reproduction {
|
|
15
|
-
private player;
|
|
16
|
-
private requiresCountingIn;
|
|
17
|
-
private songTempo;
|
|
22
|
+
private readonly player;
|
|
23
|
+
private readonly requiresCountingIn;
|
|
24
|
+
private readonly songTempo;
|
|
18
25
|
private state;
|
|
19
26
|
private interval;
|
|
27
|
+
private loopInterval;
|
|
28
|
+
private loopRange;
|
|
20
29
|
private countingInCounter;
|
|
21
30
|
private [dispatchOnReadyHandlers];
|
|
22
31
|
private [dispatchOnSongStartHandlers];
|
|
@@ -43,16 +52,19 @@ export declare class Reproduction {
|
|
|
43
52
|
PAUSED: number;
|
|
44
53
|
};
|
|
45
54
|
static newBuilder(): ReproductionBuilder;
|
|
46
|
-
on(eventName: keyof typeof Reproduction.EVENTS, handler: Handler):
|
|
55
|
+
on(eventName: keyof typeof Reproduction.EVENTS, handler: Handler): () => void;
|
|
56
|
+
off(eventName: keyof typeof Reproduction.EVENTS, handler: Handler): void;
|
|
47
57
|
dispatch(eventName: keyof typeof Reproduction.EVENTS, args?: {}): void;
|
|
48
58
|
start(): void;
|
|
49
59
|
play(): void;
|
|
60
|
+
playLoop(from: number, to: number): void;
|
|
50
61
|
pause(): void;
|
|
51
62
|
stop(): void;
|
|
52
63
|
isPlaying(): boolean;
|
|
53
64
|
isStopped(): boolean;
|
|
54
65
|
isPaused(): boolean;
|
|
55
66
|
isCountingIn(): boolean;
|
|
67
|
+
getState(): ReproductionState;
|
|
56
68
|
getPlayer(): Player;
|
|
57
69
|
getTempo(): number;
|
|
58
70
|
getCurrentTime(): number;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { PLAYER_EVENTS } from './Player/PlayerEvents';
|
|
2
2
|
import { ReproductionBuilder } from './ReproductionBuilder';
|
|
3
|
-
const
|
|
3
|
+
export const REPRODUCTION_STATES = {
|
|
4
4
|
STOPPED: 0,
|
|
5
5
|
COUNTING_IN: 1,
|
|
6
6
|
PLAYING: 2,
|
|
@@ -37,6 +37,8 @@ export class Reproduction {
|
|
|
37
37
|
this.player = player;
|
|
38
38
|
this.state = Reproduction.STATES.STOPPED;
|
|
39
39
|
this.interval = null;
|
|
40
|
+
this.loopInterval = null;
|
|
41
|
+
this.loopRange = null;
|
|
40
42
|
this.requiresCountingIn = requiresCountingIn;
|
|
41
43
|
this.countingInCounter = 0;
|
|
42
44
|
this.player.setVolume(volume);
|
|
@@ -47,6 +49,9 @@ export class Reproduction {
|
|
|
47
49
|
this.player.on(PLAYER_EVENTS.FINISH, () => {
|
|
48
50
|
this.state = Reproduction.STATES.STOPPED;
|
|
49
51
|
clearInterval(this.interval);
|
|
52
|
+
clearInterval(this.loopInterval);
|
|
53
|
+
this.loopInterval = null;
|
|
54
|
+
this.loopRange = null;
|
|
50
55
|
this.dispatch(Reproduction.EVENTS.FINISH);
|
|
51
56
|
});
|
|
52
57
|
this.player.on(PLAYER_EVENTS.ERROR, (error) => {
|
|
@@ -57,29 +62,75 @@ export class Reproduction {
|
|
|
57
62
|
return EVENTS;
|
|
58
63
|
}
|
|
59
64
|
static get STATES() {
|
|
60
|
-
return
|
|
65
|
+
return REPRODUCTION_STATES;
|
|
61
66
|
}
|
|
62
67
|
static newBuilder() {
|
|
63
68
|
return new ReproductionBuilder();
|
|
64
69
|
}
|
|
65
70
|
on(eventName, handler) {
|
|
71
|
+
if (typeof handler !== 'function') {
|
|
72
|
+
throw new Error('Handler must be a function');
|
|
73
|
+
}
|
|
66
74
|
switch (eventName) {
|
|
67
75
|
case Reproduction.EVENTS.START:
|
|
68
|
-
|
|
76
|
+
this[dispatchOnSongStartHandlers].push(handler);
|
|
77
|
+
break;
|
|
69
78
|
case Reproduction.EVENTS.COUNTING_IN:
|
|
70
|
-
|
|
79
|
+
this[dispatchOnCountingInHandlers].push(handler);
|
|
80
|
+
break;
|
|
71
81
|
case Reproduction.EVENTS.PLAY:
|
|
72
|
-
|
|
82
|
+
this[dispatchOnPlayHandlers].push(handler);
|
|
83
|
+
break;
|
|
73
84
|
case Reproduction.EVENTS.PLAYING:
|
|
74
|
-
|
|
85
|
+
this[dispatchOnPlayingHandlers].push(handler);
|
|
86
|
+
break;
|
|
75
87
|
case Reproduction.EVENTS.PAUSED:
|
|
76
|
-
|
|
88
|
+
this[dispatchOnPausedHandlers].push(handler);
|
|
89
|
+
break;
|
|
77
90
|
case Reproduction.EVENTS.FINISH:
|
|
78
|
-
|
|
91
|
+
this[dispatchOnFinishHandlers].push(handler);
|
|
92
|
+
break;
|
|
79
93
|
case Reproduction.EVENTS.ERROR:
|
|
80
|
-
|
|
94
|
+
this[dispatchOnErrorHandlers].push(handler);
|
|
95
|
+
break;
|
|
81
96
|
default:
|
|
97
|
+
throw new Error(`Unknown event: ${eventName}`);
|
|
98
|
+
}
|
|
99
|
+
return () => this.off(eventName, handler);
|
|
100
|
+
}
|
|
101
|
+
off(eventName, handler) {
|
|
102
|
+
if (typeof handler !== 'function') {
|
|
103
|
+
throw new Error('Handler must be a function');
|
|
104
|
+
}
|
|
105
|
+
let handlers;
|
|
106
|
+
switch (eventName) {
|
|
107
|
+
case Reproduction.EVENTS.START:
|
|
108
|
+
handlers = this[dispatchOnSongStartHandlers];
|
|
109
|
+
break;
|
|
110
|
+
case Reproduction.EVENTS.COUNTING_IN:
|
|
111
|
+
handlers = this[dispatchOnCountingInHandlers];
|
|
112
|
+
break;
|
|
113
|
+
case Reproduction.EVENTS.PLAY:
|
|
114
|
+
handlers = this[dispatchOnPlayHandlers];
|
|
82
115
|
break;
|
|
116
|
+
case Reproduction.EVENTS.PLAYING:
|
|
117
|
+
handlers = this[dispatchOnPlayingHandlers];
|
|
118
|
+
break;
|
|
119
|
+
case Reproduction.EVENTS.PAUSED:
|
|
120
|
+
handlers = this[dispatchOnPausedHandlers];
|
|
121
|
+
break;
|
|
122
|
+
case Reproduction.EVENTS.FINISH:
|
|
123
|
+
handlers = this[dispatchOnFinishHandlers];
|
|
124
|
+
break;
|
|
125
|
+
case Reproduction.EVENTS.ERROR:
|
|
126
|
+
handlers = this[dispatchOnErrorHandlers];
|
|
127
|
+
break;
|
|
128
|
+
default:
|
|
129
|
+
throw new Error(`Unknown event: ${eventName}`);
|
|
130
|
+
}
|
|
131
|
+
const index = handlers.indexOf(handler);
|
|
132
|
+
if (index > -1) {
|
|
133
|
+
handlers.splice(index, 1);
|
|
83
134
|
}
|
|
84
135
|
}
|
|
85
136
|
dispatch(eventName, args = {}) {
|
|
@@ -129,24 +180,55 @@ export class Reproduction {
|
|
|
129
180
|
}
|
|
130
181
|
}
|
|
131
182
|
play() {
|
|
183
|
+
clearInterval(this.interval);
|
|
132
184
|
this.player.play();
|
|
133
|
-
const
|
|
185
|
+
const bpmInterval = this.getBPMInterval();
|
|
186
|
+
const tickInterval = Math.min(bpmInterval / 4, 50);
|
|
134
187
|
this.interval = setInterval(() => {
|
|
135
188
|
if (this.isPlaying()) {
|
|
136
189
|
this.dispatch(Reproduction.EVENTS.PLAYING);
|
|
137
190
|
}
|
|
138
|
-
},
|
|
191
|
+
}, tickInterval);
|
|
192
|
+
}
|
|
193
|
+
playLoop(from, to) {
|
|
194
|
+
if (!Number.isFinite(from) || !Number.isFinite(to)) {
|
|
195
|
+
return;
|
|
196
|
+
}
|
|
197
|
+
if (to <= from) {
|
|
198
|
+
return;
|
|
199
|
+
}
|
|
200
|
+
clearInterval(this.loopInterval);
|
|
201
|
+
this.loopInterval = null;
|
|
202
|
+
this.loopRange = { from, to };
|
|
203
|
+
this.seekTo(from);
|
|
204
|
+
this.play();
|
|
205
|
+
const loopCheckInterval = 100;
|
|
206
|
+
this.loopInterval = setInterval(() => {
|
|
207
|
+
if (!this.isPlaying() || !this.loopRange) {
|
|
208
|
+
return;
|
|
209
|
+
}
|
|
210
|
+
const currentTime = this.getCurrentTime();
|
|
211
|
+
if (currentTime >= this.loopRange.to) {
|
|
212
|
+
this.seekTo(this.loopRange.from);
|
|
213
|
+
}
|
|
214
|
+
}, loopCheckInterval);
|
|
139
215
|
}
|
|
140
216
|
pause() {
|
|
141
217
|
this.state = Reproduction.STATES.PAUSED;
|
|
142
218
|
this.player.pause();
|
|
143
219
|
clearInterval(this.interval);
|
|
220
|
+
clearInterval(this.loopInterval);
|
|
221
|
+
this.loopInterval = null;
|
|
222
|
+
this.loopRange = null;
|
|
144
223
|
this.dispatch(Reproduction.EVENTS.PAUSED);
|
|
145
224
|
}
|
|
146
225
|
stop() {
|
|
147
226
|
this.state = Reproduction.STATES.STOPPED;
|
|
148
227
|
this.player.stop();
|
|
149
228
|
clearInterval(this.interval);
|
|
229
|
+
clearInterval(this.loopInterval);
|
|
230
|
+
this.loopInterval = null;
|
|
231
|
+
this.loopRange = null;
|
|
150
232
|
this.dispatch(Reproduction.EVENTS.FINISH);
|
|
151
233
|
}
|
|
152
234
|
isPlaying() {
|
|
@@ -161,6 +243,9 @@ export class Reproduction {
|
|
|
161
243
|
isCountingIn() {
|
|
162
244
|
return this.state === Reproduction.STATES.COUNTING_IN;
|
|
163
245
|
}
|
|
246
|
+
getState() {
|
|
247
|
+
return this.state;
|
|
248
|
+
}
|
|
164
249
|
getPlayer() {
|
|
165
250
|
return this.player;
|
|
166
251
|
}
|
|
@@ -1,7 +1,8 @@
|
|
|
1
|
+
import { Meta } from '@storybook/react';
|
|
1
2
|
import { ReproductionWidgetProps } from '../components/reproduction-widget';
|
|
2
|
-
declare const _default:
|
|
3
|
+
declare const _default: Meta;
|
|
3
4
|
export default _default;
|
|
4
|
-
export declare const Default: import("storybook/internal/csf").AnnotatedStoryFn<import("@storybook/react
|
|
5
|
-
export declare const WhisperingVideo: import("storybook/internal/csf").AnnotatedStoryFn<import("@storybook/react
|
|
6
|
-
export declare const PlayAlong: import("storybook/internal/csf").AnnotatedStoryFn<import("@storybook/react
|
|
7
|
-
export declare const InvalidVideo: import("storybook/internal/csf").AnnotatedStoryFn<import("@storybook/react
|
|
5
|
+
export declare const Default: import("storybook/internal/csf").AnnotatedStoryFn<import("@storybook/react").ReactRenderer, ReproductionWidgetProps>;
|
|
6
|
+
export declare const WhisperingVideo: import("storybook/internal/csf").AnnotatedStoryFn<import("@storybook/react").ReactRenderer, ReproductionWidgetProps>;
|
|
7
|
+
export declare const PlayAlong: import("storybook/internal/csf").AnnotatedStoryFn<import("@storybook/react").ReactRenderer, ReproductionWidgetProps>;
|
|
8
|
+
export declare const InvalidVideo: import("storybook/internal/csf").AnnotatedStoryFn<import("@storybook/react").ReactRenderer, ReproductionWidgetProps>;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import React, { useCallback, useState } from 'react';
|
|
2
|
-
import { ReproductionWidget } from '../components/reproduction-widget';
|
|
2
|
+
import { ReproductionWidget, } from '../components/reproduction-widget';
|
|
3
3
|
export default {
|
|
4
4
|
title: 'ReproductionWidget',
|
|
5
5
|
component: ReproductionWidget,
|
|
@@ -12,13 +12,19 @@ const Template = (args) => {
|
|
|
12
12
|
const [reproductionTimestamp, setReproductionTimestamp] = useState(0);
|
|
13
13
|
// Handle initialization of reproduction
|
|
14
14
|
const handleInit = useCallback((reproductionInstance) => {
|
|
15
|
-
const refreshEvent = (args) => {
|
|
15
|
+
const refreshEvent = (args) => {
|
|
16
|
+
setReproductionTimestamp(new Date().getTime());
|
|
17
|
+
};
|
|
16
18
|
setReproduction(reproductionInstance);
|
|
17
|
-
reproductionInstance.on('COUNTING_IN', (args) => {
|
|
19
|
+
reproductionInstance.on('COUNTING_IN', (args) => {
|
|
20
|
+
console.log('counting in', args);
|
|
21
|
+
});
|
|
18
22
|
reproductionInstance.on('PLAYING', refreshEvent);
|
|
19
23
|
reproductionInstance.on('PAUSED', refreshEvent);
|
|
20
24
|
reproductionInstance.on('FINISH', refreshEvent);
|
|
21
|
-
reproductionInstance.on('ERROR', (args) => {
|
|
25
|
+
reproductionInstance.on('ERROR', (args) => {
|
|
26
|
+
console.error('Reproduction error', args);
|
|
27
|
+
});
|
|
22
28
|
}, []);
|
|
23
29
|
const handleStop = () => {
|
|
24
30
|
if (reproduction) {
|
|
@@ -40,19 +46,27 @@ const Template = (args) => {
|
|
|
40
46
|
reproduction.start();
|
|
41
47
|
}
|
|
42
48
|
};
|
|
49
|
+
const handleLoop = () => {
|
|
50
|
+
if (reproduction) {
|
|
51
|
+
reproduction.playLoop(10, 20);
|
|
52
|
+
}
|
|
53
|
+
};
|
|
43
54
|
return (React.createElement("div", null,
|
|
44
55
|
React.createElement(ReproductionWidget, Object.assign({}, args, { onInit: handleInit })),
|
|
45
56
|
React.createElement("div", null,
|
|
46
57
|
React.createElement("button", { onClick: handleStop, disabled: !reproduction || reproduction.isStopped() }, "Stop"),
|
|
47
58
|
React.createElement("button", { onClick: handlePause, disabled: !reproduction || !reproduction.isPlaying() }, "Pause"),
|
|
48
|
-
React.createElement("button", { onClick: handleResume, disabled: !reproduction ||
|
|
59
|
+
React.createElement("button", { onClick: handleResume, disabled: !reproduction ||
|
|
60
|
+
reproduction.isPlaying() ||
|
|
61
|
+
reproduction.getCurrentTime() === 0 }, "Resume"),
|
|
49
62
|
React.createElement("button", { onClick: handleStart, disabled: !reproduction || reproduction.isPlaying() }, "Start"),
|
|
63
|
+
React.createElement("button", { onClick: handleLoop, disabled: !reproduction }, "Loop 10-20"),
|
|
50
64
|
reproduction && (React.createElement("div", null,
|
|
51
65
|
"Current time: ", reproduction === null || reproduction === void 0 ? void 0 :
|
|
52
66
|
reproduction.getCurrentTime())),
|
|
53
|
-
reproduction &&
|
|
67
|
+
reproduction && React.createElement("div", null,
|
|
54
68
|
"Volume: ", reproduction === null || reproduction === void 0 ? void 0 :
|
|
55
|
-
reproduction.getVolume())
|
|
69
|
+
reproduction.getVolume()),
|
|
56
70
|
React.createElement("button", { onClick: () => reproduction === null || reproduction === void 0 ? void 0 : reproduction.setVolume(reproduction.getVolume() - 10), disabled: !reproduction || reproduction.getVolume() <= 10 }, "Volume -10"),
|
|
57
71
|
React.createElement("button", { onClick: () => reproduction === null || reproduction === void 0 ? void 0 : reproduction.setVolume(reproduction.getVolume() + 10), disabled: !reproduction || reproduction.getVolume() >= 100 }, "Volume +10"))));
|
|
58
72
|
};
|
|
@@ -1,10 +1,11 @@
|
|
|
1
|
+
import type { Meta } from '@storybook/react';
|
|
1
2
|
import { TimelineProps } from '../components/timeline';
|
|
2
3
|
import './timeline.stories.custom.css';
|
|
3
|
-
declare const _default:
|
|
4
|
+
declare const _default: Meta;
|
|
4
5
|
export default _default;
|
|
5
|
-
export declare const Default: import("storybook/internal/csf").AnnotatedStoryFn<import("@storybook/react
|
|
6
|
-
export declare const WithSelectedRange: import("storybook/internal/csf").AnnotatedStoryFn<import("@storybook/react
|
|
7
|
-
export declare const WithCustomClassName: import("storybook/internal/csf").AnnotatedStoryFn<import("@storybook/react
|
|
8
|
-
export declare const WithoutTimeBlocks: import("storybook/internal/csf").AnnotatedStoryFn<import("@storybook/react
|
|
9
|
-
export declare const Minimalist: import("storybook/internal/csf").AnnotatedStoryFn<import("@storybook/react
|
|
10
|
-
export declare const WithSelectedRangeAndMarkers: import("storybook/internal/csf").AnnotatedStoryFn<import("@storybook/react
|
|
6
|
+
export declare const Default: import("storybook/internal/csf").AnnotatedStoryFn<import("@storybook/react").ReactRenderer, TimelineProps>;
|
|
7
|
+
export declare const WithSelectedRange: import("storybook/internal/csf").AnnotatedStoryFn<import("@storybook/react").ReactRenderer, TimelineProps>;
|
|
8
|
+
export declare const WithCustomClassName: import("storybook/internal/csf").AnnotatedStoryFn<import("@storybook/react").ReactRenderer, TimelineProps>;
|
|
9
|
+
export declare const WithoutTimeBlocks: import("storybook/internal/csf").AnnotatedStoryFn<import("@storybook/react").ReactRenderer, TimelineProps>;
|
|
10
|
+
export declare const Minimalist: import("storybook/internal/csf").AnnotatedStoryFn<import("@storybook/react").ReactRenderer, TimelineProps>;
|
|
11
|
+
export declare const WithSelectedRangeAndMarkers: import("storybook/internal/csf").AnnotatedStoryFn<import("@storybook/react").ReactRenderer, TimelineProps>;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
|
-
import { Timeline } from '../components/timeline';
|
|
3
2
|
import styled from 'styled-components';
|
|
3
|
+
import { Timeline } from '../components/timeline';
|
|
4
4
|
import './timeline.stories.custom.css';
|
|
5
5
|
const StyledTimeline = styled(Timeline) `
|
|
6
6
|
.media-timeline-value-line {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ldelia/react-media",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.10.0",
|
|
4
4
|
"description": "A React components collection for media-related features.",
|
|
5
5
|
"private": false,
|
|
6
6
|
"keywords": [
|
|
@@ -101,7 +101,7 @@
|
|
|
101
101
|
"styled-components": "^6.1.11",
|
|
102
102
|
"tailwindcss": "^3.0.2",
|
|
103
103
|
"terser-webpack-plugin": "^5.2.5",
|
|
104
|
-
"typescript": "^
|
|
104
|
+
"typescript": "^5.3.3",
|
|
105
105
|
"webpack": "^5.102.1",
|
|
106
106
|
"webpack-dev-server": "^5.2.2",
|
|
107
107
|
"webpack-manifest-plugin": "^5.0.1",
|
|
@@ -113,12 +113,12 @@
|
|
|
113
113
|
"@babel/preset-env": "^7.24.8",
|
|
114
114
|
"@babel/preset-react": "^7.24.7",
|
|
115
115
|
"@babel/preset-typescript": "^7.24.7",
|
|
116
|
-
"@chromatic-com/storybook": "^
|
|
117
|
-
"@storybook/addon-docs": "^
|
|
118
|
-
"@storybook/addon-links": "^
|
|
119
|
-
"@storybook/addon-onboarding": "^
|
|
116
|
+
"@chromatic-com/storybook": "^5.0.1",
|
|
117
|
+
"@storybook/addon-docs": "^10.2.8",
|
|
118
|
+
"@storybook/addon-links": "^10.2.8",
|
|
119
|
+
"@storybook/addon-onboarding": "^10.2.8",
|
|
120
120
|
"@storybook/react-docgen-typescript-plugin": "^1.0.6--canary.9.0c3f3b7.0",
|
|
121
|
-
"@storybook/react-webpack5": "^
|
|
121
|
+
"@storybook/react-webpack5": "^10.2.8",
|
|
122
122
|
"@testing-library/jest-dom": "^6.4.6",
|
|
123
123
|
"@testing-library/react": "^16.0.0",
|
|
124
124
|
"@testing-library/user-event": "^14.5.2",
|
|
@@ -131,7 +131,7 @@
|
|
|
131
131
|
"babel-loader": "^9.1.3",
|
|
132
132
|
"eslint-config-prettier": "^9.1.0",
|
|
133
133
|
"eslint-plugin-prettier": "^5.1.3",
|
|
134
|
-
"eslint-plugin-storybook": "^
|
|
134
|
+
"eslint-plugin-storybook": "^10.2.8",
|
|
135
135
|
"jest-environment-jsdom": "^30.2.0",
|
|
136
136
|
"postcss-flexbugs-fixes": "^5.0.2",
|
|
137
137
|
"postcss-normalize": "^10.0.1",
|
|
@@ -139,10 +139,10 @@
|
|
|
139
139
|
"prettier": "^3.3.2",
|
|
140
140
|
"prop-types": "^15.8.1",
|
|
141
141
|
"react-docgen-typescript-plugin": "^1.0.8",
|
|
142
|
-
"storybook": "^
|
|
142
|
+
"storybook": "^10.2.8",
|
|
143
143
|
"ts-loader": "^9.5.1",
|
|
144
144
|
"tsconfig-paths-webpack-plugin": "^4.1.0",
|
|
145
|
-
"webpack": "^5.
|
|
145
|
+
"webpack": "^5.105.2"
|
|
146
146
|
},
|
|
147
147
|
"jest": {
|
|
148
148
|
"roots": [
|