Skip to content

Commit

Permalink
✨ - feat: allow Toolbar componenent to be defined for Kanban component
Browse files Browse the repository at this point in the history
  • Loading branch information
svenvandescheur committed Aug 30, 2024
1 parent f5ab975 commit 736c2bd
Show file tree
Hide file tree
Showing 5 changed files with 81 additions and 5 deletions.
26 changes: 26 additions & 0 deletions src/components/data/kanban/kanban.stories.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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",
},
],
},
},
};
9 changes: 7 additions & 2 deletions src/components/data/kanban/kanban.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -18,14 +18,18 @@ 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";

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<ToolbarProps>;

/** The kanban "change column" (accessible) label */
labelSelectColumn?: string;

Expand Down Expand Up @@ -71,6 +75,7 @@ export const Kanban: React.FC<KanbanProps> = ({
objectLists,
renderPreview,
title,
toolbarProps,
urlFields = DEFAULT_URL_FIELDS,
onClick,
onFieldsetsChange,
Expand Down Expand Up @@ -223,9 +228,9 @@ export const Kanban: React.FC<KanbanProps> = ({
{title && (
<Body className="mykn-kanban__header">
<H2>{title}</H2>
<br />
</Body>
)}
{toolbarProps && <Toolbar pad={true} sticky="top" {...toolbarProps} />}
<Body className="mykn-kanban__body">
<Grid cols={fieldsetsState.length}>
{fieldsetsState.map((fieldset, index) => (
Expand Down
21 changes: 19 additions & 2 deletions src/components/toolbar/toolbar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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";

Expand All @@ -11,6 +12,7 @@ export type ToolbarItem =
| ButtonProps
| ButtonLinkProps
| DropdownProps
| FormControlProps
| "spacer"
| null;

Expand Down Expand Up @@ -95,6 +97,13 @@ export const Toolbar: React.FC<ToolbarProps> = ({
!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
Expand All @@ -104,6 +113,10 @@ export const Toolbar: React.FC<ToolbarProps> = ({
return ToolbarSpacer;
}

if (React.isValidElement(item)) {
return () => item;
}

if (isItemAProps(item)) {
return A;
}
Expand All @@ -117,7 +130,11 @@ export const Toolbar: React.FC<ToolbarProps> = ({
if (isItemButtonProps(item)) {
return Button;
}
return () => item;
if (isFormControlProps(item)) {
return FormControl;
}

throw new Error("Unknown toolbar item type!");
};

/**
Expand Down Expand Up @@ -156,7 +173,7 @@ export const Toolbar: React.FC<ToolbarProps> = ({
{...props}
>
{childrenPosition === "before" && children}
{items.filter((v) => v !== null).map(renderItem)}
{items.filter((v) => v).map(renderItem)}
{childrenPosition === "after" && children}
</nav>
);
Expand Down
28 changes: 28 additions & 0 deletions src/templates/kanban/kanban.stories.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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",
},
],
},
},
},
};
2 changes: 1 addition & 1 deletion src/templates/kanban/kanban.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ export const KanbanTemplate: React.FC<KanbanTemplateProps> = ({
return (
<CardBaseTemplate {...props}>
{children}
{kanbanProps.groupBy ? (
{groupBy ? (
<KanbanComponent
objectList={objectList as AttributeData[]}
fieldset={fieldset as FieldSet}
Expand Down

0 comments on commit 736c2bd

Please sign in to comment.