Add tabs comp
authorAjay Bura <ajbura@gmail.com>
Tue, 21 Dec 2021 13:04:13 +0000 (18:34 +0530)
committerAjay Bura <ajbura@gmail.com>
Tue, 21 Dec 2021 13:04:13 +0000 (18:34 +0530)
Signed-off-by: Ajay Bura <ajbura@gmail.com>
src/app/atoms/tabs/Tabs.jsx [new file with mode: 0644]
src/app/atoms/tabs/Tabs.scss [new file with mode: 0644]

diff --git a/src/app/atoms/tabs/Tabs.jsx b/src/app/atoms/tabs/Tabs.jsx
new file mode 100644 (file)
index 0000000..5426cf3
--- /dev/null
@@ -0,0 +1,87 @@
+import React, { useState } from 'react';
+import PropTypes from 'prop-types';
+import './Tabs.scss';
+
+import Button from '../button/Button';
+import ScrollView from '../scroll/ScrollView';
+
+function TabItem({
+  selected, iconSrc,
+  onClick, children, disabled,
+}) {
+  const isSelected = selected ? 'tab-item--selected' : '';
+
+  return (
+    <Button
+      className={`tab-item ${isSelected}`}
+      iconSrc={iconSrc}
+      onClick={onClick}
+      disabled={disabled}
+    >
+      {children}
+    </Button>
+  );
+}
+
+TabItem.defaultProps = {
+  selected: false,
+  iconSrc: null,
+  onClick: null,
+  disabled: false,
+};
+
+TabItem.propTypes = {
+  selected: PropTypes.bool,
+  iconSrc: PropTypes.string,
+  onClick: PropTypes.func,
+  children: PropTypes.node.isRequired,
+  disabled: PropTypes.bool,
+};
+
+function Tabs({ items, defaultSelected, onSelect }) {
+  const [selectedItem, setSelectedItem] = useState(items[defaultSelected]);
+
+  const handleTabSelection = (item, index) => {
+    if (selectedItem === item) return;
+    setSelectedItem(item);
+    onSelect(item, index);
+  };
+
+  return (
+    <div className="tabs">
+      <ScrollView horizontal vertical={false} invisible>
+        <div className="tabs__content">
+          {items.map((item, index) => (
+            <TabItem
+              key={item.text}
+              selected={selectedItem.text === item.text}
+              iconSrc={item.iconSrc}
+              disabled={item.disabled}
+              onClick={() => handleTabSelection(item, index)}
+            >
+              {item.text}
+            </TabItem>
+          ))}
+        </div>
+      </ScrollView>
+    </div>
+  );
+}
+
+Tabs.defaultProps = {
+  defaultSelected: 0,
+};
+
+Tabs.propTypes = {
+  items: PropTypes.arrayOf(
+    PropTypes.exact({
+      iconSrc: PropTypes.string,
+      text: PropTypes.string,
+      disabled: PropTypes.bool,
+    }),
+  ).isRequired,
+  defaultSelected: PropTypes.number,
+  onSelect: PropTypes.func.isRequired,
+};
+
+export { Tabs as default };
diff --git a/src/app/atoms/tabs/Tabs.scss b/src/app/atoms/tabs/Tabs.scss
new file mode 100644 (file)
index 0000000..39dddde
--- /dev/null
@@ -0,0 +1,45 @@
+@use '../../partials/dir';
+
+.tabs {
+  height: var(--header-height);
+  box-shadow: inset 0 -1px 0 var(--bg-surface-border);
+
+  &__content {
+    min-width: 100%;
+    height: 100%;
+    display: flex;
+  }
+}
+
+.tab-item {
+  flex-shrink: 0;
+  
+  @include dir.side(padding, var(--sp-normal), 24px);
+  border-radius: 0;
+  height: 100%;
+  box-shadow: none;
+  border-radius: var(--bo-radius) var(--bo-radius)   0 0;
+
+  &:focus,
+  &:active {
+    background-color: var(--bg-surface-active);
+    box-shadow: none;
+  }
+
+  &--selected {
+    --bs-tab-selected: inset 0 -2px 0 var(--tc-surface-high);
+    box-shadow: var(--bs-tab-selected);
+
+    & .ic-raw {
+      background-color: var(--ic-surface-high);
+    }
+    & .text {
+      font-weight: var(--fw-medium);
+    }
+    &:focus,
+    &:active {
+      background-color: var(--bg-surface-active);
+      box-shadow: var(--bs-tab-selected);
+    }
+  }
+}
\ No newline at end of file