Skip to content

Commit 41a43c3

Browse files
committed
table generating process overhaul
1 parent 87ef6a1 commit 41a43c3

File tree

8 files changed

+391
-102
lines changed

8 files changed

+391
-102
lines changed

src/components/FilterInput.tsx

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
import { component$, $ } from "@builder.io/qwik"
2+
import type { FilterInputProps } from "../types"
3+
4+
export default component$(
5+
({ classList, heading, filterConfigs }: FilterInputProps) => (
6+
<input
7+
type="text"
8+
class={
9+
classList ||
10+
"w-full bg-white font-normal text-black text-[14px] border rounded-md p-1"
11+
}
12+
onInput$={$(
13+
(event: any) =>
14+
(filterConfigs.params = {
15+
...filterConfigs.params,
16+
[heading]: event.target?.value,
17+
})
18+
)}
19+
/>
20+
)
21+
)

src/components/SortArrows.tsx

Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
import { component$, $ } from "@builder.io/qwik"
2+
import type { QwikIntrinsicElements } from "@builder.io/qwik"
3+
import type { SortArrowsProps } from "../types"
4+
5+
const SvgArrowUp = (props: QwikIntrinsicElements["svg"], key: string) => {
6+
return (
7+
<svg
8+
xmlns="http://www.w3.org/2000/svg"
9+
width="1em"
10+
height="1em"
11+
viewBox="0 0 24 24"
12+
{...props}
13+
key={key}
14+
>
15+
<path fill="currentColor" d="m7 14l5-5l5 5H7Z"></path>
16+
</svg>
17+
)
18+
}
19+
const SvgArrowDown = (props: QwikIntrinsicElements["svg"], key: string) => {
20+
return (
21+
<svg
22+
xmlns="http://www.w3.org/2000/svg"
23+
width="1em"
24+
height="1em"
25+
viewBox="0 0 24 24"
26+
{...props}
27+
key={key}
28+
>
29+
<path fill="currentColor" d="m12 15l-5-5h10l-5 5Z"></path>
30+
</svg>
31+
)
32+
}
33+
34+
export default component$(
35+
({
36+
heading,
37+
classList,
38+
sortConfigs,
39+
highlightColor,
40+
defaultColor,
41+
}: SortArrowsProps) => (
42+
<div
43+
class={classList?.container || "flex flex-col select-none cursor-pointer"}
44+
onClick$={$(() => {
45+
if (sortConfigs.param === heading) {
46+
sortConfigs.order = ((sortConfigs.order + 1) % 3) as 0 | 1 | 2
47+
} else {
48+
sortConfigs.param = heading
49+
sortConfigs.order = 1
50+
}
51+
})}
52+
>
53+
<SvgArrowUp
54+
class={classList?.arrowUp || "mb-[-8.5px]"}
55+
width={24}
56+
height={24}
57+
color={
58+
sortConfigs.param === heading && sortConfigs.order === 1
59+
? highlightColor
60+
: defaultColor
61+
}
62+
/>
63+
<SvgArrowDown
64+
class={classList?.arrowDown || "mb-[-8.5px]"}
65+
width={24}
66+
height={24}
67+
color={
68+
sortConfigs.param === heading && sortConfigs.order === 2
69+
? highlightColor
70+
: defaultColor
71+
}
72+
/>
73+
</div>
74+
)
75+
)

src/components/Table.tsx

