Skip to content

Commit

Permalink
fiddling with the api to find best default behavior
Browse files Browse the repository at this point in the history
  • Loading branch information
lolcabanon committed Feb 21, 2024
1 parent 554ee58 commit 2f595ba
Show file tree
Hide file tree
Showing 2 changed files with 122 additions and 72 deletions.
145 changes: 85 additions & 60 deletions src/lib/plugins/addAlignedColumns.ts
@@ -1,6 +1,6 @@
import type { HeaderCell } from '../headerCells.js';
import type { NewTableAttributeSet, NewTablePropSet, TablePlugin } from '../types/TablePlugin.js';
import { derived, writable, type Writable } from 'svelte/store';
import { derived, get, writable, type Writable } from 'svelte/store';

export interface AddAlignedColumnsConfig {
defaultAlignment?: ColumnAlignment;
Expand All @@ -12,14 +12,15 @@ export interface AlignmentKey {
alignment: ColumnAlignment;
}

const DEFAULT_TOGGLE_ORDER: ColumnAlignment[] = [null, 'left', 'center', 'right'];
const DEFAULT_TOGGLE_ORDER: ColumnAlignment[] = ['auto', 'left', 'center', 'right'];

export type ColumnAlignment = 'left' | 'right' | 'center' | null;
export type ColumnAlignment = 'auto' | 'left' | 'right' | 'center';

export type AlignmentSpan = 'head' | 'body' | 'both';

export type AlignedColumnsState = {
alignments: Writable<Record<string, ColumnAlignment | undefined>>;
alignDefault: Writable<ColumnAlignment>;
};

export type AlignedColumnsColumnOptions = {
Expand Down Expand Up @@ -54,8 +55,7 @@ export type AlignedColumnsAttributeSet = NewTableAttributeSet<{

// eslint-disable-next-line @typescript-eslint/no-explicit-any
const isCellDisabled = (cell: HeaderCell<any>, disabledIds: string[]) => {
if (disabledIds.includes(cell.id)) return true;
return false;
return disabledIds.includes(cell.id);
};

type ColumnsAlignmentState = Record<string, ColumnAlignment | undefined>;
Expand All @@ -79,16 +79,21 @@ export const addAlignedColumns =
const initialAlignments = Object.fromEntries(
Object.entries(columnOptions).map(([columnId, { alignment, disable }]) => [
columnId,
!disable ? (alignment !== undefined ? alignment : defaultAlignment) : undefined,
!disable ? alignment ?? defaultAlignment : undefined,
]),
);

const alignDefault = writable(defaultAlignment);

const columnsAlignments = writable<ColumnsAlignmentState>(initialAlignments);

// ! `initialAlignments` follows `columnsAlignments` updates, how do i stop that ??
const ogAlignments = structuredClone(initialAlignments);

const pluginState: AlignedColumnsState = { alignments: columnsAlignments };
const pluginState: AlignedColumnsState = {
alignments: columnsAlignments,
alignDefault,
};

return {
pluginState,
Expand All @@ -98,19 +103,24 @@ export const addAlignedColumns =
const onToggle = (e: Event) => {
e.stopPropagation();

const findNext = (currentAlignment: ColumnAlignment) => {
let currentIndex = toggleOrder.findIndex(
const findNext = (currentAlignment: ColumnAlignment | undefined) => {
const currentIndex = toggleOrder.findIndex(
(alignment) => alignment === currentAlignment,
);
if (currentIndex === toggleOrder.length - 1) currentIndex = -1;
return toggleOrder[currentIndex + 1];

if (currentIndex < toggleOrder.length - 1) return toggleOrder[currentIndex + 1];

const initialAlignment = columnOptions[cell.id]?.alignment ?? get(alignDefault);
return initialAlignment && toggleOrder.includes(initialAlignment)
? toggleOrder[0]
: initialAlignment;
};

columnsAlignments.update((ca) => {
const currentAlignment = ca[cell.id];
if (currentAlignment !== undefined) {
ca[cell.id] = findNext(currentAlignment);
}
// if (currentAlignment !== undefined) {
ca[cell.id] = findNext(currentAlignment);
// }

return ca;
});
Expand All @@ -127,58 +137,73 @@ export const addAlignedColumns =
};

// const alignment = get(columnsAlignments)[cell.id];
const props = derived(columnsAlignments, ($columnsAlignments) => {
const toggle = (node: Element) => {
node.addEventListener('click', onToggle);
return {
destroy() {
node.removeEventListener('click', onToggle);
},
const props = derived(
[columnsAlignments, alignDefault],
([$columnsAlignments, $alignDefault]) => {
const toggle = (node: Element) => {
node.addEventListener('click', onToggle);
return {
destroy() {
node.removeEventListener('click', onToggle);
},
};
};
};
const clear = (node: Element) => {
node.addEventListener('click', onClear);
return {
destroy() {
node.removeEventListener('click', onClear);
},
const clear = (node: Element) => {
node.addEventListener('click', onClear);
return {
destroy() {
node.removeEventListener('click', onClear);
},
};
};
};
const disabled = isCellDisabled(cell, disabledAlignIds);

return {
alignment: $columnsAlignments[cell.id],
toggle,
clear,
disabled,
};
});
const disabled = isCellDisabled(cell, disabledAlignIds);

const attrs = derived(columnsAlignments, ($columnsAlignment) => {
const alignment = $columnsAlignment[cell.id];

return columnOptions[cell.id]?.alignHead && alignment
? {
style: {
'text-align': alignment,
},
}
: {};
});
return {
alignment: columnOptions[cell.id]?.disable
? undefined
: $columnsAlignments[cell.id] ?? $alignDefault,
toggle,
clear,
disabled,
};
},
);

const attrs = derived(
[columnsAlignments, alignDefault],
([$columnsAlignments, $alignDefault]) => {
const alignment = columnOptions[cell.id]?.disable
? undefined
: $columnsAlignments[cell.id] ?? $alignDefault;

return columnOptions[cell.id]?.alignHead && alignment
? {
style: {
'text-align': alignment,
},
}
: {};
},
);
return { props, attrs };
},
'tbody.tr.td': (cell) => {
const attrs = derived(columnsAlignments, ($columnsAlignment) => {
const alignment = $columnsAlignment[cell.id];

return alignment
? {
style: {
'text-align': alignment,
},
}
: {};
});
const attrs = derived(
[columnsAlignments, alignDefault],
([$columnsAlignments, $alignDefault]) => {
const alignment = columnOptions[cell.id]?.disable
? undefined
: $columnsAlignments[cell.id] ?? $alignDefault;

return alignment
? {
style: {
'text-align': alignment,
},
}
: {};
},
);
return { attrs };
},
},
Expand Down
49 changes: 37 additions & 12 deletions src/routes/+page.svelte
Expand Up @@ -19,6 +19,7 @@
numberRangeFilter,
textPrefixFilter,
addAlignedColumns,
type ColumnAlignment,
} from '../lib/plugins/index.js';
import { mean, sum } from '../lib/utils/math.js';
import { getShuffled } from './_getShuffled.js';
Expand All @@ -37,15 +38,12 @@
let serverSide = false;
let defaultAlignment: ColumnAlignment | undefined;
const table = createTable(data, {
align: addAlignedColumns({
defaultAlignment: 'center',
// initialAlignments: [
// { id: 'age', alignment: 'center' },
// { id: 'visits', alignment: 'center' },
// ],
toggleOrder: [null, 'left', 'center', 'right'],
span: 'body',
defaultAlignment,
toggleOrder: ['auto', 'right'],
}),
subRows: addSubRows({
children: 'children',
Expand Down Expand Up @@ -209,6 +207,7 @@
plugins: {
align: {
alignment: 'right',
// disable: true,
},
group: {
getAggregateValue: (values) => mean(values),
Expand Down Expand Up @@ -279,7 +278,7 @@
const { headerRows, pageRows, tableAttrs, tableBodyAttrs, visibleColumns, pluginStates } =
table.createViewModel(columns);
const { alignments } = pluginStates.align;
const { alignments, alignDefault } = pluginStates.align;
const { groupByIds } = pluginStates.group;
const { sortKeys } = pluginStates.sort;
Expand All @@ -300,6 +299,27 @@

<h1>svelte-headless-table</h1>

<div class="default-table-align">
Table default alignment :
<label for="rb_auto">
auto
<input type="radio" id="rb_auto" value="auto" bind:group={$alignDefault} />
</label>
<label for="rb_left">
left
<input type="radio" id="rb_left" value="left" bind:group={$alignDefault} />
</label>
<label for="rb_center">
center
<input type="radio" id="rb_center" value="center" bind:group={$alignDefault} />
</label>
<label for="rb_right">
right
<input type="radio" id="rb_right" value="right" bind:group={$alignDefault} />
</label>
(current : {$alignDefault})
</div>

<button on:click={() => ($columnIdOrder = getShuffled($columnIdOrder))}>Shuffle columns</button>
<div>
<button on:click={() => $pageIndex--} disabled={!$hasPreviousPage}>Previous page</button>
Expand Down Expand Up @@ -334,11 +354,10 @@
⬆️
{/if}
</div>
{#if !props.align.disabled}

{#if !props.align.disabled && props.align.alignment !== undefined}
<button use:props.align.toggle>
{typeof props.align.alignment === 'string'
? props.align.alignment
: JSON.stringify(props.align.alignment)}
{props.align.alignment}
</button>
<button use:props.align.clear>x</button>
{/if}
Expand Down Expand Up @@ -404,6 +423,7 @@
<pre>{JSON.stringify(
{
alignments: $alignments,
alignDefault: $alignDefault,
groupByIds: $groupByIds,
sortKeys: $sortKeys,
filterValues: $filterValues,
Expand Down Expand Up @@ -464,6 +484,11 @@ serverSide: {serverSide}</pre>
font-weight: 700;
}
.default-table-align label {
padding: 0.1em 0.2em;
border: 1px solid currentColor;
}
.group {
background: rgb(144, 191, 148);
}
Expand Down

0 comments on commit 2f595ba

Please sign in to comment.