Compare commits

..

6 commits
v1.0.5 ... main

Author SHA1 Message Date
353881dead
Fix CSS import in demo.
All checks were successful
ci/woodpecker/push/woodpecker Pipeline was successful
2025-01-20 12:16:12 +01:00
6238d1e8b7
Version 1.1.2
All checks were successful
ci/woodpecker/tag/woodpecker Pipeline was successful
ci/woodpecker/push/woodpecker Pipeline was successful
2024-11-29 18:20:03 +01:00
47a9829d9b
Update dependencies.
All checks were successful
ci/woodpecker/push/woodpecker Pipeline was successful
2024-11-29 18:19:35 +01:00
04d28f880f
Allow to set className of a Smartable.
All checks were successful
ci/woodpecker/push/woodpecker Pipeline was successful
ci/woodpecker/tag/woodpecker Pipeline was successful
2024-09-25 19:13:57 +02:00
6b96a85554
Add a way to disable sort and filter features with properties.
All checks were successful
ci/woodpecker/push/woodpecker Pipeline was successful
ci/woodpecker/tag/woodpecker Pipeline was successful
2024-09-25 18:51:26 +02:00
d13f56b24a
Add missing key of table rows.
All checks were successful
ci/woodpecker/push/woodpecker Pipeline was successful
ci/woodpecker/tag/woodpecker Pipeline was successful
2024-09-25 15:42:34 +02:00
7 changed files with 865 additions and 730 deletions

View file

@ -90,6 +90,6 @@ export function RemoveDemoTable()
) )
}, },
}, },
}))} /> }))} disableFilter={true} disableSort={true} />
); );
} }

View file

@ -1,4 +1,4 @@
import "@kernelui/core/lib/style.css"; import "@kernelui/core/lib/index.css";
import "../src/styles/smartable.less"; import "../src/styles/smartable.less";
import React from "react"; import React from "react";

View file

@ -1,5 +1,5 @@
{ {
"version": "1.0.5", "version": "1.1.2",
"name": "@kernelui/smartable", "name": "@kernelui/smartable",
"description": "Kernel UI Smartable.", "description": "Kernel UI Smartable.",
"scripts": { "scripts": {
@ -17,22 +17,22 @@
"@kernelui:registry": "https://code.zeptotech.net/api/packages/UIKernel/npm/" "@kernelui:registry": "https://code.zeptotech.net/api/packages/UIKernel/npm/"
}, },
"devDependencies": { "devDependencies": {
"@kernelui/core": "^1.3.3", "@kernelui/core": "^1.8.2",
"@phosphor-icons/react": "^2.1.7", "@phosphor-icons/react": "^2.1.7",
"@types/node": "^22.0.0", "@types/node": "^22.0.0",
"@types/react": "^18.3.3", "@types/react": "^18.3.12",
"@types/react-dom": "^18.3.0", "@types/react-dom": "^18.3.1",
"@vitejs/plugin-react": "^4.3.0", "@vitejs/plugin-react": "^4.3.4",
"less": "^4.2.0", "less": "^4.2.0",
"react": "^18.3.1", "react": "^18.3.1",
"react-dom": "^18.3.1", "react-dom": "^18.3.1",
"react-router-dom": "^6.26.2", "react-router-dom": "^7.0.1",
"typescript": "^5.4.5", "typescript": "^5.4.5",
"vite": "^5.2.11", "vite": "^6.0.1",
"vite-plugin-dts": "^3.9.1" "vite-plugin-dts": "^4.3.0"
}, },
"peerDependencies": { "peerDependencies": {
"@kernelui/core": "^1.1.2" "@kernelui/core": "^1.8.2"
}, },
"packageManager": "yarn@4.5.0" "packageManager": "yarn@4.5.0"
} }

View file

