diff --git a/src/components/data/kanban/kanban.scss b/src/components/data/kanban/kanban.scss
index f908c7e6..e566aaab 100644
--- a/src/components/data/kanban/kanban.scss
+++ b/src/components/data/kanban/kanban.scss
@@ -12,25 +12,29 @@
height: 100%;
}
- &__body .mykn-column {
+ &__count {
+ margin-left: var(--spacing-h);
+ border-radius: 10px;
border: 1px solid var(--typography-color-border);
- overflow-y: auto;
+ background-color: #fafafa;
+ padding: 0 6px;
+ color: var(--typography-color-muted);
}
- &__body .mykn-column:before {
- background-color: var(--typography-color-border);
- opacity: 0.1;
- content: "";
- height: 100%;
- position: absolute;
- width: 100%;
+ &__body .mykn-column {
+ border: 1px solid var(--typography-color-border);
+ border-radius: var(--border-radius-l);
+ background-color: var(--page-color-background-alt);
+ overflow-y: auto;
+ overflow-x: hidden;
+ padding: 18px 16px;
}
&__body &__drop-indicator {
background-color: var(--page-color-accent);
border: 1px dashed var(--page-color-primary);
box-sizing: content-box;
- height: calc(var(--typography-line-height-body-s) * 2);
+ height: calc(var(--typography-line-height-body-s) * 3);
padding-block: var(--spacing-v);
}
@@ -39,27 +43,24 @@
border-style: dashed;
}
- &__body .mykn-column > .mykn-h3 {
- position: sticky;
- top: 0;
- z-index: 10;
- }
-
&__body .mykn-column > .mykn-button {
+ border: 1px solid var(--typography-color-border);
+ border-radius: var(--border-radius-l);
white-space: normal;
+ background-color: var(--typography-color-background);
+ padding: 16px;
&:focus-within {
z-index: 100;
}
}
- &__body &__preview {
- display: flex;
- flex-shrink: 0;
- height: calc(var(--typography-line-height-body-s) * 2);
- justify-content: center;
- overflow: hidden;
- width: calc(var(--typography-line-height-body-s) * 2);
+ &__body .mykn-column > .mykn-button:hover,
+ &__body .mykn-column > .mykn-button:focus {
+ border: 1px solid var(--page-color-primary);
+ scale: 100%;
+ box-shadow: unset;
+ background-color: var(--typography-color-background-alt);
}
&__body .mykn-column > .mykn-button > .mykn-select {
@@ -80,4 +81,8 @@
visibility: visible;
}
}
+
+ &__item {
+ width: 100%;
+ }
}
diff --git a/src/components/data/kanban/kanban.stories.tsx b/src/components/data/kanban/kanban.stories.tsx
index 7d67f3b5..1b1608e9 100644
--- a/src/components/data/kanban/kanban.stories.tsx
+++ b/src/components/data/kanban/kanban.stories.tsx
@@ -1,8 +1,6 @@
import type { Meta, StoryObj } from "@storybook/react";
import * as React from "react";
-import { useEffect, useState } from "react";
-import { AttributeData } from "../../../lib";
import { Page } from "../../layout";
import { Kanban } from "./kanban";
@@ -21,62 +19,52 @@ const meta: Meta = {
export default meta;
type Story = StoryObj;
-export const KanbanComponent: Story = {
- args: {
- title: "The quick brown fox jumps over the lazy dog.",
- fieldsets: [
- ["Todo", { fields: ["title"], title: "title" }],
- ["In Progress", { fields: ["title"], title: "title" }],
- ["In Review", { fields: ["title"], title: "title" }],
- ["Done", { fields: ["title"], title: "title" }],
- ],
- },
- render: (args) => {
- const abortController = new AbortController();
- const [objectList, setObjectList] = useState([]);
- // Process sorting and pagination locally in place for demonstration purposes.
+export const generateComponentList = (count: number) => {
+ const randomLorenIpsum = [
+ "This is a card",
+ "The card has the purpose to show some data",
+ "The data can either be super duper long, or also very short and concise",
+ "This is just the title",
+ ];
- useEffect(() => {
- const limit = 11;
- fetch(`https://jsonplaceholder.typicode.com/photos?_limit=${limit}`, {
- signal: abortController.signal,
- })
- .then((response) => response.json())
- .then((data: AttributeData[]) => {
- setObjectList(
- data.map((d) => ({
- ...d,
- alphaIndex: String(d.title[0]).toUpperCase(),
- })),
- );
- });
- }, [args]);
+ const randomDays = ["20 days", "30 days", "40 days", "50 days", "60 days"];
- const even = objectList.filter((o, index) => index % 2 === 0);
- const odd = objectList.filter((o, index) => index % 2 !== 0);
+ const randomData = [
+ "Some random test",
+ "Some more test data to differentiate",
+ "And slightly more so that we can see the difference",
+ ];
- return "groupBy" in args ? (
-
- ) : (
-
- );
- },
-};
+ const getRandomInt = (max: number) => {
+ return Math.floor(Math.random() * max);
+ };
-export const WithCustomPreview = {
- ...KanbanComponent,
- args: {
- ...KanbanComponent.args,
- renderPreview: (attributeData) => (
-
+ return Array.from({ length: count }, (_, i) => ({
+ id: i.toString(),
+ content: (
+
+ {randomDays[getRandomInt(randomDays.length)]}
+ {randomLorenIpsum[getRandomInt(randomLorenIpsum.length)]}
+ {randomData[getRandomInt(randomData.length)]}
+
),
- },
+ }));
};
-export const GroupBy = {
- ...KanbanComponent,
+// Define the component list
+const componentList = [
+ { title: "Todo", id: "1", items: generateComponentList(10) },
+ { title: "In Progress", id: "2", items: generateComponentList(10) },
+ { title: "In Review", id: "3", items: generateComponentList(10) },
+ { title: "Done", id: "4", items: generateComponentList(10) },
+];
+
+export const KanbanComponent: Story = {
args: {
- fieldset: [`{group}`, { fields: ["title"], title: "title" }],
- groupBy: "alphaIndex",
+ title: "The quick brown fox jumps over the lazy dog.",
+ componentList,
+ },
+ render: (args) => {
+ return ;
},
};
diff --git a/src/components/data/kanban/kanban.tsx b/src/components/data/kanban/kanban.tsx
index 5fe5ddd4..12127765 100644
--- a/src/components/data/kanban/kanban.tsx
+++ b/src/components/data/kanban/kanban.tsx
@@ -1,127 +1,88 @@
import React, { useEffect, useState } from "react";
-import {
- AttributeData,
- DEFAULT_URL_FIELDS,
- FieldSet,
- field2Title,
- formatMessage,
- useIntl,
-} from "../../../lib";
-import {
- GroupedAttributeDataProps,
- getContextData,
-} from "../../../lib/data/groupedattributedata";
-import { Button, ButtonLink, ButtonLinkProps, ButtonProps } from "../../button";
+import { Button, ButtonProps } from "../../button";
import { Select } from "../../form";
import { Column, Grid } from "../../layout";
-import { Body, H1, H2, H3, P } from "../../typography";
+import { Body, H2, H3 } from "../../typography";
import "./kanban.scss";
-export type KanbanProps = GroupedAttributeDataProps & {
- /** If set, items are `draggable` allowing the user to rearrange them (across) columns). */
+export type KanbanProps = {
+ /** If set, items are `draggable` allowing the user to rearrange them (across columns). */
draggable?: boolean;
- /** The kanban "change column" (accessible) label */
+ /** The kanban "change column" (accessible) label. It will be shown as an accessible label when selecting columns */
labelSelectColumn?: string;
- /** The kanban "move object position" (accessible) label. */
+ /** The kanban "move object position" (accessible) label. It will be shown as an accessible label on dragging */
labelMoveObject?: string;
- /** Get called when the fieldsets change. */
- onFieldsetsChange?: (fieldsets: FieldSet[]) => void;
+ /** Get called when the componentList changes. */
+ onComponentListChange?: (componentList: KanbanColumn[]) => void;
- /** Get called when the objectLists change. */
- onObjectListsChange?: (objectLists: AttributeData[][]) => void;
-
- /** Get called when an object is dropped onto a column. */
- onObjectChange?: (
- object: AttributeData,
+ /** Get called when a component changes columns. */
+ onComponentChange?: (
+ movedComponent: KanbanColumnItem,
sourceColumnIndex: number,
- targetColumnIndex: number,
sourceObjectIndex: number,
+ targetColumnIndex: number,
targetObjectIndex: number,
) => void;
+
+ /** The new componentList prop defining columns and their items */
+ componentList: KanbanColumn[];
+
+ /** The title of the kanban */
+ title?: string;
+};
+
+export type KanbanColumn = {
+ title: string;
+ id: string;
+ items: KanbanColumnItem[];
+};
+
+export type KanbanColumnItem = {
+ id: string;
+ content: React.ReactNode;
};
export type KanbanDragData = {
sourceColumnIndex: number;
sourceObjectIndex: number;
- object: AttributeData;
};
-/**
- * Kanban component, shows item over various columns. Items can be made `draggable` allowing the user to rearrange them
- * (across columns).
- */
export const Kanban: React.FC = ({
- buttonProps,
- buttonLinkProps,
+ componentList,
draggable = false,
- fieldset,
- fieldsets,
- groupBy,
labelSelectColumn,
labelMoveObject,
- objectList,
- objectLists,
- renderPreview,
+ onComponentListChange,
title,
- urlFields = DEFAULT_URL_FIELDS,
- onClick,
- onFieldsetsChange,
- onObjectListsChange,
- onObjectChange,
+ onComponentChange,
...props
}) => {
const [dragIndexState, setDragIndexState] = useState<[number, number] | null>(
null,
);
- const [fieldsetsState, setFieldsetsState] = useState
-
- {fieldsetsState.map((fieldset, index) => (
-
- ))}
+
+ {componentListState.map((column, columnIndex) => {
+ const count = column.items.length;
+ return (
+
+
+ {column.title}
+
{count}
+
+
+
+ );
+ })}