Skip to content

Commit

Permalink
feat: array
Browse files Browse the repository at this point in the history
  • Loading branch information
YuJianghao committed Oct 2, 2023
1 parent 53cfdd7 commit 1abe042
Show file tree
Hide file tree
Showing 9 changed files with 197 additions and 21 deletions.
3 changes: 2 additions & 1 deletion packages/carbon/src/AddButton/AddButton.tsx
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { Add } from '@carbon/icons-react';
import { Button } from '@carbon/react';
import { FormContextType, IconButtonProps, RJSFSchema, StrictRJSFSchema, TranslatableString } from '@rjsf/utils';

Expand All @@ -8,7 +9,7 @@ export default function AddButton<T = any, S extends StrictRJSFSchema = RJSFSche
}: IconButtonProps<T, S, F>) {
const { translateString } = registry;
return (
<Button size='sm' kind='tertiary' {...props}>
<Button size='sm' kind='ghost' renderIcon={Add} {...props}>
{translateString(TranslatableString.AddItemButton)}
</Button>
);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
import { useMemo } from 'react';
import { ArrayFieldTemplateItemType, FormContextType, RJSFSchema, StrictRJSFSchema } from '@rjsf/utils';

export default function ArrayFieldItemTemplate<
T = any,
S extends StrictRJSFSchema = RJSFSchema,
F extends FormContextType = any
>(props: ArrayFieldTemplateItemType<T, S, F>) {
const {
children,
disabled,
hasToolbar,
hasCopy,
hasMoveDown,
hasMoveUp,
hasRemove,
index,
onCopyIndexClick,
onDropIndexClick,
onReorderClick,
readonly,
uiSchema,
registry,
} = props;
const { CopyButton, MoveDownButton, MoveUpButton, RemoveButton } = registry.templates.ButtonTemplates;
const onCopyClick = useMemo(() => onCopyIndexClick(index), [index, onCopyIndexClick]);

const onRemoveClick = useMemo(() => onDropIndexClick(index), [index, onDropIndexClick]);

const onArrowUpClick = useMemo(() => onReorderClick(index, index - 1), [index, onReorderClick]);

const onArrowDownClick = useMemo(() => onReorderClick(index, index + 1), [index, onReorderClick]);

return (
<div style={{ display: 'flex', alignItems: 'flex-start', justifyContent: 'center' }}>
<div style={{ flex: 1 }}>{children}</div>
{hasToolbar && (
<div
style={{
marginLeft: '1rem',
maxWidth: '4rem',
}}
>
{(hasMoveUp || hasMoveDown) && (
<MoveUpButton
disabled={disabled || readonly || !hasMoveUp}
onClick={onArrowUpClick}
uiSchema={uiSchema}
registry={registry}
/>
)}
{(hasMoveUp || hasMoveDown) && (
<MoveDownButton
disabled={disabled || readonly || !hasMoveDown}
onClick={onArrowDownClick}
uiSchema={uiSchema}
registry={registry}
/>
)}
{hasCopy && (
<CopyButton disabled={disabled || readonly} onClick={onCopyClick} uiSchema={uiSchema} registry={registry} />
)}
{hasRemove && (
<RemoveButton
disabled={disabled || readonly}
onClick={onRemoveClick}
uiSchema={uiSchema}
registry={registry}
/>
)}
<span />
</div>
)}
</div>
);
}
2 changes: 2 additions & 0 deletions packages/carbon/src/ArrayFieldItemTemplate/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
export { default } from './ArrayFieldItemTemplate';
export * from './ArrayFieldItemTemplate';
81 changes: 81 additions & 0 deletions packages/carbon/src/ArrayFieldTemplate/ArrayFieldTemplate.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
// @ts-expect-error there's no type definition for Stack
import { Stack } from '@carbon/react';
import {
getTemplate,
getUiOptions,
ArrayFieldTemplateItemType,
ArrayFieldTemplateProps,
StrictRJSFSchema,
RJSFSchema,
FormContextType,
} from '@rjsf/utils';
import { Layer, LayerBackground } from '../components/Layer';

export default function ArrayFieldTemplate<
T = any,
S extends StrictRJSFSchema = RJSFSchema,
F extends FormContextType = any
>(props: ArrayFieldTemplateProps<T, S, F>) {
const { canAdd, disabled, idSchema, uiSchema, items, onAddClick, readonly, registry, required, schema, title } =
props;
const uiOptions = getUiOptions<T, S, F>(uiSchema);
const ArrayFieldDescriptionTemplate = getTemplate<'ArrayFieldDescriptionTemplate', T, S, F>(
'ArrayFieldDescriptionTemplate',
registry,
uiOptions
);
const ArrayFieldItemTemplate = getTemplate<'ArrayFieldItemTemplate', T, S, F>(
'ArrayFieldItemTemplate',
registry,
uiOptions
);
const ArrayFieldTitleTemplate = getTemplate<'ArrayFieldTitleTemplate', T, S, F>(
'ArrayFieldTitleTemplate',
registry,
uiOptions
);
// Button templates are not overridden in the uiSchema
const {
ButtonTemplates: { AddButton },
} = registry.templates;
return (
<div>
<ArrayFieldTitleTemplate
idSchema={idSchema}
title={uiOptions.title || title}
schema={schema}
uiSchema={uiSchema}
required={required}
registry={registry}
/>
<ArrayFieldDescriptionTemplate
idSchema={idSchema}
description={uiOptions.description || schema.description}
schema={schema}
uiSchema={uiSchema}
registry={registry}
/>
<LayerBackground>
<Stack gap={7}>
<Layer>
<Stack gap={7}>
{items.length > 0 &&
items.map(({ key, ...itemProps }: ArrayFieldTemplateItemType<T, S, F>) => (
<ArrayFieldItemTemplate key={key} {...itemProps} />
))}
</Stack>
</Layer>
{canAdd && (
<AddButton
className='array-item-add'
onClick={onAddClick}
disabled={disabled || readonly}
uiSchema={uiSchema}
registry={registry}
/>
)}
</Stack>
</LayerBackground>
</div>
);
}
2 changes: 2 additions & 0 deletions packages/carbon/src/ArrayFieldTemplate/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
export { default } from './ArrayFieldTemplate';
export * from './ArrayFieldTemplate';
10 changes: 6 additions & 4 deletions packages/carbon/src/IconButton/IconButton.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ export function CopyButton<T = any, S extends StrictRJSFSchema = RJSFSchema, F e
return (
<Button
size='sm'
kind='tertiary'
kind='ghost'
hasIconOnly
iconDescription={translateString(TranslatableString.CopyButton)}
renderIcon={Copy}
Expand All @@ -30,7 +30,7 @@ export function MoveDownButton<T = any, S extends StrictRJSFSchema = RJSFSchema,
return (
<Button
size='sm'
kind='tertiary'
kind='ghost'
hasIconOnly
iconDescription={translateString(TranslatableString.MoveDownButton)}
renderIcon={ArrowDown}
Expand All @@ -48,7 +48,7 @@ export function MoveUpButton<T = any, S extends StrictRJSFSchema = RJSFSchema, F
return (
<Button
size='sm'
kind='tertiary'
kind='ghost'
hasIconOnly
iconDescription={translateString(TranslatableString.MoveUpButton)}
renderIcon={ArrowUp}
Expand All @@ -66,7 +66,9 @@ export function RemoveButton<T = any, S extends StrictRJSFSchema = RJSFSchema, F
return (
<Button
size='sm'
kind='danger--tertiary'
kind='danger--ghost'
// there's a css bug in carbon design
style={{ paddingRight: 0 }}
hasIconOnly
iconDescription={translateString(TranslatableString.RemoveButton)}
{...props}
Expand Down
20 changes: 4 additions & 16 deletions packages/carbon/src/ObjectFieldTemplate/ObjectFieldTemplate.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,8 @@ import {
titleId,
TranslatableString,
} from '@rjsf/utils';
import { useCarbonOptions, useNestDepth } from '../contexts';
import { Layer } from '../components/Layer';
import { useCarbonOptions } from '../contexts';
import { Layer, LayerBackground } from '../components/Layer';
import { Add } from '@carbon/icons-react';

export default function ObjectFieldTemplate<
Expand All @@ -37,7 +37,6 @@ export default function ObjectFieldTemplate<
} = props;
const uiOptions = getUiOptions<T, S, F>(uiSchema);
const carbonOptions = useCarbonOptions();
const nestDepth = useNestDepth();
const { translateString } = registry;
const TitleFieldTemplate = getTemplate<'TitleFieldTemplate', T, S, F>('TitleFieldTemplate', registry, uiOptions);
const DescriptionFieldTemplate = getTemplate<'DescriptionFieldTemplate', T, S, F>(
Expand Down Expand Up @@ -73,18 +72,7 @@ export default function ObjectFieldTemplate<
/>
</div>
)}
<div
style={
nestDepth
? {
padding: '1rem',
backgroundColor: 'var(--cds-layer)',
}
: {
margin: '2.5rem 0',
}
}
>
<LayerBackground>
<Stack gap={carbonOptions.stackGap}>
<Layer>
<Stack gap={carbonOptions.stackGap}>{properties.map((item) => item.content)}</Stack>
Expand All @@ -103,7 +91,7 @@ export default function ObjectFieldTemplate<
</Button>
)}
</Stack>
</div>
</LayerBackground>
</>
);
}
4 changes: 4 additions & 0 deletions packages/carbon/src/Templates/Templates.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ import FieldHelpTemplate from '../FieldHelpTemplate';
import DescriptionField from '../DescriptionField';
import FieldErrorTemplate from '../FieldErrorTemplate';
import TitleField from '../TitleField';
import ArrayFieldTemplate from '../ArrayFieldTemplate';
import ArrayFieldItemTemplate from '../ArrayFieldItemTemplate';

export function generateTemplates<
T = any,
Expand All @@ -31,6 +33,8 @@ export function generateTemplates<
FieldTemplate,
FieldHelpTemplate,
ObjectFieldTemplate,
ArrayFieldTemplate,
ArrayFieldItemTemplate,
};
}

Expand Down
20 changes: 20 additions & 0 deletions packages/carbon/src/components/Layer.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,3 +11,23 @@ export function Layer({ children }: { children: ReactNode }) {
</CarbonLayer>
);
}

export function LayerBackground({ children }: { children: ReactNode }) {
const nestDepth = useNestDepth();
return (
<div
style={
nestDepth
? {
padding: '1rem',
backgroundColor: 'var(--cds-layer)',
}
: {
margin: '2.5rem 0',
}
}
>
{children}
</div>
);
}

0 comments on commit 1abe042

Please sign in to comment.