diff --git a/README.md b/README.md index 534dd7b..6a1401a 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # @arkejs/table -![Table](https://github.com/arkemishub/table/assets/81776297/36560ef9-a4b0-4e4c-83dd-971eaa433efb) +![Types](https://github.com/arkemishub/table/assets/81776297/36560ef9-a4b0-4e4c-83dd-971eaa433efb) [![License](https://img.shields.io/badge/license-Apache2.0-blue.svg)](https://github.com/arkemishub/arke-monorepo/blob/master/LICENSE.txt) @@ -30,7 +30,7 @@ npm i @arkejs/table The basic implementation allows you to display data without having any sort of control over pagination, filtering and more. ```jsx - + ``` --- @@ -51,11 +51,11 @@ function MyTable() { }, }); - return
+ return } ``` -As you can see by using `useTable` we don't need to define props for the `Table` component since they are returned in `tableProps`. +As you can see by using `useTable` we don't need to define props for the `Types` component since they are returned in `tableProps`. In addition, the hook provides us some ways to manage the table externally. Let's now implement a simple pagination, fully controlled by outside. @@ -71,7 +71,7 @@ function MyTable() { return ( <> -
+
- - ), - p: (props: React.HTMLAttributes) => ( -

- ), - a: (props: React.HTMLAttributes) => ( - - ), -}; - -function Mdx({ code }: { code: string }) { - const Component = useMDXComponent(code); - - return ; -} - -export default Mdx; diff --git a/apps/docs/components/MobileNavbar.tsx b/apps/docs/components/MobileNavbar.tsx deleted file mode 100644 index 6242165..0000000 --- a/apps/docs/components/MobileNavbar.tsx +++ /dev/null @@ -1,57 +0,0 @@ -"use client"; - -import Image from "next/image"; -import { Button, Drawer } from "@arkejs/ui"; -import { MenuSquareIcon } from "lucide-react"; -import { useState } from "react"; -import sidebar from "@/config/sidebar"; -import Link from "next/link"; -import { usePathname } from "next/navigation"; -import { twMerge } from "tailwind-merge"; - -function MobileNavbar() { - const [open, setOpen] = useState(false); - const pathname = usePathname(); - - return ( -

- - -
- -

arkejs/ui

-
- - setOpen(false)}> -
- {sidebar.map(({ title, href }, index) => - href ? ( - setOpen(false)} - key={index} - href={href} - className={twMerge( - "text-neutral block py-1 text-sm hover:underline", - href === pathname && "text-background-contrast" - )} - > - {title} - - ) : ( - - {title} - - ) - )} -
-
-
- ); -} - -export default MobileNavbar; diff --git a/apps/docs/components/Navbar.tsx b/apps/docs/components/Navbar.tsx deleted file mode 100644 index de58bd5..0000000 --- a/apps/docs/components/Navbar.tsx +++ /dev/null @@ -1,44 +0,0 @@ -import Image from "next/image"; -import navbarConfig from "@/config/navbar"; -import Link from "next/link"; - -function Navbar() { - return ( -
-
-
- -

arkejs/table

-
- -
- - - - - -
-
-
- ); -} - -export default Navbar; diff --git a/apps/docs/components/Pagination.tsx b/apps/docs/components/Pagination.tsx deleted file mode 100644 index 5a5288a..0000000 --- a/apps/docs/components/Pagination.tsx +++ /dev/null @@ -1,37 +0,0 @@ -"use client"; - -import { usePathname } from "next/navigation"; -import sidebar from "@/config/sidebar"; -import Link from "next/link"; -import { ChevronLeftIcon, ChevronRightIcon } from "lucide-react"; - -const getPrevNextPages = (pathname: string) => { - const index = sidebar.findIndex((item) => item.href === pathname); - - return [sidebar[index - 1], sidebar[index + 1]]; -}; - -function Pagination() { - const pathname = usePathname(); - - const [prevPage, nextPage] = getPrevNextPages(pathname); - - return ( -
- {prevPage?.href && ( - - - {prevPage.title} - - )} - {nextPage?.href && ( - - {nextPage.title} - - - )} -
- ); -} - -export default Pagination; diff --git a/apps/docs/components/Preview.tsx b/apps/docs/components/Preview.tsx deleted file mode 100644 index 609e343..0000000 --- a/apps/docs/components/Preview.tsx +++ /dev/null @@ -1,40 +0,0 @@ -"use client"; - -import React, { PropsWithChildren } from "react"; -import { Tabs } from "@arkejs/ui"; -import examples from "@/config/examples"; -import { notFound } from "next/navigation"; - -function Preview({ - id, - children, -}: PropsWithChildren<{ - id: string; -}>) { - const Component = examples.find((item) => item.id === id)?.component; - - if (!Component) { - return notFound(); - } - - return ( - <> - - Preview - Code - -
- -
-
- -
- {children} -
-
-
- - ); -} - -export default Preview; diff --git a/apps/docs/components/Sidebar.tsx b/apps/docs/components/Sidebar.tsx deleted file mode 100644 index aa94433..0000000 --- a/apps/docs/components/Sidebar.tsx +++ /dev/null @@ -1,41 +0,0 @@ -"use client"; - -import sidebar from "@/config/sidebar"; -import Link from "next/link"; -import { usePathname } from "next/navigation"; -import { twMerge } from "tailwind-merge"; - -function Sidebar() { - const pathname = usePathname(); - return ( - - ); -} - -export default Sidebar; diff --git a/apps/docs/components/TableOfContents.tsx b/apps/docs/components/TableOfContents.tsx deleted file mode 100644 index ddfdc80..0000000 --- a/apps/docs/components/TableOfContents.tsx +++ /dev/null @@ -1,25 +0,0 @@ -function TableOfContents({ - headings, -}: { - headings: Array<{ content: string; href: string }>; -}) { - return ( -
-

Table of Contents

- -
- ); -} - -export default TableOfContents; diff --git a/apps/docs/config/examples.ts b/apps/docs/config/examples.ts deleted file mode 100644 index 6182ad2..0000000 --- a/apps/docs/config/examples.ts +++ /dev/null @@ -1,55 +0,0 @@ -import Basic from "@/examples/basic"; -import Pagination from "@/examples/pagination"; -import CustomPagination from "@/examples/custom-pagination"; -import DefaultSort from "@/examples/sort"; -import CustomSort from "@/examples/custom-sort"; -import ColumnHiding from "@/examples/column-hiding"; -import Filtering from "@/examples/filtering"; -import Expandable from "@/examples/expandable"; -import TableConfigProvider from "@/examples/table-config-provider"; -import ExpandableState from "@/examples/expandable-state"; - -const examples = [ - { - id: "basic", - component: Basic, - }, - { - id: "pagination", - component: Pagination, - }, - { - id: "custom-pagination", - component: CustomPagination, - }, - { - id: "sort", - component: DefaultSort, - }, - { - id: "custom-sort", - component: CustomSort, - }, - { - id: "column-hiding", - component: ColumnHiding, - }, - { - id: "filtering", - component: Filtering, - }, - { - id: "expandable", - component: Expandable, - }, - { - id: "expandable-state", - component: ExpandableState, - }, - { - id: "table-config-provider", - component: TableConfigProvider, - }, -]; - -export default examples; diff --git a/apps/docs/config/navbar.ts b/apps/docs/config/navbar.ts deleted file mode 100644 index 0227872..0000000 --- a/apps/docs/config/navbar.ts +++ /dev/null @@ -1,3 +0,0 @@ -const navbarConfig = [{ title: "Documentation", href: "/docs/install" }]; - -export default navbarConfig; diff --git a/apps/docs/config/sidebar.ts b/apps/docs/config/sidebar.ts deleted file mode 100644 index a5e3522..0000000 --- a/apps/docs/config/sidebar.ts +++ /dev/null @@ -1,22 +0,0 @@ -const sidebarConfig = [ - { title: "Getting Started" }, - { title: "Install", href: "/docs/install" }, - { title: "Usage", href: "/docs/usage" }, - { title: "API Reference" }, - { title: "Table", href: "/docs/api/table" }, - { title: "TableConfigProvider", href: "/docs/api/table-config-provider" }, - { title: "Examples" }, - { title: "Basic", href: "/docs/examples/basic" }, - { title: "Column Hiding", href: "/docs/examples/column-hiding" }, - { title: "Expandable", href: "/docs/examples/expandable" }, - { title: "Filtering", href: "/docs/examples/filtering" }, - { title: "Sorting", href: "/docs/examples/sort" }, - { title: "Pagination", href: "/docs/examples/pagination" }, - { title: "" }, - { - title: "TableConfigProvider", - href: "/docs/examples/table-config-provider", - }, -]; - -export default sidebarConfig; diff --git a/apps/docs/content/docs/api/table-config-provider.mdx b/apps/docs/content/docs/api/table-config-provider.mdx deleted file mode 100644 index f0300df..0000000 --- a/apps/docs/content/docs/api/table-config-provider.mdx +++ /dev/null @@ -1,12 +0,0 @@ ---- -title: TableConfigProvider ---- - -## `components` - -```ts -components: TableComponents; -``` - -An object containing the components to be used for rendering the table. -It provides a way to map field types such `string`, `number`, `boolean` to a custom component. It also allows to define new keys for custom components. diff --git a/apps/docs/content/docs/api/table.mdx b/apps/docs/content/docs/api/table.mdx deleted file mode 100644 index 7d80543..0000000 --- a/apps/docs/content/docs/api/table.mdx +++ /dev/null @@ -1,69 +0,0 @@ ---- -title: Table ---- - -## `actions` - -```ts -actions: ActionsConfig; -``` - -A list of actions to be displayed for each of the table rows. - -## `columns` - -```ts -columns: TableColumn[]; -``` - -A list of columns to be displayed in the table. - -## `components` - -```ts -components: TableComponents; -``` - -An object containing the components to be used for rendering the table. -It provides a way to map type such `string`, `number`, `boolean` to a custom component and also allows to define new keys for custom components. -By using this property, you can override the default components used by the table defined by `TableConfigProvider`. - -## `data` - -```ts -data: any[]; -``` - -The data to be displayed in the table. - -## `expandedRows` - -```ts -expandedRows: TableExpandedState; -``` - -The state of the expanded rows. - -## `noResult` - -```ts -noResult: ReactNode; -``` - -The content to be displayed when there is no data to be displayed. - -## `onExpandRow` - -```ts -onExpandRow?: (index: number) => void; -``` - -A function to be called when a row is expanded. - -## `renderHeader` - -```ts -renderHeader?: (column: TableColumn) => ReactNode; -``` - -A function to render the header of the table. diff --git a/apps/docs/content/docs/examples/basic.mdx b/apps/docs/content/docs/examples/basic.mdx deleted file mode 100644 index aa1d7a2..0000000 --- a/apps/docs/content/docs/examples/basic.mdx +++ /dev/null @@ -1,6 +0,0 @@ ---- -title: Basic Example -toc: false ---- - - diff --git a/apps/docs/content/docs/examples/column-hiding.mdx b/apps/docs/content/docs/examples/column-hiding.mdx deleted file mode 100644 index 56a59e1..0000000 --- a/apps/docs/content/docs/examples/column-hiding.mdx +++ /dev/null @@ -1,6 +0,0 @@ ---- -title: Custom pagination -toc: false ---- - - diff --git a/apps/docs/content/docs/examples/expandable.mdx b/apps/docs/content/docs/examples/expandable.mdx deleted file mode 100644 index ba0792b..0000000 --- a/apps/docs/content/docs/examples/expandable.mdx +++ /dev/null @@ -1,41 +0,0 @@ ---- -title: Expandable ---- - -### Default - -In order to make rows expandable you need to set `expandable` property in `useTable` hook arguments. - -```tsx -const { tableProps } = useTable({ - expandable: true, - columns, -}); -``` - -In order to trigger row expansion you can use `handleExpandRow` within `render` function arguments: - -```tsx -const columns = [ - // ... other columns - { - id: "toggle", - label: "toggle", - render: (_, { handleExpandRow }) => ( - - ), - }, -]; -``` - -By combining these two features you can create expandable rows as shown in the example below. - - - -## Managing your own state - -Columns can be expanded even without using `useTable` hook. - -In that case you need to manage your own state and pass `onExpandRow` and `expandedRows` props to `Table` component. - - diff --git a/apps/docs/content/docs/examples/filtering.mdx b/apps/docs/content/docs/examples/filtering.mdx deleted file mode 100644 index 5cd0316..0000000 --- a/apps/docs/content/docs/examples/filtering.mdx +++ /dev/null @@ -1,6 +0,0 @@ ---- -title: Filtering -toc: false ---- - - diff --git a/apps/docs/content/docs/examples/pagination.mdx b/apps/docs/content/docs/examples/pagination.mdx deleted file mode 100644 index b8ba934..0000000 --- a/apps/docs/content/docs/examples/pagination.mdx +++ /dev/null @@ -1,42 +0,0 @@ ---- -title: Pagination ---- - -## Default pagination - -For enabling pagination you need to set `pagination` property in `useTable` hook arguments. - -```tsx -const { tableProps, goToPage, currentPage, pageCount } = useTable({ - //... - columns, - pagination: { - totalCount: 100, - pageSize, - }, -}); -``` - -By doing this, `tableProps` will be updated in order to display a pagination component. - - - -## Custom pagination - -Pagination component can be customized by setting `pagination` in `useTable` as follows: - -```tsx -const { tableProps, goToPage, currentPage, pageCount } = useTable({ - //... - columns, - pagination: { - totalCount: 100, - pageSize, - type: "custom", - }, -}); -``` - -This will give you the possibility of using `currentPage`, `pageCount` and `goToPage` to build your own pagination component as shown below. - - diff --git a/apps/docs/content/docs/examples/sort.mdx b/apps/docs/content/docs/examples/sort.mdx deleted file mode 100644 index 87afe6a..0000000 --- a/apps/docs/content/docs/examples/sort.mdx +++ /dev/null @@ -1,40 +0,0 @@ ---- -title: Sorting ---- - -## Default sorting - -For enabling sorting you need to set `sorting` property in `useTable` hook arguments. - -```tsx -const { sort } = useTable({ - //... - columns, - sorting: { - sortable: true, - }, -}); -``` - -Default sorting allows you to sort by any column by clicking on the column header. - - - -## Custom sorting - -Sorting can be customized by setting `sorting` in `useTable` as follows: - -```tsx -const { sort, setSort } = useTable({ - //... - columns, - sorting: { - sortable: true, - type: "custom", - }, -}); -``` - -By doing this you will have full control over sorting. You can use `setSort` to set sorting state and `sort` to get the current sorting state. - - diff --git a/apps/docs/content/docs/examples/table-config-provider.mdx b/apps/docs/content/docs/examples/table-config-provider.mdx deleted file mode 100644 index 7df69d8..0000000 --- a/apps/docs/content/docs/examples/table-config-provider.mdx +++ /dev/null @@ -1,12 +0,0 @@ ---- -title: TableConfigProvider -toc: false ---- - -`TableConfigProvider` is a component that provides a configuration for the `Table` component. - -It allows you to define your own component to be displayed for each type of column provided to the `Table` component. - -You can place it in the root component of your app in order to provide a global configuration for all the `Table` components. - - diff --git a/apps/docs/content/docs/install.mdx b/apps/docs/content/docs/install.mdx deleted file mode 100644 index 12ac7f1..0000000 --- a/apps/docs/content/docs/install.mdx +++ /dev/null @@ -1,27 +0,0 @@ ---- -title: Install ---- - -Install and configure `@arkejs/table` - -## Install with your favorite package manager - -Install `@arkejs/table` - -```shell -npm i @arkejs/table -``` - -## Using Tailwind CSS? - -If you're using Tailwind CSS remember to add this line to your `tailwind.config.cjs` - -```js title='tailwind.config.cjs' -module.exports = { - // ... - content: [ - // ... - "./node_modules/@arkejs/table/dist/**/*.{js,ts,jsx,tsx}", - ], -}; -``` diff --git a/apps/docs/content/docs/usage.mdx b/apps/docs/content/docs/usage.mdx deleted file mode 100644 index b05097e..0000000 --- a/apps/docs/content/docs/usage.mdx +++ /dev/null @@ -1,76 +0,0 @@ ---- -title: Usage ---- - -`@arkejs/table` can be used in two different ways, based on your needs. - -## Basic Usage - -The basic implementation allows you to display data without having any sort of control over pagination, filtering and more. - -```jsx -
-``` - -Please refer to `Table` Api Reference in order to have more information about the available props. - -## Advanced Usage - -Advanced use cases which includes filtering, pagination and more can be achieved by using `useTable` hook. -The `useTable` hook provides several functionalities for managing the table in a _headless_ way. - -Let's dive into this example: - -```jsx -function MyTable() { - const { tableProps, goToPage, currentPage, pageCount } = useTable({ - pagination: { - totalCount: 100, - pageSize, - }, - }); - - return
; -} -``` - -As you can see by using `useTable` we don't need to define props for the `Table` component since they are returned in `tableProps`. -In addition, the hook provides us some ways to manage the table externally. - -Let's now implement a simple pagination, fully controlled by outside. - -```jsx -function MyTable() { - const { tableProps, goToPage, currentPage, pageCount } = useTable({ - pagination: { - totalCount: 100, - pageSize, - }, - }); - - return ( - <> -
- - - - ); -} -``` - -By using `useTable` exported function we ended up with a `Table` which pagination is managed in the way that we like. -Please refer to `useTable` Api Reference for more info about the usage. diff --git a/apps/docs/contentlayer.config.ts b/apps/docs/contentlayer.config.ts deleted file mode 100644 index e70c38e..0000000 --- a/apps/docs/contentlayer.config.ts +++ /dev/null @@ -1,75 +0,0 @@ -import { defineDocumentType, makeSource } from "contentlayer/source-files"; -import rehypePrettyCode from "rehype-pretty-code"; -import { visit } from "unist-util-visit"; -import { rehypeComponentToRawCode } from "./lib/rehypeComponentToRawCode"; -import remarkGfm from "remark-gfm"; -import rehypeSlug from "rehype-slug"; -import GithubSlugger from "github-slugger"; - -const Doc = defineDocumentType(() => ({ - name: "Doc", - filePathPattern: `**/*.mdx`, - contentType: "mdx", - fields: { - title: { - type: "string", - description: "The title of the document", - required: true, - }, - toc: { - type: "boolean", - required: false, - default: true, - }, - }, - computedFields: { - path: { - type: "string", - resolve: (doc) => doc._raw.flattenedPath.split("/").slice(1).join("/"), - }, - headings: { - type: "json", - resolve: async (doc) => { - const slugger = new GithubSlugger(); - const regex = - /\n(?#{1,6})\s+(?.+)|<(?h[1-6])>(?.+)<\/\k>/g; - - return Array.from(doc.body.raw.matchAll(regex)).map(({ groups }) => { - const content = groups?.mdxContent ?? groups?.htmlContent; - return { - content, - href: content ? slugger.slug(content) : undefined, - }; - }); - }, - }, - }, -})); - -export default makeSource({ - contentDirPath: "./content", - documentTypes: [Doc], - mdx: { - remarkPlugins: [remarkGfm], - rehypePlugins: [ - rehypeSlug, - rehypeComponentToRawCode, - [rehypePrettyCode, { theme: "github-dark" }], - () => (tree) => { - visit(tree, (node) => { - if (node?.type === "element" && node?.tagName === "div") { - if (!("data-rehype-pretty-code-fragment" in node.properties)) { - return; - } - - for (const child of node.children) { - if (child.tagName === "pre") { - child.properties["raw"] = node.raw; - } - } - } - }); - }, - ], - }, -}); diff --git a/apps/docs/examples/basic.tsx b/apps/docs/examples/basic.tsx deleted file mode 100644 index 8ffff3c..0000000 --- a/apps/docs/examples/basic.tsx +++ /dev/null @@ -1,9 +0,0 @@ -import { Table } from "@arkejs/table"; -import columns from "@/examples/mocks/columns"; -import data from "@/examples/mocks/data"; - -function BasicTable() { - return
; -} - -export default BasicTable; diff --git a/apps/docs/examples/column-hiding.tsx b/apps/docs/examples/column-hiding.tsx deleted file mode 100644 index 4503b7e..0000000 --- a/apps/docs/examples/column-hiding.tsx +++ /dev/null @@ -1,41 +0,0 @@ -import columns from "@/examples/mocks/columns"; -import { Table, useTable } from "@arkejs/table"; -import data from "@/examples/mocks/data"; - -function ColumnHiding() { - const { tableProps, allColumns, toggleHideAll } = useTable({ - columns, - }); - - return ( - <> -
-
- !c.hidden)} - onClick={toggleHideAll} - type="checkbox" - id="all" - /> - -
-
- {allColumns.map(({ id, label, toggleHide, hidden }) => ( -
- - -
- ))} -
-
-
- - ); -} - -export default ColumnHiding; diff --git a/apps/docs/examples/custom-pagination.tsx b/apps/docs/examples/custom-pagination.tsx deleted file mode 100644 index 70c798d..0000000 --- a/apps/docs/examples/custom-pagination.tsx +++ /dev/null @@ -1,47 +0,0 @@ -import { Table, useTable } from "@arkejs/table"; -import data from "@/examples/mocks/data"; -import columns from "@/examples/mocks/columns"; - -const pageSize = 10; - -function CustomPagination() { - const { tableProps, goToPage, currentPage, pageCount } = useTable({ - pagination: { - totalCount: 100, - pageSize, - type: "custom", - }, - columns, - }); - - const pagedData = data.slice( - currentPage * pageSize, - (currentPage + 1) * pageSize - ); - - return ( - <> -
-
- - -
- - ); -} - -export default CustomPagination; diff --git a/apps/docs/examples/custom-sort.tsx b/apps/docs/examples/custom-sort.tsx deleted file mode 100644 index 7595889..0000000 --- a/apps/docs/examples/custom-sort.tsx +++ /dev/null @@ -1,35 +0,0 @@ -import { Table, useTable } from "@arkejs/table"; -import columns from "@/examples/mocks/columns"; -import data from "@/examples/mocks/data"; - -function CustomSort() { - const { tableProps, sort, setSort } = useTable({ - sorting: { - sortable: true, - type: "custom", - }, - columns, - }); - - return ( - <> -
- - -
-
- Selected: {JSON.stringify(sort)} -
-
- - ); -} - -export default CustomSort; diff --git a/apps/docs/examples/expandable-state.tsx b/apps/docs/examples/expandable-state.tsx deleted file mode 100644 index e6f4a4c..0000000 --- a/apps/docs/examples/expandable-state.tsx +++ /dev/null @@ -1,45 +0,0 @@ -import React, { useState } from "react"; -import { TableColumn, TableExpandedState, Table } from "@arkejs/table"; -import { default as mockColumns } from "@/examples/mocks/columns"; -import data from "@/examples/mocks/data"; - -function ExpandableState() { - const [expandedRows, setExpandedRows] = useState({}); - - const columns: TableColumn[] = [ - { - id: "toggle", - label: "toggle", - render: (_, { handleExpandRow }) => ( - - ), - }, - ...mockColumns, - ]; - - const handleExpandRow = (index: number) => { - setExpandedRows((prevState) => ({ - ...prevState, - [index]: !prevState[index], - })); - }; - - return ( -
( -
-
Expanded row
-
{JSON.stringify(rowData)}
-
- ), - }} - /> - ); -} - -export default ExpandableState; diff --git a/apps/docs/examples/expandable.tsx b/apps/docs/examples/expandable.tsx deleted file mode 100644 index 50ce924..0000000 --- a/apps/docs/examples/expandable.tsx +++ /dev/null @@ -1,38 +0,0 @@ -import { TableColumn, Table, useTable } from "@arkejs/table"; -import { default as mockColumns } from "@/examples/mocks/columns"; -import data from "@/examples/mocks/data"; - -function Expandable() { - const columns: TableColumn[] = [ - { - id: "toggle", - label: "toggle", - render: (_, { handleExpandRow }) => ( - - ), - }, - ...mockColumns, - ]; - - const { tableProps } = useTable({ - expandable: true, - columns, - }); - - return ( -
( -
-
Expanded row
-
{JSON.stringify(rowData)}
-
- ), - }} - /> - ); -} - -export default Expandable; diff --git a/apps/docs/examples/filtering.tsx b/apps/docs/examples/filtering.tsx deleted file mode 100644 index 883e047..0000000 --- a/apps/docs/examples/filtering.tsx +++ /dev/null @@ -1,55 +0,0 @@ -import { Table, useTable } from "@arkejs/table"; -import data from "@/examples/mocks/data"; -import columns from "@/examples/mocks/columns"; - -function Filtering() { - const { tableProps, filters, setFilters, allColumns } = useTable({ - columns, - }); - - return ( - <> -
- {allColumns - .filter((c) => c.availableFilterOperators?.length) - .map((c) => ( -
{ - e.preventDefault(); - // @ts-ignore - const operator = e.target?.operator?.value; - // @ts-ignore - const value = e.target?.value?.value; - if (operator && value) { - setFilters([...filters, { operator, value, key: c.id }]); - // @ts-ignore - e.target.reset(); - } - }} - className="mb-4 grid grid-cols-4 gap-4" - > - {c.label} - - - - - ))} -
-
- Selected: {JSON.stringify(filters)} -
-
- - ); -} - -export default Filtering; diff --git a/apps/docs/examples/mocks/columns.ts b/apps/docs/examples/mocks/columns.ts deleted file mode 100644 index eed1d77..0000000 --- a/apps/docs/examples/mocks/columns.ts +++ /dev/null @@ -1,22 +0,0 @@ -import { TableColumn } from "@arkejs/table"; - -const columns: TableColumn[] = [ - { label: "ID", id: "id" }, - { label: "Name", id: "first_name", type: "string" }, - { - label: "Surname", - id: "last_name", - type: "string", - render: (data: Record) => `Mr. ${data.last_name}`, - }, - { label: "Email", id: "email" }, - { - label: "Gender", - id: "gender", - hidden: true, - renderHeader: () => "Gender (M/F)", - }, - { label: "IP Address", id: "ip_address", sortable: false }, -]; - -export default columns; diff --git a/apps/docs/examples/mocks/data.ts b/apps/docs/examples/mocks/data.ts deleted file mode 100644 index d0785ca..0000000 --- a/apps/docs/examples/mocks/data.ts +++ /dev/null @@ -1,804 +0,0 @@ -const data = [ - { - id: 1, - first_name: "Danya", - last_name: "Hubber", - email: "dhubber0@yahoo.co.jp", - gender: "Male", - ip_address: "180.28.236.190", - }, - { - id: 2, - first_name: "Flin", - last_name: "Danelet", - email: "fdanelet1@youtu.be", - gender: "Male", - ip_address: "92.240.14.83", - }, - { - id: 3, - first_name: "Peterus", - last_name: "Blaxall", - email: "pblaxall2@nationalgeographic.com", - gender: "Male", - ip_address: "202.36.4.24", - }, - { - id: 4, - first_name: "Maryann", - last_name: "Birrell", - email: "mbirrell3@geocities.jp", - gender: "Female", - ip_address: "125.113.220.61", - }, - { - id: 5, - first_name: "Sascha", - last_name: "Starcks", - email: "sstarcks4@marriott.com", - gender: "Female", - ip_address: "255.232.24.24", - }, - { - id: 6, - first_name: "Andriana", - last_name: "Milazzo", - email: "amilazzo5@marketwatch.com", - gender: "Female", - ip_address: "78.0.154.18", - }, - { - id: 7, - first_name: "Mattie", - last_name: "Danby", - email: "mdanby6@squidoo.com", - gender: "Genderqueer", - ip_address: "133.7.128.164", - }, - { - id: 8, - first_name: "Mirabella", - last_name: "Beausang", - email: "mbeausang7@wikimedia.org", - gender: "Female", - ip_address: "222.11.115.94", - }, - { - id: 9, - first_name: "Guthrey", - last_name: "Casbon", - email: "gcasbon8@intel.com", - gender: "Male", - ip_address: "116.27.250.34", - }, - { - id: 10, - first_name: "Allegra", - last_name: "Remmers", - email: "aremmers9@thetimes.co.uk", - gender: "Female", - ip_address: "191.141.74.239", - }, - { - id: 11, - first_name: "Towney", - last_name: "Giffaut", - email: "tgiffauta@bloglovin.com", - gender: "Male", - ip_address: "182.45.176.210", - }, - { - id: 12, - first_name: "Lorry", - last_name: "Pooly", - email: "lpoolyb@umich.edu", - gender: "Male", - ip_address: "221.229.109.5", - }, - { - id: 13, - first_name: "Jen", - last_name: "Collecott", - email: "jcollecottc@i2i.jp", - gender: "Female", - ip_address: "159.243.146.124", - }, - { - id: 14, - first_name: "Raynell", - last_name: "Nickerson", - email: "rnickersond@amazon.com", - gender: "Female", - ip_address: "41.98.157.43", - }, - { - id: 15, - first_name: "Dickie", - last_name: "Surby", - email: "dsurbye@discuz.net", - gender: "Male", - ip_address: "104.19.201.106", - }, - { - id: 16, - first_name: "Iosep", - last_name: "Mattusevich", - email: "imattusevichf@hud.gov", - gender: "Male", - ip_address: "74.48.69.161", - }, - { - id: 17, - first_name: "Meris", - last_name: "Crayke", - email: "mcraykeg@ovh.net", - gender: "Female", - ip_address: "204.217.20.3", - }, - { - id: 18, - first_name: "Blair", - last_name: "Maplethorp", - email: "bmaplethorph@addtoany.com", - gender: "Male", - ip_address: "31.53.110.140", - }, - { - id: 19, - first_name: "Sibel", - last_name: "Dawney", - email: "sdawneyi@paginegialle.it", - gender: "Female", - ip_address: "43.35.89.117", - }, - { - id: 20, - first_name: "Shina", - last_name: "Pinnijar", - email: "spinnijarj@paginegialle.it", - gender: "Female", - ip_address: "221.35.219.55", - }, - { - id: 21, - first_name: "Enrique", - last_name: "Morilla", - email: "emorillak@answers.com", - gender: "Male", - ip_address: "48.55.107.153", - }, - { - id: 22, - first_name: "Audry", - last_name: "Luten", - email: "alutenl@google.com", - gender: "Female", - ip_address: "149.28.107.196", - }, - { - id: 23, - first_name: "Chane", - last_name: "Hannum", - email: "channumm@discuz.net", - gender: "Genderfluid", - ip_address: "248.73.142.90", - }, - { - id: 24, - first_name: "Guy", - last_name: "Schechter", - email: "gschechtern@mayoclinic.com", - gender: "Male", - ip_address: "164.202.138.173", - }, - { - id: 25, - first_name: "Werner", - last_name: "Paolicchi", - email: "wpaolicchio@uol.com.br", - gender: "Male", - ip_address: "252.152.189.33", - }, - { - id: 26, - first_name: "Raphaela", - last_name: "Pymer", - email: "rpymerp@desdev.cn", - gender: "Female", - ip_address: "1.234.80.250", - }, - { - id: 27, - first_name: "Pavia", - last_name: "Fraine", - email: "pfraineq@yolasite.com", - gender: "Female", - ip_address: "100.127.217.154", - }, - { - id: 28, - first_name: "Leonerd", - last_name: "Bleything", - email: "lbleythingr@cargocollective.com", - gender: "Male", - ip_address: "214.107.97.240", - }, - { - id: 29, - first_name: "Sasha", - last_name: "Astall", - email: "sastalls@cmu.edu", - gender: "Male", - ip_address: "56.228.211.31", - }, - { - id: 30, - first_name: "Merill", - last_name: "Chatwin", - email: "mchatwint@is.gd", - gender: "Male", - ip_address: "234.235.90.204", - }, - { - id: 31, - first_name: "Drugi", - last_name: "Derby", - email: "dderbyu@independent.co.uk", - gender: "Male", - ip_address: "59.44.129.5", - }, - { - id: 32, - first_name: "Frederic", - last_name: "Petru", - email: "fpetruv@techcrunch.com", - gender: "Male", - ip_address: "127.118.85.58", - }, - { - id: 33, - first_name: "Enrico", - last_name: "Kersaw", - email: "ekersaww@gov.uk", - gender: "Bigender", - ip_address: "236.64.147.10", - }, - { - id: 34, - first_name: "Gerik", - last_name: "Mitford", - email: "gmitfordx@stanford.edu", - gender: "Male", - ip_address: "217.234.218.98", - }, - { - id: 35, - first_name: "Ted", - last_name: "Puleston", - email: "tpulestony@bravesites.com", - gender: "Male", - ip_address: "114.87.16.95", - }, - { - id: 36, - first_name: "Ricardo", - last_name: "Carrier", - email: "rcarrierz@boston.com", - gender: "Male", - ip_address: "149.197.126.205", - }, - { - id: 37, - first_name: "Johnette", - last_name: "Beere", - email: "jbeere10@1und1.de", - gender: "Female", - ip_address: "153.158.90.183", - }, - { - id: 38, - first_name: "Aubrey", - last_name: "Hollidge", - email: "ahollidge11@skyrock.com", - gender: "Male", - ip_address: "111.110.30.104", - }, - { - id: 39, - first_name: "Vincents", - last_name: "Bullivant", - email: "vbullivant12@creativecommons.org", - gender: "Male", - ip_address: "35.177.38.170", - }, - { - id: 40, - first_name: "Ronna", - last_name: "Cheyney", - email: "rcheyney13@miitbeian.gov.cn", - gender: "Female", - ip_address: "199.195.124.165", - }, - { - id: 41, - first_name: "Kimbell", - last_name: "Stearnes", - email: "kstearnes14@com.com", - gender: "Male", - ip_address: "175.183.228.128", - }, - { - id: 42, - first_name: "Zuzana", - last_name: "Gallemore", - email: "zgallemore15@gizmodo.com", - gender: "Female", - ip_address: "105.10.28.108", - }, - { - id: 43, - first_name: "Sebastien", - last_name: "Burgoine", - email: "sburgoine16@opera.com", - gender: "Male", - ip_address: "191.85.130.219", - }, - { - id: 44, - first_name: "Arte", - last_name: "Cantillion", - email: "acantillion17@forbes.com", - gender: "Male", - ip_address: "146.226.92.3", - }, - { - id: 45, - first_name: "Noel", - last_name: "Virr", - email: "nvirr18@utexas.edu", - gender: "Female", - ip_address: "199.18.71.100", - }, - { - id: 46, - first_name: "Cleopatra", - last_name: "Jarratt", - email: "cjarratt19@macromedia.com", - gender: "Polygender", - ip_address: "198.117.4.223", - }, - { - id: 47, - first_name: "Gretchen", - last_name: "Bewly", - email: "gbewly1a@artisteer.com", - gender: "Female", - ip_address: "61.166.64.128", - }, - { - id: 48, - first_name: "Hew", - last_name: "Mogg", - email: "hmogg1b@google.es", - gender: "Male", - ip_address: "211.86.100.140", - }, - { - id: 49, - first_name: "Rania", - last_name: "Priest", - email: "rpriest1c@columbia.edu", - gender: "Female", - ip_address: "75.248.144.34", - }, - { - id: 50, - first_name: "Hedvige", - last_name: "Fernihough", - email: "hfernihough1d@blogs.com", - gender: "Female", - ip_address: "11.130.145.232", - }, - { - id: 51, - first_name: "Norrie", - last_name: "Keller", - email: "nkeller1e@prlog.org", - gender: "Male", - ip_address: "221.87.189.124", - }, - { - id: 52, - first_name: "Ximenez", - last_name: "Kempson", - email: "xkempson1f@amazonaws.com", - gender: "Male", - ip_address: "23.35.65.100", - }, - { - id: 53, - first_name: "Trever", - last_name: "Treagus", - email: "ttreagus1g@abc.net.au", - gender: "Male", - ip_address: "170.102.160.194", - }, - { - id: 54, - first_name: "Norma", - last_name: "Fairy", - email: "nfairy1h@phpbb.com", - gender: "Female", - ip_address: "208.118.192.2", - }, - { - id: 55, - first_name: "Patton", - last_name: "Gerritsma", - email: "pgerritsma1i@jimdo.com", - gender: "Male", - ip_address: "140.138.207.0", - }, - { - id: 56, - first_name: "Kakalina", - last_name: "Farbrother", - email: "kfarbrother1j@intel.com", - gender: "Female", - ip_address: "72.176.228.201", - }, - { - id: 57, - first_name: "Wilone", - last_name: "Di Batista", - email: "wdibatista1k@tmall.com", - gender: "Female", - ip_address: "79.144.23.187", - }, - { - id: 58, - first_name: "Sari", - last_name: "Ostrich", - email: "sostrich1l@admin.ch", - gender: "Polygender", - ip_address: "159.228.14.137", - }, - { - id: 59, - first_name: "Mahmud", - last_name: "Binner", - email: "mbinner1m@elpais.com", - gender: "Male", - ip_address: "48.124.81.138", - }, - { - id: 60, - first_name: "Winnah", - last_name: "Angrick", - email: "wangrick1n@google.com.hk", - gender: "Female", - ip_address: "10.158.24.179", - }, - { - id: 61, - first_name: "Adrianna", - last_name: "Baynton", - email: "abaynton1o@wunderground.com", - gender: "Female", - ip_address: "93.211.113.4", - }, - { - id: 62, - first_name: "Bride", - last_name: "Florey", - email: "bflorey1p@webs.com", - gender: "Female", - ip_address: "174.194.215.186", - }, - { - id: 63, - first_name: "Cecile", - last_name: "De Bischop", - email: "cdebischop1q@instagram.com", - gender: "Female", - ip_address: "111.69.130.226", - }, - { - id: 64, - first_name: "Timmy", - last_name: "Bonfield", - email: "tbonfield1r@typepad.com", - gender: "Genderqueer", - ip_address: "177.154.255.110", - }, - { - id: 65, - first_name: "Elga", - last_name: "Hutt", - email: "ehutt1s@ucla.edu", - gender: "Female", - ip_address: "20.179.2.76", - }, - { - id: 66, - first_name: "Adrianna", - last_name: "Kerry", - email: "akerry1t@joomla.org", - gender: "Female", - ip_address: "164.105.4.37", - }, - { - id: 67, - first_name: "James", - last_name: "Gristock", - email: "jgristock1u@hostgator.com", - gender: "Male", - ip_address: "243.249.237.230", - }, - { - id: 68, - first_name: "Andriette", - last_name: "Senton", - email: "asenton1v@toplist.cz", - gender: "Female", - ip_address: "180.57.39.144", - }, - { - id: 69, - first_name: "Ted", - last_name: "England", - email: "tengland1w@istockphoto.com", - gender: "Female", - ip_address: "30.171.128.52", - }, - { - id: 70, - first_name: "Collen", - last_name: "Milmo", - email: "cmilmo1x@mozilla.com", - gender: "Bigender", - ip_address: "208.89.59.249", - }, - { - id: 71, - first_name: "Mallissa", - last_name: "Tranfield", - email: "mtranfield1y@ehow.com", - gender: "Female", - ip_address: "188.63.236.225", - }, - { - id: 72, - first_name: "Maurie", - last_name: "Ciotti", - email: "mciotti1z@feedburner.com", - gender: "Male", - ip_address: "112.247.8.135", - }, - { - id: 73, - first_name: "Rhody", - last_name: "Giocannoni", - email: "rgiocannoni20@statcounter.com", - gender: "Female", - ip_address: "192.91.148.64", - }, - { - id: 74, - first_name: "Celestyn", - last_name: "Pinilla", - email: "cpinilla21@devhub.com", - gender: "Female", - ip_address: "139.72.70.149", - }, - { - id: 75, - first_name: "Dionysus", - last_name: "Figgins", - email: "dfiggins22@usatoday.com", - gender: "Male", - ip_address: "219.68.119.137", - }, - { - id: 76, - first_name: "Helenka", - last_name: "Durnian", - email: "hdurnian23@wp.com", - gender: "Female", - ip_address: "82.52.131.138", - }, - { - id: 77, - first_name: "Pietrek", - last_name: "Vidloc", - email: "pvidloc24@samsung.com", - gender: "Male", - ip_address: "85.25.88.31", - }, - { - id: 78, - first_name: "Roderigo", - last_name: "Earlam", - email: "rearlam25@blogtalkradio.com", - gender: "Male", - ip_address: "150.28.148.70", - }, - { - id: 79, - first_name: "Sara-ann", - last_name: "Gammon", - email: "sgammon26@opensource.org", - gender: "Female", - ip_address: "190.89.129.2", - }, - { - id: 80, - first_name: "Helenelizabeth", - last_name: "Ablewhite", - email: "hablewhite27@hp.com", - gender: "Female", - ip_address: "42.146.141.162", - }, - { - id: 81, - first_name: "Natty", - last_name: "Tregea", - email: "ntregea28@unc.edu", - gender: "Male", - ip_address: "53.64.109.115", - }, - { - id: 82, - first_name: "Marji", - last_name: "Fowlds", - email: "mfowlds29@goo.gl", - gender: "Female", - ip_address: "164.208.19.138", - }, - { - id: 83, - first_name: "Nicoli", - last_name: "Mulligan", - email: "nmulligan2a@paginegialle.it", - gender: "Female", - ip_address: "79.244.75.118", - }, - { - id: 84, - first_name: "Celinda", - last_name: "Bates", - email: "cbates2b@netvibes.com", - gender: "Female", - ip_address: "163.79.46.228", - }, - { - id: 85, - first_name: "Jonathan", - last_name: "Lindner", - email: "jlindner2c@homestead.com", - gender: "Male", - ip_address: "5.249.195.3", - }, - { - id: 86, - first_name: "Kacey", - last_name: "Buxsey", - email: "kbuxsey2d@so-net.ne.jp", - gender: "Female", - ip_address: "201.209.45.45", - }, - { - id: 87, - first_name: "Ashia", - last_name: "Gaskell", - email: "agaskell2e@shareasale.com", - gender: "Female", - ip_address: "100.102.232.104", - }, - { - id: 88, - first_name: "Yankee", - last_name: "Emanueli", - email: "yemanueli2f@amazon.com", - gender: "Male", - ip_address: "102.96.102.112", - }, - { - id: 89, - first_name: "Dunn", - last_name: "Peter", - email: "dpeter2g@businesswire.com", - gender: "Male", - ip_address: "157.150.253.191", - }, - { - id: 90, - first_name: "Gabriel", - last_name: "Gealy", - email: "ggealy2h@youku.com", - gender: "Male", - ip_address: "57.128.80.110", - }, - { - id: 91, - first_name: "Neala", - last_name: "Done", - email: "ndone2i@bloglines.com", - gender: "Female", - ip_address: "249.157.117.143", - }, - { - id: 92, - first_name: "Donnell", - last_name: "Hasslocher", - email: "dhasslocher2j@com.com", - gender: "Male", - ip_address: "178.19.240.229", - }, - { - id: 93, - first_name: "Charmane", - last_name: "Stebles", - email: "cstebles2k@phpbb.com", - gender: "Female", - ip_address: "134.75.156.151", - }, - { - id: 94, - first_name: "Wait", - last_name: "Cuddehy", - email: "wcuddehy2l@free.fr", - gender: "Male", - ip_address: "109.122.137.141", - }, - { - id: 95, - first_name: "Chip", - last_name: "Harefoot", - email: "charefoot2m@taobao.com", - gender: "Male", - ip_address: "227.13.151.91", - }, - { - id: 96, - first_name: "Holly-anne", - last_name: "Dyas", - email: "hdyas2n@ehow.com", - gender: "Female", - ip_address: "15.148.10.175", - }, - { - id: 97, - first_name: "Helen", - last_name: "Whittleton", - email: "hwhittleton2o@163.com", - gender: "Female", - ip_address: "177.140.56.53", - }, - { - id: 98, - first_name: "Derick", - last_name: "Winsor", - email: "dwinsor2p@nifty.com", - gender: "Non-binary", - ip_address: "1.205.95.229", - }, - { - id: 99, - first_name: "Scarface", - last_name: "Steven", - email: "ssteven2q@goo.ne.jp", - gender: "Male", - ip_address: "201.237.117.236", - }, - { - id: 100, - first_name: "Jasper", - last_name: "Wolfarth", - email: "jwolfarth2r@thetimes.co.uk", - gender: "Male", - ip_address: "91.184.182.131", - }, -]; - -export default data; diff --git a/apps/docs/examples/pagination.tsx b/apps/docs/examples/pagination.tsx deleted file mode 100644 index 11d51d9..0000000 --- a/apps/docs/examples/pagination.tsx +++ /dev/null @@ -1,34 +0,0 @@ -import { useTable, Table } from "@arkejs/table"; -import data from "@/examples/mocks/data"; -import columns from "@/examples/mocks/columns"; - -const pageSize = 10; - -function App() { - const { tableProps, goToPage, currentPage, pageCount } = useTable({ - pagination: { - totalCount: 100, - pageSize, - }, - columns, - }); - - const pagedData = data.slice( - currentPage * pageSize, - (currentPage + 1) * pageSize - ); - - return ( - <> - -
- - ); -} - -export default App; diff --git a/apps/docs/examples/sort.tsx b/apps/docs/examples/sort.tsx deleted file mode 100644 index dc79d93..0000000 --- a/apps/docs/examples/sort.tsx +++ /dev/null @@ -1,21 +0,0 @@ -import columns from "@/examples/mocks/columns"; -import { Table, useTable } from "@arkejs/table"; -import data from "@/examples/mocks/data"; - -function DefaultSort() { - const { tableProps, sort } = useTable({ - sorting: { - sortable: true, - }, - columns, - }); - - return ( - <> -
Selected: {JSON.stringify(sort)}
-
- - ); -} - -export default DefaultSort; diff --git a/apps/docs/examples/table-config-provider.tsx b/apps/docs/examples/table-config-provider.tsx deleted file mode 100644 index 207ee40..0000000 --- a/apps/docs/examples/table-config-provider.tsx +++ /dev/null @@ -1,18 +0,0 @@ -import { Table, TableConfigProvider } from "@arkejs/table"; -import data from "@/examples/mocks/data"; -import columns from "@/examples/mocks/columns"; -import { Chip } from "@arkejs/ui"; - -function MyTableConfigProvider() { - return ( - {value}, - }} - > -
- - ); -} - -export default MyTableConfigProvider; diff --git a/apps/docs/lib/rehypeComponentToRawCode.ts b/apps/docs/lib/rehypeComponentToRawCode.ts deleted file mode 100644 index cf4e19c..0000000 --- a/apps/docs/lib/rehypeComponentToRawCode.ts +++ /dev/null @@ -1,50 +0,0 @@ -import { visit } from "unist-util-visit"; -import fs from "fs"; -import path from "path"; -import { u } from "unist-builder"; - -export function rehypeComponentToRawCode() { - return async (tree: any) => { - visit(tree, (node: any) => { - if (node.name === "Preview") { - const componentName = node.attributes?.find( - (attr: any) => attr.name === "id" - )?.value; - - if (!componentName) { - return null; - } - - const src = path.join( - process.cwd(), - "examples", - componentName + ".tsx" - ); - - const sourceCode = fs.readFileSync(src, "utf-8"); - node.children?.push( - u("element", { - tagName: "pre", - properties: { - __src__: src, - }, - children: [ - u("element", { - tagName: "code", - properties: { - className: ["language-tsx"], - }, - children: [ - { - type: "text", - value: sourceCode, - }, - ], - }), - ], - }) - ); - } - }); - }; -} diff --git a/apps/docs/next-env.d.ts b/apps/docs/next-env.d.ts deleted file mode 100644 index 4f11a03..0000000 --- a/apps/docs/next-env.d.ts +++ /dev/null @@ -1,5 +0,0 @@ -/// -/// - -// NOTE: This file should not be edited -// see https://nextjs.org/docs/basic-features/typescript for more information. diff --git a/apps/docs/next.config.js b/apps/docs/next.config.js deleted file mode 100644 index e0496c5..0000000 --- a/apps/docs/next.config.js +++ /dev/null @@ -1,9 +0,0 @@ -const { withContentlayer } = require("next-contentlayer"); - -const nextConfig = { - reactStrictMode: true, - transpilePackages: ["@arkejs/table"], - output: "standalone", -}; - -module.exports = withContentlayer(nextConfig); diff --git a/apps/docs/package.json b/apps/docs/package.json deleted file mode 100644 index d7a937e..0000000 --- a/apps/docs/package.json +++ /dev/null @@ -1,40 +0,0 @@ -{ - "name": "docs", - "version": "1.0.0", - "private": true, - "scripts": { - "dev": "next dev --port 3001", - "build": "next build", - "start": "next start", - "lint": "next lint" - }, - "dependencies": { - "@arkejs/ui": "^0.28.4", - "@arkejs/table": "workspace:table", - "contentlayer": "^0.3.3", - "date-fns": "^2.30.0", - "github-slugger": "^2.0.0", - "install": "^0.13.0", - "lucide-react": "^0.258.0", - "next": "^13.4.2", - "next-contentlayer": "^0.3.3", - "react": "^18.2.0", - "react-dom": "^18.2.0", - "rehype-pretty-code": "^0.9.11", - "rehype-slug": "^5.1.0", - "remark-gfm": "^3.0.1", - "shiki": "^0.14.2", - "tailwind-merge": "^1.9.0", - "unist-builder": "^3.0.1", - "unist-util-visit": "^4.1.2" - }, - "devDependencies": { - "@types/node": "^17.0.12", - "@types/react": "^18.0.27", - "@types/react-dom": "^18.0.7", - "autoprefixer": "^10.4.13", - "postcss": "^8.4.21", - "tailwindcss": "^3.2.4", - "typescript": "^4.9.5" - } -} diff --git a/apps/docs/postcss.config.js b/apps/docs/postcss.config.js deleted file mode 100644 index 33ad091..0000000 --- a/apps/docs/postcss.config.js +++ /dev/null @@ -1,6 +0,0 @@ -module.exports = { - plugins: { - tailwindcss: {}, - autoprefixer: {}, - }, -} diff --git a/apps/docs/public/arke.svg b/apps/docs/public/arke.svg deleted file mode 100644 index fc366dd..0000000 --- a/apps/docs/public/arke.svg +++ /dev/null @@ -1,17 +0,0 @@ - - - - - - - - - - - - - - - - - diff --git a/apps/docs/public/favicon.ico b/apps/docs/public/favicon.ico deleted file mode 100644 index 333b37e..0000000 Binary files a/apps/docs/public/favicon.ico and /dev/null differ diff --git a/apps/docs/public/logo.png b/apps/docs/public/logo.png deleted file mode 100644 index 59a588e..0000000 Binary files a/apps/docs/public/logo.png and /dev/null differ diff --git a/apps/docs/public/mokka.svg b/apps/docs/public/mokka.svg deleted file mode 100644 index 5f70db4..0000000 --- a/apps/docs/public/mokka.svg +++ /dev/null @@ -1,14 +0,0 @@ - - - - - - - - - - - - - - diff --git a/apps/docs/styles/globals.css b/apps/docs/styles/globals.css deleted file mode 100644 index f1077c6..0000000 --- a/apps/docs/styles/globals.css +++ /dev/null @@ -1,79 +0,0 @@ -@tailwind base; -@import "syntax-highlight.css"; -@tailwind components; -@tailwind utilities; - -@layer components { - - .docs__content { - @apply max-w-[90rem] mx-auto - } - - .docs__paragraph { - @apply my-4 - } - - .docs__pagination { - @apply border-2 border-background-400 px-4 py-2 rounded-theme flex items-center - } - - .docs__paragraph code { - @apply bg-background-400 rounded-theme-sm px-2 py-1 font-sans - } - - .docs__link { - @apply text-primary - } - - .docs__tabs__list { - @apply inline-flex w-auto mb-4 - } - - .docs__tabs__list .tab { - @apply border-b-2 border-transparent rounded-none text-left mr-8 text-sm whitespace-nowrap w-auto px-4 - } - - .docs__tabs__list .tab--selected { - @apply border-b-2 bg-transparent text-primary border-primary - } - - .docs__table { - @apply rounded-theme border-2 border-background-400 overflow-x-auto w-full block - } - - .docs__table th:first-child { - @apply rounded-tl-theme-sm - } - - .docs__table th:last-child { - @apply rounded-tr-theme-sm - } - - .docs__table code { - @apply bg-background-400 rounded-theme-sm px-2 py-1 - } - - .docs__table table { - @apply w-full - } - - .docs__table table th { - @apply bg-background-400 text-left px-4 py-2 md:text-base text-sm - } - - .docs__table table td { - @apply px-4 py-2 border-b border-background-400 text-sm - } - - .docs__table table tr:last-child td { - @apply border-none - } - - .docs__table .chip { - @apply text-neutral px-0 - } - - .section__heading { - @apply mb-4 mt-8 text-2xl font-semibold - } -} diff --git a/apps/docs/styles/syntax-highlight.css b/apps/docs/styles/syntax-highlight.css deleted file mode 100644 index 4bad12a..0000000 --- a/apps/docs/styles/syntax-highlight.css +++ /dev/null @@ -1,15 +0,0 @@ -@tailwind components; - -@layer components { - div[data-rehype-pretty-code-fragment] { - @apply overflow-hidden bg-background-400 rounded-theme p-4 text-sm - } - - div[data-rehype-pretty-code-fragment] code { - @apply grid - } - - div[data-rehype-pretty-code-fragment] pre { - @apply overflow-x-auto - } -} diff --git a/apps/docs/tailwind.config.js b/apps/docs/tailwind.config.js deleted file mode 100644 index d62cabe..0000000 --- a/apps/docs/tailwind.config.js +++ /dev/null @@ -1,27 +0,0 @@ -/** @type {import('tailwindcss').Config} */ -module.exports = { - content: [ - "./app/**/*.{js,ts,jsx,tsx,mdx}", - "./components/**/*.{js,ts,jsx,tsx,mdx}", - "./examples/**/*.{js,ts,jsx,tsx,mdx}", - "./content/**/*.{js,ts,jsx,tsx,mdx}", - "./node_modules/@arkejs/ui/dist/**/*.{js,ts,jsx,tsx}", - ], - theme: { - extend: {}, - }, - plugins: [require("@arkejs/ui/plugin")], - arkeUI: { - theme: { - colors: { - background: { - 400: "#111218", - DEFAULT: "#0B0C11", - }, - neutral: { - DEFAULT: "#8f8f8f", - }, - }, - }, - }, -}; diff --git a/apps/docs/tsconfig.json b/apps/docs/tsconfig.json deleted file mode 100644 index e2ae6be..0000000 --- a/apps/docs/tsconfig.json +++ /dev/null @@ -1,44 +0,0 @@ -{ - "compilerOptions": { - "target": "es5", - "lib": [ - "dom", - "dom.iterable", - "esnext" - ], - "allowJs": true, - "skipLibCheck": true, - "strict": true, - "forceConsistentCasingInFileNames": true, - "noEmit": true, - "esModuleInterop": true, - "module": "esnext", - "moduleResolution": "node", - "resolveJsonModule": true, - "isolatedModules": true, - "jsx": "preserve", - "incremental": true, - "baseUrl": ".", - "paths": { - "@/*": [ - "./*" - ], - "contentlayer/generated": ["./.contentlayer/generated"] - }, - "plugins": [ - { - "name": "next" - } - ] - }, - "include": [ - "next-env.d.ts", - "**/*.ts", - "**/*.tsx", - ".next/types/**/*.ts", - ".contentlayer/generated" - ], - "exclude": [ - "node_modules" - ] -} diff --git a/apps/storybook/package.json b/apps/storybook/package.json index 2a72480..2500ab5 100644 --- a/apps/storybook/package.json +++ b/apps/storybook/package.json @@ -13,6 +13,7 @@ }, "dependencies": { "@arkejs/table": "workspace:table", + "class-variance-authority": "^0.7.0", "clsx": "^2.1.0", "react": "^18.2.0", "react-dom": "^18.2.0", diff --git a/apps/storybook/src/components/button.tsx b/apps/storybook/src/components/button.tsx new file mode 100644 index 0000000..1d610db --- /dev/null +++ b/apps/storybook/src/components/button.tsx @@ -0,0 +1,77 @@ +import * as React from "react"; +import { cva, type VariantProps } from "class-variance-authority"; +import { cn } from "../lib/cn.ts"; + +const buttonVariants = cva( + "inline-flex items-center justify-center whitespace-nowrap rounded-md text-sm font-medium transition-colors focus-visible:outline-none disabled:pointer-events-none disabled:opacity-50", + { + variants: { + variant: { + default: "", + outlined: "border", + ghost: "hover:bg-neutral hover:text-neutral-foreground", + }, + color: { + primary: "", + secondary: "", + }, + size: { + default: "h-10 px-4 py-2", + sm: "h-9 rounded-md px-3", + lg: "h-11 rounded-md px-8", + icon: "h-10 w-10", + }, + }, + compoundVariants: [ + { + color: "primary", + variant: "default", + className: "bg-primary text-primary-foreground hover:bg-primary/90", + }, + { + color: "secondary", + variant: "default", + className: + "bg-secondary text-secondary-foreground hover:bg-secondary/90", + }, + { + color: "primary", + variant: "outlined", + className: + "border-primary text-primary hover:border-primary/90 hover:text-primary/90", + }, + { + color: "secondary", + variant: "outlined", + className: + "border-secondary text-secondary hover:border-secondary/90 hover:text-secondary/90", + }, + ], + defaultVariants: { + variant: "default", + color: "primary", + size: "default", + }, + } +); + +export interface ButtonProps + extends Omit, "color">, + VariantProps { + asChild?: boolean; +} + +const Button = React.forwardRef( + ({ className, variant, color, ...props }, ref) => { + return ( +
, - TableBody: (props) => , - TableHeader: (props) => , - TableRow: (props) => , - TableCell: (props) => , - TableHead: (props) => , - }} - /> - ); -}; - -// arke-ui cli components +import { cn } from "../lib/cn.ts"; const Table = React.forwardRef< HTMLTableElement, React.HTMLAttributes >(({ className, ...props }, ref) => ( -
+
>(({ className, ...props }, ref) => ( - + )); TableHeader.displayName = "TableHeader"; @@ -74,7 +42,7 @@ const TableFooter = React.forwardRef< tr]:last:border-b-0", + "bg-neutral/50 border-t font-medium [&>tr]:last:border-b-0", className )} {...props} @@ -89,7 +57,7 @@ const TableRow = React.forwardRef< [role=checkbox]]:translate-y-[2px]", + "text-neutral-foreground h-10 px-2 text-left align-middle font-medium [&:has([role=checkbox])]:pr-0 [&>[role=checkbox]]:translate-y-[2px]", className )} {...props} @@ -133,8 +101,19 @@ const TableCaption = React.forwardRef< >(({ className, ...props }, ref) => (
)); TableCaption.displayName = "TableCaption"; + +export { + Table, + TableHeader, + TableBody, + TableFooter, + TableHead, + TableRow, + TableCell, + TableCaption, +}; diff --git a/apps/storybook/src/index.css b/apps/storybook/src/index.css index 246b360..77c378b 100644 --- a/apps/storybook/src/index.css +++ b/apps/storybook/src/index.css @@ -11,6 +11,6 @@ --secondary: 0, 0%, 0%; --secondary-foreground: 0, 0%, 100%; --neutral: 220, 25%, 91%; - --neutral-foreground: 0, 0%, 100%; + --neutral-foreground: 0, 0%, 0%; } } \ No newline at end of file diff --git a/apps/storybook/src/lib/cn.ts b/apps/storybook/src/lib/cn.ts new file mode 100644 index 0000000..a5ef193 --- /dev/null +++ b/apps/storybook/src/lib/cn.ts @@ -0,0 +1,6 @@ +import { clsx, type ClassValue } from "clsx"; +import { twMerge } from "tailwind-merge"; + +export function cn(...inputs: ClassValue[]) { + return twMerge(clsx(inputs)); +} diff --git a/apps/storybook/src/mocks/data.tsx b/apps/storybook/src/mocks/data.tsx new file mode 100644 index 0000000..4fb3631 --- /dev/null +++ b/apps/storybook/src/mocks/data.tsx @@ -0,0 +1,67 @@ +import { ColumnDef } from "@arkejs/table"; + +export type Invoice = { + invoice: string; + paymentStatus: string; + totalAmount: string; + paymentMethod: string; +}; +export const invoices: Invoice[] = [ + { + invoice: "INV001", + paymentStatus: "Paid", + totalAmount: "$250.00", + paymentMethod: "Credit Card", + }, + { + invoice: "INV002", + paymentStatus: "Pending", + totalAmount: "$150.00", + paymentMethod: "PayPal", + }, + { + invoice: "INV003", + paymentStatus: "Unpaid", + totalAmount: "$350.00", + paymentMethod: "Bank Transfer", + }, + { + invoice: "INV004", + paymentStatus: "Paid", + totalAmount: "$450.00", + paymentMethod: "Credit Card", + }, + { + invoice: "INV005", + paymentStatus: "Paid", + totalAmount: "$550.00", + paymentMethod: "PayPal", + }, + { + invoice: "INV006", + paymentStatus: "Pending", + totalAmount: "$200.00", + paymentMethod: "Bank Transfer", + }, + { + invoice: "INV007", + paymentStatus: "Unpaid", + totalAmount: "$300.00", + paymentMethod: "Credit Card", + }, +]; + +export const columns: ColumnDef[] = [ + { + id: "invoice", + }, + { + id: "paymentStatus", + }, + { + id: "paymentMethod", + }, + { + id: "totalAmount", + }, +]; diff --git a/apps/storybook/src/mocks/mockColumns.ts b/apps/storybook/src/mocks/mockColumns.ts deleted file mode 100644 index ab6fb39..0000000 --- a/apps/storybook/src/mocks/mockColumns.ts +++ /dev/null @@ -1,22 +0,0 @@ -import { TableColumn } from "@arkejs/table"; - -const mockColumns: TableColumn[] = [ - { label: "ID", id: "id" }, - { label: "Name", id: "first_name", type: "string" }, - { - label: "Surname", - id: "last_name", - type: "string", - render: (data: Record) => `Mr. ${data.last_name}`, - }, - { label: "Email", id: "email" }, - { - label: "Gender", - id: "gender", - hidden: true, - renderHeader: () => "Gender (M/F)", - }, - { label: "IP Address", id: "ip_address", sortable: false }, -]; - -export default mockColumns; diff --git a/apps/storybook/src/mocks/mockData.ts b/apps/storybook/src/mocks/mockData.ts deleted file mode 100644 index bad8632..0000000 --- a/apps/storybook/src/mocks/mockData.ts +++ /dev/null @@ -1,804 +0,0 @@ -const mockData = [ - { - id: 1, - first_name: "Danya", - last_name: "Hubber", - email: "dhubber0@yahoo.co.jp", - gender: "Male", - ip_address: "180.28.236.190", - }, - { - id: 2, - first_name: "Flin", - last_name: "Danelet", - email: "fdanelet1@youtu.be", - gender: "Male", - ip_address: "92.240.14.83", - }, - { - id: 3, - first_name: "Peterus", - last_name: "Blaxall", - email: "pblaxall2@nationalgeographic.com", - gender: "Male", - ip_address: "202.36.4.24", - }, - { - id: 4, - first_name: "Maryann", - last_name: "Birrell", - email: "mbirrell3@geocities.jp", - gender: "Female", - ip_address: "125.113.220.61", - }, - { - id: 5, - first_name: "Sascha", - last_name: "Starcks", - email: "sstarcks4@marriott.com", - gender: "Female", - ip_address: "255.232.24.24", - }, - { - id: 6, - first_name: "Andriana", - last_name: "Milazzo", - email: "amilazzo5@marketwatch.com", - gender: "Female", - ip_address: "78.0.154.18", - }, - { - id: 7, - first_name: "Mattie", - last_name: "Danby", - email: "mdanby6@squidoo.com", - gender: "Genderqueer", - ip_address: "133.7.128.164", - }, - { - id: 8, - first_name: "Mirabella", - last_name: "Beausang", - email: "mbeausang7@wikimedia.org", - gender: "Female", - ip_address: "222.11.115.94", - }, - { - id: 9, - first_name: "Guthrey", - last_name: "Casbon", - email: "gcasbon8@intel.com", - gender: "Male", - ip_address: "116.27.250.34", - }, - { - id: 10, - first_name: "Allegra", - last_name: "Remmers", - email: "aremmers9@thetimes.co.uk", - gender: "Female", - ip_address: "191.141.74.239", - }, - { - id: 11, - first_name: "Towney", - last_name: "Giffaut", - email: "tgiffauta@bloglovin.com", - gender: "Male", - ip_address: "182.45.176.210", - }, - { - id: 12, - first_name: "Lorry", - last_name: "Pooly", - email: "lpoolyb@umich.edu", - gender: "Male", - ip_address: "221.229.109.5", - }, - { - id: 13, - first_name: "Jen", - last_name: "Collecott", - email: "jcollecottc@i2i.jp", - gender: "Female", - ip_address: "159.243.146.124", - }, - { - id: 14, - first_name: "Raynell", - last_name: "Nickerson", - email: "rnickersond@amazon.com", - gender: "Female", - ip_address: "41.98.157.43", - }, - { - id: 15, - first_name: "Dickie", - last_name: "Surby", - email: "dsurbye@discuz.net", - gender: "Male", - ip_address: "104.19.201.106", - }, - { - id: 16, - first_name: "Iosep", - last_name: "Mattusevich", - email: "imattusevichf@hud.gov", - gender: "Male", - ip_address: "74.48.69.161", - }, - { - id: 17, - first_name: "Meris", - last_name: "Crayke", - email: "mcraykeg@ovh.net", - gender: "Female", - ip_address: "204.217.20.3", - }, - { - id: 18, - first_name: "Blair", - last_name: "Maplethorp", - email: "bmaplethorph@addtoany.com", - gender: "Male", - ip_address: "31.53.110.140", - }, - { - id: 19, - first_name: "Sibel", - last_name: "Dawney", - email: "sdawneyi@paginegialle.it", - gender: "Female", - ip_address: "43.35.89.117", - }, - { - id: 20, - first_name: "Shina", - last_name: "Pinnijar", - email: "spinnijarj@paginegialle.it", - gender: "Female", - ip_address: "221.35.219.55", - }, - { - id: 21, - first_name: "Enrique", - last_name: "Morilla", - email: "emorillak@answers.com", - gender: "Male", - ip_address: "48.55.107.153", - }, - { - id: 22, - first_name: "Audry", - last_name: "Luten", - email: "alutenl@google.com", - gender: "Female", - ip_address: "149.28.107.196", - }, - { - id: 23, - first_name: "Chane", - last_name: "Hannum", - email: "channumm@discuz.net", - gender: "Genderfluid", - ip_address: "248.73.142.90", - }, - { - id: 24, - first_name: "Guy", - last_name: "Schechter", - email: "gschechtern@mayoclinic.com", - gender: "Male", - ip_address: "164.202.138.173", - }, - { - id: 25, - first_name: "Werner", - last_name: "Paolicchi", - email: "wpaolicchio@uol.com.br", - gender: "Male", - ip_address: "252.152.189.33", - }, - { - id: 26, - first_name: "Raphaela", - last_name: "Pymer", - email: "rpymerp@desdev.cn", - gender: "Female", - ip_address: "1.234.80.250", - }, - { - id: 27, - first_name: "Pavia", - last_name: "Fraine", - email: "pfraineq@yolasite.com", - gender: "Female", - ip_address: "100.127.217.154", - }, - { - id: 28, - first_name: "Leonerd", - last_name: "Bleything", - email: "lbleythingr@cargocollective.com", - gender: "Male", - ip_address: "214.107.97.240", - }, - { - id: 29, - first_name: "Sasha", - last_name: "Astall", - email: "sastalls@cmu.edu", - gender: "Male", - ip_address: "56.228.211.31", - }, - { - id: 30, - first_name: "Merill", - last_name: "Chatwin", - email: "mchatwint@is.gd", - gender: "Male", - ip_address: "234.235.90.204", - }, - { - id: 31, - first_name: "Drugi", - last_name: "Derby", - email: "dderbyu@independent.co.uk", - gender: "Male", - ip_address: "59.44.129.5", - }, - { - id: 32, - first_name: "Frederic", - last_name: "Petru", - email: "fpetruv@techcrunch.com", - gender: "Male", - ip_address: "127.118.85.58", - }, - { - id: 33, - first_name: "Enrico", - last_name: "Kersaw", - email: "ekersaww@gov.uk", - gender: "Bigender", - ip_address: "236.64.147.10", - }, - { - id: 34, - first_name: "Gerik", - last_name: "Mitford", - email: "gmitfordx@stanford.edu", - gender: "Male", - ip_address: "217.234.218.98", - }, - { - id: 35, - first_name: "Ted", - last_name: "Puleston", - email: "tpulestony@bravesites.com", - gender: "Male", - ip_address: "114.87.16.95", - }, - { - id: 36, - first_name: "Ricardo", - last_name: "Carrier", - email: "rcarrierz@boston.com", - gender: "Male", - ip_address: "149.197.126.205", - }, - { - id: 37, - first_name: "Johnette", - last_name: "Beere", - email: "jbeere10@1und1.de", - gender: "Female", - ip_address: "153.158.90.183", - }, - { - id: 38, - first_name: "Aubrey", - last_name: "Hollidge", - email: "ahollidge11@skyrock.com", - gender: "Male", - ip_address: "111.110.30.104", - }, - { - id: 39, - first_name: "Vincents", - last_name: "Bullivant", - email: "vbullivant12@creativecommons.org", - gender: "Male", - ip_address: "35.177.38.170", - }, - { - id: 40, - first_name: "Ronna", - last_name: "Cheyney", - email: "rcheyney13@miitbeian.gov.cn", - gender: "Female", - ip_address: "199.195.124.165", - }, - { - id: 41, - first_name: "Kimbell", - last_name: "Stearnes", - email: "kstearnes14@com.com", - gender: "Male", - ip_address: "175.183.228.128", - }, - { - id: 42, - first_name: "Zuzana", - last_name: "Gallemore", - email: "zgallemore15@gizmodo.com", - gender: "Female", - ip_address: "105.10.28.108", - }, - { - id: 43, - first_name: "Sebastien", - last_name: "Burgoine", - email: "sburgoine16@opera.com", - gender: "Male", - ip_address: "191.85.130.219", - }, - { - id: 44, - first_name: "Arte", - last_name: "Cantillion", - email: "acantillion17@forbes.com", - gender: "Male", - ip_address: "146.226.92.3", - }, - { - id: 45, - first_name: "Noel", - last_name: "Virr", - email: "nvirr18@utexas.edu", - gender: "Female", - ip_address: "199.18.71.100", - }, - { - id: 46, - first_name: "Cleopatra", - last_name: "Jarratt", - email: "cjarratt19@macromedia.com", - gender: "Polygender", - ip_address: "198.117.4.223", - }, - { - id: 47, - first_name: "Gretchen", - last_name: "Bewly", - email: "gbewly1a@artisteer.com", - gender: "Female", - ip_address: "61.166.64.128", - }, - { - id: 48, - first_name: "Hew", - last_name: "Mogg", - email: "hmogg1b@google.es", - gender: "Male", - ip_address: "211.86.100.140", - }, - { - id: 49, - first_name: "Rania", - last_name: "Priest", - email: "rpriest1c@columbia.edu", - gender: "Female", - ip_address: "75.248.144.34", - }, - { - id: 50, - first_name: "Hedvige", - last_name: "Fernihough", - email: "hfernihough1d@blogs.com", - gender: "Female", - ip_address: "11.130.145.232", - }, - { - id: 51, - first_name: "Norrie", - last_name: "Keller", - email: "nkeller1e@prlog.org", - gender: "Male", - ip_address: "221.87.189.124", - }, - { - id: 52, - first_name: "Ximenez", - last_name: "Kempson", - email: "xkempson1f@amazonaws.com", - gender: "Male", - ip_address: "23.35.65.100", - }, - { - id: 53, - first_name: "Trever", - last_name: "Treagus", - email: "ttreagus1g@abc.net.au", - gender: "Male", - ip_address: "170.102.160.194", - }, - { - id: 54, - first_name: "Norma", - last_name: "Fairy", - email: "nfairy1h@phpbb.com", - gender: "Female", - ip_address: "208.118.192.2", - }, - { - id: 55, - first_name: "Patton", - last_name: "Gerritsma", - email: "pgerritsma1i@jimdo.com", - gender: "Male", - ip_address: "140.138.207.0", - }, - { - id: 56, - first_name: "Kakalina", - last_name: "Farbrother", - email: "kfarbrother1j@intel.com", - gender: "Female", - ip_address: "72.176.228.201", - }, - { - id: 57, - first_name: "Wilone", - last_name: "Di Batista", - email: "wdibatista1k@tmall.com", - gender: "Female", - ip_address: "79.144.23.187", - }, - { - id: 58, - first_name: "Sari", - last_name: "Ostrich", - email: "sostrich1l@admin.ch", - gender: "Polygender", - ip_address: "159.228.14.137", - }, - { - id: 59, - first_name: "Mahmud", - last_name: "Binner", - email: "mbinner1m@elpais.com", - gender: "Male", - ip_address: "48.124.81.138", - }, - { - id: 60, - first_name: "Winnah", - last_name: "Angrick", - email: "wangrick1n@google.com.hk", - gender: "Female", - ip_address: "10.158.24.179", - }, - { - id: 61, - first_name: "Adrianna", - last_name: "Baynton", - email: "abaynton1o@wunderground.com", - gender: "Female", - ip_address: "93.211.113.4", - }, - { - id: 62, - first_name: "Bride", - last_name: "Florey", - email: "bflorey1p@webs.com", - gender: "Female", - ip_address: "174.194.215.186", - }, - { - id: 63, - first_name: "Cecile", - last_name: "De Bischop", - email: "cdebischop1q@instagram.com", - gender: "Female", - ip_address: "111.69.130.226", - }, - { - id: 64, - first_name: "Timmy", - last_name: "Bonfield", - email: "tbonfield1r@typepad.com", - gender: "Genderqueer", - ip_address: "177.154.255.110", - }, - { - id: 65, - first_name: "Elga", - last_name: "Hutt", - email: "ehutt1s@ucla.edu", - gender: "Female", - ip_address: "20.179.2.76", - }, - { - id: 66, - first_name: "Adrianna", - last_name: "Kerry", - email: "akerry1t@joomla.org", - gender: "Female", - ip_address: "164.105.4.37", - }, - { - id: 67, - first_name: "James", - last_name: "Gristock", - email: "jgristock1u@hostgator.com", - gender: "Male", - ip_address: "243.249.237.230", - }, - { - id: 68, - first_name: "Andriette", - last_name: "Senton", - email: "asenton1v@toplist.cz", - gender: "Female", - ip_address: "180.57.39.144", - }, - { - id: 69, - first_name: "Ted", - last_name: "England", - email: "tengland1w@istockphoto.com", - gender: "Female", - ip_address: "30.171.128.52", - }, - { - id: 70, - first_name: "Collen", - last_name: "Milmo", - email: "cmilmo1x@mozilla.com", - gender: "Bigender", - ip_address: "208.89.59.249", - }, - { - id: 71, - first_name: "Mallissa", - last_name: "Tranfield", - email: "mtranfield1y@ehow.com", - gender: "Female", - ip_address: "188.63.236.225", - }, - { - id: 72, - first_name: "Maurie", - last_name: "Ciotti", - email: "mciotti1z@feedburner.com", - gender: "Male", - ip_address: "112.247.8.135", - }, - { - id: 73, - first_name: "Rhody", - last_name: "Giocannoni", - email: "rgiocannoni20@statcounter.com", - gender: "Female", - ip_address: "192.91.148.64", - }, - { - id: 74, - first_name: "Celestyn", - last_name: "Pinilla", - email: "cpinilla21@devhub.com", - gender: "Female", - ip_address: "139.72.70.149", - }, - { - id: 75, - first_name: "Dionysus", - last_name: "Figgins", - email: "dfiggins22@usatoday.com", - gender: "Male", - ip_address: "219.68.119.137", - }, - { - id: 76, - first_name: "Helenka", - last_name: "Durnian", - email: "hdurnian23@wp.com", - gender: "Female", - ip_address: "82.52.131.138", - }, - { - id: 77, - first_name: "Pietrek", - last_name: "Vidloc", - email: "pvidloc24@samsung.com", - gender: "Male", - ip_address: "85.25.88.31", - }, - { - id: 78, - first_name: "Roderigo", - last_name: "Earlam", - email: "rearlam25@blogtalkradio.com", - gender: "Male", - ip_address: "150.28.148.70", - }, - { - id: 79, - first_name: "Sara-ann", - last_name: "Gammon", - email: "sgammon26@opensource.org", - gender: "Female", - ip_address: "190.89.129.2", - }, - { - id: 80, - first_name: "Helenelizabeth", - last_name: "Ablewhite", - email: "hablewhite27@hp.com", - gender: "Female", - ip_address: "42.146.141.162", - }, - { - id: 81, - first_name: "Natty", - last_name: "Tregea", - email: "ntregea28@unc.edu", - gender: "Male", - ip_address: "53.64.109.115", - }, - { - id: 82, - first_name: "Marji", - last_name: "Fowlds", - email: "mfowlds29@goo.gl", - gender: "Female", - ip_address: "164.208.19.138", - }, - { - id: 83, - first_name: "Nicoli", - last_name: "Mulligan", - email: "nmulligan2a@paginegialle.it", - gender: "Female", - ip_address: "79.244.75.118", - }, - { - id: 84, - first_name: "Celinda", - last_name: "Bates", - email: "cbates2b@netvibes.com", - gender: "Female", - ip_address: "163.79.46.228", - }, - { - id: 85, - first_name: "Jonathan", - last_name: "Lindner", - email: "jlindner2c@homestead.com", - gender: "Male", - ip_address: "5.249.195.3", - }, - { - id: 86, - first_name: "Kacey", - last_name: "Buxsey", - email: "kbuxsey2d@so-net.ne.jp", - gender: "Female", - ip_address: "201.209.45.45", - }, - { - id: 87, - first_name: "Ashia", - last_name: "Gaskell", - email: "agaskell2e@shareasale.com", - gender: "Female", - ip_address: "100.102.232.104", - }, - { - id: 88, - first_name: "Yankee", - last_name: "Emanueli", - email: "yemanueli2f@amazon.com", - gender: "Male", - ip_address: "102.96.102.112", - }, - { - id: 89, - first_name: "Dunn", - last_name: "Peter", - email: "dpeter2g@businesswire.com", - gender: "Male", - ip_address: "157.150.253.191", - }, - { - id: 90, - first_name: "Gabriel", - last_name: "Gealy", - email: "ggealy2h@youku.com", - gender: "Male", - ip_address: "57.128.80.110", - }, - { - id: 91, - first_name: "Neala", - last_name: "Done", - email: "ndone2i@bloglines.com", - gender: "Female", - ip_address: "249.157.117.143", - }, - { - id: 92, - first_name: "Donnell", - last_name: "Hasslocher", - email: "dhasslocher2j@com.com", - gender: "Male", - ip_address: "178.19.240.229", - }, - { - id: 93, - first_name: "Charmane", - last_name: "Stebles", - email: "cstebles2k@phpbb.com", - gender: "Female", - ip_address: "134.75.156.151", - }, - { - id: 94, - first_name: "Wait", - last_name: "Cuddehy", - email: "wcuddehy2l@free.fr", - gender: "Male", - ip_address: "109.122.137.141", - }, - { - id: 95, - first_name: "Chip", - last_name: "Harefoot", - email: "charefoot2m@taobao.com", - gender: "Male", - ip_address: "227.13.151.91", - }, - { - id: 96, - first_name: "Holly-anne", - last_name: "Dyas", - email: "hdyas2n@ehow.com", - gender: "Female", - ip_address: "15.148.10.175", - }, - { - id: 97, - first_name: "Helen", - last_name: "Whittleton", - email: "hwhittleton2o@163.com", - gender: "Female", - ip_address: "177.140.56.53", - }, - { - id: 98, - first_name: "Derick", - last_name: "Winsor", - email: "dwinsor2p@nifty.com", - gender: "Non-binary", - ip_address: "1.205.95.229", - }, - { - id: 99, - first_name: "Scarface", - last_name: "Steven", - email: "ssteven2q@goo.ne.jp", - gender: "Male", - ip_address: "201.237.117.236", - }, - { - id: 100, - first_name: "Jasper", - last_name: "Wolfarth", - email: "jwolfarth2r@thetimes.co.uk", - gender: "Male", - ip_address: "91.184.182.131", - }, -]; - -export default mockData; diff --git a/apps/storybook/src/stories/Table.stories.tsx b/apps/storybook/src/stories/Table.stories.tsx deleted file mode 100644 index 6973d94..0000000 --- a/apps/storybook/src/stories/Table.stories.tsx +++ /dev/null @@ -1,451 +0,0 @@ -import { - TableColumn, - TableExpandedState, - ITableProps, - Table, - useTable, -} from "@arkejs/table"; -import mockData from "../mocks/mockData"; -import mockColumns from "../mocks/mockColumns"; -import { useEffect, useState } from "react"; - -export default { - title: "Table", - component: Table, -}; - -export const Default = (args: Partial) => { - return ; -}; - -export const WithPagination = (args: Partial) => { - const data = mockData; - const pageSize = 10; - - const { tableProps, currentPage } = useTable({ - pagination: { - totalCount: 100, - }, - columns: mockColumns, - }); - - const pagedData = data.slice( - currentPage * pageSize, - (currentPage + 1) * pageSize - ); - - return
; -}; - -export const WithCustomHeader = (args: Partial) => { - const data = mockData; - const pageSize = 10; - - const { tableProps, currentPage } = useTable({ - pagination: { - totalCount: 100, - }, - columns: mockColumns, - }); - - const pagedData = data.slice( - currentPage * pageSize, - (currentPage + 1) * pageSize - ); - - return ( -
column.id} - data={pagedData} - {...args} - /> - ); -}; - -export const WithLoadingConfiguration = (args: Partial) => { - const [hasLoaded, setHasLoaded] = useState(false); - const { tableProps, currentPage } = useTable( - hasLoaded - ? { - pagination: { - totalCount: 100, - }, - columns: mockColumns, - } - : null - ); - - const data = mockData; - const pageSize = 10; - - useEffect(() => { - setTimeout(() => { - setHasLoaded(true); - }, 3000); - }, []); - - const pagedData = data.slice( - currentPage * pageSize, - (currentPage + 1) * pageSize - ); - - return ( - <> - table will load after 3 seconds ... - {hasLoaded &&
} - - ); -}; - -export const WithCustomPagination = (args: Partial) => { - const data = mockData; - const pageSize = 25; - - const { tableProps, goToPage, currentPage, pageCount } = useTable({ - pagination: { - totalCount: 100, - pageSize, - type: "custom", - }, - columns: mockColumns, - }); - - const pagedData = data.slice( - currentPage * pageSize, - (currentPage + 1) * pageSize - ); - - return ( - <> -
- - - - ); -}; - -export const WithDefaultSorting = (args: Partial) => { - const { tableProps, sort } = useTable({ - sorting: { - sortable: true, - }, - columns: mockColumns, - }); - - return ( - <> -
Selected: {JSON.stringify(sort)}
-
- - ); -}; - -export const WithCustomSorting = (args: Partial) => { - const { tableProps, sort, setSort } = useTable({ - sorting: { - sortable: true, - type: "custom", - }, - columns: mockColumns, - }); - - return ( - <> - - -
- Selected: {JSON.stringify(sort)} -
-
- - ); -}; - -export const WithColumnHiding = (args: Partial) => { - const data = mockData; - - const { tableProps, allColumns, toggleHideAll } = useTable({ - columns: mockColumns, - }); - - return ( - <> -
- !c.hidden)} - onClick={toggleHideAll} - type="checkbox" - id="all" - /> - - {allColumns.map(({ id, label, toggleHide, hidden }) => ( -
- - -
- ))} -
-
- - ); -}; - -export const WithMultipleColumnHiding = (args: Partial) => { - const data = mockData; - - const { tableProps, allColumns, toggleHide } = useTable({ - columns: mockColumns, - }); - const [tempColumns, setTempColumns] = useState(allColumns); - - const handleChange = (column: TableColumn) => { - setTempColumns((prevState) => - prevState.map((c) => - c.id === column.id ? { ...c, hidden: !c.hidden } : c - ) - ); - }; - - return ( - <> -
- {allColumns.map((col) => ( -
- c.id === col.id)?.hidden} - onClick={() => handleChange(col)} - type="checkbox" - id={col.id} - /> - -
- ))} - - -
-
- - ); -}; - -export const WithFilter = (args: Partial) => { - const data = mockData; - - const { tableProps, filters, setFilters, allColumns } = useTable({ - columns: mockColumns, - }); - - return ( - <> -
- {allColumns - .filter((c) => c.availableFilterOperators?.length) - .map((c) => ( -
{ - e.preventDefault(); - // @ts-ignore - const operator = e.target?.operator?.value; - // @ts-ignore - const value = e.target?.value?.value; - if (operator && value) { - setFilters([...filters, { operator, value, key: c.id }]); - // @ts-ignore - e.target.reset(); - } - }} - style={{ - display: "grid", - gridTemplateColumns: "100px 1fr 1fr 1fr", - columnGap: 12, - }} - > - {c.label} - - - - - ))} -
-
- Selected: {JSON.stringify(filters)} -
-
- - ); -}; - -export const WithActions = (args: Partial) => { - return ( -
alert("Action 1"), - }, - { - content: () => "Action 2", - onClick: () => alert("Action 2"), - }, - ], - }} - {...args} - /> - ); -}; - -export const ExpandableState = (args: Partial) => { - const [expandedRows, setExpandedRows] = useState({}); - const data = mockData; - const pageSize = 10; - - const columns: TableColumn[] = [ - { - id: "toggle", - label: "toggle", - render: (_, { handleExpandRow }) => ( - - ), - }, - ...mockColumns, - ]; - - const { tableProps, currentPage } = useTable({ - pagination: { - totalCount: 100, - }, - columns, - }); - - const pagedData = data.slice( - currentPage * pageSize, - (currentPage + 1) * pageSize - ); - - const handleExpandRow = (index: number) => { - setExpandedRows((prevState) => ({ - ...prevState, - [index]: !prevState[index], - })); - }; - - return ( -
( -
-
Expanded row
-
{JSON.stringify(rowData)}
-
- ), - }} - /> - ); -}; - -export const ExpandableUseTable = (args: Partial) => { - const data = mockData; - const pageSize = 10; - - const columns: TableColumn[] = [ - { - id: "toggle", - label: "toggle", - render: (_, { handleExpandRow }) => ( - - ), - }, - ...mockColumns, - ]; - - const { tableProps, currentPage } = useTable({ - pagination: { - totalCount: 100, - }, - expandable: true, - columns, - }); - - const pagedData = data.slice( - currentPage * pageSize, - (currentPage + 1) * pageSize - ); - - return ( -
( -
-
Expanded row
-
{JSON.stringify(rowData)}
-
- ), - }} - /> - ); -}; - -export const NoResult = (args: Partial) => { - return ( -
alert("Action 1"), - }, - { - content: () => "Action 2", - onClick: () => alert("Action 2"), - }, - ], - }} - noResult="No result" - {...args} - /> - ); -}; diff --git a/apps/storybook/src/stories/TableConfigProvider.stories.tsx b/apps/storybook/src/stories/TableConfigProvider.stories.tsx deleted file mode 100644 index 9f078e0..0000000 --- a/apps/storybook/src/stories/TableConfigProvider.stories.tsx +++ /dev/null @@ -1,20 +0,0 @@ -import { ITableProps, Table, TableConfigProvider } from "@arkejs/table"; -import mockData from "../mocks/mockData.ts"; -import mockColumns from "../mocks/mockColumns.ts"; - -export default { - title: "TableConfigProvider", - component: TableConfigProvider, -}; - -export const Default = (args: Partial) => { - return ( -

{value}

, - }} - > -
- - ); -}; diff --git a/apps/storybook/src/stories/assets/accessibility.png b/apps/storybook/src/stories/assets/accessibility.png deleted file mode 100644 index 6ffe6fe..0000000 Binary files a/apps/storybook/src/stories/assets/accessibility.png and /dev/null differ diff --git a/apps/storybook/src/stories/assets/accessibility.svg b/apps/storybook/src/stories/assets/accessibility.svg deleted file mode 100644 index a328883..0000000 --- a/apps/storybook/src/stories/assets/accessibility.svg +++ /dev/null @@ -1,5 +0,0 @@ - - Accessibility - - - \ No newline at end of file diff --git a/apps/storybook/src/stories/assets/addon-library.png b/apps/storybook/src/stories/assets/addon-library.png deleted file mode 100644 index 95deb38..0000000 Binary files a/apps/storybook/src/stories/assets/addon-library.png and /dev/null differ diff --git a/apps/storybook/src/stories/assets/assets.png b/apps/storybook/src/stories/assets/assets.png deleted file mode 100644 index cfba681..0000000 Binary files a/apps/storybook/src/stories/assets/assets.png and /dev/null differ diff --git a/apps/storybook/src/stories/assets/context.png b/apps/storybook/src/stories/assets/context.png deleted file mode 100644 index e5cd249..0000000 Binary files a/apps/storybook/src/stories/assets/context.png and /dev/null differ diff --git a/apps/storybook/src/stories/assets/discord.svg b/apps/storybook/src/stories/assets/discord.svg deleted file mode 100644 index 1204df9..0000000 --- a/apps/storybook/src/stories/assets/discord.svg +++ /dev/null @@ -1,15 +0,0 @@ - - - - - - - - - - - - - - - diff --git a/apps/storybook/src/stories/assets/docs.png b/apps/storybook/src/stories/assets/docs.png deleted file mode 100644 index a749629..0000000 Binary files a/apps/storybook/src/stories/assets/docs.png and /dev/null differ diff --git a/apps/storybook/src/stories/assets/figma-plugin.png b/apps/storybook/src/stories/assets/figma-plugin.png deleted file mode 100644 index 8f79b08..0000000 Binary files a/apps/storybook/src/stories/assets/figma-plugin.png and /dev/null differ diff --git a/apps/storybook/src/stories/assets/github.svg b/apps/storybook/src/stories/assets/github.svg deleted file mode 100644 index 158e026..0000000 --- a/apps/storybook/src/stories/assets/github.svg +++ /dev/null @@ -1,3 +0,0 @@ - - - diff --git a/apps/storybook/src/stories/assets/share.png b/apps/storybook/src/stories/assets/share.png deleted file mode 100644 index 8097a37..0000000 Binary files a/apps/storybook/src/stories/assets/share.png and /dev/null differ diff --git a/apps/storybook/src/stories/assets/styling.png b/apps/storybook/src/stories/assets/styling.png deleted file mode 100644 index d341e82..0000000 Binary files a/apps/storybook/src/stories/assets/styling.png and /dev/null differ diff --git a/apps/storybook/src/stories/assets/testing.png b/apps/storybook/src/stories/assets/testing.png deleted file mode 100644 index d4ac39a..0000000 Binary files a/apps/storybook/src/stories/assets/testing.png and /dev/null differ diff --git a/apps/storybook/src/stories/assets/theming.png b/apps/storybook/src/stories/assets/theming.png deleted file mode 100644 index 1535eb9..0000000 Binary files a/apps/storybook/src/stories/assets/theming.png and /dev/null differ diff --git a/apps/storybook/src/stories/assets/tutorials.svg b/apps/storybook/src/stories/assets/tutorials.svg deleted file mode 100644 index 4b2fc7c..0000000 --- a/apps/storybook/src/stories/assets/tutorials.svg +++ /dev/null @@ -1,12 +0,0 @@ - - - - - - - - - - - - diff --git a/apps/storybook/src/stories/assets/youtube.svg b/apps/storybook/src/stories/assets/youtube.svg deleted file mode 100644 index 33a3a61..0000000 --- a/apps/storybook/src/stories/assets/youtube.svg +++ /dev/null @@ -1,4 +0,0 @@ - - - - diff --git a/apps/storybook/src/stories/basic.stories.tsx b/apps/storybook/src/stories/basic.stories.tsx new file mode 100644 index 0000000..0e7f6e5 --- /dev/null +++ b/apps/storybook/src/stories/basic.stories.tsx @@ -0,0 +1,48 @@ +import { useTable } from "@arkejs/table"; +import { + Table, + TableBody, + TableCaption, + TableCell, + TableFooter, + TableHead, + TableHeader, + TableRow, +} from "../components/table.tsx"; +import { columns, invoices } from "../mocks/data.tsx"; + +export default { + title: "Basic", +}; + +export const Basic = () => { + const table = useTable({ columns, data: invoices }); + + return ( +
+ A list of your recent invoices. + + + {table.getAllColumns().map((column) => ( + {column.id} + ))} + + + + {table.getRows().map((row) => ( + + {row.getAllCells().map((cell) => ( + {cell.getValue()} + ))} + + ))} + + + + Total + $2,500.00 + + +
+ ); +}; diff --git a/apps/storybook/src/stories/column-filtering.stories.tsx b/apps/storybook/src/stories/column-filtering.stories.tsx new file mode 100644 index 0000000..6b221b9 --- /dev/null +++ b/apps/storybook/src/stories/column-filtering.stories.tsx @@ -0,0 +1,75 @@ +import { useTable } from "@arkejs/table"; +import { + Table, + TableBody, + TableCaption, + TableCell, + TableFooter, + TableHead, + TableHeader, + TableRow, +} from "../components/table.tsx"; +import { columns, invoices } from "../mocks/data.tsx"; + +export default { + title: "Column Filtering", +}; +export const ColumnFiltering = () => { + const table = useTable({ + columns, + data: invoices, + initialState: { + columnFilters: { + invoice: { test: true }, + }, + }, + }); + + const columnFilters = table.getState().columnFilters; + + return ( + <> +
+ Active fitlers: {JSON.stringify(columnFilters)} +
+ + A list of your recent invoices. + + + {table.getVisibleColumns().map((column) => ( + + {column.id} + + column.setFilter({ + value: event.target.value, + any: "", + key: "", + allowed: "", + }) + } + /> + + ))} + + + + {table.getRows().map((row) => ( + + {row.getVisibleCells().map((cell) => ( + {cell.getValue()} + ))} + + ))} + + + + Total + $2,500.00 + + +
+ + ); +}; diff --git a/apps/storybook/src/stories/column-pinning.stories.tsx b/apps/storybook/src/stories/column-pinning.stories.tsx new file mode 100644 index 0000000..0a69429 --- /dev/null +++ b/apps/storybook/src/stories/column-pinning.stories.tsx @@ -0,0 +1,93 @@ +import { useTable } from "@arkejs/table"; +import { + Table, + TableBody, + TableCaption, + TableCell, + TableFooter, + TableHead, + TableHeader, + TableRow, +} from "../components/table.tsx"; +import { columns, invoices } from "../mocks/data.tsx"; +import { cn } from "../lib/cn.ts"; + +export default { + title: "Column Pinning", +}; + +export const ColumnPinning = () => { + const table = useTable({ columns, data: invoices }); + + return ( + <> +
+ {table.getAllColumns().map((column) => ( + + ))} +
+ + A list of your recent invoices. + + + {[ + ...table.getVisiblePinnedColumns(), + ...table.getVisibleUnpinnedColumns(), + ].map((column, index) => ( + + {column.id} + + ))} + + + + {table.getRows().map((row) => ( + + {[ + ...row.getVisiblePinnedCells(), + ...row.getVisibleUnpinnedCells(), + ].map((cell, index) => { + return ( + + {cell.getValue()} + + ); + })} + + ))} + + + + Total + $2,500.00 + + +
+ + ); +}; diff --git a/apps/storybook/src/stories/column-visibility.stories.tsx b/apps/storybook/src/stories/column-visibility.stories.tsx new file mode 100644 index 0000000..ee34e0f --- /dev/null +++ b/apps/storybook/src/stories/column-visibility.stories.tsx @@ -0,0 +1,62 @@ +import { useTable } from "@arkejs/table"; +import { + Table, + TableBody, + TableCaption, + TableCell, + TableFooter, + TableHead, + TableHeader, + TableRow, +} from "../components/table.tsx"; +import { columns, invoices } from "../mocks/data.tsx"; + +export default { + title: "Column Visibility", +}; + +export const ColumnVisibility = () => { + const table = useTable({ columns, data: invoices }); + + return ( + <> +
+ {table.getAllColumns().map((column) => ( + + ))} +
+ + A list of your recent invoices. + + + {table.getVisibleColumns().map((column) => ( + {column.id} + ))} + + + + {table.getRows().map((row) => ( + + {row.getVisibleCells().map((cell) => ( + {cell.getValue()} + ))} + + ))} + + + + Total + $2,500.00 + + +
+ + ); +}; diff --git a/apps/storybook/src/stories/custom-cell-render.stories.tsx b/apps/storybook/src/stories/custom-cell-render.stories.tsx new file mode 100644 index 0000000..a776c93 --- /dev/null +++ b/apps/storybook/src/stories/custom-cell-render.stories.tsx @@ -0,0 +1,74 @@ +import { ColumnDef, useTable } from "@arkejs/table"; +import { Invoice, invoices } from "../mocks/data.tsx"; +import { + Table, + TableBody, + TableCaption, + TableCell, + TableFooter, + TableHead, + TableHeader, + TableRow, +} from "../components/table.tsx"; + +export default { + title: "Custom Cell Render", +}; + +const columns: ColumnDef[] = [ + { + id: "invoice", + header: "Invoice", + cell: { + renderValue: (value) => ( +
+ + {value.invoice} +
+ ), + }, + }, + { + id: "paymentStatus", + }, + { + id: "paymentMethod", + }, + { + id: "totalAmount", + }, +]; + +export const CustomCellRender = () => { + const table = useTable({ columns, data: invoices }); + + return ( + + A list of your recent invoices. + + + {table.getAllColumns().map((column) => ( + {column.columnDef.header} + ))} + + + + {table.getRows().map((row) => ( + + {row.getAllCells().map((cell) => ( + + {cell.renderValue()} + + ))} + + ))} + + + + Total + $2,500.00 + + +
+ ); +}; diff --git a/apps/storybook/src/stories/pagination.stories.tsx b/apps/storybook/src/stories/pagination.stories.tsx new file mode 100644 index 0000000..3f75858 --- /dev/null +++ b/apps/storybook/src/stories/pagination.stories.tsx @@ -0,0 +1,101 @@ +import { useTable } from "@arkejs/table"; +import { + Table, + TableBody, + TableCell, + TableFooter, + TableHead, + TableHeader, + TableRow, +} from "../components/table.tsx"; +import { + Pagination as PaginationComponent, + PaginationContent, + PaginationEllipsis, + PaginationItem, + PaginationLink, + PaginationNext, + PaginationPrevious, +} from "../components/pagination.tsx"; +import { columns, invoices } from "../mocks/data.tsx"; + +export default { + title: "Pagination", +}; + +export const Pagination = () => { + const table = useTable({ columns, data: invoices }); + const { + pagination: { pageIndex }, + } = table.getState(); + + return ( + <> + + + + Invoice + Status + Method + Amount + + + + {invoices.map((invoice) => ( + + {invoice.invoice} + {invoice.paymentStatus} + {invoice.paymentMethod} + + {invoice.totalAmount} + + + ))} + + + + Total + $2,500.00 + + +
+ + + + table.previousPage()} /> + + + table.setPageIndex(0)} + isActive={pageIndex === 0} + > + 1 + + + + table.setPageIndex(1)} + isActive={pageIndex === 1} + > + 2 + + + + table.setPageIndex(2)} + isActive={pageIndex === 2} + > + 3 + + + + + + + table.nextPage()} /> + + + + + ); +}; diff --git a/apps/storybook/src/stories/row-selection.stories.tsx b/apps/storybook/src/stories/row-selection.stories.tsx new file mode 100644 index 0000000..a959662 --- /dev/null +++ b/apps/storybook/src/stories/row-selection.stories.tsx @@ -0,0 +1,81 @@ +import { useTable } from "@arkejs/table"; +import { + Table, + TableBody, + TableCaption, + TableCell, + TableFooter, + TableHead, + TableHeader, + TableRow, +} from "../components/table.tsx"; +import { columns, invoices } from "../mocks/data.tsx"; + +export default { + title: "Row Selection", +}; +export const RowSelection = () => { + const table = useTable({ + columns, + data: invoices, + getRowId: (row) => row.invoice, + }); + + return ( + <> +
+ Selected rows:{" "} + {JSON.stringify(table.getSelectedRows().map((row) => row.id))} +
+ + A list of your recent invoices. + + + Action + {table.getVisibleColumns().map((column) => { + const sorting = column.getSortingValue(); + return ( + + column.setSort(sorting === "asc" ? "desc" : "asc") + } + key={column.id} + > + {column.id} + {sorting === "asc" ? "🔼" : sorting === "desc" ? "🔽" : ""} + + ); + })} + + + + {table.getRows().map((row) => ( + + + row.toggleRowSelection()} + /> + + {row.getVisibleCells().map((cell) => ( + + {cell.getValue()} + + ))} + + ))} + + + + Total + $2,500.00 + + +
+ + ); +}; diff --git a/apps/storybook/src/stories/sorting.stories.tsx b/apps/storybook/src/stories/sorting.stories.tsx new file mode 100644 index 0000000..6fab620 --- /dev/null +++ b/apps/storybook/src/stories/sorting.stories.tsx @@ -0,0 +1,99 @@ +import { ColumnDef, useTable } from "@arkejs/table"; +import { + Table, + TableBody, + TableCaption, + TableCell, + TableFooter, + TableHead, + TableHeader, + TableRow, +} from "../components/table.tsx"; +import { Invoice, invoices } from "../mocks/data.tsx"; +import { useState } from "react"; + +export default { + title: "Sorting", +}; + +const columns: ColumnDef[] = [ + { + id: "invoice", + }, + { + id: "paymentStatus", + enableSorting: false, + }, + { + id: "paymentMethod", + }, + { + id: "totalAmount", + }, +]; + +export const Sorting = () => { + const [enableSorting, setEnableSorting] = useState(true); + + const table = useTable({ + columns, + data: invoices, + enableSorting, + initialState: { + sorting: { + invoice: "asc", + }, + }, + }); + + return ( + <> +
+ setEnableSorting((prevState) => !prevState)} + /> + +
+ {JSON.stringify(table.getState().sorting)} + + A list of your recent invoices. + + + {table.getVisibleColumns().map((column) => { + const sorting = column.getSortingValue(); + return ( + + column.setSort(sorting === "asc" ? "desc" : "asc") + } + key={column.id} + > + {column.id} + {sorting === "asc" ? "🔼" : sorting === "desc" ? "🔽" : ""} + + ); + })} + + + + {table.getRows().map((row) => ( + + {row.getVisibleCells().map((cell) => ( + {cell.getValue()} + ))} + + ))} + + + + Total + $2,500.00 + + +
+ + ); +}; diff --git a/packages/table/README.md b/packages/table/README.md index e0427a3..54afd8f 100644 --- a/packages/table/README.md +++ b/packages/table/README.md @@ -1,6 +1,6 @@ # @arkejs/table -![Table](https://user-images.githubusercontent.com/81776297/233088195-b7781154-e5da-4a6c-bc27-25ae73d6f49c.png) +![Types](https://user-images.githubusercontent.com/81776297/233088195-b7781154-e5da-4a6c-bc27-25ae73d6f49c.png) [![License](https://img.shields.io/badge/license-Apache2.0-blue.svg)](https://github.com/arkemishub/arke-monorepo/blob/master/LICENSE.txt) @@ -30,7 +30,7 @@ npm i @arkejs/table The basic implementation allows you to display data without having any sort of control over pagination, filtering and more. ```jsx - + ``` --- @@ -51,11 +51,11 @@ function MyTable() { }, }); - return
+ return } ``` -As you can see by using `useTable` we don't need to define props for the `Table` component since they are returned in `tableProps`. +As you can see by using `useTable` we don't need to define props for the `Types` component since they are returned in `tableProps`. In addition, the hook provides us some ways to manage the table externally. Let's now implement a simple pagination, fully controlled by outside. @@ -71,7 +71,7 @@ function MyTable() { return ( <> -
+ - - {pages?.map((page) => ( - - ))} - - - - ); -} - -export default Pagination; diff --git a/packages/table/src/components/Pagination/index.ts b/packages/table/src/components/Pagination/index.ts deleted file mode 100644 index 411b916..0000000 --- a/packages/table/src/components/Pagination/index.ts +++ /dev/null @@ -1,18 +0,0 @@ -/** - * Copyright 2023 Arkemis S.r.l. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -export { default as Pagination } from "./Pagination"; -export * from "./Pagination.types"; diff --git a/packages/table/src/components/TableConfigProvider/TableConfigProvider.tsx b/packages/table/src/components/TableConfigProvider/TableConfigProvider.tsx deleted file mode 100644 index e7ebc09..0000000 --- a/packages/table/src/components/TableConfigProvider/TableConfigProvider.tsx +++ /dev/null @@ -1,46 +0,0 @@ -/** - * Copyright 2023 Arkemis S.r.l. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -import { createContext, useContext } from "react"; -import { - TableConfigProviderProps, - TableConfigValue, -} from "./TableConfigProvider.types"; -import { TableComponents } from "../../types"; - -const TableContext = createContext({ - components: {} as TableComponents, -}); - -function TableConfigProvider({ - children, - components, -}: TableConfigProviderProps) { - return ( - - {children} - - ); -} - -function useTableConfig() { - return useContext(TableContext) ?? {}; -} - -export default TableConfigProvider; -export { useTableConfig }; diff --git a/packages/table/src/components/TableConfigProvider/TableConfigProvider.types.ts b/packages/table/src/components/TableConfigProvider/TableConfigProvider.types.ts deleted file mode 100644 index d62a653..0000000 --- a/packages/table/src/components/TableConfigProvider/TableConfigProvider.types.ts +++ /dev/null @@ -1,28 +0,0 @@ -/** - * Copyright 2023 Arkemis S.r.l. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -import { PropsWithChildren } from "react"; -import { TableComponents } from "../../types"; - -type TableConfigProviderProps = PropsWithChildren<{}> & { - components?: TableComponents; -}; - -type TableConfigValue = { - components: TableComponents; -}; - -export { TableConfigProviderProps, TableConfigValue }; diff --git a/packages/table/src/components/TableConfigProvider/index.ts b/packages/table/src/components/TableConfigProvider/index.ts deleted file mode 100644 index 4a9d7ff..0000000 --- a/packages/table/src/components/TableConfigProvider/index.ts +++ /dev/null @@ -1,18 +0,0 @@ -/** - * Copyright 2023 Arkemis S.r.l. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -export { default as TableConfigProvider } from "./TableConfigProvider"; -export * from "./TableConfigProvider.types"; diff --git a/packages/table/src/components/TableHeadCell/TableHeadCell.tsx b/packages/table/src/components/TableHeadCell/TableHeadCell.tsx deleted file mode 100644 index 7ab059d..0000000 --- a/packages/table/src/components/TableHeadCell/TableHeadCell.tsx +++ /dev/null @@ -1,104 +0,0 @@ -/** - * Copyright 2023 Arkemis S.r.l. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -import { TableColumn, TableComponents } from "../../types"; -import { ISortData } from "../../hooks"; -import { useCallback, useMemo } from "react"; - -function Icon({ type }: { type: "asc" | "desc" }) { - return ( - - - - ); -} - -function TableHeadCell({ - className, - id, - style, - label, - sort, - sortable, - setSort, - sortType, - renderHeader, - components, -}: TableColumn & Partial & { components?: TableComponents }) { - const isSortingEnabled = sortable && sortType !== "custom"; - - const columnSort = useMemo(() => { - if (isSortingEnabled) { - return sort?.find((s) => s.key === id); - } - return undefined; - }, [sort, isSortingEnabled, id]); - - const handleChangeSort = useCallback(() => { - if (isSortingEnabled) { - const newSort = sort?.filter((s) => s.key !== id) ?? []; - - if (columnSort) { - if (columnSort.type === "asc") { - setSort?.([...newSort, { key: id, type: "desc" }]); - } else { - setSort?.(newSort); - } - } else { - setSort?.([...newSort, { key: id, type: "asc" }]); - } - } - }, [columnSort, id, setSort, sort, isSortingEnabled]); - - const Th = components?.TableHead ?? "th"; - - return ( - - ); -} - -export default TableHeadCell; diff --git a/packages/table/src/components/TableHeadCell/index.ts b/packages/table/src/components/TableHeadCell/index.ts deleted file mode 100644 index dcc22c1..0000000 --- a/packages/table/src/components/TableHeadCell/index.ts +++ /dev/null @@ -1,17 +0,0 @@ -/** - * Copyright 2023 Arkemis S.r.l. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -export { default as TableHeadCell } from "./TableHeadCell"; diff --git a/packages/table/src/components/index.ts b/packages/table/src/components/index.ts deleted file mode 100644 index 5211dd4..0000000 --- a/packages/table/src/components/index.ts +++ /dev/null @@ -1,19 +0,0 @@ -/** - * Copyright 2023 Arkemis S.r.l. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -export * from "./Pagination"; -export * from "./TableConfigProvider"; -export * from "./table"; diff --git a/packages/table/src/components/table.tsx b/packages/table/src/components/table.tsx deleted file mode 100644 index 470497b..0000000 --- a/packages/table/src/components/table.tsx +++ /dev/null @@ -1,233 +0,0 @@ -/** - * Copyright 2023 Arkemis S.r.l. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -import * as React from "react"; -import { Action, ITableProps, TableColumn } from "../types"; -import { useTableConfig } from "./TableConfigProvider/TableConfigProvider"; -import { TableHeadCell } from "./TableHeadCell"; -import { Fragment, ReactNode } from "react"; -import { Pagination } from "./Pagination"; - -const getPagedIndex = (index: number, currentPage: number, pageSize = 0) => - index + pageSize * currentPage; - -const TableComponent = React.forwardRef< - HTMLTableElement, - { children?: ReactNode } ->((props, ref) =>
- {renderHeader?.() ?? label} - {columnSort && } -
); - -TableComponent.displayName = "TableComponent"; - -const Table = React.forwardRef< - HTMLTableElement, - React.HTMLAttributes & ITableProps ->( - ( - { - columns, - data, - actions, - pages, - pageCount, - pageSize, - currentPage = 0, - goToPage, - paginationType, - sortable, - sort, - setSort, - sortType, - noResult = "No Result", - renderHeader, - expandedRows, - onExpandRow, - ...props - }, - ref - ) => { - const config = useTableConfig(); - const components = React.useMemo( - () => ({ ...config.components, ...props.components }), - [config.components, props.components] - ); - - const RenderedTable = components?.Table ?? TableComponent; - const Thead = components?.TableHeader ?? "thead"; - const Tbody = components?.TableBody ?? "tbody"; - const Tr = components?.TableRow ?? "tr"; - const Th = components?.TableHead ?? "th"; - const Td = components?.TableCell ?? "td"; - - const renderData = React.useCallback( - (column: TableColumn, row: Record, index: number) => { - if (column.render) { - return column.render(row, { - handleExpandRow: () => - onExpandRow?.(getPagedIndex(index, currentPage, pageSize)), - }); - } - - if (column.type && components[column.type]) { - return components[column.type]?.(row?.[column.id], row, column); - } - - return row?.[column.id] as React.ReactNode; - }, - [components, onExpandRow, currentPage, pageSize] - ); - - const displayedColumnCount = React.useMemo( - () => - actions ? actions.actions.length + columns.length : columns.length, - [columns.length, actions?.actions.length] - ); - - const renderExpanded = React.useCallback( - (row: Record, index: number) => { - if ( - !expandedRows?.[getPagedIndex(index, currentPage, pageSize)] || - !components.ExpandedRow - ) - return null; - - return ( - - - - ); - }, - [expandedRows, currentPage, pageSize, columns.length, components] - ); - - return ( - <> - - - - {actions && actions?.position !== "end" && ( - - )} - {columns.map((col) => ( - - col?.renderHeader?.() ?? renderHeader?.(col) - } - /> - ))} - {actions && actions?.position === "end" && ( - - )} - - - - {data?.length > 0 - ? data.map((row, index) => ( - - - {actions && actions.position !== "end" && ( - - )} - {columns.map((col) => ( - - ))} - {actions && actions.position === "end" && ( - - )} - - {renderExpanded(row, index)} - - )) - : noResult && ( - - - - )} - - - {pages && goToPage && paginationType !== "custom" && ( - - )} - - ); - } -); - -const TableAction = ({ - content, - onClick, - data, -}: Action & { data: Record }) => { - return ( - - ); -}; - -Table.displayName = "Table"; - -export { Table }; diff --git a/packages/table/src/constants/filters.ts b/packages/table/src/constants/filters.ts deleted file mode 100644 index 66e6c7d..0000000 --- a/packages/table/src/constants/filters.ts +++ /dev/null @@ -1,42 +0,0 @@ -/** - * Copyright 2023 Arkemis S.r.l. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -import { FilterOperator } from "../types"; - -const numericFilters = [ - FilterOperator.EQ, - FilterOperator.GE, - FilterOperator.GT, - FilterOperator.LT, - FilterOperator.LE, -]; - -const filters = { - string: [ - FilterOperator.ICONTAINS, - FilterOperator.ISTARTSWITH, - FilterOperator.IENDSWITH, - FilterOperator.EQ, - ], - boolean: [FilterOperator.EQ], - integer: numericFilters, - float: numericFilters, - date: numericFilters, - datetime: numericFilters, - time: numericFilters, -}; - -export default filters; diff --git a/packages/table/src/core/cell.ts b/packages/table/src/core/cell.ts new file mode 100644 index 0000000..631a379 --- /dev/null +++ b/packages/table/src/core/cell.ts @@ -0,0 +1,49 @@ +/* + * Copyright 2024 Arkemis S.r.l. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { Column, Row, Table, Cell } from "../types"; + +export type BaseCell = { + column: Column; + getValue: () => any; + renderValue: () => any; + id: string; + row: Row; +}; +export function initCell( + table: Table, + column: Column, + row: Row +) { + const getValue = () => (row.data as any)[column.id]; + + let cell: Cell = { + id: `${row.id}_${column.id}`, + row, + column, + getValue, + renderValue: () => + column?.columnDef.cell?.renderValue + ? column.columnDef.cell.renderValue(row.data) + : getValue(), + }; + + for (const feature of table.features) { + feature.initCell?.(table, cell, column, row); + } + + return cell; +} diff --git a/packages/table/src/core/column.ts b/packages/table/src/core/column.ts new file mode 100644 index 0000000..811fb8e --- /dev/null +++ b/packages/table/src/core/column.ts @@ -0,0 +1,41 @@ +/* + * Copyright 2024 Arkemis S.r.l. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { ColumnDef, Column, Table } from "../types"; + +export type BaseColumn = { + id: string; + columnDef: ColumnDef; +}; + +export function initColumn( + table: Table, + columnDef: ColumnDef +) { + let column: BaseColumn = { + id: columnDef.id, + columnDef: { + ...columnDef, + header: columnDef.header ?? columnDef.id, + }, + }; + + for (const feature of table.features) { + feature.initColumn?.(table, column as Column); + } + + return column; +} diff --git a/packages/table/src/core/row.ts b/packages/table/src/core/row.ts new file mode 100644 index 0000000..50458f3 --- /dev/null +++ b/packages/table/src/core/row.ts @@ -0,0 +1,45 @@ +/* + * Copyright 2024 Arkemis S.r.l. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { Cell, Row, Table } from "../types"; +import { initCell } from "./cell"; + +export type BaseRow = { + getAllCells: () => Cell[]; + id: string; + data: TData; +}; + +export function initRow( + table: Table, + id: string, + data: TData +) { + let row: BaseRow = { + id, + data, + getAllCells: () => + table + .getAllColumns() + .map((column) => initCell(table, column, row as Row)), + }; + + for (const feature of table.features) { + feature.initRow?.(table, row as Row); + } + + return row; +} diff --git a/packages/table/src/core/table.ts b/packages/table/src/core/table.ts new file mode 100644 index 0000000..4a3000a --- /dev/null +++ b/packages/table/src/core/table.ts @@ -0,0 +1,77 @@ +/* + * Copyright 2024 Arkemis S.r.l. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { Table, TableOptions, TableResolvedOptions } from "../types"; +import { functionalUpdate } from "../utils/functional-update"; +import { pagination } from "../features/pagination"; +import { initColumn } from "./column"; +import { columnVisibility } from "../features/column-visibility"; +import { initRow } from "./row"; +import { columnFiltering } from "../features/column-filtering"; +import { sorting } from "../features/sorting"; +import { rowSelection } from "../features/row-selection"; +import { columnPinning } from "../features/column-pinning"; + +const features = [ + pagination, + columnVisibility, + columnFiltering, + sorting, + rowSelection, + columnPinning, +]; +export function initTable( + options: TableOptions +): Table { + let initialState = options?.initialState ?? {}; + features.forEach((feature) => { + initialState = feature.getInitialState?.(initialState) ?? initialState; + }); + + let table = { features } as Table; + + const defaultOptions = features.reduce( + (obj, feature) => Object.assign(obj, feature.getDefaultOptions?.(table)), + {} as TableResolvedOptions + ); + + let instance = { + options: { + ...defaultOptions, + ...options, + }, + initialState, + setOptions: (updater) => { + table.options = functionalUpdate(updater, table.options); + }, + getState: () => table.options.state, + setState: (updater) => { + table.options.onStateChange?.(updater); + }, + getAllColumns: () => + table.options.columns?.map((column) => initColumn(table, column)) ?? [], + getRows: () => + table.options.data?.map((data, index) => + initRow(table, table.options.getRowId?.(data) ?? index.toString(), data) + ), + } as Table; + + Object.assign(table, instance); + + features.forEach((feature) => feature.init(table)); + + return table; +} diff --git a/packages/table/src/features/column-filtering.ts b/packages/table/src/features/column-filtering.ts new file mode 100644 index 0000000..27a517b --- /dev/null +++ b/packages/table/src/features/column-filtering.ts @@ -0,0 +1,77 @@ +/* + * Copyright 2024 Arkemis S.r.l. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import * as React from "react"; +import { TableFeature } from "../types"; +import { functionalUpdate } from "../utils/functional-update"; + +export type ColumnFilteringState = Record; + +export type ColumnFilteringTableState = { + columnFilters: ColumnFilteringState; +}; + +export type ColumnFilteringOptions = { + onColumnFiltersChange: ( + updater: React.SetStateAction + ) => void; + enableColumnFiltering?: boolean; +}; + +export type ColumnFilteringColumnDef = { + enableColumnFiltering?: boolean; +}; + +export type ColumnFilteringColumn = { + getFilterValue: () => unknown; + setFilter: (value: unknown) => void; + canFilter: () => boolean; +}; + +export type ColumnFilteringInstance = { + setColumnFilters: ( + updater: React.SetStateAction + ) => void; +}; + +export const columnFiltering: TableFeature = { + getDefaultOptions: (table) => ({ + onColumnFiltersChange: (updater) => + table.setState((prev) => ({ + ...prev, + columnFilters: functionalUpdate(updater, prev.columnFilters), + })), + }), + getInitialState: (state) => ({ + columnFilters: {}, + ...state, + }), + init: (table) => { + table.setColumnFilters = (updater) => + table.options.onColumnFiltersChange?.(updater); + }, + initColumn: (table, column) => { + column.getFilterValue = () => table.getState().columnFilters?.[column.id]; + column.setFilter = (value) => + table.setColumnFilters({ + ...table.getState().columnFilters, + [column.id]: value, + }); + column.canFilter = () => + (column.columnDef.enableColumnFiltering ?? true) && + (table.options.enableColumnFiltering ?? true); + }, +}; diff --git a/packages/table/src/features/column-pinning.ts b/packages/table/src/features/column-pinning.ts new file mode 100644 index 0000000..8551ddb --- /dev/null +++ b/packages/table/src/features/column-pinning.ts @@ -0,0 +1,89 @@ +/* + * Copyright 2024 Arkemis S.r.l. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import * as React from "react"; +import { Cell, Column, TableFeature } from "../types"; +import { functionalUpdate } from "../utils/functional-update"; + +export type ColumnPinningState = Record; + +export type ColumnPinningTableState = { + columnPinning: ColumnPinningState; +}; + +export type ColumnPinningOptions = { + onColumnPinningChange: ( + updater: React.SetStateAction + ) => void; +}; + +export type ColumnPinningInstance = { + setColumnPinning: (updater: React.SetStateAction) => void; + getAllPinnedColumns: () => Column[]; + getVisiblePinnedColumns: () => Column[]; + getVisibleUnpinnedColumns: () => Column[]; +}; + +export type ColumnPinningColumn = { + isPinned: () => boolean; + pin: (value?: boolean) => void; +}; + +export type ColumnPinningRow = { + getAllPinnedCells: () => Cell[]; + getVisiblePinnedCells: () => Cell[]; + getVisibleUnpinnedCells: () => Cell[]; +}; + +export const columnPinning: TableFeature = { + getDefaultOptions: (table) => ({ + onColumnPinningChange: (updater) => + table.setState((prev) => ({ + ...prev, + columnPinning: functionalUpdate(updater, prev.columnPinning), + })), + }), + getInitialState: (state) => ({ + columnPinning: {}, + ...state, + }), + init: (table) => { + table.setColumnPinning = (updater) => + table.options.onColumnPinningChange?.(updater); + table.getAllPinnedColumns = () => + table.getAllColumns().filter((column) => column.isPinned()); + table.getVisiblePinnedColumns = () => + table.getVisibleColumns().filter((column) => column.isPinned()); + table.getVisibleUnpinnedColumns = () => + table.getVisibleColumns().filter((column) => !column.isPinned()); + }, + initColumn: (table, column) => { + column.isPinned = () => table.getState().columnPinning[column.id] ?? false; + column.pin = (value) => + table.setColumnPinning((prev) => ({ + ...prev, + [column.id]: value ?? !prev[column.id], + })); + }, + initRow: (table, row) => { + row.getAllPinnedCells = () => + row.getAllCells().filter((cell) => cell.column.isPinned()); + row.getVisiblePinnedCells = () => + row.getVisibleCells().filter((cell) => cell.column.isPinned()); + row.getVisibleUnpinnedCells = () => + row.getVisibleCells().filter((cell) => !cell.column.isPinned()); + }, +}; diff --git a/packages/table/src/features/column-visibility.ts b/packages/table/src/features/column-visibility.ts new file mode 100644 index 0000000..cb30eb9 --- /dev/null +++ b/packages/table/src/features/column-visibility.ts @@ -0,0 +1,80 @@ +/* + * Copyright 2024 Arkemis S.r.l. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import * as React from "react"; +import { Cell, Column, TableFeature } from "../types"; +import { functionalUpdate } from "../utils/functional-update"; + +export type ColumnVisibilityState = Record; + +export type ColumnVisibilityTableState = { + columnVisibility: ColumnVisibilityState; +}; + +export type ColumnVisibilityOptions = { + onColumnVisibilityChange: ( + updater: React.SetStateAction + ) => void; +}; + +export type ColumnVisibilityInstance = { + setColumnVisibility: ( + updater: React.SetStateAction + ) => void; + getVisibleColumns: () => Column[]; +}; + +export type ColumnVisibilityColumn = { + isVisible: () => boolean; + toggleVisibility: (value?: boolean) => void; +}; + +export type ColumnVisibilityRow = { + getVisibleCells: () => Cell[]; +}; + +export const columnVisibility: TableFeature = { + getDefaultOptions: (table) => ({ + onColumnVisibilityChange: (updater) => + table.setState((prev) => ({ + ...prev, + columnVisibility: functionalUpdate(updater, prev.columnVisibility), + })), + }), + getInitialState: (state) => ({ + columnVisibility: {}, + ...state, + }), + init: (table) => { + table.setColumnVisibility = (updater) => + table.options.onColumnVisibilityChange?.(updater); + table.getVisibleColumns = () => + table.getAllColumns().filter((column) => column.isVisible()); + }, + initColumn: (table, column) => { + column.isVisible = () => + table.getState().columnVisibility?.[column.id] ?? true; + column.toggleVisibility = (value) => + table.setColumnVisibility((prev) => ({ + ...prev, + [column.id]: value ?? !column.isVisible(), + })); + }, + initRow: (table, row) => { + row.getVisibleCells = () => + row.getAllCells().filter((cell) => cell.column.isVisible()); + }, +}; diff --git a/packages/table/src/features/pagination.ts b/packages/table/src/features/pagination.ts new file mode 100644 index 0000000..15b1645 --- /dev/null +++ b/packages/table/src/features/pagination.ts @@ -0,0 +1,93 @@ +/* + * Copyright 2024 Arkemis S.r.l. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +// pagination is currently manual only + +import * as React from "react"; +import { TableFeature } from "../types"; +import { functionalUpdate } from "../utils/functional-update"; + +const DEFAULT_PAGE_SIZE = 10; +const DEFAULT_PAGE_INDEX = 0; + +export type PaginationState = { + pageSize: number; + pageIndex: number; +}; + +export type PaginationTableState = { + pagination: PaginationState; +}; + +export type PaginationOptions = { + onPaginationChange: (updater: React.SetStateAction) => void; + pageCount?: number; + rowCount?: number; +}; + +export type PaginationInstance = { + setPagination: (updater: React.SetStateAction) => void; + setPageIndex: (updater: React.SetStateAction) => void; + setPageSize: (updater: React.SetStateAction) => void; + getPageCount: () => number; + getRowCount: () => number; + nextPage: () => void; + previousPage: () => void; +}; + +const getDefaultPaginationState = (): PaginationState => ({ + pageIndex: DEFAULT_PAGE_INDEX, + pageSize: DEFAULT_PAGE_SIZE, +}); + +export const pagination: TableFeature = { + getDefaultOptions: (table) => ({ + onPaginationChange: (updater) => + table.setState((prev) => ({ + ...prev, + pagination: functionalUpdate(updater, prev.pagination), + })), + }), + getInitialState: (state) => ({ + ...state, + pagination: { + ...getDefaultPaginationState(), + ...state?.pagination, + }, + }), + init: (table) => { + table.setPagination = (updater) => + table.options.onPaginationChange?.(updater); + table.setPageIndex = (updater) => + table.setPagination((prev) => { + return { + ...prev, + pageIndex: functionalUpdate(updater, prev.pageIndex), + }; + }); + table.nextPage = () => table.setPageIndex((prev) => prev + 1); + table.previousPage = () => + table.setPageIndex((prev) => Math.max(prev - 1, 0)); + table.setPageSize = (updater) => + table.setPagination((prev) => { + return { ...prev, pageSize: functionalUpdate(updater, prev.pageSize) }; + }); + table.getPageCount = () => + table.options.pageCount ?? + Math.ceil(table.getRowCount() / table.getState().pagination.pageSize); + table.getRowCount = () => table.options.rowCount ?? 0; + }, +}; diff --git a/packages/table/src/features/row-selection.ts b/packages/table/src/features/row-selection.ts new file mode 100644 index 0000000..c7b9cbe --- /dev/null +++ b/packages/table/src/features/row-selection.ts @@ -0,0 +1,72 @@ +/* + * Copyright 2024 Arkemis S.r.l. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import * as React from "react"; +import { Row, TableFeature } from "../types"; +import { functionalUpdate } from "../utils/functional-update"; + +export type RowSelectionState = Record; + +export type RowSelectionTableState = { + rowSelection: RowSelectionState; +}; + +export type RowSelectionOptions = { + onRowSelectionChange: ( + updater: React.SetStateAction + ) => void; + enableRowSelection?: boolean; +}; + +export type RowSelectionInstance = { + setRowSelection: (updater: React.SetStateAction) => void; + getSelectedRows: () => Row[]; +}; + +export type RowSelectionRow = { + isSelected: () => boolean; + toggleRowSelection: (value?: boolean) => void; + canSelect: () => boolean; +}; + +export const rowSelection: TableFeature = { + getDefaultOptions: (table) => ({ + onRowSelectionChange: (updater) => + table.setState((prev) => ({ + ...prev, + rowSelection: functionalUpdate(updater, prev.rowSelection), + })), + }), + getInitialState: (state) => ({ + rowSelection: {}, + ...state, + }), + init: (table) => { + table.setRowSelection = (updater) => + table.options.onRowSelectionChange?.(updater); + table.getSelectedRows = () => + table.getRows().filter((row) => row.isSelected()); + }, + initRow: (table, row) => { + row.toggleRowSelection = (value) => + table.setRowSelection((prev) => ({ + ...prev, + [row.id]: value ?? !prev[row.id], + })); + row.isSelected = () => table.getState().rowSelection[row.id] ?? false; + row.canSelect = () => table.options.enableRowSelection ?? true; + }, +}; diff --git a/packages/table/src/features/sorting.ts b/packages/table/src/features/sorting.ts new file mode 100644 index 0000000..28c85fc --- /dev/null +++ b/packages/table/src/features/sorting.ts @@ -0,0 +1,76 @@ +/* + * Copyright 2024 Arkemis S.r.l. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import * as React from "react"; +import { TableFeature } from "../types"; +import { functionalUpdate } from "../utils/functional-update"; +import pre from "@changesets/cli/dist/declarations/src/commands/pre"; + +export type Sort = "asc" | "desc" | undefined; +export type SortingState = Record; + +export type SortTableState = { + sorting: SortingState; +}; + +export type SortingOptions = { + onSortingChange: (updater: React.SetStateAction) => void; + enableSorting?: boolean; +}; + +export type SortingColumnDef = { + enableSorting?: boolean; +}; + +export type SortingColumn = { + getSortingValue: () => Sort; + canSort: () => boolean; + setSort: (value: Sort) => void; +}; + +export type SortingInstance = { + setSorting: (updater: React.SetStateAction) => void; +}; + +export const sorting: TableFeature = { + getDefaultOptions: (table) => ({ + onSortingChange: (updater) => + table.setState((prev) => ({ + ...prev, + sorting: functionalUpdate(updater, prev.sorting), + })), + }), + getInitialState: (state) => ({ + sorting: {}, + ...state, + }), + init: (table) => { + table.setSorting = (updater) => table.options.onSortingChange?.(updater); + }, + initColumn: (table, column) => { + column.canSort = () => + (column.columnDef.enableSorting ?? true) && + (table.options.enableSorting ?? true); + column.getSortingValue = () => table.getState().sorting?.[column.id]; + column.setSort = (value) => { + if (column.canSort()) + table.setSorting((prevState) => ({ + ...prevState, + [column.id]: value, + })); + }; + }, +}; diff --git a/packages/table/src/hooks/index.ts b/packages/table/src/hooks/index.ts deleted file mode 100644 index f30d0fa..0000000 --- a/packages/table/src/hooks/index.ts +++ /dev/null @@ -1,17 +0,0 @@ -/** - * Copyright 2023 Arkemis S.r.l. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -export * from "./useTable"; diff --git a/packages/table/src/hooks/usePagination.ts b/packages/table/src/hooks/usePagination.ts deleted file mode 100644 index 02df54a..0000000 --- a/packages/table/src/hooks/usePagination.ts +++ /dev/null @@ -1,65 +0,0 @@ -/** - * Copyright 2023 Arkemis S.r.l. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -import { useMemo } from "react"; - -const range = (start: number, end: number) => { - let length = end - start + 1; - return Array.from({ length }, (_, idx) => idx + start); -}; - -const usePagination = ({ - totalCount, - pageSize, - siblingCount = 3, - currentPage = 0, -}: { - totalCount: number; - pageSize: number; - siblingCount?: number; - currentPage: number; -}) => { - return useMemo(() => { - const totalPageCount = Math.ceil(totalCount / pageSize); - - // first page - if (currentPage < siblingCount) { - const firstItem = Math.min(0, currentPage); - const lastItem = Math.min(siblingCount * 2, totalPageCount); - return { pageCount: totalPageCount, pages: range(firstItem, lastItem) }; - } - - // last pages - if (totalPageCount - currentPage <= siblingCount) { - const firstItem = Math.min( - totalPageCount - siblingCount * 2, - currentPage - ); - return { - pageCount: totalPageCount, - pages: range(firstItem, totalPageCount - 1), - }; - } - - const lastItem = Math.min(currentPage + siblingCount, totalPageCount); - return { - pageCount: totalPageCount, - pages: range(currentPage - siblingCount, lastItem), - }; - }, [totalCount, pageSize, siblingCount, currentPage]); -}; - -export default usePagination; diff --git a/packages/table/src/hooks/useTable/index.ts b/packages/table/src/hooks/useTable/index.ts deleted file mode 100644 index 5745c07..0000000 --- a/packages/table/src/hooks/useTable/index.ts +++ /dev/null @@ -1,18 +0,0 @@ -/** - * Copyright 2023 Arkemis S.r.l. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -export { default as useTable } from "./useTable"; -export * from "./useTable.types"; diff --git a/packages/table/src/hooks/useTable/useTable.ts b/packages/table/src/hooks/useTable/useTable.ts deleted file mode 100644 index 2402588..0000000 --- a/packages/table/src/hooks/useTable/useTable.ts +++ /dev/null @@ -1,202 +0,0 @@ -/** - * Copyright 2023 Arkemis S.r.l. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -import { useReducer, useState } from "react"; -import usePagination from "../usePagination"; -import type { TableColumn, TableFilter, TableSort } from "../../types"; -import type { - IPaginationConfig, - ISortConfig, - IUseTableConfig, - IUseTableData, - TableState, - UseTableAction, -} from "./useTable.types"; -import { default as availableFilters } from "../../constants/filters"; - -function tableReducer(state: TableState, action: UseTableAction) { - const { type, payload } = action; - - switch (type) { - case "updateCurrentPage": - return { ...state, currentPage: payload }; - case "updatePageSize": - return { ...state, pageSize: payload }; - case "toggleVisibleItem": - return { - ...state, - visibleColumns: state.visibleColumns.includes(payload) - ? state.visibleColumns.filter((c) => c !== payload) - : [...state.visibleColumns, payload], - }; - case "toggleMultipleVisibleItems": - return { - ...state, - visibleColumns: payload.filter((c) => !c.hidden).map((c) => c.id), - }; - case "toggleAllVisibleItems": - return { - ...state, - visibleColumns: payload?.every((c) => - state.visibleColumns.includes(c.id) - ) - ? [] - : payload?.map((c) => c.id), - }; - case "setFilters": - return { - ...state, - filters: payload, - // reset expanded rows when filters change - expandedRows: {}, - }; - case "resetAllFilters": - return { - ...state, - filters: state.initialFilters ?? [], - }; - case "setSort": - return { - ...state, - sort: payload, - }; - case "setExpandedRows": - return { - ...state, - expandedRows: { - ...state.expandedRows, - [payload]: !state.expandedRows[payload], - }, - }; - - case "refresh": - return { ...state, ...payload }; - default: - return state; - } -} - -function useTable< - P extends IPaginationConfig | undefined, - S extends ISortConfig | undefined, - E extends boolean ->(config: IUseTableConfig | null): IUseTableData { - const { pagination, columns, initialFilters, sorting, expandable } = - config ?? {}; - const [prevConfig, setPrevConfig] = useState(config ?? null); - const [ - { currentPage, pageSize, visibleColumns, filters, sort, expandedRows }, - dispatch, - ] = useReducer(tableReducer, { - currentPage: pagination?.initialPage || 0, - pageSize: pagination?.pageSize || 10, - visibleColumns: columns?.filter((c) => !c.hidden).map((c) => c.id) ?? [], - filters: initialFilters ?? [], - initialFilters: initialFilters ?? [], - sort: sorting?.default ?? [], - expandedRows: {}, - }); - - if (JSON.stringify(config) !== JSON.stringify(prevConfig)) { - setPrevConfig(config); - dispatch({ - type: "refresh", - payload: { - pageSize: config?.pagination?.pageSize ?? 10, - currentPage: config?.pagination?.initialPage ?? 0, - visibleColumns: - config?.columns?.filter((c) => !c.hidden).map((c) => c.id) ?? [], - sort: [], - }, - }); - } - - const { pages, pageCount } = usePagination({ - totalCount: pagination?.totalCount ?? 0, - pageSize, - currentPage, - }); - - let data = {}; - - if (pagination) { - data = { - ...data, - goToPage: (page: number) => { - dispatch({ type: "updateCurrentPage", payload: page }); - pagination.onChange?.(page); - }, - setPageSize: (size: number) => - dispatch({ type: "updatePageSize", payload: size }), - pageCount, - pages, - pageSize, - currentPage, - paginationType: pagination.type, - totalCount: pagination?.totalCount ?? 0, - }; - } - - if (columns) { - data = { - ...data, - filters, - allColumns: columns.map((c) => ({ - ...c, - toggleHide: () => - dispatch({ type: "toggleVisibleItem", payload: c.id }), - hidden: !visibleColumns.includes(c.id), - availableFilterOperators: - c?.availableFilterOperators ?? - (c?.type && availableFilters?.[c.type]), - })), - toggleHide: (columns: TableColumn[]) => - dispatch({ type: "toggleMultipleVisibleItems", payload: columns }), - toggleHideAll: () => - dispatch({ type: "toggleAllVisibleItems", payload: columns }), - columns: columns - .filter((c) => visibleColumns.includes(c.id)) - .map((column) => ({ ...column, sortable: column?.sortable ?? true })), - setFilters: (filters: TableFilter[]) => - dispatch({ type: "setFilters", payload: filters }), - resetAllFilters: () => - dispatch({ type: "resetAllFilters", payload: undefined }), - }; - - if (sorting) { - data = { - ...data, - sort, - sortable: !!config?.sorting?.sortable, - setSort: (sort: TableSort[]) => dispatch({ type: "setSort", payload: sort }), - sortType: sorting.type, - }; - } - - if (expandable) { - data = { - ...data, - expandedRows, - onExpandRow: (id: number) => - dispatch({ type: "setExpandedRows", payload: id }), - }; - } - } - - return { tableProps: data, ...data } as IUseTableData; -} - -export default useTable; diff --git a/packages/table/src/hooks/useTable/useTable.types.ts b/packages/table/src/hooks/useTable/useTable.types.ts deleted file mode 100644 index 8609c6e..0000000 --- a/packages/table/src/hooks/useTable/useTable.types.ts +++ /dev/null @@ -1,130 +0,0 @@ -/** - * Copyright 2023 Arkemis S.r.l. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -import { TableColumn, TableExpandedState, TableFilter, TableSort } from "../../types"; - -type AllColumns = Array< - TableColumn & { - toggleHide: () => void; - hidden: boolean; - } ->; - -type IPaginationConfig = { - initialPage?: number; - pageSize?: number; - totalCount: number; - siblingCount?: number; - onChange?: (page: number) => void; - type?: "custom"; -}; - -type ISortConfig = { default?: TableSort[]; sortable?: boolean; type?: "custom" }; - -interface IUseTableConfig { - pagination?: Pagination; - columns: TableColumn[]; - sorting?: ISortConfig; - expandable?: Expandable; - initialFilters?: TableFilter[]; -} - -interface IPaginationData { - goToPage: (page: number) => void; - setPageSize: (size: number) => void; - pageSize: number; - pageCount: number; - pages: number[]; - currentPage: number; - paginationType?: "custom"; - totalCount?: number; -} - -type IColumnsData = { - allColumns: AllColumns; - toggleHideAll: () => void; - toggleHide: (columns: TableColumn[]) => void; - columns: Array>; - resetAllFilters: () => void; - setFilters: (filters: TableFilter[]) => void; - filters: Array; -}; - -type ISortData = { - sort: TableSort[]; - setSort: (sort: TableSort[]) => void; - sortable: boolean; - sortType?: "custom"; -}; - -type IExpandableData = { - expandedRows: TableExpandedState; -}; - -type IUseTableResult = - (Pagination extends undefined ? undefined : IPaginationData) & - (TableSort extends undefined ? undefined : ISortData) & - (Expandable extends true ? IExpandableData : undefined) & - IColumnsData; - -type IUseTableForwardedProps = IUseTableResult< - Pagination, - TableSort, - Expandable -> & { - onExpandRow?: (index: number) => void; -}; - -type IUseTableData = { - tableProps: IUseTableForwardedProps; -} & IUseTableResult; - -type TableState = { - currentPage: number; - pageSize: number; - visibleColumns: string[]; - filters: TableFilter[]; - sort: TableSort[]; - expandedRows: TableExpandedState; - initialFilters: TableFilter[]; -}; - -type UseTableAction = - | { - type: "updateCurrentPage" | "updatePageSize"; - payload: number; - } - | { type: "toggleVisibleItem"; payload: string } - | { type: "toggleMultipleVisibleItems"; payload: TableColumn[] } - | { type: "toggleAllVisibleItems"; payload: TableColumn[] } - | { type: "refresh"; payload: Partial } - | { type: "setFilters"; payload: TableFilter[] } - | { type: "resetAllFilters"; payload: undefined } - | { type: "setSort"; payload: TableSort[] } - | { type: "setExpandedRows"; payload: number }; - -export { - IUseTableData, - IUseTableConfig, - IPaginationData, - IPaginationConfig, - ISortConfig, - ISortData, - TableState, - UseTableAction, - AllColumns, - IUseTableForwardedProps, -}; diff --git a/packages/table/src/index.ts b/packages/table/src/index.ts index da0ad36..19a42c5 100644 --- a/packages/table/src/index.ts +++ b/packages/table/src/index.ts @@ -1,11 +1,11 @@ -/** - * Copyright 2023 Arkemis S.r.l. +/* + * Copyright 2024 Arkemis S.r.l. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, @@ -14,6 +14,12 @@ * limitations under the License. */ -export * from "./components"; -export * from "./hooks"; +export * from "./use-table"; + +export * from "./features/column-filtering"; +export * from "./features/column-visibility"; +export * from "./features/pagination"; +export * from "./features/row-selection"; +export * from "./features/sorting"; + export * from "./types"; diff --git a/packages/table/src/types.ts b/packages/table/src/types.ts new file mode 100644 index 0000000..f67f3e8 --- /dev/null +++ b/packages/table/src/types.ts @@ -0,0 +1,147 @@ +/* + * Copyright 2024 Arkemis S.r.l. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import * as React from "react"; +import { + PaginationInstance, + PaginationOptions, + PaginationTableState, +} from "./features/pagination"; +import { + ColumnVisibilityColumn, + ColumnVisibilityInstance, + ColumnVisibilityOptions, + ColumnVisibilityRow, + ColumnVisibilityTableState, +} from "./features/column-visibility"; +import { BaseRow } from "./core/row"; +import { BaseCell } from "./core/cell"; +import { + ColumnFilteringColumn, + ColumnFilteringColumnDef, + ColumnFilteringInstance, + ColumnFilteringOptions, + ColumnFilteringTableState, +} from "./features/column-filtering"; +import { + SortingColumn, + SortingColumnDef, + SortingInstance, + SortingOptions, + SortTableState, +} from "./features/sorting"; +import { + RowSelectionInstance, + RowSelectionOptions, + RowSelectionRow, + RowSelectionTableState, +} from "./features/row-selection"; +import { + ColumnPinningColumn, + ColumnPinningInstance, + ColumnPinningOptions, + ColumnPinningRow, + ColumnPinningTableState, +} from "./features/column-pinning"; +import { BaseColumn } from "./core/column"; + +export type TableState = PaginationTableState & + ColumnVisibilityTableState & + ColumnFilteringTableState & + SortTableState & + RowSelectionTableState & + ColumnPinningTableState; + +export type TableBaseOptions = { + columns: ColumnDef[]; + state: Partial; + onStateChange: React.Dispatch>; + initialState?: Partial; + data: TData[]; + getRowId?: (data: TData) => string; +}; + +export type TableResolvedOptions = TableBaseOptions & + PaginationOptions & + ColumnVisibilityOptions & + ColumnFilteringOptions & + SortingOptions & + RowSelectionOptions & + ColumnPinningOptions; + +export type TableOptions = Partial< + TableResolvedOptions +>; + +export type TableBaseInstance = { + features: TableFeature[]; + setOptions: React.Dispatch>>; + options: TableOptions; + initialState: TableState; + getState: () => TableState; + setState: React.Dispatch>; + getAllColumns: () => Column[]; + getRows: () => Row[]; +}; + +export type Table = TableBaseInstance & + PaginationInstance & + ColumnVisibilityInstance & + ColumnFilteringInstance & + SortingInstance & + RowSelectionInstance & + ColumnPinningInstance; + +export type ColumnConfig = Record; + +export type ColumnDef = SortingColumnDef & + ColumnFilteringColumnDef & { + id: string; + header?: string; + cell?: { + renderValue?: (value: TData) => React.ReactNode; + }; + config?: ColumnConfig; + }; + +export type Row = BaseRow & + ColumnVisibilityRow & + RowSelectionRow & + ColumnPinningRow; + +export type Cell = BaseCell; + +export type Column = BaseColumn & + ColumnVisibilityColumn & + ColumnFilteringColumn & + SortingColumn & + ColumnPinningColumn; + +export type TableFeature = { + getInitialState?: (state?: Partial) => Partial; + init: (table: Table) => void; + getDefaultOptions?: ( + table: Table + ) => Partial>; + initColumn?: (table: Table, column: Column) => void; + initRow?: (table: Table, row: Row) => void; + initCell?: ( + table: Table, + cell: Cell, + column: Column, + row: Row + ) => void; +}; diff --git a/packages/table/src/types/action.ts b/packages/table/src/types/action.ts deleted file mode 100644 index 23db141..0000000 --- a/packages/table/src/types/action.ts +++ /dev/null @@ -1,24 +0,0 @@ -/** - * Copyright 2023 Arkemis S.r.l. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -import { ReactNode } from "react"; - -type Action = { - content: ((data: Record) => ReactNode) | ReactNode; - onClick?: (data: Record) => void; -}; - -export type { Action }; diff --git a/packages/table/src/types/column.ts b/packages/table/src/types/column.ts deleted file mode 100644 index 4de0cd2..0000000 --- a/packages/table/src/types/column.ts +++ /dev/null @@ -1,41 +0,0 @@ -/** - * Copyright 2023 Arkemis S.r.l. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -import { CSSProperties, ReactNode } from "react"; -import { FilterOperator } from "./filters"; - -export type TableColumn = { - id: string; - label: string; - renderHeader?: () => string | number | ReactNode; - render?: ( - data: Record, - actions: { handleExpandRow: () => void } - ) => string | number | ReactNode; - className?: string; - style?: CSSProperties; - type?: - | "boolean" - | "date" - | "datetime" - | "float" - | "integer" - | "string" - | "time"; - availableFilterOperators?: Array; - sortable?: boolean; - hidden?: boolean; -}; diff --git a/packages/table/src/types/components.ts b/packages/table/src/types/components.ts deleted file mode 100644 index 7575db3..0000000 --- a/packages/table/src/types/components.ts +++ /dev/null @@ -1,52 +0,0 @@ -/** - * Copyright 2023 Arkemis S.r.l. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -import { TableColumn } from "./column"; -import * as React from "react"; - -type TableComponents = Partial< - Record< - string, - ( - value: any, - rowData: Record, - column: TableColumn - ) => React.ReactElement - > -> & { - ExpandedRow?: (rowData: Record) => React.ReactElement; - Table?: (props: React.HTMLAttributes) => JSX.Element | null; - TableHeader?: ( - props: React.HTMLAttributes - ) => JSX.Element | null; - TableBody?: ( - props: React.HTMLAttributes - ) => JSX.Element | null; - TableRow?: ( - props: React.HTMLAttributes - ) => JSX.Element | null; - TableHead?: ( - props: React.ThHTMLAttributes - ) => JSX.Element | null; - TableCell?: ( - props: React.TdHTMLAttributes - ) => JSX.Element | null; - TableFooter?: ( - props: React.HTMLAttributes - ) => JSX.Element | null; -}; - -export type { TableComponents }; diff --git a/packages/table/src/types/expandable.ts b/packages/table/src/types/expandable.ts deleted file mode 100644 index 6afcefa..0000000 --- a/packages/table/src/types/expandable.ts +++ /dev/null @@ -1,19 +0,0 @@ -/** - * Copyright 2023 Arkemis S.r.l. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -type TableExpandedState = Record; - -export type { TableExpandedState }; diff --git a/packages/table/src/types/filters.ts b/packages/table/src/types/filters.ts deleted file mode 100644 index 175ec56..0000000 --- a/packages/table/src/types/filters.ts +++ /dev/null @@ -1,38 +0,0 @@ -/** - * Copyright 2023 Arkemis S.r.l. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -export enum FilterOperator { - EQ = "eq", - LE = "le", - LT = "lt", - GT = "gt", - GE = "ge", - NE = "ne", - CONTAINS = "contains", - ICONTAINS = "icontains", - STARTSWITH = "startswith", - ISTARTSWITH = "istartswith", - ENDSWITH = "endswith", - IENDSWITH = "iendswith", - IN = "in", - BETWEEN = "between", -} - -export type TableFilter = { - key: string; - operator: FilterOperator; - value: string | number; -}; diff --git a/packages/table/src/types/index.ts b/packages/table/src/types/index.ts deleted file mode 100644 index 99f7378..0000000 --- a/packages/table/src/types/index.ts +++ /dev/null @@ -1,23 +0,0 @@ -/** - * Copyright 2023 Arkemis S.r.l. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -export * from "./action"; -export * from "./column"; -export * from "./components"; -export * from "./expandable"; -export * from "./filters"; -export * from "./sort"; -export * from "./table"; diff --git a/packages/table/src/types/sort.ts b/packages/table/src/types/sort.ts deleted file mode 100644 index aed5c1c..0000000 --- a/packages/table/src/types/sort.ts +++ /dev/null @@ -1,22 +0,0 @@ -/** - * Copyright 2023 Arkemis S.r.l. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -type TableSort = { - type: "asc" | "desc"; - key: string; -}; - -export { TableSort }; diff --git a/packages/table/src/types/table.ts b/packages/table/src/types/table.ts deleted file mode 100644 index 7923711..0000000 --- a/packages/table/src/types/table.ts +++ /dev/null @@ -1,43 +0,0 @@ -/** - * Copyright 2023 Arkemis S.r.l. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -import { CSSProperties, ReactNode } from "react"; -import { TableColumn } from "./column"; -import { TableComponents } from "./components"; -import { IUseTableForwardedProps } from "../hooks"; -import { Action } from "./action"; - -type ITableProps = { - /** - * Table Columns - */ - columns: Omit[]; - data: Record[]; - actions?: ActionsConfig; - noResult?: ReactNode; - renderHeader?: (column: TableColumn) => ReactNode; - components?: TableComponents; -} & Partial>; - -type ActionsConfig = { - label: string | ReactNode; - position?: "start" | "end"; - className?: string; - style?: CSSProperties; - actions: Array; -}; - -export { ITableProps }; diff --git a/packages/table/src/use-table.tsx b/packages/table/src/use-table.tsx new file mode 100644 index 0000000..894ea0a --- /dev/null +++ b/packages/table/src/use-table.tsx @@ -0,0 +1,46 @@ +/* + * Copyright 2024 Arkemis S.r.l. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import * as React from "react"; +import { TableOptions } from "./types"; +import { initTable } from "./core/table"; + +export function useTable(options: TableOptions) { + const [table] = React.useState(() => + initTable({ + state: {}, + onStateChange: () => {}, + ...options, + }) + ); + + const [state, setState] = React.useState(() => table.initialState); + + table.setOptions((prev) => ({ + ...prev, + ...options, + state: { + ...state, + ...options.state, + }, + onStateChange: (state) => { + setState(state); + options.onStateChange?.(state); + }, + })); + + return table; +} diff --git a/packages/table/src/components/Pagination/Pagination.types.ts b/packages/table/src/utils/functional-update.ts similarity index 63% rename from packages/table/src/components/Pagination/Pagination.types.ts rename to packages/table/src/utils/functional-update.ts index e3e5064..09708aa 100644 --- a/packages/table/src/components/Pagination/Pagination.types.ts +++ b/packages/table/src/utils/functional-update.ts @@ -1,11 +1,11 @@ -/** - * Copyright 2023 Arkemis S.r.l. +/* + * Copyright 2024 Arkemis S.r.l. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, @@ -14,11 +14,12 @@ * limitations under the License. */ -interface IPaginationProps { - pageCount: number; - pages: number[]; - currentPage: number; - onChange: (page: number) => void; +import * as React from "react"; +export function functionalUpdate( + updater: React.SetStateAction, + input: T +): T { + return typeof updater === "function" + ? (updater as (input: T) => T)(input) + : updater; } - -export { IPaginationProps }; diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index b3ece02..35452bc 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -25,7 +25,7 @@ importers: version: 2.26.2 '@turbo/gen': specifier: ^1.9.7 - version: 1.9.7(@types/node@17.0.12)(typescript@5.1.6) + version: 1.9.7(@types/node@18.16.19)(typescript@5.1.6) eslint: specifier: ^8.41.0 version: 8.41.0 @@ -141,6 +141,9 @@ importers: '@arkejs/table': specifier: workspace:table version: link:../../packages/table + class-variance-authority: + specifier: ^0.7.0 + version: 0.7.0 clsx: specifier: ^2.1.0 version: 2.1.0 @@ -228,7 +231,7 @@ importers: version: 5.1.6 vite: specifier: ^4.4.0 - version: 4.4.4(@types/node@17.0.12) + version: 4.4.4(@types/node@18.16.19) packages/table: dependencies: @@ -2743,7 +2746,7 @@ packages: magic-string: 0.27.0 react-docgen-typescript: 2.2.2(typescript@5.1.6) typescript: 5.1.6 - vite: 4.4.4(@types/node@17.0.12) + vite: 4.4.4(@types/node@18.16.19) dev: true /@jridgewell/gen-mapping@0.3.3: @@ -4139,7 +4142,7 @@ packages: magic-string: 0.30.1 rollup: 3.26.2 typescript: 5.1.6 - vite: 4.4.4(@types/node@17.0.12) + vite: 4.4.4(@types/node@18.16.19) transitivePeerDependencies: - encoding - supports-color @@ -4616,7 +4619,7 @@ packages: react: 18.2.0 react-docgen: 7.0.3 react-dom: 18.2.0(react@18.2.0) - vite: 4.4.4(@types/node@17.0.12) + vite: 4.4.4(@types/node@18.16.19) transitivePeerDependencies: - '@preact/preset-vite' - encoding @@ -4821,7 +4824,7 @@ packages: resolution: {integrity: sha512-vxhUy4J8lyeyinH7Azl1pdd43GJhZH/tP2weN8TntQblOY+A0XbT8DJk1/oCPuOOyg/Ja757rG0CgHcWC8OfMA==} dev: false - /@turbo/gen@1.9.7(@types/node@17.0.12)(typescript@5.1.6): + /@turbo/gen@1.9.7(@types/node@18.16.19)(typescript@5.1.6): resolution: {integrity: sha512-mjenROdRNvYxZixNfamJY/XxwKMT+01PuQby8+qdRUUa5ZLBPOv4rw11n+II1O8ZnpFpBJIGGFJcnRNY+lCddw==} hasBin: true dependencies: @@ -4832,7 +4835,7 @@ packages: minimatch: 9.0.3 node-plop: 0.26.3 semver: 7.5.4 - ts-node: 10.9.1(@types/node@17.0.12)(typescript@5.1.6) + ts-node: 10.9.1(@types/node@18.16.19)(typescript@5.1.6) update-check: 1.5.4 validate-npm-package-name: 5.0.0 transitivePeerDependencies: @@ -5384,7 +5387,7 @@ packages: '@babel/plugin-transform-react-jsx-source': 7.22.5(@babel/core@7.22.9) magic-string: 0.27.0 react-refresh: 0.14.0 - vite: 4.4.4(@types/node@17.0.12) + vite: 4.4.4(@types/node@18.16.19) transitivePeerDependencies: - supports-color dev: true @@ -5399,7 +5402,7 @@ packages: '@babel/plugin-transform-react-jsx-self': 7.22.5(@babel/core@7.22.9) '@babel/plugin-transform-react-jsx-source': 7.22.5(@babel/core@7.22.9) react-refresh: 0.14.0 - vite: 4.4.4(@types/node@17.0.12) + vite: 4.4.4(@types/node@18.16.19) transitivePeerDependencies: - supports-color dev: true @@ -6337,6 +6340,12 @@ packages: resolution: {integrity: sha512-eXTggHWSooYhq49F2opQhuHWgzucfF2YgODK4e1566GQs5BIfP30B0oenwBJHfWxAs2fyPB1s7Mg949zLf61Yw==} engines: {node: '>=8'} + /class-variance-authority@0.7.0: + resolution: {integrity: sha512-jFI8IQw4hczaL4ALINxqLEXQbWcNjoSkloa4IaufXCJr6QawJyw7tuRysRsrE8w2p/4gGaxKIt/hX3qz/IbD1A==} + dependencies: + clsx: 2.0.0 + dev: false + /clean-stack@2.2.0: resolution: {integrity: sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A==} engines: {node: '>=6'} @@ -6407,6 +6416,11 @@ packages: resolution: {integrity: sha512-JQHZ2QMW6l3aH/j6xCqQThY/9OH4D/9ls34cgkUBiEeocRTU04tHfKPBsUK1PqZCUQM7GiA0IIXJSuXHI64Kbg==} engines: {node: '>=0.8'} + /clsx@2.0.0: + resolution: {integrity: sha512-rQ1+kcj+ttHG0MKVGBUXwayCCF1oh39BF5COIpRzuCEv8Mwjv0XucrI2ExNTOn9IlLifGClWQcU9BrZORvtw6Q==} + engines: {node: '>=6'} + dev: false + /clsx@2.1.0: resolution: {integrity: sha512-m3iNNWpd9rl3jvvcBnu70ylMdrXt8Vlq4HYadnU5fwcOtvkSQWPmj7amUcDT2qYI7risszBjI5AUIUox9D16pg==} engines: {node: '>=6'} @@ -9266,7 +9280,7 @@ packages: resolution: {integrity: sha512-7vuh85V5cdDofPyxn58nrPjBktZo0u9x1g8WtjQol+jZDaE+fhN+cIvTj11GndBnMnyfrUOG1sZQxCdjKh+DKg==} engines: {node: '>= 10.13.0'} dependencies: - '@types/node': 17.0.12 + '@types/node': 18.16.19 merge-stream: 2.0.0 supports-color: 8.1.1 dev: true @@ -11155,6 +11169,22 @@ packages: camelcase-css: 2.0.1 postcss: 8.4.35 + /postcss-load-config@3.1.4: + resolution: {integrity: sha512-6DiM4E7v4coTE4uzA8U//WhtPwyhiim3eyjEMFCnUpzbrkK9wJHgKDT2mR+HbtSrd/NubVaYTOpSpjUl8NQeRg==} + engines: {node: '>= 10'} + peerDependencies: + postcss: '>=8.0.9' + ts-node: '>=9.0.0' + peerDependenciesMeta: + postcss: + optional: true + ts-node: + optional: true + dependencies: + lilconfig: 2.1.0 + yaml: 1.10.2 + dev: true + /postcss-load-config@3.1.4(postcss@8.4.21): resolution: {integrity: sha512-6DiM4E7v4coTE4uzA8U//WhtPwyhiim3eyjEMFCnUpzbrkK9wJHgKDT2mR+HbtSrd/NubVaYTOpSpjUl8NQeRg==} engines: {node: '>= 10'} @@ -12909,7 +12939,7 @@ packages: /ts-interface-checker@0.1.13: resolution: {integrity: sha512-Y/arvbn+rrz3JCKl9C4kVNfTfSm2/mEp5FSz5EsZSANGPSlQrpRI5M4PKF+mJnE52jOO90PnPSc3Ur3bTQw0gA==} - /ts-node@10.9.1(@types/node@17.0.12)(typescript@5.1.6): + /ts-node@10.9.1(@types/node@18.16.19)(typescript@5.1.6): resolution: {integrity: sha512-NtVysVPkxxrwFGUUxGYhfux8k78pQB3JqYBXlLRZgdGUqTO5wU/UyHop5p70iEbGhB7q5KmiZiU0Y3KlJrScEw==} hasBin: true peerDependencies: @@ -12928,7 +12958,7 @@ packages: '@tsconfig/node12': 1.0.11 '@tsconfig/node14': 1.0.3 '@tsconfig/node16': 1.0.4 - '@types/node': 17.0.12 + '@types/node': 18.16.19 acorn: 8.10.0 acorn-walk: 8.2.0 arg: 4.1.3 @@ -12983,7 +13013,7 @@ packages: execa: 5.1.1 globby: 11.1.0 joycon: 3.1.1 - postcss-load-config: 3.1.4(postcss@8.4.21) + postcss-load-config: 3.1.4 resolve-from: 5.0.0 rollup: 3.26.2 source-map: 0.8.0-beta.0 @@ -13567,7 +13597,7 @@ packages: vfile-message: 3.1.4 dev: false - /vite@4.4.4(@types/node@17.0.12): + /vite@4.4.4(@types/node@18.16.19): resolution: {integrity: sha512-4mvsTxjkveWrKDJI70QmelfVqTm+ihFAb6+xf4sjEU2TmUCTlVX87tmg/QooPEMQb/lM9qGHT99ebqPziEd3wg==} engines: {node: ^14.18.0 || >=16.0.0} hasBin: true @@ -13595,7 +13625,7 @@ packages: terser: optional: true dependencies: - '@types/node': 17.0.12 + '@types/node': 18.16.19 esbuild: 0.18.11 postcss: 8.4.35 rollup: 3.26.2
- {components.ExpandedRow(row)} -
{actions.label}{actions.label}
- {actions.actions.map((action, index) => ( - - ))} - - {renderData(col, row, index)} - - {actions.actions.map((action, index) => ( - - ))} -
{noResult}