1
+ import React from "react" ;
2
+ import { DataEditorAll as DataEditor } from "../../data-editor-all.js" ;
3
+ import {
4
+ BeautifulWrapper ,
5
+ Description ,
6
+ PropName ,
7
+ useMockDataGenerator ,
8
+ } from "../../data-editor/stories/utils.js" ;
9
+ import type { GridSelection , CompactSelectionRanges } from "../../internal/data-grid/data-grid-types.js" ;
10
+ import { CompactSelection } from "../../internal/data-grid/data-grid-types.js" ;
11
+ import { SimpleThemeWrapper } from "../../stories/story-utils.js" ;
12
+
13
+ export default {
14
+ title : "Glide-Data-Grid/DataEditor Demos" ,
15
+
16
+ decorators : [
17
+ ( Story : React . ComponentType ) => (
18
+ < SimpleThemeWrapper >
19
+ < Story />
20
+ </ SimpleThemeWrapper >
21
+ ) ,
22
+ ] ,
23
+ } ;
24
+
25
+ export const SelectionSerialization : React . VFC = ( ) => {
26
+ const { cols, getCellContent } = useMockDataGenerator ( 30 , true , true ) ;
27
+
28
+ // Load selection from localStorage on mount
29
+ const [ selection , setSelection ] = React . useState < GridSelection > ( ( ) => {
30
+ try {
31
+ const saved = localStorage . getItem ( "grid-selection-demo" ) ;
32
+ if ( saved !== null ) {
33
+ const parsed = JSON . parse ( saved ) as { columns ?: any [ ] ; rows ?: any [ ] ; current ?: any } ;
34
+ return {
35
+ columns : CompactSelection . create ( Array . isArray ( parsed . columns ) ? parsed . columns : [ ] ) ,
36
+ rows : CompactSelection . create ( Array . isArray ( parsed . rows ) ? parsed . rows : [ ] ) ,
37
+ current : parsed . current ,
38
+ } ;
39
+ }
40
+ } catch ( error ) {
41
+ console . error ( "Failed to restore selection" , error ) ;
42
+ }
43
+ return {
44
+ columns : CompactSelection . empty ( ) ,
45
+ rows : CompactSelection . empty ( ) ,
46
+ } ;
47
+ } ) ;
48
+
49
+ // Save selection to localStorage whenever it changes
50
+ React . useEffect ( ( ) => {
51
+ const toSave = {
52
+ columns : selection . columns . items ,
53
+ rows : selection . rows . items ,
54
+ current : selection . current ,
55
+ } ;
56
+ localStorage . setItem ( "grid-selection-demo" , JSON . stringify ( toSave ) ) ;
57
+ } , [ selection ] ) ;
58
+
59
+ const clearSelection = ( ) => {
60
+ setSelection ( {
61
+ columns : CompactSelection . empty ( ) ,
62
+ rows : CompactSelection . empty ( ) ,
63
+ current : undefined ,
64
+ } ) ;
65
+ } ;
66
+
67
+ const createExampleSelection = ( ) => {
68
+ setSelection ( {
69
+ columns : CompactSelection . create ( [ [ 2 , 5 ] , [ 8 , 10 ] ] ) ,
70
+ rows : CompactSelection . create ( [ [ 1 , 4 ] , [ 10 , 15 ] , [ 20 , 23 ] ] ) ,
71
+ current : {
72
+ cell : [ 3 , 5 ] ,
73
+ range : { x : 3 , y : 5 , width : 1 , height : 1 } ,
74
+ rangeStack : [ ] ,
75
+ } ,
76
+ } ) ;
77
+ } ;
78
+
79
+ return (
80
+ < BeautifulWrapper
81
+ title = "Selection Serialization"
82
+ description = {
83
+ < Description >
84
+ This example demonstrates how to serialize and persist grid selections using the new{ " " }
85
+ < PropName > CompactSelection.create()</ PropName > and < PropName > .items</ PropName > APIs.
86
+ The selection is automatically saved to localStorage and restored when the page refreshes.
87
+ < br />
88
+ < br />
89
+ < button onClick = { createExampleSelection } style = { { marginRight : 8 } } >
90
+ Create Example Selection
91
+ </ button >
92
+ < button onClick = { clearSelection } > Clear Selection</ button >
93
+ < br />
94
+ < br />
95
+ < strong > Current selection:</ strong > { selection . rows . length } rows, { selection . columns . length } columns
96
+ < br />
97
+ < strong > Persisted data:</ strong > < code > { JSON . stringify ( { columns : selection . columns . items , rows : selection . rows . items } ) } </ code >
98
+ </ Description >
99
+ } >
100
+ < DataEditor
101
+ { ...useMockDataGenerator ( 30 , false ) }
102
+ columns = { cols }
103
+ getCellContent = { getCellContent }
104
+ rows = { 10_000 }
105
+ gridSelection = { selection }
106
+ onGridSelectionChange = { setSelection }
107
+ rowMarkers = "both"
108
+ columnSelect = "multi"
109
+ />
110
+ </ BeautifulWrapper >
111
+ ) ;
112
+ } ;
113
+
114
+ export const SelectionRoundTrip : React . VFC = ( ) => {
115
+ const { cols, getCellContent } = useMockDataGenerator ( 30 , true , true ) ;
116
+
117
+ const [ originalSelection , setOriginalSelection ] = React . useState < GridSelection > ( {
118
+ columns : CompactSelection . empty ( ) ,
119
+ rows : CompactSelection . empty ( ) ,
120
+ } ) ;
121
+
122
+ const [ restoredSelection , setRestoredSelection ] = React . useState < GridSelection > ( {
123
+ columns : CompactSelection . empty ( ) ,
124
+ rows : CompactSelection . empty ( ) ,
125
+ } ) ;
126
+
127
+ const performRoundTrip = ( ) => {
128
+ // Serialize the selection
129
+ const serialized = {
130
+ columns : originalSelection . columns . items ,
131
+ rows : originalSelection . rows . items ,
132
+ current : originalSelection . current ,
133
+ } ;
134
+
135
+ // Simulate persistence (e.g., sending to server, storing in database)
136
+ const jsonString = JSON . stringify ( serialized ) ;
137
+ console . log ( "Serialized selection:" , jsonString ) ;
138
+
139
+ // Deserialize and restore
140
+ const parsed = JSON . parse ( jsonString ) as { columns : CompactSelectionRanges ; rows : CompactSelectionRanges ; current ?: any } ;
141
+ const restored = {
142
+ columns : CompactSelection . create ( parsed . columns ) ,
143
+ rows : CompactSelection . create ( parsed . rows ) ,
144
+ current : parsed . current ,
145
+ } ;
146
+
147
+ setRestoredSelection ( restored ) ;
148
+ } ;
149
+
150
+ return (
151
+ < BeautifulWrapper
152
+ title = "Selection Round Trip"
153
+ description = {
154
+ < Description >
155
+ This example demonstrates a complete round trip: create a selection, serialize it to JSON,
156
+ then deserialize it back to a < PropName > CompactSelection</ PropName > using the new APIs.
157
+ < br />
158
+ < br />
159
+ < button onClick = { performRoundTrip } > Perform Round Trip</ button >
160
+ < br />
161
+ < br />
162
+ < strong > Original equals restored:</ strong > { originalSelection . columns . equals ( restoredSelection . columns ) && originalSelection . rows . equals ( restoredSelection . rows ) ? "✅ Yes" : "❌ No" }
163
+ </ Description >
164
+ } >
165
+ < div style = { { display : "grid" , gridTemplateColumns : "1fr 1fr" , gap : 16 , height : 600 } } >
166
+ < div >
167
+ < h3 > Original Selection</ h3 >
168
+ < DataEditor
169
+ { ...useMockDataGenerator ( 30 , false ) }
170
+ columns = { cols }
171
+ getCellContent = { getCellContent }
172
+ rows = { 1000 }
173
+ gridSelection = { originalSelection }
174
+ onGridSelectionChange = { setOriginalSelection }
175
+ rowMarkers = "both"
176
+ columnSelect = "multi"
177
+ />
178
+ </ div >
179
+ < div >
180
+ < h3 > Restored Selection</ h3 >
181
+ < DataEditor
182
+ { ...useMockDataGenerator ( 30 , false ) }
183
+ columns = { cols }
184
+ getCellContent = { getCellContent }
185
+ rows = { 1000 }
186
+ gridSelection = { restoredSelection }
187
+ onGridSelectionChange = { setRestoredSelection }
188
+ rowMarkers = "both"
189
+ columnSelect = "multi"
190
+ />
191
+ </ div >
192
+ </ div >
193
+ </ BeautifulWrapper >
194
+ ) ;
195
+ } ;
0 commit comments