Skip to content

Commit

Permalink
Merge branch 'main' into affiliates-protocol
Browse files Browse the repository at this point in the history
  • Loading branch information
rosepuppy committed Oct 3, 2024
2 parents 26698d4 + 5650d36 commit 21677ce
Show file tree
Hide file tree
Showing 41 changed files with 1,032 additions and 789 deletions.
80 changes: 53 additions & 27 deletions src/components/CollapsibleTabs.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,13 +14,16 @@ import {
import styled, { css, keyframes } from 'styled-components';

import { layoutMixins } from '@/styles/layoutMixins';
import { tabMixins } from '@/styles/tabMixins';

import { IconName } from '@/components/Icon';
import { IconButton } from '@/components/IconButton';
import { type TabItem } from '@/components/Tabs';
import { Tag } from '@/components/Tag';
import { Toolbar } from '@/components/Toolbar';

import { testFlags } from '@/lib/testFlags';

type ElementProps<TabItemsValue> = {
defaultTab?: TabItemsValue;
tab: TabItemsValue;
Expand All @@ -32,8 +35,9 @@ type ElementProps<TabItemsValue> = {
};

type StyleProps = {
className?: string;
fullWidthTabs?: boolean;
dividerStyle?: 'border' | 'underline' | 'none';
className?: string;
};

export type CollapsibleTabsProps<TabItemsValue> = ElementProps<TabItemsValue> & StyleProps;
Expand All @@ -48,17 +52,23 @@ export const CollapsibleTabs = <TabItemsValue extends string>({
onOpenChange,

fullWidthTabs,
dividerStyle = 'none',

className,
}: CollapsibleTabsProps<TabItemsValue>) => {
const { uiRefresh } = testFlags;

const currentTab = tabItems.find((tabItem) => tabItem.value === tab);
const withBorders = dividerStyle === 'border';
const withUnderline = dividerStyle === 'underline';

return (
<$TabsRoot
className={className}
defaultValue={defaultTab}
value={tab}
onValueChange={(v) => setTab?.(v as TabItemsValue)}
uiRefreshEnabled={uiRefresh}
asChild
>
<$CollapsibleRoot
Expand All @@ -67,9 +77,15 @@ export const CollapsibleTabs = <TabItemsValue extends string>({
onOpenChange={(isOpen: boolean) => onOpenChange?.(isOpen)}
>
<$Header>
<$TabsList $fullWidthTabs={fullWidthTabs}>
<$TabsList $fullWidthTabs={fullWidthTabs} $withBorders={withBorders}>
{tabItems.map(({ value, label, tag, slotRight }) => (
<$TabsTrigger key={value} value={value} onClick={() => onOpenChange?.(true)}>
<$TabsTrigger
key={value}
value={value}
$withBorders={withBorders}
$withUnderline={withUnderline}
onClick={() => onOpenChange?.(true)}
>
{label}
{tag && <Tag>{tag}</Tag>}
{slotRight}
Expand All @@ -96,13 +112,18 @@ export const CollapsibleTabs = <TabItemsValue extends string>({
</$TabsRoot>
);
};
const $TabsRoot = styled(TabsRoot)`
const $TabsRoot = styled(TabsRoot)<{ uiRefreshEnabled: boolean }>`
/* Overrides */
--trigger-backgroundColor: var(--color-layer-2);
--trigger-textColor: var(--color-text-0);
--trigger-active-backgroundColor: var(--color-layer-1);
--trigger-active-textColor: var(--color-text-2);
--trigger-active-underlineColor: ${({ uiRefreshEnabled }) => css`
${uiRefreshEnabled ? css`var(--color-accent);` : css`var(--color-text-2);`}
`};
--trigger-active-underline-size: 2px;
--trigger-underline-size: 0px;
/* Rules */
${layoutMixins.scrollArea}
Expand All @@ -119,11 +140,18 @@ const $TabsRoot = styled(TabsRoot)`
${layoutMixins.withInnerHorizontalBorders}
`;

const $TabsList = styled(TabsList)<{ $fullWidthTabs?: boolean }>`
${layoutMixins.withOuterAndInnerBorders}
const $TabsList = styled(TabsList)<{ $fullWidthTabs?: boolean; $withBorders: boolean }>`
align-self: stretch;
${({ $withBorders }) =>
$withBorders &&
css`
${layoutMixins.withOuterAndInnerBorders}
margin: 0 calc(-1 * var(--border-width));
padding: 0 var(--border-width);
`}
${({ $fullWidthTabs }) =>
$fullWidthTabs
? css`
Expand All @@ -135,31 +163,28 @@ const $TabsList = styled(TabsList)<{ $fullWidthTabs?: boolean }>`
`}
overflow-x: auto;
margin: 0 calc(-1 * var(--border-width));
padding: 0 var(--border-width);
`;

const $TabsTrigger = styled(TabsTrigger)`
${layoutMixins.withOuterBorder}
${layoutMixins.row}
justify-content: center;
gap: 0.5ch;
align-self: stretch;
padding: 0 1.5rem;
font: var(--font-base-book);
color: var(--trigger-textColor);
background-color: var(--trigger-backgroundColor);
&[data-state='active'] {
color: var(--trigger-active-textColor);
background-color: var(--trigger-active-backgroundColor);
}
const $TabsTrigger = styled(TabsTrigger)<{
$withBorders: boolean;
$withUnderline: boolean;
}>`
${tabMixins.tabTriggerStyle}
${({ $withBorders }) =>
$withBorders &&
css`
${layoutMixins.withOuterBorder}
`}
${({ $withUnderline }) =>
$withUnderline &&
css`
${tabMixins.tabTriggerUnderlineStyle}
`}
`;
const $TabsContent = styled(TabsContent)`
${layoutMixins.flexColumn}
outline: none;
box-shadow: none;
Expand Down Expand Up @@ -208,6 +233,7 @@ const $Header = styled.header`
box-shadow: none;
}
`;

const $IconButton = styled(IconButton)`
--button-icon-size: 1em;
${$CollapsibleRoot}[data-state='closed'] & {
Expand Down
6 changes: 6 additions & 0 deletions src/components/Tabs.stories.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ export const TabsStory: Story<Parameters<typeof Tabs>[0]> = (args) => {

TabsStory.args = {
fullWidthTabs: false,
dividerStyle: 'underline',
items: [
{
value: TabItem.Item1,
Expand All @@ -50,6 +51,11 @@ TabsStory.argTypes = {
control: { type: 'select' },
defaultValue: TabItem.Item1,
},
dividerStyle: {
options: ['none', 'border', 'underline'],
control: { type: 'select' },
defaultValue: 'underline',
},
};
const $Container = styled.section`
background: var(--color-layer-3);
Expand Down
100 changes: 50 additions & 50 deletions src/components/Tabs.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,14 @@ import { type MenuItem } from '@/constants/menus';

import breakpoints from '@/styles/breakpoints';
import { layoutMixins } from '@/styles/layoutMixins';
import { tabMixins } from '@/styles/tabMixins';

import { DropdownSelectMenu } from '@/components/DropdownSelectMenu';
import { Tag } from '@/components/Tag';
import { Toolbar } from '@/components/Toolbar';

import { getSimpleStyledOutputType } from '@/lib/genericFunctionalComponentUtils';
import { testFlags } from '@/lib/testFlags';

export type TabItem<TabItemsValue> = {
value: TabItemsValue;
Expand Down Expand Up @@ -42,9 +44,8 @@ type ElementProps<TabItemsValue> = {
type StyleProps = {
fullWidthTabs?: boolean;
side?: 'top' | 'bottom';
withBorders?: boolean;
dividerStyle?: 'border' | 'underline' | 'none';
withTransitions?: boolean;
withUnderline?: boolean;
className?: string;
};

Expand All @@ -60,13 +61,15 @@ export const Tabs = <TabItemsValue extends string>({
onWheel,
fullWidthTabs,
side = 'top',
withBorders = true,
withUnderline = false,
dividerStyle = 'none',
withTransitions = true,
disabled = false,
className,
}: ElementProps<TabItemsValue> & StyleProps) => {
const currentItem = items.find((item) => item.value === value);
const { uiRefresh } = testFlags;
const withBorders = dividerStyle === 'border';
const withUnderline = dividerStyle === 'underline';

const triggers = (
<>
Expand Down Expand Up @@ -94,6 +97,7 @@ export const Tabs = <TabItemsValue extends string>({
onValueChange={onValueChange}
align="end"
$isActive={item.subitems.some((subitem) => subitem.value === value)}
$withUnderline={withUnderline}
slotTrigger={
<$DropdownTabTrigger value={value ?? ''} $withUnderline={withUnderline} />
}
Expand Down Expand Up @@ -121,7 +125,8 @@ export const Tabs = <TabItemsValue extends string>({
}
onWheel={onWheel}
$side={side}
$withInnerBorder={withBorders}
$withInnerBorder={withBorders || withUnderline}
uiRefreshEnabled={uiRefresh}
>
<$Header $side={side}>{triggers}</$Header>

Expand All @@ -145,46 +150,28 @@ export const Tabs = <TabItemsValue extends string>({
</$Root>
);
};
const tabTriggerStyle = css`
${layoutMixins.row}
justify-content: center;
gap: 0.5ch;
align-self: stretch;
padding: 0 1.5rem;

font: var(--trigger-font, var(--font-base-book));
color: var(--trigger-textColor);
background-color: var(--trigger-backgroundColor);
&[data-state='active'] {
color: var(--trigger-active-textColor);
background-color: var(--trigger-active-backgroundColor);
}
`;

const tabTriggerUnderlineStyle = css`
box-shadow: inset 0 calc(var(--trigger-underline-size) * -1) 0 var(--trigger-active-textColor);
&[data-state='active'] {
box-shadow: inset 0 calc(var(--trigger-active-underline-size) * -1) 0
var(--trigger-active-textColor);
}
`;

const $Root = styled(Root)<{ $side: 'top' | 'bottom'; $withInnerBorder?: boolean }>`
const $Root = styled(Root)<{
$side: 'top' | 'bottom';
$withInnerBorder?: boolean;
uiRefreshEnabled: boolean;
}>`
/* Overrides */
--trigger-backgroundColor: var(--color-layer-2);
--trigger-textColor: var(--color-text-0);
--trigger-active-backgroundColor: var(--color-layer-1);
--trigger-active-textColor: var(--color-text-2);
--trigger-active-underline-size: 0px;
--trigger-hover-textColor: var(--trigger-active-textColor);
--trigger-active-underlineColor: ${({ uiRefreshEnabled }) => css`
${uiRefreshEnabled ? css`var(--color-accent);` : css`var(--color-text-2);`}
`};
--trigger-active-underline-backgroundColor: transparent;
--trigger-active-underline-size: 2px;
--trigger-underline-size: 0px;
/* Variants */
--tabs-currentHeight: var(--tabs-height);
@media ${breakpoints.tablet} {
--tabs-currentHeight: var(--tabs-height-mobile);
}
Expand Down Expand Up @@ -264,8 +251,11 @@ const $List = styled(List)<{ $fullWidthTabs?: boolean; $withBorders?: boolean }>
`}
`;

const $Trigger = styled(Trigger)<{ $withBorders?: boolean; $withUnderline?: boolean }>`
${tabTriggerStyle}
const $Trigger = styled(Trigger)<{
$withBorders?: boolean;
$withUnderline?: boolean;
}>`
${tabMixins.tabTriggerStyle}
${({ $withBorders }) =>
$withBorders &&
Expand All @@ -276,7 +266,7 @@ const $Trigger = styled(Trigger)<{ $withBorders?: boolean; $withUnderline?: bool
${({ $withUnderline }) =>
$withUnderline &&
css`
${tabTriggerUnderlineStyle}
${tabMixins.tabTriggerUnderlineStyle}
`}
`;
const $Content = styled(Content)<{ $hide?: boolean; $withTransitions: boolean }>`
Expand Down Expand Up @@ -327,35 +317,45 @@ const $Content = styled(Content)<{ $hide?: boolean; $withTransitions: boolean }>
}
`;

const $DropdownTabTrigger = styled(Trigger)<{ $withUnderline?: boolean }>`
${tabTriggerStyle}
const $DropdownTabTrigger = styled(Trigger)<{
$withUnderline?: boolean;
}>`
${tabMixins.tabTriggerStyle}
gap: 1ch;
height: 100%;
width: 100%;
${({ $withUnderline }) =>
$withUnderline &&
css`
${tabTriggerUnderlineStyle}
${tabMixins.tabTriggerUnderlineStyle}
`}
`;

const dropdownSelectMenuType = getSimpleStyledOutputType(
DropdownSelectMenu,
{} as { $isActive?: boolean }
{} as { $isActive?: boolean; $withUnderline?: boolean }
);
const $DropdownSelectMenu = styled(DropdownSelectMenu)<{ $isActive?: boolean }>`
const $DropdownSelectMenu = styled(DropdownSelectMenu)<{
$isActive?: boolean;
$withUnderline?: boolean;
}>`
--trigger-radius: 0;
--dropdownSelectMenu-item-font-size: var(--fontSize-base);
${({ $isActive }) =>
$isActive &&
css`
--trigger-textColor: var(--trigger-active-textColor);
--trigger-backgroundColor: var(--trigger-active-backgroundColor);
--trigger-underline-size: var(--trigger-active-underline-size);
`}
${({ $isActive, $withUnderline }) =>
$isActive
? $withUnderline
? css`
${tabMixins.tabTriggerUnderlineStyle}
${tabMixins.tabTriggerActiveUnderlineStyle}
`
: css`
--trigger-textColor: var(--trigger-active-textColor);
--trigger-backgroundColor: var(--trigger-active-backgroundColor);
--trigger-underline-size: var(--trigger-active-underline-size);
`
: css``}
` as typeof dropdownSelectMenuType;

export const MobileTabs = styled(Tabs)`
Expand Down
Loading

0 comments on commit 21677ce

Please sign in to comment.