working on types....

This commit is contained in:
MinamiFunakoshiTR 2025-03-25 13:29:29 -07:00
parent bbe68f489f
commit b7fc8b6064
Failed to extract signature
3 changed files with 52 additions and 24 deletions

View file

@ -48,3 +48,10 @@ export interface ScrollerStep {
*/
foregroundProps?: object;
}
/** Datum type for data that goes into the Table component */
type TableDatum = {
[key: string]: string | number | boolean | undefined | null;
searchStr?: string;
};
export type TableData = TableDatum[];

View file

@ -1,7 +1,5 @@
<!-- @component `Table` [Read the docs.](https://reuters-graphics.github.io/graphics-components/?path=/docs/components-text-elements-table--docs) -->
<script lang="ts">
import { onMount } from 'svelte';
/** Import local helpers */
import Block from '../Block/Block.svelte';
import Pagination from './Pagination.svelte';
@ -10,9 +8,13 @@
import SearchInput from '../SearchInput/SearchInput.svelte';
import { filterArray, paginateArray, getOptions } from './utils';
// Types
import type { TableData } from '../@types/global';
interface Props {
/** Data for the table as an array of objects. */
data: object[];
data: TableData;
/** A title that runs above the table. */
title?: string;
/** A block of text that runs above the table. */
@ -184,15 +186,16 @@
console.log('currentPageData', currentPageData);
});
/** Boot it up. */
onMount(() => {
// eslint-disable-next-line @typescript-eslint/no-explicit-any
data.forEach((d: any) => {
// Compose the string we will allow users to search
d.searchStr = includedFieldsDerived
.map((field) => d[field])
.join(' ')
.toLowerCase();
/** Add the `searchStr` field to data */
let searchableData = $derived.by(() => {
return data.map((d) => {
return {
...d,
searchStr: includedFieldsDerived
.map((field) => d[field])
.join(' ')
.toLowerCase(),
};
});
});
</script>
@ -234,7 +237,9 @@
<table
class="w-full"
class:paginated
class:truncated={truncated && !showAll && data.length > truncateLength}
class:truncated={truncated &&
!showAll &&
searchableData.length > truncateLength}
>
<thead class="table--thead">
<tr>
@ -310,7 +315,7 @@
{/if}
</table>
</div>
{#if truncated && data.length > truncateLength}
{#if truncated && searchableData.length > truncateLength}
<nav
aria-label="Show all button"
class="show-all flex items-center justify-center fmt-2"
@ -319,7 +324,7 @@
{#if showAll}
Show fewer rows
{:else}
Show {data.length - truncateLength}
Show {searchableData.length - truncateLength}
more rows
{/if}
</button>

View file

@ -1,10 +1,17 @@
export function filterArray(data, searchText, filterField, filterValue) {
import type { TableData } from '../@types/global';
export function filterArray(
data: TableData,
searchText: string,
filterField: string | undefined,
filterValue: string
) {
if (searchText) {
data = data.filter((item) => {
return item.searchStr.includes(searchText.toLowerCase());
return item.searchStr?.includes(searchText.toLowerCase());
});
}
if (filterValue && filterValue) {
if (filterField && filterValue) {
data = data.filter((item) => {
return item[filterField] === filterValue;
});
@ -12,25 +19,34 @@ export function filterArray(data, searchText, filterField, filterValue) {
return data;
}
export function paginateArray(array, pageSize, pageNumber) {
export function paginateArray(
array: TableData,
pageSize: number,
pageNumber: number
) {
return array.slice((pageNumber - 1) * pageSize, pageNumber * pageSize);
}
function uniqueAttr(array, attr) {
function uniqueAttr(array: TableData, attr: string) {
return array.map((e) => e[attr]).filter(unique);
}
function unique(value, index, array) {
// rewrite this with types
function unique(value: any, index: number, array: TableData) {
return array.indexOf(value) === index;
}
export function getOptions(data, attr) {
export function getOptions(data: TableData, attr: string) {
// Get all the unique values in the provided field. Sort it.
const attrList = uniqueAttr(data, attr).sort((a, b) => a.localeCompare(b));
// @TODO - check if a and b need to be typed and sorted for non-strings
const attrList = uniqueAttr(data, attr).sort((a: any, b: any) =>
a.localeCompare(b)
);
// Tack 'All' as the front as the first option.
attrList.unshift('All');
// Convert the list into Option typed objects ready for our Select component
return attrList.map((a) => ({ text: a, value: a }));
return attrList.map((a: string) => ({ text: a, value: a }));
}