From 9a8607f77117748732511c08d7827c055e9cdb9e Mon Sep 17 00:00:00 2001
From: Bonaventura Galang <77723914+bonaventuragal@users.noreply.github.com>
Date: Tue, 10 Jan 2023 15:35:21 +0700
Subject: [PATCH 1/2] add tabs
---
src/Tabs/Tab/Tab.stories.tsx | 47 +++++++++++++++++++++++
src/Tabs/Tab/Tab.style.tsx | 43 +++++++++++++++++++++
src/Tabs/Tab/index.tsx | 16 ++++++++
src/Tabs/Tab/interface.ts | 10 +++++
src/Tabs/TabGroup/TabGroup.stories.tsx | 52 ++++++++++++++++++++++++++
src/Tabs/TabGroup/TabGroup.style.tsx | 11 ++++++
src/Tabs/TabGroup/index.tsx | 27 +++++++++++++
src/Tabs/TabGroup/interface.ts | 6 +++
8 files changed, 212 insertions(+)
create mode 100644 src/Tabs/Tab/Tab.stories.tsx
create mode 100644 src/Tabs/Tab/Tab.style.tsx
create mode 100644 src/Tabs/Tab/index.tsx
create mode 100644 src/Tabs/Tab/interface.ts
create mode 100644 src/Tabs/TabGroup/TabGroup.stories.tsx
create mode 100644 src/Tabs/TabGroup/TabGroup.style.tsx
create mode 100644 src/Tabs/TabGroup/index.tsx
create mode 100644 src/Tabs/TabGroup/interface.ts
diff --git a/src/Tabs/Tab/Tab.stories.tsx b/src/Tabs/Tab/Tab.stories.tsx
new file mode 100644
index 0000000..a9583ba
--- /dev/null
+++ b/src/Tabs/Tab/Tab.stories.tsx
@@ -0,0 +1,47 @@
+import React from 'react'
+import { Story } from '@storybook/react'
+import Tab from '.'
+import { TabProps } from './interface'
+
+const ExampleIcon = () => (
+
+)
+
+export default {
+ id: 'tab',
+ title: 'Tab',
+ component: Tab,
+ argTypes: {
+ icon: {
+ if: {
+ arg: 'withIcon',
+ },
+ defaultValue: ,
+ table: {
+ disable: true,
+ },
+ },
+ withIcon: {
+ control: 'boolean',
+ defaultValue: false,
+ },
+ },
+}
+
+const Template: Story = (args) =>
+
+export const _Tab = Template.bind({})
+_Tab.args = {
+ title: 'Hello',
+}
diff --git a/src/Tabs/Tab/Tab.style.tsx b/src/Tabs/Tab/Tab.style.tsx
new file mode 100644
index 0000000..cf909b2
--- /dev/null
+++ b/src/Tabs/Tab/Tab.style.tsx
@@ -0,0 +1,43 @@
+import styled from 'styled-components'
+import { StyledTabProps } from './interface'
+
+export const StyledTab = styled.button`
+ display: flex;
+ justify-content: center;
+ align-items: center;
+
+ padding: 12px 32px;
+ gap: 8px;
+ border: none;
+ border-radius: 12px;
+
+ font-weight: 600;
+ font-size: 16px;
+ line-height: 24px;
+
+ color: white;
+
+ cursor: pointer;
+
+ ${(props) =>
+ !props.selected &&
+ `
+ background-color: transparent;
+
+ :hover {
+ background-color: rgba(255, 255, 255, 0.1);
+ }
+ `}
+
+ ${(props) =>
+ props.selected &&
+ `
+ background-image: linear-gradient(
+ rgba(85, 97, 255, 1),
+ rgba(54, 67, 252, 1),
+ rgba(54, 67, 252, 1)
+ );
+
+ outline: 4px solid rgba(255, 255, 255, 0.1);
+ `}
+`
diff --git a/src/Tabs/Tab/index.tsx b/src/Tabs/Tab/index.tsx
new file mode 100644
index 0000000..6182b5e
--- /dev/null
+++ b/src/Tabs/Tab/index.tsx
@@ -0,0 +1,16 @@
+import React from 'react'
+import { TabProps } from './interface'
+import { StyledTab } from './Tab.style'
+
+const Tab: React.FC = ({ title, icon, selected = false }) => {
+ return (
+ <>
+
+ {icon}
+ {title}
+
+ >
+ )
+}
+
+export default Tab
diff --git a/src/Tabs/Tab/interface.ts b/src/Tabs/Tab/interface.ts
new file mode 100644
index 0000000..729671e
--- /dev/null
+++ b/src/Tabs/Tab/interface.ts
@@ -0,0 +1,10 @@
+import { ReactNode } from 'react'
+
+export interface StyledTabProps {
+ selected?: boolean
+}
+
+export interface TabProps extends StyledTabProps {
+ title?: string
+ icon?: ReactNode
+}
diff --git a/src/Tabs/TabGroup/TabGroup.stories.tsx b/src/Tabs/TabGroup/TabGroup.stories.tsx
new file mode 100644
index 0000000..e84873b
--- /dev/null
+++ b/src/Tabs/TabGroup/TabGroup.stories.tsx
@@ -0,0 +1,52 @@
+import React from 'react'
+import { Story } from '@storybook/react'
+import TabGroup from '.'
+import { TabGroupProps } from './interface'
+import Tab from '../Tab'
+import { TabProps } from '../Tab/interface'
+
+const ExampleIcon = () => (
+
+)
+
+export default {
+ id: 'tab',
+ title: 'Tab',
+ component: TabGroup,
+ argTypes: {
+ withIcon: {
+ defaultValue: false,
+ control: 'boolean',
+ },
+ icon: {
+ if: {
+ arg: 'withIcon',
+ },
+ defaultValue: ,
+ table: {
+ disable: true,
+ },
+ },
+ },
+}
+
+const Template: Story = (args) => (
+
+
+
+
+
+)
+
+export const _TabGroup = Template.bind({})
diff --git a/src/Tabs/TabGroup/TabGroup.style.tsx b/src/Tabs/TabGroup/TabGroup.style.tsx
new file mode 100644
index 0000000..b0f0590
--- /dev/null
+++ b/src/Tabs/TabGroup/TabGroup.style.tsx
@@ -0,0 +1,11 @@
+import styled from 'styled-components'
+
+export const TabGroupDiv = styled.div`
+ display: flex;
+ gap: 4px;
+ padding: 4px;
+ background-color: rgba(0, 0, 0, 0.1);
+ border-radius: 12px;
+`
+
+export const TabDiv = styled.div``
diff --git a/src/Tabs/TabGroup/index.tsx b/src/Tabs/TabGroup/index.tsx
new file mode 100644
index 0000000..ec7ac25
--- /dev/null
+++ b/src/Tabs/TabGroup/index.tsx
@@ -0,0 +1,27 @@
+import React, { cloneElement, useState } from 'react'
+import { TabGroupProps } from './interface'
+import { TabDiv, TabGroupDiv } from './TabGroup.style'
+
+const TabGroup: React.FC = ({ children }) => {
+ const [selected, setSelected] = useState(0)
+
+ return (
+ <>
+
+ {children?.map((value, idx) => {
+ return (
+ setSelected(idx)} key={idx}>
+ {cloneElement(value, {
+ title: value.props.title,
+ icon: value.props.icon,
+ selected: selected === idx,
+ })}
+
+ )
+ })}
+
+ >
+ )
+}
+
+export default TabGroup
diff --git a/src/Tabs/TabGroup/interface.ts b/src/Tabs/TabGroup/interface.ts
new file mode 100644
index 0000000..f24c970
--- /dev/null
+++ b/src/Tabs/TabGroup/interface.ts
@@ -0,0 +1,6 @@
+import { ReactElement } from 'react'
+import { TabProps } from '../Tab/interface'
+
+export interface TabGroupProps {
+ children?: ReactElement[]
+}
From b17a7cdd4f81220de20ef6f4310dc61fd8b6db32 Mon Sep 17 00:00:00 2001
From: Belati
Date: Sun, 5 Feb 2023 00:29:37 +0700
Subject: [PATCH 2/2] tab group testing
---
package.json | 3 +-
src/Tabs/TabGroup/TabGroup.stories.tsx | 24 +-
yarn.lock | 433 ++++++++++++++++++++++++-
3 files changed, 440 insertions(+), 20 deletions(-)
diff --git a/package.json b/package.json
index f1a05c4..a3fe3aa 100644
--- a/package.json
+++ b/package.json
@@ -17,9 +17,10 @@
"@rollup/plugin-node-resolve": "^15.0.1",
"@storybook/addon-actions": "^6.5.15",
"@storybook/addon-essentials": "^6.5.15",
- "@storybook/addon-interactions": "^6.5.15",
+ "@storybook/addon-interactions": "^6.5.16",
"@storybook/addon-links": "^6.5.15",
"@storybook/builder-webpack4": "^6.5.15",
+ "@storybook/jest": "^0.0.10",
"@storybook/manager-webpack4": "^6.5.15",
"@storybook/react": "^6.5.15",
"@storybook/testing-library": "^0.0.13",
diff --git a/src/Tabs/TabGroup/TabGroup.stories.tsx b/src/Tabs/TabGroup/TabGroup.stories.tsx
index e84873b..8d8951b 100644
--- a/src/Tabs/TabGroup/TabGroup.stories.tsx
+++ b/src/Tabs/TabGroup/TabGroup.stories.tsx
@@ -4,6 +4,8 @@ import TabGroup from '.'
import { TabGroupProps } from './interface'
import Tab from '../Tab'
import { TabProps } from '../Tab/interface'
+import { within, userEvent } from '@storybook/testing-library'
+import { expect } from '@storybook/jest'
const ExampleIcon = () => (