1
1
import * as React from 'react' ;
2
2
import { storiesOf } from '@storybook/react' ;
3
3
4
+ import DescriptionOutlinedIcon from '@mui/icons-material/DescriptionOutlined' ;
5
+ import KeyboardArrowRightIcon from '@mui/icons-material/KeyboardArrowRight' ;
6
+ import ExpandMoreIcon from '@mui/icons-material/ExpandMore' ;
4
7
import FolderIcon from '@mui/icons-material/Folder' ;
5
8
import FolderOpenIcon from '@mui/icons-material/FolderOpen' ;
6
9
import InsertDriveFileOutlinedIcon from '@mui/icons-material/InsertDriveFileOutlined' ;
@@ -16,6 +19,8 @@ import {
16
19
} from '@table-library/react-table-library/table' ;
17
20
18
21
import { useTree , CellTree , TreeExpandClickTypes } from '@table-library/react-table-library/tree' ;
22
+ import { useTheme } from '@table-library/react-table-library/theme' ;
23
+ import { findNodeById } from '@table-library/react-table-library/common' ;
19
24
20
25
import { nodes } from '../data' ;
21
26
@@ -395,6 +400,79 @@ storiesOf('Features/Tree', module)
395
400
</ Table >
396
401
) ;
397
402
} )
403
+ . add ( 'double icon' , ( ) => {
404
+ const data = { nodes } ;
405
+
406
+ const tree = useTree (
407
+ data ,
408
+ {
409
+ onChange : onTreeChange ,
410
+ } ,
411
+ {
412
+ treeIcon : {
413
+ margin : '4px' ,
414
+ iconDefault : (
415
+ < div style = { { display : 'flex' , alignItems : 'center' } } >
416
+ < div style = { { height : '20px' , width : '20px' } } />
417
+ < DescriptionOutlinedIcon fontSize = "small" />
418
+ </ div >
419
+ ) ,
420
+ iconRight : (
421
+ < div style = { { display : 'flex' , alignItems : 'center' } } >
422
+ < KeyboardArrowRightIcon fontSize = "small" />
423
+ < FolderIcon fontSize = "small" />
424
+ </ div >
425
+ ) ,
426
+ iconDown : (
427
+ < div style = { { display : 'flex' , alignItems : 'center' } } >
428
+ < ExpandMoreIcon fontSize = "small" />
429
+ < FolderOpenIcon fontSize = "small" />
430
+ </ div >
431
+ ) ,
432
+ } ,
433
+ } ,
434
+ ) ;
435
+
436
+ function onTreeChange ( action , state ) {
437
+ console . log ( action , state ) ;
438
+ }
439
+
440
+ return (
441
+ < Table data = { data } tree = { tree } >
442
+ { ( tableList ) => (
443
+ < >
444
+ < Header >
445
+ < HeaderRow >
446
+ < HeaderCell > Task</ HeaderCell >
447
+ < HeaderCell > Deadline</ HeaderCell >
448
+ < HeaderCell > Type</ HeaderCell >
449
+ < HeaderCell > Complete</ HeaderCell >
450
+ < HeaderCell > Tasks</ HeaderCell >
451
+ </ HeaderRow >
452
+ </ Header >
453
+
454
+ < Body >
455
+ { tableList . map ( ( item ) => (
456
+ < Row key = { item . id } item = { item } >
457
+ < CellTree item = { item } > { item . name } </ CellTree >
458
+ < Cell >
459
+ { item . deadline . toLocaleDateString ( 'en-US' , {
460
+ year : 'numeric' ,
461
+ month : '2-digit' ,
462
+ day : '2-digit' ,
463
+ } ) }
464
+ </ Cell >
465
+ < Cell > { item . type } </ Cell >
466
+ < Cell > { item . isComplete . toString ( ) } </ Cell >
467
+ < Cell > { item . nodes ?. length } </ Cell >
468
+ </ Row >
469
+ ) ) }
470
+ </ Body >
471
+ </ >
472
+ ) }
473
+ </ Table >
474
+ ) ;
475
+ } )
398
476
. add ( 'no icon margin' , ( ) => {
399
477
const data = { nodes } ;
400
478
@@ -606,4 +684,207 @@ storiesOf('Features/Tree', module)
606
684
) }
607
685
</ Table >
608
686
) ;
687
+ } )
688
+ . add ( 'custom lines' , ( ) => {
689
+ const data = { nodes } ;
690
+
691
+ const isLastChild = ( nodes , node ) => {
692
+ const parentNode = findNodeById (
693
+ nodes ,
694
+ node . parentNode ?. id ? node . parentNode . id . toString ( ) : null ,
695
+ ) ;
696
+
697
+ if ( ! parentNode && nodes [ nodes . length - 1 ] . id === node . id ) {
698
+ return true ;
699
+ } else if ( ! parentNode && nodes [ nodes . length - 1 ] . id !== node . id ) {
700
+ return false ;
701
+ }
702
+
703
+ if ( ! parentNode ?. nodes ) return true ;
704
+ return parentNode ?. nodes [ parentNode ?. nodes . length - 1 ] . id === node . id ;
705
+ } ;
706
+
707
+ const isFirstChild = ( nodes , node ) => {
708
+ return nodes [ 0 ] . id === node . id ;
709
+ } ;
710
+
711
+ const theme = useTheme ( {
712
+ Cell : `
713
+ height: 40px;
714
+
715
+ position: relative;
716
+
717
+ &:nth-of-type(1) {
718
+ margin-left: 8px;
719
+ padding-left: 8px;
720
+ }
721
+
722
+ & .line {
723
+ background-color: #0097e0;
724
+ }
725
+
726
+ &:first-of-type div {
727
+ max-width: 100%;
728
+
729
+ height: 100%;
730
+ display: flex;
731
+ align-items: center;
732
+ }
733
+
734
+ & .line-icon-container > * {
735
+ position: absolute;
736
+ pointer-events: none;
737
+ }
738
+ ` ,
739
+ } ) ;
740
+
741
+ const tree = useTree (
742
+ data ,
743
+ {
744
+ onChange : onTreeChange ,
745
+ } ,
746
+ {
747
+ treeIcon : {
748
+ margin : '4px' ,
749
+ iconDefault : (
750
+ < LineIcon >
751
+ < InsertDriveFileOutlinedIcon fontSize = "small" />
752
+ </ LineIcon >
753
+ ) ,
754
+ iconRight : (
755
+ < LineIcon >
756
+ < FolderIcon fontSize = "small" />
757
+ </ LineIcon >
758
+ ) ,
759
+ iconDown : (
760
+ < LineIcon >
761
+ < FolderOpenIcon fontSize = "small" />
762
+ </ LineIcon >
763
+ ) ,
764
+ } ,
765
+ } ,
766
+ ) ;
767
+
768
+ function onTreeChange ( action , state ) {
769
+ console . log ( action , state ) ;
770
+ }
771
+
772
+ return (
773
+ < Table data = { data } theme = { theme } tree = { tree } >
774
+ { ( tableList ) => (
775
+ < >
776
+ < Header >
777
+ < HeaderRow >
778
+ < HeaderCell > Task</ HeaderCell >
779
+ < HeaderCell > Deadline</ HeaderCell >
780
+ < HeaderCell > Type</ HeaderCell >
781
+ < HeaderCell > Complete</ HeaderCell >
782
+ < HeaderCell > Tasks</ HeaderCell >
783
+ </ HeaderRow >
784
+ </ Header >
785
+
786
+ < Body >
787
+ { tableList . map ( ( item , index ) => (
788
+ < Row key = { item . id } item = { item } >
789
+ < CellTree item = { item } >
790
+ < Line
791
+ isFirst = { isFirstChild ( data . nodes , item ) }
792
+ isLast = { isLastChild ( data . nodes , item ) }
793
+ treeXLevel = { item . treeXLevel }
794
+ >
795
+ { item . name }
796
+ </ Line >
797
+ </ CellTree >
798
+ < Cell >
799
+ { item . deadline . toLocaleDateString ( 'en-US' , {
800
+ year : 'numeric' ,
801
+ month : '2-digit' ,
802
+ day : '2-digit' ,
803
+ } ) }
804
+ </ Cell >
805
+ < Cell > { item . type } </ Cell >
806
+ < Cell > { item . isComplete . toString ( ) } </ Cell >
807
+ < Cell > { item . nodes ?. length } </ Cell >
808
+ </ Row >
809
+ ) ) }
810
+ </ Body >
811
+ </ >
812
+ ) }
813
+ </ Table >
814
+ ) ;
609
815
} ) ;
816
+
817
+ const LineIcon = ( { children } ) => (
818
+ < div
819
+ className = "line-icon-container"
820
+ style = { {
821
+ zIndex : 2 ,
822
+ width : 24 ,
823
+ height : 24 ,
824
+ color : '#5472d3' ,
825
+ display : 'flex' ,
826
+ justifyContent : 'center' ,
827
+ alignItems : 'center' ,
828
+ position : 'relative' ,
829
+ pointerEvents : 'none' ,
830
+ } }
831
+ >
832
+ < div style = { { height : '20px' , width : '20px' , backgroundColor : '#ffffff' } } />
833
+ { children }
834
+ </ div >
835
+ ) ;
836
+
837
+ const Line = ( { isFirst, isLast, treeXLevel, children } ) => {
838
+ return (
839
+ < >
840
+ < div
841
+ style = { {
842
+ zIndex : 1 ,
843
+ display : 'inline-block' ,
844
+ width : '9px' ,
845
+ height : '40px' ,
846
+ pointerEvents : 'none' ,
847
+ } }
848
+ >
849
+ < div
850
+ className = "line"
851
+ style = { {
852
+ position : 'absolute' ,
853
+ top : isFirst ? '20px' : '0' ,
854
+ left : `${ 19 + treeXLevel * 20 } px` ,
855
+ width : '1px' ,
856
+ height : isLast ? '20px' : '40px' ,
857
+ } }
858
+ />
859
+ < div
860
+ className = "line"
861
+ style = { {
862
+ position : 'absolute' ,
863
+ top : '20px' ,
864
+ left : `${ 19 + treeXLevel * 20 } px` ,
865
+ width : '18px' ,
866
+ height : '1px' ,
867
+ } }
868
+ />
869
+ </ div >
870
+
871
+ < span
872
+ style = { {
873
+ display : 'flex' ,
874
+ alignItems : 'center' ,
875
+ minWidth : 0 ,
876
+ } }
877
+ >
878
+ < span
879
+ style = { {
880
+ whiteSpace : 'nowrap' ,
881
+ textOverflow : 'ellipsis' ,
882
+ overflow : 'hidden' ,
883
+ } }
884
+ >
885
+ { children }
886
+ </ span >
887
+ </ span >
888
+ </ >
889
+ ) ;
890
+ } ;
0 commit comments