summaryrefslogtreecommitdiffstats
path: root/src/components/molecules/layout/widget.tsx
diff options
context:
space:
mode:
Diffstat (limited to 'src/components/molecules/layout/widget.tsx')
-rw-r--r--src/components/molecules/layout/widget.tsx54
1 files changed, 54 insertions, 0 deletions
diff --git a/src/components/molecules/layout/widget.tsx b/src/components/molecules/layout/widget.tsx
new file mode 100644
index 0000000..c04362a
--- /dev/null
+++ b/src/components/molecules/layout/widget.tsx
@@ -0,0 +1,54 @@
+import { FC, useState } from 'react';
+import HeadingButton, { HeadingButtonProps } from '../buttons/heading-button';
+import styles from './widget.module.scss';
+
+export type WidgetProps = Pick<
+ HeadingButtonProps,
+ 'expanded' | 'level' | 'title'
+> & {
+ /**
+ * Set additional classnames to the widget wrapper.
+ */
+ className?: string;
+ /**
+ * Determine if the widget body should have borders. Default: false.
+ */
+ withBorders?: boolean;
+};
+
+/**
+ * Widget component
+ *
+ * Render an expandable widget.
+ */
+const Widget: FC<WidgetProps> = ({
+ children,
+ className = '',
+ expanded = true,
+ level,
+ title,
+ withBorders = false,
+}) => {
+ const [isExpanded, setIsExpanded] = useState<boolean>(expanded);
+ const stateClass = isExpanded ? 'widget--expanded' : 'widget--collapsed';
+ const bordersClass = withBorders
+ ? 'widget--has-borders'
+ : 'widget--no-borders';
+
+ return (
+ <div
+ className={`${styles.widget} ${styles[bordersClass]} ${styles[stateClass]} ${className}`}
+ >
+ <HeadingButton
+ level={level}
+ title={title}
+ expanded={isExpanded}
+ setExpanded={setIsExpanded}
+ className={styles.widget__header}
+ />
+ <div className={styles.widget__body}>{children}</div>
+ </div>
+ );
+};
+
+export default Widget;