Lines changed: 169 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,169 @@
1+
import { useStore, useTask$, component$ } from "@builder.io/qwik"
2+
import SortArrows from "./SortArrows"
3+
import FilterInput from "./FilterInput"
4+
import { param2string, sortTable, filterTable } from "../utils"
5+
import type {
6+
TableProps,
7+
TableRecord,
8+
TableData,
9+
SortConfigs,
10+
FilterConfigs,
11+
} from "../types"
12+
13+
export default component$(
14+
({
15+
tData,
16+
tHeadings,
17+
tColumns,
18+
tRows,
19+
tableOptions,
20+
sortOptions,
21+
filterOptions,
22+
}: TableProps) => {
23+
const sortConfigs = useStore<SortConfigs>({
24+
param: "",
25+
order: 0,
26+
})
27+
const filterConfigs = useStore<FilterConfigs>({
28+
params: {},
29+
})
30+
const tableData = useStore<TableData>({
31+
tData: tData,
32+
tHeadings: {
33+
headingList: Object.keys(tData[0]),
34+
customHeadings: { ...tHeadings.customHeadings },
35+
...tHeadings,
36+
},
37+
tColumns: {
38+
...tColumns,
39+
},
40+
tRows: {
41+
...tRows,
42+
},
43+
tableOptions: {
44+
...tableOptions,
45+
},
46+
sortOptions: {
47+
defaultColor: sortOptions?.defaultColor || "#aaa",
48+
highlightColor: sortOptions?.highlightColor || "#484848",
49+
...sortOptions,
50+
},
51+
filterOptions: {
52+
...filterOptions,
53+
},
54+
})
55+
56+
useTask$(async ({ track }) => {
57+
track(() => [sortConfigs.param, sortConfigs.order, filterConfigs.params])
58+
59+
const filteredData = await filterTable(
60+
tData,
61+
tableData.tHeadings.headingList,
62+
filterConfigs
63+
)
64+
65+
if (sortConfigs.order === 0) {
66+
tableData.tData = filteredData
67+
} else {
68+
tableData.tData = await sortTable(
69+
filteredData,
70+
sortConfigs.param,
71+
sortConfigs.order === 1
72+
)
73+
}
74+
})
75+
76+
return (
77+
<table class={tableData.tableOptions?.classList}>
78+
<thead>
79+
<tr>
80+
{tableData.tHeadings.headingList.map(
81+
(heading: string, index: number) => (
82+
<th
83+
key={index}
84+
class={`
85+
${tableData.tHeadings.classList}
86+
${tableData.tColumns?.classList}
87+
${tableData.tColumns?.columnClassList?.[heading]}
88+
`}
89+
>
90+
<div class="flex flex-col">
91+
<div class="flex flex-row items-center justify-between gap-[10px]">
92+
{Object.keys(
93+
tableData.tHeadings.customHeadings || []
94+
).includes(heading)
95+
? tableData.tHeadings.element$[heading](
96+
tableData.tHeadings.customHeadings?.[heading]!
97+
) || tableData.tHeadings.customHeadings?.[heading]
98+
: tableData.tHeadings.element$[heading](
99+
param2string(heading)
100+
) || param2string(heading)}
101+
{tableData.sortOptions?.params?.includes(heading) && (
102+
<SortArrows
103+
heading={heading}
104+
classList={{
105+
container: "",
106+
arrowUp: "",
107+
arrowDown: "",
108+
}}
109+
sortConfigs={sortConfigs}
110+
highlightColor={tableData.sortOptions.highlightColor}
111+
defaultColor={tableData.sortOptions.defaultColor}
112+
/>
113+
)}
114+
</div>
115+
{Object.keys(tableData.filterOptions?.params || []).length >
116+
0 && (
117+
<div class="relative min-h-[30px] flex items-center">
118+
{tableData.filterOptions?.params?.[heading] ===
119+
"search" ? (
120+
<FilterInput
121+
classList={""}
122+
heading={heading}
123+
filterConfigs={filterConfigs}
124+
/>
125+
) : tableData.filterOptions?.params?.[heading] ===
126+
"options" ? (
127+
<></>
128+
) : (
129+
<></>
130+
)}
131+
</div>
132+
)}
133+
</div>
134+
</th>
135+
)
136+
)}
137+
</tr>
138+
</thead>
139+
<tbody>
140+
{tableData.tData.map((record: TableRecord, index: number) => {
141+
return (
142+
<tr key={index}>
143+
{tableData.tHeadings.headingList.map(
144+
(param: string, index: number) => (
145+
<td
146+
key={index}
147+
class={`
148+
${tableData.tRows?.classList}
149+
${tableData.tColumns?.classList}
150+
${tableData.tColumns?.columnClassList?.[param]}
151+
`}
152+
>
153+
{tableData.tColumns?.element$?.[param]?.(record, param) ||
154+
tableData.tColumns?.customColumns?.[param]?.(
155+
record,
156+
param
157+
) ||
158+
record[param]}
159+
</td>
160+
)
161+
)}
162+
</tr>
163+
)
164+
})}
165+
</tbody>
166+
</table>
167+
)
168+
}
169+
)

src/index.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,2 @@
1-
export * from "./loaders/tableLoader"
1+
export * from "./components/Table"
22
export * from "./types"

src/loaders/tableLoader.tsx

Lines changed: 0 additions & 70 deletions
This file was deleted.

0 commit comments

Comments
 (0)