Skip to content

Commit

Permalink
feat: wip DynamicZoneBlock opened icon, state, FormDynamicZone onToggle
Browse files Browse the repository at this point in the history
  • Loading branch information
Quentin Le Caignec committed Aug 21, 2024
1 parent ddb325b commit 617f8e0
Show file tree
Hide file tree
Showing 10 changed files with 262 additions and 74 deletions.
4 changes: 3 additions & 1 deletion packages/haring-react/src/Components/ActionBar/ActionBar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,9 @@ export function ActionBar<Data extends Record<string, unknown>>(
`${selectedElements} file(s) selected`,
...actionRowOverflowProps
} = props;
const numberOfSelectedElements = selectedElements.length;
const numberOfSelectedElements = Array.isArray(selectedElements)
? selectedElements.length
: [selectedElements].length;

return (
<div className={`${classes.actionBar} actionBarRef`}>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import type { IActionListAction } from './ActionList';
import type { IThumbnail } from '../../types';
import type { Meta, StoryObj } from '@storybook/react';

import { ActionList as Cmp } from './ActionList';
Expand All @@ -16,19 +16,17 @@ const meta = {
type: { name: 'number' },
},
},
component: Cmp,
component: Cmp<IThumbnail>,
tags: ['autodocs'],
title: '3-custom/Components/ActionList',
} satisfies Meta<typeof Cmp>;
} satisfies Meta<typeof Cmp<IThumbnail>>;

export default meta;
type IStory = StoryObj<typeof meta>;

