Skip to content

Commit

Permalink
Implement panel as collapsible
Browse files Browse the repository at this point in the history
- Bind canCollapse attribute to allow panel to be collapsible
- Bind collapseIf and collapse attr to make panle collapse

Fixes #114
  • Loading branch information
itsmemyk08 committed Jun 14, 2023
1 parent 481c349 commit 1fd4c33
Show file tree
Hide file tree
Showing 3 changed files with 49 additions and 13 deletions.
2 changes: 1 addition & 1 deletion axelor-front/src/views/form/builder/form-widget.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -336,7 +336,7 @@ function useExpressions({
if (hideIf) handleCondition(ctx, "hidden", hideIf);
if (readonlyIf) handleCondition(ctx, "readonly", readonlyIf);
if (requiredIf) handleCondition(ctx, "required", requiredIf);
if (collapseIf) handleCondition(ctx, "collapsed", collapseIf);
if (collapseIf) handleCondition(ctx, "collapse", collapseIf);
if (validIf) handleValidation(ctx, validIf);

if (canNew) handleCondition(ctx, "canNew", canNew);
Expand Down
4 changes: 4 additions & 0 deletions axelor-front/src/views/form/widgets/panel/panel.module.css
Original file line number Diff line number Diff line change
Expand Up @@ -8,3 +8,7 @@
align-items: center;
font-weight: 600;
}
.panelHeader.collapsible {
justify-content: space-between;
cursor: pointer;
}
56 changes: 44 additions & 12 deletions axelor-front/src/views/form/widgets/panel/panel.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
import { Box, StyleProps } from "@axelor/ui";
import { Box, Collapse, StyleProps } from "@axelor/ui";
import { useAtomValue } from "jotai";
import { useEffect, useState } from "react";
import { MaterialIcon } from "@axelor/ui/icons/meterial-icon";
import clsx from "clsx";

import { FieldLabel, GridLayout, WidgetProps } from "../../builder";
import styles from "./panel.module.css";

Expand All @@ -14,33 +18,61 @@ const withHeaderBodyProps: StyleProps = {

export function Panel(props: WidgetProps) {
const { schema, formAtom, widgetAtom, readonly } = props;
const { showTitle = true, showFrame = true } = schema;
const { showTitle = true, showFrame = true, canCollapse } = schema;
const { attrs } = useAtomValue(widgetAtom);
const { title } = attrs;
const { title, collapse } = attrs;
const [isCollapse, setCollapse] = useState(collapse);

const hasHeader = showTitle !== false && showFrame !== false && title;
const moreProps = hasHeader && withHeaderProps;
const bodyProps = hasHeader && withHeaderBodyProps;

useEffect(() => {
canCollapse && setCollapse(collapse);
}, [canCollapse, collapse]);

function renderBody() {
return (
<Box className={styles.panelBody} {...bodyProps}>
<GridLayout
readonly={readonly}
formAtom={formAtom}
parentAtom={widgetAtom}
schema={schema}
/>
</Box>
);
}

return (
<Box className={styles.panel} {...moreProps}>
{hasHeader && (
<Box className={styles.panelHeader} borderBottom px={3} py={2}>
<Box
className={clsx(styles.panelHeader, {
[styles.collapsible]: canCollapse,
})}
borderBottom
px={3}
py={2}
{...(canCollapse && {
onClick: () => setCollapse((c) => !c),
})}
>
<FieldLabel
schema={schema}
formAtom={formAtom}
widgetAtom={widgetAtom}
/>
{canCollapse && (
<MaterialIcon icon={isCollapse ? "expand_more" : "expand_less"} />
)}
</Box>
)}
<Box className={styles.panelBody} {...bodyProps}>
<GridLayout
readonly={readonly}
formAtom={formAtom}
parentAtom={widgetAtom}
schema={schema}
/>
</Box>
{canCollapse ? (
<Collapse in={!isCollapse}>{renderBody()}</Collapse>
) : (
renderBody()
)}
</Box>
);
}

0 comments on commit 1fd4c33

Please sign in to comment.