1- import { statelessComponent , render , map , element , onClick , stopDirtyChecking , setupScheduler , invalidateHandler } from "ivi" ;
1+ import { connect , render , map , element , onClick , stopDirtyChecking , setupScheduler , invalidateHandler , invalidate } from "ivi" ;
22import { h1 , div , span , table , tbody , tr , td , a , button } from "ivi-html" ;
3- import { createStore } from "ivi-state" ;
3+ import { createStore , createBox } from "ivi-state" ;
44
55function random ( max ) {
66 return Math . round ( Math . random ( ) * 1000 ) % max ;
@@ -27,103 +27,99 @@ function buildData(count) {
2727}
2828
2929const STORE = createStore (
30- { data : [ ] , selected : null } ,
30+ { data : createBox ( [ ] ) , selected : 0 } ,
3131 function ( state , action ) {
32- const data = state . data ;
33- const selected = state . selected ;
32+ const { data, selected } = state ;
33+ const itemList = data . value ;
3434 switch ( action . type ) {
3535 case "delete" :
36- data . splice ( data . findIndex ( ( d ) => d . id === action . id ) , 1 ) ;
37- return { data, selected } ;
36+ itemList . splice ( itemList . findIndex ( ( d ) => d . id === action . id ) , 1 ) ;
37+ return { data : createBox ( itemList ) , selected } ;
3838 case "run" :
39- return { data : buildData ( 1000 ) , selected : null } ;
39+ return { data : createBox ( buildData ( 1000 ) ) , selected : 0 } ;
4040 case "add" :
41- return { data : state . data . concat ( buildData ( 1000 ) ) , selected } ;
41+ return { data : createBox ( itemList . concat ( buildData ( 1000 ) ) ) , selected } ;
4242 case "update" :
43- for ( let i = 0 ; i < data . length ; i += 10 ) {
44- const r = data [ i ] ;
45- data [ i ] = { id : r . id , label : r . label + " !!!" } ;
43+ for ( let i = 0 ; i < itemList . length ; i += 10 ) {
44+ const r = itemList [ i ] ;
45+ itemList [ i ] = { id : r . id , label : r . label + " !!!" } ;
4646 }
4747 return { data, selected } ;
4848 case "select" :
49- return { data, selected : data . find ( ( d ) => d . id === action . id ) } ;
49+ return { data, selected : action . id } ;
5050 case "runlots" :
51- return { data : buildData ( 10000 ) , selected : null } ;
51+ return { data : createBox ( buildData ( 10000 ) ) , selected : 0 } ;
5252 case "clear" :
53- return { data : [ ] , selected : null } ;
53+ return { data : createBox ( [ ] ) , selected : 0 } ;
5454 case "swaprows" :
55- if ( data . length > 998 ) {
56- const a = data [ 1 ] ;
57- data [ 1 ] = data [ 998 ] ;
58- data [ 998 ] = a ;
55+ if ( itemList . length > 998 ) {
56+ const a = itemList [ 1 ] ;
57+ itemList [ 1 ] = itemList [ 998 ] ;
58+ itemList [ 998 ] = a ;
5959 }
60- return { data, selected } ;
60+ return { data : createBox ( itemList ) , selected } ;
6161 }
6262 return state ;
6363 } ,
64- update ,
64+ invalidate ,
6565) ;
6666
6767const GlyphIcon = element ( span ( "" , { "aria-hidden" : "true" } ) ) ;
68+ const RemoveRowButton = element ( td ( "col-md-1" ) . c ( a ( ) . c ( GlyphIcon ( "glyphicon glyphicon-remove" ) ) ) ) ;
6869
69- const Row = statelessComponent ( ( { id, label, selected } ) => (
70- stopDirtyChecking (
71- tr ( selected ? "danger" : "" ) . c (
72- td ( "col-md-1" ) . c ( id ) ,
73- td ( "col-md-4" ) . c ( a ( ) . c ( label ) ) ,
74- td ( "col-md-1" ) . c ( a ( ) . c ( GlyphIcon ( "glyphicon glyphicon-remove delete" ) ) ) ,
70+ const Row = connect (
71+ ( _ , idx ) => {
72+ const state = STORE . state ;
73+ const item = state . data . value [ idx ] ;
74+ return state . selected === item . id ? { id : item . id , label : item . label , selected : true } : item ;
75+ } ,
76+ ( item ) => (
77+ stopDirtyChecking ( tr ( item . selected === true ? "danger" : "" ) . c (
78+ td ( "col-md-1" ) . t ( item . id ) ,
79+ td ( "col-md-4" ) . c ( a ( ) . t ( item . label ) ) ,
80+ RemoveRowButton ( ) ,
7581 td ( "col-md-6" ) ,
76- ) ,
77- )
78- ) ) ;
82+ ) )
83+ ) ,
84+ ) ;
85+
86+ const RowList = connect (
87+ ( ) => STORE . state . data ,
88+ ( { value } ) => (
89+ tbody ( ) . e ( onClick ( ( ev ) => {
90+ const target = ev . target ;
91+ STORE . dispatch ( {
92+ type : target . matches ( ".glyphicon" ) ? "delete" : "select" ,
93+ id : + target . closest ( "tr" ) . firstChild . textContent ,
94+ } ) ;
95+ } ) ) . c ( map ( value , ( { id } , i ) => Row ( i ) . k ( id ) ) )
96+ ) ,
97+ ) ;
7998
8099function Button ( text , id ) {
81100 return div ( "col-sm-6 smallpad" ) . c (
82101 button ( "btn btn-primary btn-block" , { type : "button" , id } )
83102 . e ( onClick ( ( ) => { STORE . dispatch ( { type : id } ) ; } ) )
84- . c ( text ) ,
103+ . t ( text ) ,
85104 ) ;
86105}
87106
88- const Jumbotron = statelessComponent ( ( ) => (
89- div ( "jumbotron" ) . c (
90- div ( "row" ) . c (
91- div ( "col-md-6" ) . c ( h1 ( ) . c ( "ivi" ) ) ,
92- div ( "col-md-6" ) . c (
93- div ( "row" ) . c (
94- Button ( "Create 1,000 rows" , "run" ) ,
95- Button ( "Create 10,000 rows" , "runlots" ) ,
96- Button ( "Append 1,000 rows" , "add" ) ,
97- Button ( "Update every 10th row" , "update" ) ,
98- Button ( "Clear" , "clear" ) ,
99- Button ( "Swap Rows" , "swaprows" ) ,
100- ) ,
101- ) ,
102- ) ,
103- )
104- ) ) ;
105-
106107setupScheduler ( invalidateHandler ) ;
107- const CONTAINER = document . getElementById ( "main" ) ;
108- function update ( ) {
109- const { data, selected } = STORE . state ;
110- render (
111- div ( "container" ) . c (
112- Jumbotron ( ) ,
113- table ( "table table-hover table-striped test-data" ) . c (
114- tbody ( )
115- . e ( onClick ( ( ev ) => {
116- const target = ev . target ;
117- STORE . dispatch ( {
118- type : target . matches ( ".delete" ) ? "delete" : "select" ,
119- id : + target . closest ( "tr" ) . firstChild . textContent ,
120- } ) ;
121- } ) )
122- . c ( map ( data , ( item ) => Row ( item === selected ? { id : item . id , label : item . label , selected : item === selected } : item ) . k ( item . id ) ) ) ,
123- ) ,
124- GlyphIcon ( "preloadicon glyphicon glyphicon-remove" ) ,
125- ) ,
126- CONTAINER ,
127- ) ;
128- }
129- update ( ) ;
108+ render (
109+ div ( "container" ) . c (
110+ stopDirtyChecking ( div ( "jumbotron" ) . c ( div ( "row" ) . c (
111+ div ( "col-md-6" ) . c ( h1 ( ) . t ( "ivi" ) ) ,
112+ div ( "col-md-6" ) . c ( div ( "row" ) . c (
113+ Button ( "Create 1,000 rows" , "run" ) ,
114+ Button ( "Create 10,000 rows" , "runlots" ) ,
115+ Button ( "Append 1,000 rows" , "add" ) ,
116+ Button ( "Update every 10th row" , "update" ) ,
117+ Button ( "Clear" , "clear" ) ,
118+ Button ( "Swap Rows" , "swaprows" ) ,
119+ ) ) ,
120+ ) ) ) ,
121+ table ( "table table-hover table-striped test-data" ) . c ( RowList ( ) ) ,
122+ GlyphIcon ( "preloadicon glyphicon glyphicon-remove" ) ,
123+ ) ,
124+ document . getElementById ( "main" ) ,
125+ ) ;
0 commit comments