diff --git a/src/components/data/kanban/kanban.stories.tsx b/src/components/data/kanban/kanban.stories.tsx index bd436638..e92d0bf3 100644 --- a/src/components/data/kanban/kanban.stories.tsx +++ b/src/components/data/kanban/kanban.stories.tsx @@ -125,3 +125,29 @@ export const Draggable: Story = { draggable: true, }, }; + +export const WithToolbar: Story = { + ...KanbanComponent, + // @ts-expect-error - Fix never + args: { + ...(KanbanComponent.args as KanbanProps), + toolbarProps: { + items: [ + { + direction: "horizontal", + label: "Sorteren", + required: true, + options: [ + { label: "Nieuwste eerst", value: "-pk", selected: true }, + { label: "Oudste eerst", value: "pk", selected: true }, + ], + }, + "spacer", + { + children: "Item toevoegen", + variant: "primary", + }, + ], + }, + }, +}; diff --git a/src/components/data/kanban/kanban.tsx b/src/components/data/kanban/kanban.tsx index 0d114186..c723d0b0 100644 --- a/src/components/data/kanban/kanban.tsx +++ b/src/components/data/kanban/kanban.tsx @@ -18,7 +18,7 @@ import { Card } from "../../card"; import { Select } from "../../form"; import { Column, Grid } from "../../layout"; import { StackCtx } from "../../stackctx"; -import { Toolbar } from "../../toolbar"; +import { Toolbar, ToolbarProps } from "../../toolbar"; import { Body, H2, H3, Hr, P } from "../../typography"; import { Value } from "../value"; import "./kanban.scss"; @@ -26,6 +26,10 @@ import "./kanban.scss"; export type KanbanProps = GroupedAttributeDataProps & { /** If set, items are `draggable` allowing the user to rearrange them (across) columns). */ draggable?: boolean; + + /** Props to pass to Toolbar. */ + toolbarProps?: Partial; + /** The kanban "change column" (accessible) label */ labelSelectColumn?: string; @@ -71,6 +75,7 @@ export const Kanban: React.FC = ({ objectLists, renderPreview, title, + toolbarProps, urlFields = DEFAULT_URL_FIELDS, onClick, onFieldsetsChange, @@ -223,9 +228,9 @@ export const Kanban: React.FC = ({ {title && (

{title}

-
)} + {toolbarProps && } {fieldsetsState.map((fieldset, index) => ( diff --git a/src/components/toolbar/toolbar.tsx b/src/components/toolbar/toolbar.tsx index 0dd262e8..ad67d6c9 100644 --- a/src/components/toolbar/toolbar.tsx +++ b/src/components/toolbar/toolbar.tsx @@ -3,6 +3,7 @@ import React from "react"; import { Button, ButtonLink, ButtonLinkProps, ButtonProps } from "../button"; import { Dropdown, DropdownProps } from "../dropdown"; +import { FormControl, FormControlProps } from "../form"; import { A, AProps } from "../typography"; import "./toolbar.scss"; @@ -11,6 +12,7 @@ export type ToolbarItem = | ButtonProps | ButtonLinkProps | DropdownProps + | FormControlProps | "spacer" | null; @@ -95,6 +97,13 @@ export const Toolbar: React.FC = ({ !Object.hasOwn(Object(item), "href") && Object.hasOwn(Object(item), "children"); // Does button always have children? + // TODO: Improve + const isFormControlProps = (item: ToolbarItem): item is FormControlProps => + !isItemAProps(item) && + !isItemButtonProps(item) && + !isItemDropdownProps(item) && + !isItemButtonProps(item); + /** * Returns the React.FC for the item based on its shape. * @param item @@ -104,6 +113,10 @@ export const Toolbar: React.FC = ({ return ToolbarSpacer; } + if (React.isValidElement(item)) { + return () => item; + } + if (isItemAProps(item)) { return A; } @@ -117,7 +130,11 @@ export const Toolbar: React.FC = ({ if (isItemButtonProps(item)) { return Button; } - return () => item; + if (isFormControlProps(item)) { + return FormControl; + } + + throw new Error("Unknown toolbar item type!"); }; /** @@ -156,7 +173,7 @@ export const Toolbar: React.FC = ({ {...props} > {childrenPosition === "before" && children} - {items.filter((v) => v !== null).map(renderItem)} + {items.filter((v) => v).map(renderItem)} {childrenPosition === "after" && children} ); diff --git a/src/templates/kanban/kanban.stories.tsx b/src/templates/kanban/kanban.stories.tsx index 2c6ebcc5..6c997528 100644 --- a/src/templates/kanban/kanban.stories.tsx +++ b/src/templates/kanban/kanban.stories.tsx @@ -204,3 +204,31 @@ export const Draggable: Story = { }, }, }; + +export const WithToolbar: Story = { + ...WithSecondaryNavigation, + args: { + ...WithSecondaryNavigation.args, + kanbanProps: { + ...(WithSecondaryNavigation.args!.kanbanProps as KanbanProps), + toolbarProps: { + items: [ + { + direction: "horizontal", + label: "Sorteren", + required: true, + options: [ + { label: "Nieuwste eerst", value: "-pk", selected: true }, + { label: "Oudste eerst", value: "pk", selected: true }, + ], + }, + "spacer", + { + children: "Item toevoegen", + variant: "primary", + }, + ], + }, + }, + }, +}; diff --git a/src/templates/kanban/kanban.tsx b/src/templates/kanban/kanban.tsx index 7f80bb81..41892aed 100644 --- a/src/templates/kanban/kanban.tsx +++ b/src/templates/kanban/kanban.tsx @@ -24,7 +24,7 @@ export const KanbanTemplate: React.FC = ({ return ( {children} - {kanbanProps.groupBy ? ( + {groupBy ? (