@lizzelabs/react-harmony 1.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.
Files changed (3) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +586 -0
  3. package/package.json +140 -0
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 lizzelabs
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,586 @@
1
+ # πŸ“¦ React Harmony
2
+
3
+ A new way of build user interfaces with react.
4
+
5
+ - Everything is JS its easy to maintain.
6
+ - You're totally able to create your CSS systems and share between sort of
7
+ pieces with just JS.
8
+ - Lightweight library: 13.5K
9
+
10
+ ---
11
+
12
+ ## 🧭 Índice
13
+
14
+ - [πŸ“– Why](#-why)
15
+ - [βš™οΈ Quick Start](#️-quick-start)
16
+ - [πŸ”§ Piece](#-piece)
17
+ - [πŸ› οΈ Piece Provider](#-piece-provider)
18
+ - [♾️ Default CSS System](#-estrutura-do-projeto)
19
+ - [πŸ–₯️ Screen](#-screen)
20
+ - [✏️ Text](#-text)
21
+ - [↕️↔️ Scrollable](#-scrollable)
22
+ - [πŸ“ Media](#-media)
23
+ - [🎨 Animations](#-animations)
24
+ - [πŸš€ withPieceAsContainer](#-withpieceascontainer)
25
+ - [πŸ–ΌοΈ Example Projects](#-example-projects)
26
+ - [🀝 Contributing](#-contributing)
27
+ - [πŸ“„ License](#-license)
28
+
29
+ ---
30
+
31
+ ## πŸ“– Why
32
+
33
+ Nowadays we have a lot of libs of style, and many times we dont need to
34
+ everything in each one to build our interfaces after all it costs to our users
35
+ download every css class unused, so i think in an easy and elegant way to style
36
+ all of components and how to keep everything easy to mantain.
37
+
38
+ ---
39
+
40
+ ## βš™οΈ Quick Start
41
+
42
+ NPM:
43
+
44
+ ```sh
45
+ npm i --save @lizzelabs/react-harmony
46
+ ```
47
+
48
+ YARN:
49
+
50
+ ```sh
51
+ yarn add @lizzelabs/react-harmony
52
+
53
+ ```
54
+
55
+ PNPM:
56
+
57
+ ```sh
58
+ pnpm add @lizzelabs/react-harmony
59
+
60
+ ```
61
+
62
+ Bun:
63
+
64
+ ```sh
65
+ bun add @lizzelabs/react-harmony
66
+ ```
67
+
68
+ after it, its just importing from:
69
+
70
+ ```javascript
71
+ import { Piece } from '@lizzelabs/react-harmony';
72
+ ```
73
+
74
+ `@lizzelabs/react-harmony/components/piece` => splitted by component ex: /screen
75
+ /animations /media /text.
76
+
77
+ `@lizzelabs/react-harmony/components` => all components
78
+
79
+ `@lizzelabs/react-harmony/hocs` => HOCS
80
+
81
+ `@lizzelabs/react-harmony/systems` => CSS systems
82
+
83
+ ## πŸ”§ Piece
84
+
85
+ First of all eveything you want to put in your screen is a piece and i would
86
+ like that you start to think on it:
87
+
88
+ I want to put a link on my page:
89
+
90
+ ```javascript
91
+ import { Piece } from '@lizzelabs/react-harmony';
92
+
93
+ <Piece
94
+ as='a'
95
+ href='https://mywebsite.com'
96
+ ></Piece>;
97
+ ```
98
+
99
+ Or some input:
100
+
101
+ ```javascript
102
+ import { Piece } from '@lizzelabs/react-harmony';
103
+
104
+ <Piece
105
+ as='input'
106
+ type='text'
107
+ onChange={handleText}
108
+ ></Piece>;
109
+ ```
110
+
111
+ Even a simple div:
112
+
113
+ ```javascript
114
+ import { Piece } from '@lizzelabs/react-harmony';
115
+
116
+ <Piece
117
+ as='div'
118
+ onBlur={handleBlur}
119
+ ></Piece>;
120
+ ```
121
+
122
+ I offer a attractive way to style each one with **withStyle**:
123
+
124
+ ```javascript
125
+
126
+ import { Piece } from '@lizzelabs/react-harmony';
127
+
128
+
129
+ <Piece withStyle={{
130
+ containerType: 'inline-size',
131
+ containerName: 'card'
132
+ flex: '0 0 100%'
133
+ }} > <Piece withStyle={{
134
+ background: 'blue',
135
+ transition: 'all 0.3s ease-in-out',
136
+ '&:hover': {
137
+ background: 'red'
138
+ },
139
+ '@media screen (max-width: 500px)': {
140
+ background: 'yellow'
141
+ },
142
+ '@container card (max-width: 600px)': {
143
+ flexDirection: 'column'
144
+ }
145
+ '@keyframes fade': {
146
+ from: {
147
+ opacity: 0;
148
+ }
149
+ to: {
150
+ opacity: 1;
151
+ }
152
+ }
153
+ }} >
154
+ <Piece as='span'>Hello world!</Piece>
155
+ </Piece>
156
+ </Piece>
157
+
158
+ ```
159
+
160
+ I can't forget about aria:
161
+
162
+ ```javascript
163
+ import { Piece } from '@lizzelabs/react-harmony';
164
+
165
+ <Piece
166
+ aria={{
167
+ 'aria-autocomplete': 'none',
168
+ 'aria-description': 'This is a test',
169
+ }}
170
+ />;
171
+ ```
172
+
173
+ or some properties inline like:
174
+
175
+ ```javascript
176
+ import { Piece } from '@lizzelabs/react-harmony';
177
+
178
+ <Piece
179
+ <!-- margin='10px' -->
180
+ <!-- margin={theme => theme.margin} -->
181
+ <!-- padding='12px' -->
182
+ <!-- padding={theme => theme.padding} -->
183
+ <!-- textColor='#FFF' -->
184
+ <!-- textColor={theme => theme.text} -->
185
+ <!-- background='#333' -->
186
+ <!-- background={theme => theme.background} -->
187
+ <!-- backgroundColor='#333' -->
188
+ <!-- backgroundColor={theme => theme.background} -->
189
+ <!-- fontSize='20px' -->
190
+ <!-- fontSize={theme => theme.main.textSize} -->
191
+ gap='5px'
192
+ direction='column'
193
+ alignContent='center'
194
+ justifyContent='center'
195
+ alignItems='center'
196
+ justifyItems='center'
197
+ height='30px'
198
+ width='30px'
199
+ display='block'
200
+ <!-- contentColumns='1fr 1fr' -->
201
+ <!-- contentColumns={2} -->
202
+ <!-- contentRows='1fr 1fr 1fr' -->
203
+ <!-- contentRows={3} -->
204
+ <!-- atColumn='1 / 2' -->
205
+ <!-- atColumn={2} -->
206
+ <!-- atRow='1 / 2' -->
207
+ <!-- atRow={4} -->
208
+ flex='1 0 auto'
209
+ />
210
+
211
+ ```
212
+
213
+ **Important:** you can pass the theme to withStyle like:
214
+
215
+ `withStyle={(theme: Theme) => ({ ///CSS Properties Here })}`
216
+
217
+ or and array of styles like:
218
+
219
+ ```javascript
220
+ import { AlignCenter, FlexDirectionColumn } from './mylib/styles';
221
+
222
+ <Piece withStyle={[AlignCenter, FlexDirectionColumn]}></Piece>;
223
+ ```
224
+
225
+ last but not less important
226
+
227
+ ```javascript
228
+ import { Piece } from '@lizzelabs/react-harmony';
229
+
230
+ <Piece
231
+ as='section'
232
+ kind='page'
233
+ ></Piece>;
234
+ ```
235
+
236
+ you can define and set default properties or styles in the provider that we will
237
+ see below.
238
+
239
+ ---
240
+
241
+ ## πŸ› οΈ Piece Provider
242
+
243
+ Basic syntax
244
+
245
+ ```typescript
246
+
247
+ import { PieceProvider, Piece } from '@lizzelabs/react-harmony';
248
+
249
+ type MyCustomPersonalTheme = {
250
+ primary: string;
251
+ secondary: string;
252
+ text: string;
253
+ }
254
+
255
+ <PieceProvider
256
+ theme={{
257
+ primary: 'blue',
258
+ secondary: 'yellow',
259
+ text: 'rgb(235, 235, 235)'
260
+ } satisfies MyCustomPersonalTheme}
261
+ patterns={[
262
+ {
263
+ applyOn: 'all',
264
+ styles: (theme: MyCustomPersonalTheme) => ({
265
+ background: theme.primary,
266
+ fontSize: '16px',
267
+ overflow: 'hidden'
268
+ })
269
+ },
270
+ {
271
+ applyOn: (props: PieceProperties<MyCustomPersonalTheme, any, any>) => props.kind === 'link',
272
+ defaults: (theme: MyCustomPersonalTheme) => ({
273
+ aria: {
274
+ 'aria-description': 'Click to go to the link'
275
+ }
276
+ }),
277
+ styles: {
278
+ textDecoration: 'none'
279
+ }
280
+ },
281
+ {
282
+ applyOn: 'section',
283
+ styles: {
284
+ height: '100%',
285
+ width: '100%'
286
+ }
287
+ }
288
+ ]} >
289
+ <Piece as='p' background={(theme: MyCustomPersonalTheme) => theme.primary} textColor={(theme: MyCustomPersonalTheme) => theme.text} >
290
+ Hello World
291
+ </Piece>
292
+ </PieceProvider>
293
+
294
+ ```
295
+
296
+ Basically we have:
297
+
298
+ **Theme:** Custom object could be anything and could be typed with typescript if
299
+ you rather and use.
300
+
301
+ **Patterns** An array of objects that receive:
302
+
303
+ - **applyOn:**
304
+ - `all`: All of components utils if you want a css reset.
305
+ - `(properties: PieceProperties<Theme, any>) => boolean`: a function that
306
+ receive a PieceProperty and returns a boolean.
307
+ - `span` | `div` | `a`: HtmlTag
308
+ - **defaults:**: Object of default properties of categorized piece.
309
+ - **styles**: Object with styles that you can put your own style in each kind
310
+ piece.
311
+
312
+ **(In styles or default props, you can receive a theme object turning it into a
313
+ function)**
314
+
315
+ ---
316
+
317
+ ## ♾️ Default CSS System
318
+
319
+ ```javascript
320
+ import { HARMONY_SYSTEM, PieceProvider } from '@lizzelabs/react-harmony';
321
+
322
+ <PieceProvider patterns={HARMONY_SYSTEM}>//Your Components ...</PieceProvider>;
323
+ ```
324
+
325
+ harmony system is simple and designed to be css Flex or Grid friend and **anti
326
+ overflow** or thats say where you want to put an overflow you have a special
327
+ component called <Scrollable></Scrollable> where you are able to set if it is
328
+ vertical or horizontal. Basically what you have be in mind is Flex = every
329
+ component, every small detail, Grid = Complex areas to organize/big areas to
330
+ organize. and you can extend the system:
331
+
332
+ ```javascript
333
+ import { HARMONY_SYSTEM, mergeSystems, PieceProvider } from '@lizzelabs/react-harmony';
334
+
335
+ const MyOwnSystem = mergeSystems(HARMONY_SYSTEM, { applyOn: // the rest.... });
336
+
337
+ <PieceProvider patterns={MyOwnSystem}>
338
+ //Other Components
339
+ </PieceProvider>
340
+
341
+ ```
342
+
343
+ Or even create your own system for each piece etc...
344
+
345
+ ```javascript
346
+ import { PieceProvider } from '@lizzelabs/react-harmony';
347
+
348
+ const MyOwnSystem = [
349
+ {
350
+ applyOn: 'all',
351
+ styles: {} // MyResetCssObject
352
+ },
353
+ {
354
+ applyOn: props => props.kind === 'all-left-div',
355
+ styles: {
356
+ display: 'block',
357
+ float: 'left' // I'm kidding 🀣 (Nothing against the old school).
358
+ }
359
+ }
360
+ ]
361
+
362
+ <PieceProvider patterns={MyOwnSystem}>
363
+ //Other Components
364
+ </PieceProvider>
365
+
366
+ ```
367
+
368
+ ---
369
+
370
+ ## πŸ–₯️ Screen
371
+
372
+ A component that offers to you a way to stylize your html, body, set some global
373
+ style, with just one piece too and thats called by Screen
374
+
375
+ ```javascript
376
+ import { Screen } from '@lizzelabs/react-harmony';
377
+
378
+ <Screen
379
+ containerId='root'
380
+ fontSize='16px'
381
+ fontFamily='"Mozilla Text", sans-serif' //Important to have the font on html file
382
+ globalStyle={{
383
+ div: {
384
+ borderRadius: '50%',
385
+ },
386
+ }}
387
+ >
388
+ //My Components here
389
+ </Screen>;
390
+ ```
391
+
392
+ **`containerId:`** Important the react root id where it will be rendered
393
+ normally where you do createRoot(document.getElementById('root' // this ID))
394
+
395
+ **`fontSize:`** Set a fontsize for all document, important to have a base size.
396
+
397
+ **`fontFamily:`** Important to have the font on html file
398
+
399
+ **`globalStyle:`** Global styles.
400
+
401
+ ---
402
+
403
+ ## ✏️ Text
404
+
405
+ Just for texts its another kind of piece that i limit it as
406
+
407
+ ```javascript
408
+ import { Text } from '@lizzelabs/react-harmony';
409
+
410
+ <Text as='p'></Text>;
411
+ ```
412
+
413
+ **Important** the default kind here is text and about the as you just can put
414
+ text tags ....
415
+
416
+ ---
417
+
418
+ ## ↕️↔️ Scrollable
419
+
420
+ Everytime i see in websites scrolls that broke your navigation, and more in
421
+ general it is ugly so i offer to you a component that you can personalize your
422
+ scroll with the colors from your theme like:
423
+
424
+ ```javascript
425
+ import { PieceProvider, mergeSystems, HARMONY_SYSTEM, Scrollable } from '@lizzelabs/react-harmony';
426
+
427
+
428
+ <PieceProvider patterns={mergeSystems(HARMONY_SYSTEM, {
429
+ applyOn: (props) => props.kind === 'scrollable',
430
+ theme={{ color: 'blue', highlight: 'orangeblue' }}
431
+ style: (theme: Theme) => ({
432
+ '--color': theme.color,
433
+ '--highlight': theme.highlight,
434
+ }),
435
+ })} >
436
+ <Scrollable
437
+ horizontal
438
+ scrollSnap='x mandatory' // Optional
439
+ behavior='instant' //Optional
440
+ >
441
+ //My Horizontal items
442
+ </Scrollable>
443
+ </PieceProvider>
444
+
445
+ ```
446
+
447
+ ** Important: I will put an example bellow **
448
+
449
+ ---
450
+
451
+ ## πŸ“ Media
452
+
453
+ Sometimes you want to hide something on a screen and I have a ready and fast way
454
+ to do it like:
455
+
456
+ ```javascript
457
+ import { Media } from '@lizzelabs/react-harmony'
458
+
459
+
460
+ <Media query='(max-width: 500px)' removeFromHtml={true or false} >
461
+ //Your component that you want to hide on screens bigger than 500px of width
462
+ </Media>
463
+
464
+ ```
465
+
466
+ ---
467
+
468
+ ## 🎨 Animations
469
+
470
+ Sometimes you wanna share some animations between N kind component so you can do
471
+ it with Animations
472
+
473
+ ```javascript
474
+ import { Animations } from '@lizzelabs/react-harmony';
475
+
476
+
477
+ <Animations value={{
478
+ name: 'fade',
479
+ animation: {
480
+ '@keyframes fade': {
481
+ from: {
482
+ opacity: 0,
483
+ },
484
+ to: {
485
+ opacity: 1,
486
+ },
487
+ },
488
+ },
489
+ }
490
+ }} >
491
+ //you compoennt
492
+ </Animations>
493
+
494
+ ```
495
+
496
+ And now you can use animate: fade 0.3s infinite anywhere of course inside your
497
+ Animations component.
498
+
499
+ ---
500
+
501
+ ## πŸš€ withPieceAsContainer
502
+
503
+ Sometimes you want to write your own component but when you have to use, you
504
+ want align, move and etc, so i have a simple hoc that involve your component
505
+ into Piece container, you can align outside ask for props or something else
506
+ like:
507
+
508
+ ```typescript
509
+ import { withPieceAsContainer, Piece } from '@lizzelabs/react-harmony';
510
+
511
+
512
+ const InternalButton = withPieceAsContainer((props: ButtonProps) => {
513
+ return (
514
+ <Piece
515
+ as='button'
516
+ kind='button'
517
+ withStyle={(theme: Theme) => (
518
+ {
519
+ alignItems: 'center',
520
+ justifyContent: 'center',
521
+ flex: `1 0 auto`,
522
+ padding: theme.buttonPadding,
523
+ background: theme.color,
524
+ color: theme.text,
525
+ fontSize: `${size}px`,
526
+ borderRadius: radius,
527
+ aspectRatio: '1 / 1',
528
+ outline: 'none',
529
+ boxSizing: 'border-box',
530
+ '&:hover': {
531
+ background: theme.highlight,
532
+ },
533
+ },
534
+ )}
535
+ onClick={props.onClick}
536
+ >
537
+ {props.children}
538
+ </Piece>
539
+ )
540
+ }, { withStyle: { flex: '1 1 auto' } });
541
+
542
+
543
+ export const IconButton = InternalButton as typeof InternalButton;
544
+
545
+ ```
546
+
547
+ Now you are able to align, justify, etc outside of button, its very nice do it.
548
+ and i have to you remember if you will use this, you have always to think like
549
+ you component fills every space and the outside just align you know.
550
+
551
+ ---
552
+
553
+ ## πŸ–ΌοΈ Example Projects
554
+
555
+ Here are some examples that you are free to get some inspiration:
556
+
557
+ ---
558
+
559
+ ## 🀝 Contributing
560
+
561
+ I will be so happy that you like to contribute, in this guide you will find
562
+ instructions, how to setup the repo locally.
563
+
564
+ 1. Install **PNPM**
565
+ 2. Before all run: `pnpm install`
566
+ 3. Do your changes inside a branch with this convention:
567
+
568
+ - `fix/you-fix-name` -> if your change is a fix for something broken.
569
+ - `feature/your-feature-name` -> if your change will add something.
570
+
571
+ 4. Commit convention:
572
+
573
+ - I use the
574
+ [Conventional Commits](https://www.conventionalcommits.org/en/v1.0.0/#summary)
575
+ for my commit messages. **Example** `feat: [#555] this is my commit message.`
576
+
577
+ 5. Push the branch to the repository, fill the PR that will be opened with
578
+ informations about what you add, etc.
579
+
580
+ ---
581
+
582
+ ## πŸ“„ License
583
+
584
+ MIT License Β© 2026 - [Gustavo Lizze](https://github.com/gustavolizze)
585
+
586
+ ---
package/package.json ADDED
@@ -0,0 +1,140 @@
1
+ {
2
+ "name": "@lizzelabs/react-harmony",
3
+ "private": false,
4
+ "version": "1.0.0",
5
+ "main": "./dist/index.js",
6
+ "types": "./dist/index.d.ts",
7
+ "type": "module",
8
+ "files": [
9
+ "dist"
10
+ ],
11
+ "exports": {
12
+ ".": {
13
+ "import": "./dist/index.es.js",
14
+ "require": "./dist/index.es.js",
15
+ "types": "./dist/index.d.ts"
16
+ },
17
+ "./components": {
18
+ "import": "./dist/components.es.js",
19
+ "require": "./dist/components.es.js",
20
+ "types": "./dist/components/index.d.ts"
21
+ },
22
+ "./systems": {
23
+ "import": "./dist/systems.es.js",
24
+ "require": "./dist/systems.es.js",
25
+ "types": "./dist/components/piece-provider/static.d.ts"
26
+ },
27
+ "./types": {
28
+ "import": "./dist/types.es.js",
29
+ "require": "./dist/types.es.js",
30
+ "types": "./dist/types/index.d.ts"
31
+ },
32
+ "./utils": {
33
+ "import": "./dist/utils.es.js",
34
+ "require": "./dist/utils.es.js",
35
+ "types": "./dist/utils/index.d.ts"
36
+ },
37
+ "./piece": {
38
+ "import": "./dist/piece.es.js",
39
+ "require": "./dist/piece.es.js",
40
+ "types": "./dist/components/piece/index.d.ts"
41
+ },
42
+ "./piece-provider": {
43
+ "import": "./dist/piece-provider.es.js",
44
+ "require": "./dist/piece-provider.es.js",
45
+ "types": "./dist/components/piece-provider/index.d.ts"
46
+ },
47
+ "./screen": {
48
+ "import": "./dist/screen.es.js",
49
+ "require": "./dist/screen.es.js",
50
+ "types": "./dist/components/screen/index.d.ts"
51
+ },
52
+ "./scrollable": {
53
+ "import": "./dist/scrollable.es.js",
54
+ "require": "./dist/scrollable.es.js",
55
+ "types": "./dist/components/scrollable/index.d.ts"
56
+ },
57
+ "./text": {
58
+ "import": "./dist/text.es.js",
59
+ "require": "./dist/text.es.js",
60
+ "types": "./dist/components/text/text.d.ts"
61
+ },
62
+ "./media": {
63
+ "import": "./dist/media.es.js",
64
+ "require": "./dist/media.es.js",
65
+ "types": "./dist/components/media/index.d.ts"
66
+ },
67
+ "./animations": {
68
+ "import": "./dist/animations.es.js",
69
+ "require": "./dist/animations.es.js",
70
+ "types": "./dist/components/animations/index.d.ts"
71
+ }
72
+ },
73
+ "publishConfig": {
74
+ "registry": "https://registry.npmjs.org/"
75
+ },
76
+ "devDependencies": {
77
+ "@eslint/js": "^9.39.1",
78
+ "@testing-library/dom": "^10.4.1",
79
+ "@testing-library/jest-dom": "^6.9.1",
80
+ "@testing-library/react": "^16.3.2",
81
+ "@testing-library/user-event": "^14.6.1",
82
+ "@types/jest": "^30.0.0",
83
+ "@types/lodash": "^4.17.21",
84
+ "@types/node": "^24.10.1",
85
+ "@types/react": "^19.2.5",
86
+ "@types/react-dom": "^19.2.3",
87
+ "@types/stylis": "^4.2.7",
88
+ "@typescript-eslint/parser": "^8.56.0",
89
+ "@vitejs/plugin-react-swc": "^4.2.2",
90
+ "@vitest/coverage-v8": "^4.0.15",
91
+ "csstype": "^3.2.3",
92
+ "eslint": "^9.39.1",
93
+ "eslint-config-prettier": "^10.1.8",
94
+ "eslint-plugin-prettier": "^5.5.4",
95
+ "eslint-plugin-react-hooks": "^7.0.1",
96
+ "eslint-plugin-react-refresh": "^0.4.24",
97
+ "globals": "^16.5.0",
98
+ "happy-dom": "^20.6.3",
99
+ "husky": "^9.1.7",
100
+ "lint-staged": "^16.2.7",
101
+ "nodemon": "^3.1.11",
102
+ "prettier": "3.7.4",
103
+ "react": "^19.2.1",
104
+ "react-dom": "^19.2.1",
105
+ "typescript": "~5.9.3",
106
+ "typescript-eslint": "^8.46.4",
107
+ "vite": "^7.2.4",
108
+ "vite-plugin-dts": "^4.5.4",
109
+ "vite-tsconfig-paths": "^6.0.3",
110
+ "vitest": "^4.0.15"
111
+ },
112
+ "peerDependencies": {
113
+ "react": "^19.2.1",
114
+ "react-dom": "^19.2.1"
115
+ },
116
+ "dependencies": {
117
+ "lodash": "^4.17.23",
118
+ "stylis": "^4.3.6"
119
+ },
120
+ "lint-staged": {
121
+ "*.{ts,tsx}": [
122
+ "eslint --fix",
123
+ "prettier --write"
124
+ ],
125
+ "*.{json,md,css}": [
126
+ "prettier --write"
127
+ ]
128
+ },
129
+ "scripts": {
130
+ "development": "nodemon",
131
+ "build:dev": "tsc --noEmit && vite build --config vite.config.development.ts",
132
+ "build:prd": "tsc --noEmit && vite build --config vite.config.ts",
133
+ "test": "vitest",
134
+ "test:ci": "vitest run",
135
+ "coverage": "vitest run --coverage",
136
+ "storybook": "storybook dev -p 6006",
137
+ "build-storybook": "storybook build",
138
+ "lint": "eslint ."
139
+ }
140
+ }