File tree Expand file tree Collapse file tree 4 files changed +145
-0
lines changed Expand file tree Collapse file tree 4 files changed +145
-0
lines changed Original file line number Diff line number Diff line change 3838 ]
3939 },
4040 "dependencies" : {
41+ "classnames" : " ^2.5.1" ,
42+ "is-plain-object" : " ^5.0.0" ,
4143 "react-is" : " ^18.2.0"
4244 },
4345 "devDependencies" : {
Original file line number Diff line number Diff line change 11export { default as useEvent } from './hooks/useEvent' ;
22export { default as useMergedState } from './hooks/useMergedState' ;
3+ export { default as mergeProps } from './mergeProps' ;
34export { supportNodeRef , supportRef , useComposeRef } from './ref' ;
45export { default as get } from './utils/get' ;
56export { default as set } from './utils/set' ;
Original file line number Diff line number Diff line change 1+ import classNames from 'classnames' ;
2+ import { isPlainObject } from 'is-plain-object' ;
3+
4+ function mergeClassNames < T > ( classNamesA : T , classNamesB : T ) : T {
5+ const result = { ...classNamesA } ;
6+ Object . keys ( classNamesB ) . forEach ( key => {
7+ result [ key ] = mergeClassName ( classNamesA [ key ] , classNamesB [ key ] ) ;
8+ } ) ;
9+ return result ;
10+ }
11+
12+ function mergeClassName ( classNameA ?: any , classNameB ?: any ) : string {
13+ if ( typeof classNameA === 'object' || typeof classNameB === 'object' ) {
14+ return mergeClassNames ( classNameA , classNameB ) ;
15+ }
16+
17+ return classNames ( classNameA , classNameB ) ;
18+ }
19+
20+ export default function mergeProps < T > ( ...list : T [ ] ) : T {
21+ if ( list . length > 2 ) {
22+ return mergeProps ( list [ 0 ] , mergeProps ( ...list . slice ( 1 ) ) ) ;
23+ }
24+ const result : T = { ...list [ 0 ] } ;
25+ list [ 1 ] &&
26+ Object . keys ( list [ 1 ] ) . forEach ( key => {
27+ if ( key === 'className' ) {
28+ result [ key ] = classNames ( result [ key ] , list [ 1 ] [ key ] ) ;
29+ } else if ( key === 'classNames' ) {
30+ result [ key ] = mergeClassNames ( result [ key ] , list [ 1 ] [ key ] ) ;
31+ } else if ( isPlainObject ( list [ 1 ] [ key ] ) ) {
32+ result [ key ] = mergeProps ( result [ key ] , list [ 1 ] [ key ] ) ;
33+ } else {
34+ result [ key ] = list [ 1 ] [ key ] ?? result [ key ] ;
35+ }
36+ } ) ;
37+ return result ;
38+ }
Original file line number Diff line number Diff line change 1+ import mergeProps from '../src/mergeProps' ;
2+
3+ test ( 'merge className' , ( ) => {
4+ expect ( mergeProps ( { className : 'foo' } , { className : 'bar' } ) ) . toEqual ( {
5+ className : 'foo bar' ,
6+ } ) ;
7+ } ) ;
8+
9+ test ( 'merge classNames' , ( ) => {
10+ expect (
11+ mergeProps (
12+ {
13+ classNames : {
14+ body : 'bam' ,
15+ footer : 'foo' ,
16+ } ,
17+ } ,
18+ {
19+ classNames : {
20+ footer : 'bar' ,
21+ header : 'boo' ,
22+ } ,
23+ } ,
24+ ) ,
25+ ) . toEqual ( {
26+ classNames : {
27+ body : 'bam' ,
28+ footer : 'foo bar' ,
29+ header : 'boo' ,
30+ } ,
31+ } ) ;
32+ } ) ;
33+
34+ test ( 'merge style' , ( ) => {
35+ expect (
36+ mergeProps (
37+ {
38+ style : {
39+ background : '#000' ,
40+ color : '#666' ,
41+ } ,
42+ } ,
43+ {
44+ style : {
45+ background : '#fff' ,
46+ } ,
47+ } ,
48+ ) ,
49+ ) . toEqual ( {
50+ style : {
51+ background : '#fff' ,
52+ color : '#666' ,
53+ } ,
54+ } ) ;
55+ } ) ;
56+
57+ test ( 'merge boolean prop' , ( ) => {
58+ expect (
59+ mergeProps (
60+ {
61+ disabled : true ,
62+ loading : false ,
63+ } ,
64+ {
65+ disabled : false ,
66+ } ,
67+ ) ,
68+ ) . toEqual ( {
69+ disabled : false ,
70+ loading : false ,
71+ } ) ;
72+ } ) ;
73+
74+ test ( 'merge number prop' , ( ) => {
75+ expect (
76+ mergeProps (
77+ {
78+ value : 1 ,
79+ } ,
80+ {
81+ value : 2 ,
82+ } ,
83+ ) ,
84+ ) . toEqual ( {
85+ value : 2 ,
86+ } ) ;
87+ } ) ;
88+
89+ test ( 'merge non-plain object prop' , ( ) => {
90+ const dateObj = new Date ( ) ;
91+ const urlObj = new URL ( 'https://example.com/' ) ;
92+ expect (
93+ mergeProps (
94+ {
95+ value : dateObj ,
96+ } ,
97+ {
98+ value : urlObj ,
99+ } ,
100+ ) ,
101+ ) . toEqual ( {
102+ value : urlObj ,
103+ } ) ;
104+ } ) ;
You can’t perform that action at this time.
0 commit comments