From ab68df340f57b7dbdfb386ed67a13d26a49d97ba Mon Sep 17 00:00:00 2001 From: Chris Kruining Date: Wed, 18 Dec 2024 16:32:21 +0100 Subject: [PATCH] woop in a working state again --- app.config.ts | 4 + src/components/grid/grid.tsx | 49 +++++----- src/components/grid/index.tsx | 2 +- src/components/prompt.tsx | 7 +- src/components/table/dataset.ts | 89 ++++++++++++------- src/components/table/index.tsx | 2 +- src/components/table/table.module.css | 75 ++++++++++------ src/components/table/table.tsx | 68 ++++++++------ src/features/menu/index.tsx | 5 +- src/features/selectable/index.tsx | 4 +- src/routes/(editor).tsx | 5 +- .../(editor)/experimental/grid.module.css | 17 +++- src/routes/(editor)/experimental/grid.tsx | 57 +++++++----- src/routes/(editor)/experimental/table.tsx | 32 ++++--- src/utilities.ts | 2 +- 15 files changed, 259 insertions(+), 159 deletions(-) diff --git a/app.config.ts b/app.config.ts index 01b146e..29550a6 100644 --- a/app.config.ts +++ b/app.config.ts @@ -7,6 +7,10 @@ export default defineConfig({ html: { cspNonce: 'KAAS_IS_AWESOME', }, + // css: { + // postcss: { + // }, + // }, plugins: [ solidSvg() // VitePWA({ diff --git a/src/components/grid/grid.tsx b/src/components/grid/grid.tsx index 64aca68..26b6360 100644 --- a/src/components/grid/grid.tsx +++ b/src/components/grid/grid.tsx @@ -1,11 +1,14 @@ import { Accessor, createContext, createEffect, createMemo, createSignal, JSX, useContext } from "solid-js"; -import { createStore } from "solid-js/store"; -import { deepCopy, deepDiff, Mutation } from "~/utilities"; -import { SelectionMode, Table, Column as TableColumn, TableApi, CellEditors, CellEditor, createDataSet, DataSet, DataSetNode } from "~/components/table"; +import { Mutation } from "~/utilities"; +import { SelectionMode, Table, Column as TableColumn, TableApi, DataSet, CellRenderer } from "~/components/table"; import css from './grid.module.css'; +export interface CellEditor, K extends keyof T> { + (cell: Parameters>[0] & { mutate: (next: T[K]) => any }): JSX.Element; +} + export interface Column> extends TableColumn { - editor?: (cell: { row: number, column: keyof T, value: T[keyof T], mutate: (next: T[keyof T]) => any }) => JSX.Element; + editor?: CellEditor; } export interface GridApi> extends TableApi { @@ -16,7 +19,6 @@ export interface GridApi> extends TableApi { } interface GridContextType> { - readonly rows: Accessor[]>; readonly mutations: Accessor; readonly selection: TableApi['selection']; mutate(row: number, column: K, value: T[K]): void; @@ -29,36 +31,31 @@ const GridContext = createContext>(); const useGrid = () => useContext(GridContext)!; -type GridProps> = { class?: string, groupBy?: keyof T, columns: Column[], rows: T[], api?: (api: GridApi) => any }; +type GridProps> = { class?: string, groupBy?: keyof T, columns: Column[], rows: DataSet, api?: (api: GridApi) => any }; // type GridState> = { data: DataSet, columns: Column[], numberOfRows: number }; export function Grid>(props: GridProps) { const [table, setTable] = createSignal>(); - const data = createMemo(() => createDataSet(props.rows)); - const rows = createMemo(() => data().value()); - const mutations = createMemo(() => data().mutations()); + const rows = createMemo(() => props.rows); const columns = createMemo(() => props.columns); + const mutations = createMemo(() => rows().mutations()); const ctx: GridContextType = { - rows, mutations, selection: createMemo(() => table()?.selection() ?? []), mutate(row: number, column: K, value: T[K]) { - data().mutate(row, column, value); + rows().mutate(row, column, value); }, - remove(rows: number[]) { - // setState('rows', (r) => r.filter((_, i) => rows.includes(i) === false)); + remove(indices: number[]) { + rows().remove(indices); + table()?.clear(); }, insert(row: T, at?: number) { - if (at === undefined) { - // setState('rows', state.rows.length, row); - } else { - - } + rows().insert(row, at); }, addColumn(column: keyof T, value: T[keyof T]): void { @@ -70,10 +67,8 @@ export function Grid>(props: GridProps) { props.columns .filter(c => c.editor !== undefined) .map(c => { - const Editor: CellEditor = ({ row, column, value }) => { + const Editor: CellRenderer = ({ row, column, value }) => { const mutate = (next: T[keyof T]) => { - console.log('KAAS', { next }) - ctx.mutate(row, column, next); }; @@ -87,11 +82,9 @@ export function Grid>(props: GridProps) { return -
- { - cellEditors() - }
-
+ { + cellEditors() + }
; }; @@ -114,8 +107,8 @@ function Api>(props: { api: undefined | ((api: Gri insert(row: T, at?: number) { gridContext.insert(row, at); }, - addColumn(column: keyof T, value: T[keyof T]): void { - gridContext.addColumn(column, value); + addColumn(column: keyof T): void { + // gridContext.addColumn(column, value); }, }; }); diff --git a/src/components/grid/index.tsx b/src/components/grid/index.tsx index 44b0d44..6ce5a66 100644 --- a/src/components/grid/index.tsx +++ b/src/components/grid/index.tsx @@ -1,4 +1,4 @@ export type { DataSetRowNode, DataSetGroupNode, DataSetNode, SelectionMode, SortingFunction, SortOptions, GroupingFunction, GroupOptions } from '../table'; -export type { GridApi, Column } from './grid'; +export type { GridApi, Column, CellEditor } from './grid'; export { Grid } from './grid'; \ No newline at end of file diff --git a/src/components/prompt.tsx b/src/components/prompt.tsx index 943c738..9cf04e2 100644 --- a/src/components/prompt.tsx +++ b/src/components/prompt.tsx @@ -1,4 +1,4 @@ -import { createEffect, createSignal, createUniqueId, JSX, onMount, ParentComponent, Show } from "solid-js"; +import { createEffect, createSignal, JSX, ParentComponent, Show } from "solid-js"; import css from './prompt.module.css'; export interface PromptApi { @@ -72,4 +72,7 @@ export const Prompt: ParentComponent<{ api: (api: PromptApi) => any, title?: str ; -}; \ No newline at end of file +}; + +let idCounter = 0; +const createUniqueId = () => `prompt-${idCounter++}`; \ No newline at end of file diff --git a/src/components/table/dataset.ts b/src/components/table/dataset.ts index 056f1f7..d48dd89 100644 --- a/src/components/table/dataset.ts +++ b/src/components/table/dataset.ts @@ -1,6 +1,6 @@ -import { Accessor, createMemo } from "solid-js"; -import { createStore, NotWrappable, StoreSetter } from "solid-js/store"; -import { snapshot } from "vinxi/dist/types/runtime/storage"; +import { Accessor, createEffect, createMemo } from "solid-js"; +import { createStore, NotWrappable, StoreSetter, unwrap } from "solid-js/store"; +import { CustomPartial } from "solid-js/store/types/store.js"; import { deepCopy, deepDiff, Mutation } from "~/utilities"; @@ -17,54 +17,63 @@ export interface SortOptions> { with?: SortingFunction; } -export interface GroupingFunction { - (nodes: DataSetRowNode[]): DataSetNode[]; +export interface GroupingFunction { + (nodes: DataSetRowNode[]): DataSetNode[]; } export interface GroupOptions> { by: keyof T; - with: GroupingFunction; + with?: GroupingFunction; } interface DataSetState> { - value: DataSetRowNode[]; - snapshot: DataSetRowNode[]; + value: (T | undefined)[]; + snapshot: (T | undefined)[]; sorting?: SortOptions; grouping?: GroupOptions; } +export type Setter = + | T + | CustomPartial + | ((prevState: T) => T | CustomPartial); + export interface DataSet> { data: T[]; value: Accessor[]>; mutations: Accessor; - sort: Accessor | undefined>; + sorting: Accessor | undefined>; + grouping: Accessor | undefined>; // mutate(index: number, value: T): void; mutate(index: number, prop: K, value: T[K]): void; + remove(indices: number[]): void; + insert(item: T, at?: number): void; - setSorting(options: SortOptions | undefined): void; - setGrouping(options: GroupOptions | undefined): void; + sort(options: Setter | undefined>): DataSet; + group(options: Setter | undefined>): DataSet; } const defaultComparer = (a: T, b: T) => a < b ? -1 : a > b ? 1 : 0; -function defaultGroupingFunction(groupBy: keyof T): GroupingFunction { - return (nodes: DataSetRowNode[]): DataSetNode[] => Object.entries(Object.groupBy(nodes, r => r.value[groupBy] as PropertyKey)) - .map(([key, nodes]) => ({ kind: 'group', key, groupedBy: groupBy, nodes: nodes! } as DataSetGroupNode)); +function defaultGroupingFunction(groupBy: keyof T): GroupingFunction { + return (nodes: DataSetRowNode[]): DataSetNode[] => Object.entries(Object.groupBy(nodes, r => r.value[groupBy] as PropertyKey)) + .map(([key, nodes]) => ({ kind: 'group', key, groupedBy: groupBy, nodes: nodes! } as DataSetGroupNode)); } -export const createDataSet = >(data: T[]): DataSet => { - const nodes = data.map>((value, key) => ({ kind: 'row', key: key as keyof T, value })); - +export const createDataSet = >(data: T[], initialOptions?: { sort?: SortOptions, group?: GroupOptions }): DataSet => { + const nodes = data; const [state, setState] = createStore>({ value: deepCopy(nodes), snapshot: nodes, - sorting: undefined, - grouping: undefined, + sorting: initialOptions?.sort, + grouping: initialOptions?.group, }); const value = createMemo(() => { const sorting = state.sorting; const grouping = state.grouping; - let value = state.value as DataSetNode[]; + let value: DataSetNode[] = state.value + .map | undefined>((value, key) => value === undefined ? undefined : ({ kind: 'row', key, value })) + .filter(node => node !== undefined); if (sorting) { const comparer = sorting.with ?? defaultComparer; @@ -79,37 +88,57 @@ export const createDataSet = >(data: T[]): DataSet if (grouping) { const implementation = grouping.with ?? defaultGroupingFunction(grouping.by); - value = implementation(value as DataSetRowNode[]); + value = implementation(value as DataSetRowNode[]); } - return value; + return value as DataSetNode[]; }); const mutations = createMemo(() => { // enumerate all values to make sure the memo is recalculated on any change - Object.values(state.value).map(entry => Object.values(entry)); + Object.values(state.value).map(entry => Object.values(entry ?? {})); return deepDiff(state.snapshot, state.value).toArray(); }); - const sort = createMemo(() => state.sorting); - return { + const sorting = createMemo(() => state.sorting); + const grouping = createMemo(() => state.grouping); + + const set: DataSet = { data, value, mutations, - sort, + sorting, + grouping, mutate(index, prop, value) { - console.log({ index, prop, value }); - // setState('value', index, 'value', prop as any, value); + setState('value', index, prop as any, value); }, - setSorting(options) { + remove(indices) { + setState('value', value => value.map((item, i) => indices.includes(i) ? undefined : item)); + }, + + insert(item, at) { + if (at === undefined) { + setState('value', state.value.length, item); + } else { + + } + }, + + sort(options) { setState('sorting', options); + + return set; }, - setGrouping(options) { + group(options) { setState('grouping', options) + + return set; }, }; + + return set }; \ No newline at end of file diff --git a/src/components/table/index.tsx b/src/components/table/index.tsx index d575f94..b4aabe5 100644 --- a/src/components/table/index.tsx +++ b/src/components/table/index.tsx @@ -1,5 +1,5 @@ -export type { Column, TableApi, CellEditor, CellEditors } from './table'; +export type { Column, TableApi, CellRenderer, CellRenderers } from './table'; export type { DataSet, DataSetGroupNode, DataSetRowNode, DataSetNode, SortingFunction, SortOptions, GroupingFunction, GroupOptions } from './dataset'; export { SelectionMode, Table } from './table'; export { createDataSet } from './dataset'; \ No newline at end of file diff --git a/src/components/table/table.module.css b/src/components/table/table.module.css index b29cccb..3cc9732 100644 --- a/src/components/table/table.module.css +++ b/src/components/table/table.module.css @@ -32,7 +32,7 @@ & :is(.cell:first-child, .checkbox + .cell) { position: sticky; inset-inline-start: 1px; - padding-inline-start: calc(var(--depth, 0) * 1em + var(--padding-m)); + padding-inline-start: calc(var(--depth, 0) * (1em + var(--padding-s)) + var(--padding-m)); z-index: 1; &::after { @@ -61,7 +61,6 @@ } & .caption { - /* grid-column: 1 / -1; */ position: sticky; inset-inline-start: 0; } @@ -148,40 +147,58 @@ font-weight: var(--text-bold); } - & details { + & .group { display: contents; background-color: inherit; - &::details-content { - grid-column: 1 / -1; - display: block grid; - grid-template-columns: subgrid; + & > td { + display: contents; background-color: inherit; - } - &:not([open])::details-content { - display: none; - } + & > table { + grid-column: 1 / -1; + grid-template-columns: subgrid; + background-color: inherit; + overflow: visible; - & > summary { - position: sticky; - inset-inline-start: 1px; - grid-column: 1; - padding: var(--padding-m); - padding-inline-start: calc(var(--depth) * 1em + var(--padding-m)); + & > .header { + border-block-end-color: transparent; - &::after { - content: ''; - position: absolute; - inset-inline-start: calc(100% - 1px); - inset-block-start: -.5px; - display: block; - inline-size: 2em; - block-size: 100%; - animation: column-scroll-shadow linear both; - animation-timeline: scroll(inline); - animation-range: 0 2em; - pointer-events: none; + & .cell { + justify-content: start; + column-gap: var(--padding-s); + + & > label { + --state: 0; + display: contents; + + & input[type="checkbox"] { + display: none; + } + + & > svg { + rotate: calc(var(--state) * -.25turn); + transition: rotate .3s ease-in-out; + inline-size: 1em; + aspect-ratio: 1; + } + + &:has(input:not(:checked)) { + --state: 1; + } + } + } + } + + & > .main { + block-size: calc-size(auto, size); + transition: block-size .3s ease-in-out; + overflow: clip; + } + + &:has(> .header input:not(:checked)) > .main { + block-size: 0; + } } } } diff --git a/src/components/table/table.tsx b/src/components/table/table.tsx index c28a1c5..0ba68bc 100644 --- a/src/components/table/table.tsx +++ b/src/components/table/table.tsx @@ -1,7 +1,7 @@ import { Accessor, createContext, createEffect, createMemo, createSignal, For, JSX, Match, Show, Switch, useContext } from "solid-js"; import { selectable, SelectionItem, SelectionProvider, useSelection } from "~/features/selectable"; import { DataSetRowNode, DataSetNode, DataSet } from './dataset'; -import { FaSolidSort, FaSolidSortDown, FaSolidSortUp } from "solid-icons/fa"; +import { FaSolidAngleDown, FaSolidSort, FaSolidSortDown, FaSolidSortUp } from "solid-icons/fa"; import css from './table.module.css'; selectable; @@ -14,8 +14,8 @@ export type Column = { readonly groupBy?: (rows: DataSetRowNode[]) => DataSetNode[], }; -export type CellEditor, K extends keyof T> = (cell: { row: number, column: K, value: T[K] }) => JSX.Element; -export type CellEditors> = { [K in keyof T]?: CellEditor }; +export type CellRenderer, K extends keyof T> = (cell: { row: number, column: K, value: T[K] }) => JSX.Element; +export type CellRenderers> = { [K in keyof T]?: CellRenderer }; export interface TableApi> { readonly selection: Accessor[]>; @@ -30,7 +30,7 @@ interface TableContextType> { readonly columns: Accessor[]>, readonly selection: Accessor[]>, readonly selectionMode: Accessor, - readonly cellRenderers: Accessor>, + readonly cellRenderers: Accessor>, } const TableContext = createContext>(); @@ -48,7 +48,7 @@ type TableProps> = { rows: DataSet, columns: Column[], selectionMode?: SelectionMode, - children?: CellEditors, + children?: CellRenderers, api?: (api: TableApi) => any, }; @@ -58,7 +58,7 @@ export function Table>(props: TableProps) { const rows = createMemo(() => props.rows); const columns = createMemo[]>(() => props.columns ?? []); const selectionMode = createMemo(() => props.selectionMode ?? SelectionMode.None); - const cellRenderers = createMemo>(() => props.children ?? {}); + const cellRenderers = createMemo>(() => props.children ?? {}); const context: TableContextType = { rows, @@ -86,11 +86,11 @@ function InnerTable>(props: InnerTableProps) { const columnCount = createMemo(() => table.columns().length); return - 0 ? props.summary : undefined}>{ + {/* 0 ? props.summary : undefined}>{ summary => { return ; } - } + } */} @@ -165,7 +165,7 @@ function Head(props: {}) { { ({ id, label, sortable }) => { - const sort = createMemo(() => table.rows().sort()); + const sort = createMemo(() => table.rows().sorting()); const by = String(id); const onPointerDown = (e: PointerEvent) => { @@ -173,27 +173,27 @@ function Head(props: {}) { return; } - // table.setSort(current => { - // if (current?.by !== by) { - // return { by, reversed: false }; - // } + table.rows().sort(current => { + if (current?.by !== by) { + return { by, reversed: false }; + } - // if (current.reversed === true) { - // return undefined; - // } + if (current.reversed === true) { + return undefined; + } - // return { by, reversed: true }; - // }); + return { by, reversed: true }; + }); }; return ; } } @@ -239,13 +239,29 @@ function Row>(props: { key: keyof T, value: T, dep }; function Group>(props: { key: keyof T, groupedBy: keyof T, nodes: DataSetNode[], depth: number }) { - return
- {String(props.key)} + const table = useTable(); - { - node => - } -
; + return
+ + ; }; declare module "solid-js" { diff --git a/src/features/menu/index.tsx b/src/features/menu/index.tsx index df8ef07..346b587 100644 --- a/src/features/menu/index.tsx +++ b/src/features/menu/index.tsx @@ -1,4 +1,4 @@ -import { Accessor, Component, For, JSX, Match, ParentComponent, Setter, Show, Switch, children, createContext, createEffect, createMemo, createSignal, createUniqueId, mergeProps, onCleanup, onMount, useContext } from "solid-js"; +import { Accessor, Component, For, JSX, Match, ParentComponent, Setter, Show, Switch, children, createContext, createEffect, createMemo, createSignal, mergeProps, useContext } from "solid-js"; import { Portal } from "solid-js/web"; import { createStore } from "solid-js/store"; import { CommandType, Command, useCommands } from "../command"; @@ -347,6 +347,9 @@ function SearchableList(props: SearchableListProps): JSX.Element { ; }; +let keyCounter = 0; +const createUniqueId = () => `key-${keyCounter++}`; + declare module "solid-js" { namespace JSX { interface HTMLAttributes { diff --git a/src/features/selectable/index.tsx b/src/features/selectable/index.tsx index aeef27e..1c02b12 100644 --- a/src/features/selectable/index.tsx +++ b/src/features/selectable/index.tsx @@ -119,9 +119,9 @@ export function SelectionProvider(props: ParentProps<{ selecti keyIdMap.set(key, id); idKeyMap.set(id, key); - } - setState('data', state.data.length, { key, value, element: new WeakRef(element) }); + setState('data', state.data.length, { key, value, element: new WeakRef(element) }); + } return keyIdMap.get(key)!; }, diff --git a/src/routes/(editor).tsx b/src/routes/(editor).tsx index b607078..5922e15 100644 --- a/src/routes/(editor).tsx +++ b/src/routes/(editor).tsx @@ -1,5 +1,5 @@ import { Link, Meta, Title } from "@solidjs/meta"; -import { Component, createMemo, createSignal, createUniqueId, ErrorBoundary, ParentProps, Show } from "solid-js"; +import { Component, createMemo, createSignal, ParentProps, Show } from "solid-js"; import { FilesProvider } from "~/features/file"; import { CommandPalette, CommandPaletteApi, Menu, MenuProvider } from "~/features/menu"; import { A, RouteDefinition, useBeforeLeave } from "@solidjs/router"; @@ -121,3 +121,6 @@ const ErrorComp: Component<{ error: Error }> = (props) => { Return to start ; }; + +let keyCounter = 0; +const createUniqueId = () => `key-${keyCounter++}`; \ No newline at end of file diff --git a/src/routes/(editor)/experimental/grid.module.css b/src/routes/(editor)/experimental/grid.module.css index 0243457..a375786 100644 --- a/src/routes/(editor)/experimental/grid.module.css +++ b/src/routes/(editor)/experimental/grid.module.css @@ -21,18 +21,27 @@ flex-flow: column; gap: var(--padding-m); } + + ol { + margin-block: 0; + } } & .content { + display: block grid; + grid: 1fr 1fr / 100%; background-color: var(--surface-500); border-top-left-radius: var(--radii-xl); - - & > header { - padding-inline-start: var(--padding-l); - } + padding: var(--padding-m); & .table { border-radius: inherit; } + + & > fieldset { + border-radius: var(--radii-l); + overflow: auto; + background-color: inherit; + } } } \ No newline at end of file diff --git a/src/routes/(editor)/experimental/grid.tsx b/src/routes/(editor)/experimental/grid.tsx index c7c882d..d39261a 100644 --- a/src/routes/(editor)/experimental/grid.tsx +++ b/src/routes/(editor)/experimental/grid.tsx @@ -1,12 +1,14 @@ import { Sidebar } from '~/components/sidebar'; -import { Column, DataSetGroupNode, DataSetNode, DataSetRowNode, Grid, GridApi } from '~/components/grid'; +import { CellEditor, Column, DataSetGroupNode, DataSetNode, DataSetRowNode, Grid, GridApi } from '~/components/grid'; import { people, Person } from './experimental.data'; import { Component, createEffect, createMemo, createSignal, For, Match, Switch } from 'solid-js'; -import { Created, debounce, Deleted, MutarionKind, Mutation, Updated } from '~/utilities'; +import { debounce, MutarionKind, Mutation } from '~/utilities'; import { createDataSet, Table } from '~/components/table'; import css from './grid.module.css'; export default function GridExperiment() { + const editor: CellEditor = ({ value, mutate }) => mutate(e.target.value.trim()), 300)} /> + const columns: Column[] = [ { id: 'id', @@ -24,35 +26,37 @@ export default function GridExperiment() { id: 'name', label: 'Name', sortable: true, + editor, }, { id: 'email', label: 'Email', sortable: true, - editor: ({ value, mutate }) => { - console.log('WHAAAAT????', e); - return mutate(e.target.value.trim()); - }, 100)} />, + editor, }, { id: 'address', label: 'Address', sortable: true, + editor, }, { id: 'currency', label: 'Currency', sortable: true, + editor, }, { id: 'phone', label: 'Phone', sortable: true, + editor, }, { id: 'country', label: 'Country', sortable: true, + editor, }, ]; @@ -60,46 +64,55 @@ export default function GridExperiment() { const mutations = createMemo(() => api()?.mutations() ?? []) - // createEffect(() => { - // console.log(mutations()); - // }); + const rows = createDataSet(people.slice(0, 20), { + // group: { by: 'country' }, + sort: { by: 'name', reversed: false }, + }); return
Commands - +
Selection ({api()?.selection().length}) -
{JSON.stringify(api()?.selection().map(i => i.key))}
-
- -
- Mutations ({mutations().length}) - - +
    + { + item =>
  1. {item.value().name}
  2. + }
    +
- + + +
+ Mutations ({mutations().length}) + + +
; } type M = { kind: MutarionKind, key: string, original?: any, value?: any }; const Mutations: Component<{ mutations: Mutation[] }> = (props) => { - const columns: Column[] = [{ id: 'key', label: 'Key' }, { id: 'original', label: 'original' }, { id: 'value', label: 'Value' }]; + const columns: Column[] = [{ id: 'key', label: 'Key' }, { id: 'original', label: 'Old' }, { id: 'value', label: 'New' }]; const rows = createMemo(() => createDataSet(props.mutations)); - return
{summary()}
{label} - {/* + - */} +
+ + + + + + + { + node => + } + +
+ +
+
{{ - original: ({ value }) => {value}, - value: ({ value }) => {value}, + createEffect(() => { + rows().group({ by: 'kind' }); + }); + + return
{{ + original: ({ value }) => value ?
{JSON.stringify(value, null, 2)}
: null, + value: ({ value }) => value ?
{JSON.stringify(value, null, 2)}
: null, }}
}; \ No newline at end of file diff --git a/src/routes/(editor)/experimental/table.tsx b/src/routes/(editor)/experimental/table.tsx index 4ad4016..61ae964 100644 --- a/src/routes/(editor)/experimental/table.tsx +++ b/src/routes/(editor)/experimental/table.tsx @@ -3,9 +3,8 @@ import { Column, createDataSet, DataSetGroupNode, DataSetNode, DataSetRowNode, G import { createStore } from 'solid-js/store'; import { Person, people } from './experimental.data'; import { createEffect, createMemo, For } from 'solid-js'; -import css from './table.module.css'; -import { Menu } from '~/features/menu'; import { Command, createCommand, Modifier } from '~/features/command'; +import css from './table.module.css'; export default function TableExperiment() { const columns: Column[] = [ @@ -53,20 +52,31 @@ export default function TableExperiment() { }, ]; - const [store, setStore] = createStore<{ selectionMode: SelectionMode, group?: GroupOptions, sort?: SortOptions }>({ + const [store, setStore] = createStore<{ selectionMode: SelectionMode, grouping?: GroupOptions, sorting?: SortOptions }>({ selectionMode: SelectionMode.None, - group: undefined, - sort: undefined, + grouping: { by: 'country' }, + sorting: { by: 'country', reversed: false }, }); - const rows = createMemo(() => createDataSet(people)); + const rows = createMemo(() => createDataSet(people, { + group: { by: 'country' }, + sort: { by: 'country', reversed: false }, + })); createEffect(() => { - rows().setGrouping(store.group); + rows().group(store.grouping); }); createEffect(() => { - rows().setSorting(store.sort); + rows().sort(store.sorting); + }); + + createEffect(() => { + setStore('sorting', rows().sorting()); + }); + + createEffect(() => { + setStore('grouping', rows().grouping()); }); return
@@ -93,7 +103,7 @@ export default function TableExperiment() {