From 6ec16bc15cc78e62cb94e131699625fa5363437c Mon Sep 17 00:00:00 2001
From: Armand Philippot <git@armandphilippot.com>
Date: Fri, 15 Apr 2022 15:34:21 +0200
Subject: chore: add a Widget component

---
 src/components/molecules/layout/widget.tsx | 54 ++++++++++++++++++++++++++++++
 1 file changed, 54 insertions(+)
 create mode 100644 src/components/molecules/layout/widget.tsx

(limited to 'src/components/molecules/layout/widget.tsx')

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;
-- 
cgit v1.2.3

