Skip to content

Commit 958d194

Browse files
committed
chore(solid): add new table examples
Add new examples: - basic-external-state - basic-external-stpore - basic-use-table - with-tanstack-query Update config.json to render new solid table examples
1 parent 9f5f16d commit 958d194

41 files changed

Lines changed: 1520 additions & 10 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

docs/config.json

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -822,9 +822,11 @@
822822
{
823823
"label": "solid",
824824
"children": [
825-
{ "to": "framework/solid/examples/basic", "label": "Basic" },
825+
{ "to": "framework/solid/examples/basic-use-table", "label": "Basic (useTable)" },
826826
{ "to": "framework/solid/examples/basic-app-table", "label": "Basic (useAppTable)" },
827827
{ "to": "framework/solid/examples/basic-table-helper", "label": "Basic with Helpers" },
828+
{ "to": "framework/solid/examples/basic-external-state", "label": "Basic (External State)" },
829+
{ "to": "framework/solid/examples/basic-external-store", "label": "Basic (External Store)" },
828830
{ "to": "framework/solid/examples/column-groups", "label": "Header Groups" }
829831
]
830832
},
@@ -1001,7 +1003,8 @@
10011003
"label": "solid",
10021004
"children": [
10031005
{ "to": "framework/solid/examples/bootstrap", "label": "Solid Bootstrap" },
1004-
{ "to": "framework/solid/examples/composable-tables", "label": "Composable Tables" }]
1006+
{ "to": "framework/solid/examples/composable-tables", "label": "Composable Tables" },
1007+
{ "to": "framework/solid/examples/with-tanstack-query", "label": "With TanStack Query" }]
10051008
},
10061009
{
10071010
"label": "vue",
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
node_modules
2+
dist
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
# Example
2+
3+
To run this example:
4+
5+
- `npm install` or `yarn`
6+
- `npm run start` or `yarn start`
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
<!doctype html>
2+
<html lang="en">
3+
<head>
4+
<meta charset="utf-8" />
5+
<meta name="viewport" content="width=device-width, initial-scale=1" />
6+
<meta name="theme-color" content="#000000" />
7+
<link rel="shortcut icon" type="image/ico" href="/src/assets/favicon.ico" />
8+
<title>Solid App</title>
9+
</head>
10+
<body>
11+
<noscript>You need to enable JavaScript to run this app.</noscript>
12+
<div id="root"></div>
13+
14+
<script src="/src/index.tsx" type="module"></script>
15+
</body>
16+
</html>
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
{
2+
"name": "tanstack-table-example-solid-basic-external-state",
3+
"version": "0.0.0",
4+
"description": "",
5+
"scripts": {
6+
"start": "vite",
7+
"dev": "vite",
8+
"build": "vite build",
9+
"serve": "vite preview",
10+
"lint": "eslint ./src"
11+
},
12+
"license": "MIT",
13+
"devDependencies": {
14+
"@faker-js/faker": "^10.2.0",
15+
"typescript": "5.9.3",
16+
"vite": "^7.3.1",
17+
"vite-plugin-solid": "^2.11.10"
18+
},
19+
"dependencies": {
20+
"@tanstack/solid-table": "^9.0.0-alpha.10",
21+
"solid-js": "^1.9.11"
22+
}
23+
}
Lines changed: 207 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,207 @@
1+
import {
2+
createColumnHelper,
3+
createPaginatedRowModel,
4+
createSortedRowModel,
5+
flexRender,
6+
rowPaginationFeature,
7+
rowSortingFeature,
8+
sortFns,
9+
tableFeatures,
10+
createTable,
11+
} from '@tanstack/solid-table'
12+
import { For, createSignal } from 'solid-js'
13+
import { makeData } from './makeData'
14+
import type { PaginationState, SortingState } from '@tanstack/solid-table'
15+
import type { Person } from './makeData'
16+
17+
const _features = tableFeatures({
18+
rowPaginationFeature,
19+
rowSortingFeature,
20+
})
21+
22+
const columnHelper = createColumnHelper<typeof _features, Person>()
23+
24+
const columns = columnHelper.columns([
25+
columnHelper.accessor('firstName', {
26+
header: 'First Name',
27+
cell: (info) => info.getValue(),
28+
}),
29+
columnHelper.accessor('lastName', {
30+
header: 'Last Name',
31+
cell: (info) => info.getValue(),
32+
}),
33+
columnHelper.accessor('age', {
34+
header: 'Age',
35+
}),
36+
columnHelper.accessor('visits', {
37+
header: 'Visits',
38+
}),
39+
columnHelper.accessor('status', {
40+
header: 'Status',
41+
}),
42+
columnHelper.accessor('progress', {
43+
header: 'Profile Progress',
44+
}),
45+
])
46+
47+
function App() {
48+
const [data] = createSignal(makeData(1000))
49+
const [sorting, setSorting] = createSignal<SortingState>([])
50+
const [pagination, setPagination] = createSignal<PaginationState>({
51+
pageIndex: 0,
52+
pageSize: 10,
53+
})
54+
55+
const table = createTable({
56+
_features,
57+
_rowModels: {
58+
sortedRowModel: createSortedRowModel(sortFns),
59+
paginatedRowModel: createPaginatedRowModel(),
60+
},
61+
columns,
62+
get data() {
63+
return data()
64+
},
65+
state: {
66+
get sorting() {
67+
return sorting()
68+
},
69+
get pagination() {
70+
return pagination()
71+
},
72+
},
73+
onSortingChange: setSorting,
74+
onPaginationChange: setPagination,
75+
})
76+
77+
return (
78+
<div class="p-2">
79+
<table>
80+
<thead>
81+
<For each={table.getHeaderGroups()}>
82+
{(headerGroup) => (
83+
<tr>
84+
<For each={headerGroup.headers}>
85+
{(header) => (
86+
<th colSpan={header.colSpan}>
87+
{header.isPlaceholder ? null : (
88+
<div
89+
class={
90+
header.column.getCanSort()
91+
? 'cursor-pointer select-none'
92+
: ''
93+
}
94+
onClick={header.column.getToggleSortingHandler()}
95+
>
96+
{flexRender(
97+
header.column.columnDef.header,
98+
header.getContext(),
99+
)}
100+
{{
101+
asc: ' 🔼',
102+
desc: ' 🔽',
103+
}[header.column.getIsSorted() as string] ?? null}
104+
</div>
105+
)}
106+
</th>
107+
)}
108+
</For>
109+
</tr>
110+
)}
111+
</For>
112+
</thead>
113+
<tbody>
114+
<For each={table.getRowModel().rows}>
115+
{(row) => (
116+
<tr>
117+
<For each={row.getAllCells()}>
118+
{(cell) => (
119+
<td>
120+
{flexRender(
121+
cell.column.columnDef.cell,
122+
cell.getContext(),
123+
)}
124+
</td>
125+
)}
126+
</For>
127+
</tr>
128+
)}
129+
</For>
130+
</tbody>
131+
</table>
132+
<div class="h-2" />
133+
<div class="flex items-center gap-2">
134+
<button
135+
class="border rounded p-1"
136+
onClick={() => table.setPageIndex(0)}
137+
disabled={!table.getCanPreviousPage()}
138+
>
139+
{'<<'}
140+
</button>
141+
<button
142+
class="border rounded p-1"
143+
onClick={() => table.previousPage()}
144+
disabled={!table.getCanPreviousPage()}
145+
>
146+
{'<'}
147+
</button>
148+
<button
149+
class="border rounded p-1"
150+
onClick={() => table.nextPage()}
151+
disabled={!table.getCanNextPage()}
152+
>
153+
{'>'}
154+
</button>
155+
<button
156+
class="border rounded p-1"
157+
onClick={() => table.setPageIndex(table.getPageCount() - 1)}
158+
disabled={!table.getCanNextPage()}
159+
>
160+
{'>>'}
161+
</button>
162+
<span class="flex items-center gap-1">
163+
<div>Page</div>
164+
<strong>
165+
{pagination().pageIndex + 1} of {table.getPageCount()}
166+
</strong>
167+
</span>
168+
<span class="flex items-center gap-1">
169+
| Go to page:
170+
<input
171+
type="number"
172+
min="1"
173+
max={table.getPageCount()}
174+
value={pagination().pageIndex + 1}
175+
onInput={(e) => {
176+
const page = e.currentTarget.value
177+
? Number(e.currentTarget.value) - 1
178+
: 0
179+
table.setPageIndex(page)
180+
}}
181+
class="border p-1 rounded w-16"
182+
/>
183+
</span>
184+
<select
185+
value={pagination().pageSize}
186+
onChange={(e) => {
187+
table.setPageSize(Number(e.currentTarget.value))
188+
}}
189+
>
190+
{[10, 20, 30, 40, 50].map((pageSize) => (
191+
<option value={pageSize}>Show {pageSize}</option>
192+
))}
193+
</select>
194+
</div>
195+
<div class="h-4" />
196+
<pre>
197+
{JSON.stringify(
198+
{ sorting: sorting(), pagination: pagination() },
199+
null,
200+
2,
201+
)}
202+
</pre>
203+
</div>
204+
)
205+
}
206+
207+
export default App
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
html {
2+
font-family: sans-serif;
3+
font-size: 14px;
4+
}
5+
6+
table {
7+
border: 1px solid lightgray;
8+
}
9+
10+
tbody {
11+
border-bottom: 1px solid lightgray;
12+
}
13+
14+
th {
15+
border-bottom: 1px solid lightgray;
16+
border-right: 1px solid lightgray;
17+
padding: 2px 4px;
18+
}
19+
20+
tfoot {
21+
color: gray;
22+
}
23+
24+
tfoot th {
25+
font-weight: normal;
26+
}
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
/* @refresh reload */
2+
import { render } from 'solid-js/web'
3+
import './index.css'
4+
import App from './App'
5+
6+
render(() => <App />, document.getElementById('root') as HTMLElement)
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
import { faker } from '@faker-js/faker'
2+
3+
export type Person = {
4+
firstName: string
5+
lastName: string
6+
age: number
7+
visits: number
8+
progress: number
9+
status: 'relationship' | 'complicated' | 'single'
10+
subRows?: Array<Person>
11+
}
12+
13+
const range = (len: number) => {
14+
const arr: Array<number> = []
15+
for (let i = 0; i < len; i++) {
16+
arr.push(i)
17+
}
18+
return arr
19+
}
20+
21+
const newPerson = (): Person => {
22+
return {
23+
firstName: faker.person.firstName(),
24+
lastName: faker.person.lastName(),
25+
age: faker.number.int(40),
26+
visits: faker.number.int(1000),
27+
progress: faker.number.int(100),
28+
status: faker.helpers.shuffle<Person['status']>([
29+
'relationship',
30+
'complicated',
31+
'single',
32+
])[0],
33+
}
34+
}
35+
36+
export function makeData(...lens: Array<number>) {
37+
const makeDataLevel = (depth = 0): Array<Person> => {
38+
const len = lens[depth]
39+
return range(len).map((): Person => {
40+
return {
41+
...newPerson(),
42+
subRows: lens[depth + 1] ? makeDataLevel(depth + 1) : undefined,
43+
}
44+
})
45+
}
46+
47+
return makeDataLevel()
48+
}
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
{
2+
"compilerOptions": {
3+
"target": "ES2020",
4+
"useDefineForClassFields": true,
5+
"module": "ESNext",
6+
"lib": ["ES2020", "DOM", "DOM.Iterable"],
7+
"skipLibCheck": true,
8+
9+
/* Bundler mode */
10+
"moduleResolution": "bundler",
11+
"allowImportingTsExtensions": true,
12+
"resolveJsonModule": true,
13+
"isolatedModules": true,
14+
"noEmit": true,
15+
"jsx": "preserve",
16+
"jsxImportSource": "solid-js",
17+
18+
/* Linting */
19+
"strict": true,
20+
"noUnusedLocals": true,
21+
"noUnusedParameters": true,
22+
"noFallthroughCasesInSwitch": true
23+
},
24+
"include": ["src"]
25+
}

0 commit comments

Comments
 (0)