@ -5,7 +5,7 @@ import {RowInstance, RowLoader} from "./Row";
import {useAsyncManager} from "./AsyncManager"; import {useAsyncManager} from "./AsyncManager";
import {ColumnHeading} from "./Columns/ColumnHeading"; import {ColumnHeading} from "./Columns/ColumnHeading";
import {sortRows} from "./Sort"; import {sortRows} from "./Sort";
import {AutoPaginate} from "@kernelui/core"; import {AutoPaginate, classes} from "@kernelui/core";
/** /**
* Smartable instance component properties. * Smartable instance component properties.
@ -66,10 +66,10 @@ export function PaginatedInstance<CK extends ColumnKey>(props: InstancePropertie
/** /**
* Base component for a Smartable table. * Base component for a Smartable table.
*/ */
export function Table<CK extends ColumnKey>({columns, children}: React.PropsWithChildren<InstanceProperties<CK>>) export function Table<CK extends ColumnKey>({className, columns, children}: React.PropsWithChildren<InstanceProperties<CK>>)
{ {
return ( return (
<table className={"smartable"}> <table className={classes("smartable", className)}>
<thead> <thead>
<ColumnsHeadings columns={columns} /> <ColumnsHeadings columns={columns} />
</thead> </thead>
@ -85,9 +85,12 @@ export function Table<CK extends ColumnKey>({columns, children}: React.PropsWith
*/ */
export function ColumnsHeadings<CK extends ColumnKey>({columns}: {columns: Columns<CK>}) export function ColumnsHeadings<CK extends ColumnKey>({columns}: {columns: Columns<CK>})
{ {
// Get feature disable options.
const {disableSort, disableFilter} = useTable<CK>();
return ( return (
<> <>
<tr className={"headings"}> <tr className={classes("headings", disableSort === true ? "disable-sort" : undefined)}>
{ // Showing title of each column. { // Showing title of each column.
Object.keys(columns).map((key) => ( Object.keys(columns).map((key) => (
<AutoColumnContextProvider key={key} columnKey={key}> <AutoColumnContextProvider key={key} columnKey={key}>
@ -96,17 +99,21 @@ export function ColumnsHeadings<CK extends ColumnKey>({columns}: {columns: Colum
)) ))
} }
</tr> </tr>
<tr className={"filters"}> { // Add filters if filter feature is not disabled.
{ // Add columns filters, if there are some. disableFilter !== true && (
(Object.entries(columns) as [CK, Column][]).map(([columnKey, column]) => ( <tr className={"filters"}>
column.filter && ( { // Add columns filters, if there are some.
<AutoColumnContextProvider key={columnKey as string} columnKey={columnKey}> (Object.entries(columns) as [CK, Column][]).map(([columnKey, column]) => (
<td>{column.filter.element}</td> column.filter && (
</AutoColumnContextProvider> <AutoColumnContextProvider key={columnKey as string} columnKey={columnKey}>
) <td>{column.filter.element}</td>
)) </AutoColumnContextProvider>
} )
</tr> ))
}
</tr>
)
}
</> </>
); );
} }
@ -154,7 +161,7 @@ export function TableBody<CK extends ColumnKey>({pagination}: {
sortedRows ? ( sortedRows ? (
sortedRows.map((rowData, index) => ( sortedRows.map((rowData, index) => (
// Rendering each row from its definition. // Rendering each row from its definition.
<RowInstance row={rowData} /> <RowInstance key={index} row={rowData} />
)) ))
) : ( ) : (
<RowLoader /> <RowLoader />

View file

@ -15,6 +15,11 @@ export type SmartableData<CK extends ColumnKey> = Promisable<(Promisable<RowDefi
*/ */
export interface SmartableProperties<CK extends ColumnKey> export interface SmartableProperties<CK extends ColumnKey>
{ {
/**
* Table custom class name.
*/
className?: string;
/** /**
* Table data. * Table data.
*/ */
@ -44,6 +49,16 @@ export interface SmartableProperties<CK extends ColumnKey>
*/ */
pageSize: number; pageSize: number;
}; };
/**
* Disable sort feature.
*/
disableSort?: boolean;
/**
* Disable filter feature.
*/
disableFilter?: boolean;
} }
/** /**

View file

@ -1,81 +1,89 @@
tr.headings tr.headings
{ {
th &.disable-sort
{ {
position: relative; th { pointer-events: none; }
}
cursor: pointer; &:not(.disable-sort)
{
&::before, &::after th
{ // Sorting order indicator.
transition: height 0.2s ease, background 0.2s ease, top 0.2s ease, bottom 0.2s ease;
content: "";
position: absolute;
top: 0;
bottom: 0;
display: block;
margin: auto;
box-sizing: border-box;
background: var(--background-darkest);
}
&::before
{ {
right: calc(0.33em - 1px); position: relative;
width: 2px; cursor: pointer;
height: 0;
border-radius: 2px;
}
&::after
{
right: calc(0.33em - 3px);
width: 6px; &::before, &::after
height: 6px; { // Sorting order indicator.
border-radius: 6px; transition: height 0.2s ease, background 0.2s ease, top 0.2s ease, bottom 0.2s ease;
}
&.asc, &.desc content: "";
{ position: absolute;
&::after, &::before top: 0;
{ bottom: 0;
background: var(--primary);
display: block;
margin: auto;
box-sizing: border-box;
background: var(--background-darkest);
} }
&::before &::before
{ {
height: 0.8em; right: calc(0.33em - 1px);
width: 2px;
height: 0;
border-radius: 2px;
} }
} &::after
{
right: calc(0.33em - 3px);
&.asc::after width: 6px;
{ height: 6px;
top: 0.5em; border-radius: 6px;
} }
&.desc::after
{
bottom: 0.5em;
}
.order &.asc, &.desc
{ // Sort order indicator. {
position: relative; &::after, &::before
top: 0; {
bottom: 0; background: var(--primary);
}
display: block; &::before
margin: auto 0; {
padding: 0.3em 0.3em 0; height: 0.8em;
align-items: center; }
justify-content: center; }
color: var(--foreground-lightest);
font-size: 0.7em;
float: right; &.asc::after
{
top: 0.5em;
}
&.desc::after
{
bottom: 0.5em;
}
.order
{ // Sort order indicator.
position: relative;
top: 0;
bottom: 0;
display: block;
margin: auto 0;
padding: 0.3em 0.3em 0;
align-items: center;
justify-content: center;
color: var(--foreground-lightest);
font-size: 0.7em;
float: right;
}
} }
} }
} }

1389
yarn.lock

File diff suppressed because it is too large Load diff