export const ActionList: IStory = {
args: {
actions: actionRowOverflowActionsMock as IActionListAction<
Record<string, unknown>
>[],
actions: actionRowOverflowActionsMock,
maxVisibleActions: 2,
selectedElements: actionRowOverflowSelectedMock,
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ const defaultTooltipProps = {
};

export type IActionListAction<Data extends Record<string, unknown>> = IAction<
Data[]
Data | Data[]
>;

export interface IActionListProps<Data extends Record<string, unknown>>
Expand All @@ -41,7 +41,7 @@ export interface IActionListProps<Data extends Record<string, unknown>>
maxVisibleActions?: number;
modalProps?: Omit<ModalProps, 'title'>;
overflowMenuLabel?: string;
selectedElements: Data[];
selectedElements: Data | Data[];
}

export function ActionList<Data extends Record<string, unknown>>(
Expand Down Expand Up @@ -85,7 +85,7 @@ export function ActionList<Data extends Record<string, unknown>>(
clearConfirmAction();
}

function handleModalButton(onAction?: (item: Data[]) => void): void {
function handleModalButton(onAction?: (item: Data | Data[]) => void): void {
onAction?.(selectedElements);
handleClose();
}
Expand Down
85 changes: 85 additions & 0 deletions packages/haring-react/src/Form/DynamicZone/DynamicZone.mock.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
import type { IDynamicZoneBlockReference } from './DynamicZoneBlock/DynamicZoneBlock';
import type { IActionListAction } from '../../Components/ActionList/ActionList';
import type { IBaseBlock, IBaseBlockButton } from '../../types';

import {
Alien,
ArrowDown,
ArrowUp,
Leaf,
Trash,
TreasureChest,
} from '@phosphor-icons/react';
import { action } from '@storybook/addon-actions';

const dynamicZoneBlockActionsMock: IActionListAction<IDynamicZoneBlockReference>[] =
[
{
color: 'white',
icon: <ArrowUp size={16} />,
id: 'move-up',
label: 'Move Up',
onAction: action('Move block up'),
},
{
color: 'white',
icon: <ArrowDown size={16} />,
id: 'move-down',
label: 'Move Down',
onAction: action('Move block down'),
},
{
color: 'white',
icon: <Trash size={16} />,
id: 'delete',
label: 'Delete',
onAction: action('Delete block'),
},
];

export const dynamicZoneBlocks: IBaseBlock[] = [
{
blockActions: dynamicZoneBlockActionsMock,
blockHeader: (
<>
<Alien />
First
</>
),
id: '1',
opened: false,
value: 'initial',
},
{
blockActions: dynamicZoneBlockActionsMock,
blockFooter: 'footer',
blockHeader: (
<>
<Leaf />
Second
</>
),
id: '2',
opened: true,
value: 'initial',
},
{
blockActions: dynamicZoneBlockActionsMock,
blockFooter: 'footer',
blockHeader: (
<>
<TreasureChest />
Third
</>
),
id: '3',
opened: false,
value: 'initial',
},
];

export const dynamicZoneButtons: IBaseBlockButton[] = [
{ id: 'default', label: 'Default', leftSection: <Alien /> },
{ id: 'other', label: 'Other', leftSection: <Leaf /> },
{ id: 'stuff', label: 'Stuff', leftSection: <TreasureChest /> },
];
Original file line number Diff line number Diff line change
Expand Up @@ -7,4 +7,6 @@
}

.buttonsContainer {
/* WIP */
border: 1px dashed red;
}
20 changes: 13 additions & 7 deletions packages/haring-react/src/Form/DynamicZone/DynamicZone.stories.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import type { Meta, StoryObj } from '@storybook/react';
import { action } from '@storybook/addon-actions';

import { DynamicZone as Cmp } from './DynamicZone';
import { dynamicZoneBlocks, dynamicZoneButtons } from './DynamicZone.mock';

const meta = {
component: Cmp,
Expand All @@ -15,13 +16,18 @@ type IStory = StoryObj<typeof meta>;

export const DynamicZone: IStory = {
args: {
blockOptions: ['default'],
blocks: [
{ id: '1', opened: false, type: 'default', value: 'initial' },
{ id: '2', opened: true, type: 'default', value: 'initial' },
{ id: '3', opened: false, type: 'default', value: 'initial' },
],
onAppendBlock: action('onAppendBlock, type'),
blockOptions: dynamicZoneButtons,
blocks: dynamicZoneBlocks,
internalBlockCardProps: {
headerCardSectionProps: {
bg: 'cadetblue',
c: 'white',
},
toggleComponentProps: {
actionIconProps: { color: 'white', variant: 'subtle' },
},
},
onAppendBlock: action('onAppendBlock, id'),
onRenderBlockContent: (_b, index) => <input key={index} />,
onToggleBlock: action('onToggleBlock'),
},
Expand Down
62 changes: 35 additions & 27 deletions packages/haring-react/src/Form/DynamicZone/DynamicZone.tsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
import type { IBaseBlock } from '../../types';
import type { IDynamicZoneBlockInternalComponentProps } from './DynamicZoneBlock/DynamicZoneBlock';
import type { IBaseBlock, IBaseBlockButton } from '../../types';
import type {
ButtonProps,
CardProps,
CardSectionProps,
ContainerProps,
GroupProps,
StackProps,
Expand All @@ -15,15 +14,13 @@ import classes from './DynamicZone.module.css';
import { DynamicZoneBlock } from './DynamicZoneBlock/DynamicZoneBlock';

export interface IDynamicZoneProps<Block extends IBaseBlock> {
blockCardProps?: {
cardProps?: CardProps;
cardSectionProps?: CardSectionProps;
};
blockOptions: string[];
blockCardProps?: CardProps;
blockOptions: IBaseBlockButton[];
blocks: Block[];
blocksStackProps?: StackProps;
buttonProps?: ButtonProps;
bottomContainerProps?: ContainerProps;
buttonsGroupProps?: GroupProps;
internalBlockCardProps?: IDynamicZoneBlockInternalComponentProps;
onAppendBlock: (blockType: string) => void;
onRenderBlockContent: (block: Block, index: number) => ReactElement;
onToggleBlock: (block: Block, index: number, opened: boolean) => void;
Expand All @@ -36,10 +33,11 @@ export function DynamicZone<Block extends IBaseBlock>(
const {
blockCardProps,
blockOptions,
blocks,
blocksStackProps,
buttonProps,
bottomContainerProps,
buttonsGroupProps,
blocks,
internalBlockCardProps,
onAppendBlock,
onRenderBlockContent,
onToggleBlock,
Expand All @@ -54,38 +52,48 @@ export function DynamicZone<Block extends IBaseBlock>(
<Container
className={classes.container}
fluid
p="sm"
p={0}
{...rootContainerProps}
>
<Stack className={classes.blocksContainer} gap="sm" {...blocksStackProps}>
{blocks.map((block, index) => (
<DynamicZoneBlock
cardSectionProps={blockCardProps?.cardSectionProps}
{...blockCardProps?.cardProps}
{...blockCardProps}
key={block.id}
actions={block.blockActions}
footerChildren={block.blockFooter}
headerChildren={block.blockHeader}
internalComponentProps={internalBlockCardProps}
onToggle={(opened) => onToggleBlock(block, index, opened)}
opened={block.opened}
reference={{ id: block.id, index }}
>
{onRenderBlockContent(block, index)}
</DynamicZoneBlock>
))}
</Stack>
<Group
<Container
className={classes.buttonsContainer}
fluid
mt="lg"
{...buttonsGroupProps}
{...bottomContainerProps}
>
{blockOptions.map((blockType) => (
<Button
type="button"
{...buttonProps}
key={`button-${blockType}`}
onClick={() => onAddBlock(blockType)}
>
{blockType}
</Button>
))}
</Group>
<Group {...buttonsGroupProps}>
{blockOptions.map((button) => (
<Button
radius="md"
size="md"
type="button"
variant="default"
{...button}
key={`button-${button.id}`}
onClick={() => onAddBlock(button.id)}
>
{button.label}
</Button>
))}
</Group>
</Container>
</Container>
);
}
Original file line number Diff line number Diff line change
@@ -1,11 +1,4 @@
.container {
}

.header {
cursor: pointer;
user-select: none;

&:hover {
filter: contrast(40%);
}
}
Loading

0 comments on commit 617f8e0

Please sign in to comment.