Skip to content
Draft
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
175 changes: 175 additions & 0 deletions packages/core/src/Button/BrokenButton.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,175 @@
import React, { useState, useEffect } from 'react'
import styled from 'styled-components'
import { Box, Text, Button, Flex, getPaletteColor } from '..'
import { Check } from 'pcln-icons'

const PRODUCT_TABS = [
{
autobotID: 'DASH_TAB_HOTELS',
name: 'HOTELS',
tabText: 'Hotels',
id: 'hotels',
query: { tab: 'hotels' },
},
{
autobotID: 'DASH_TAB_FLIGHTS',
name: 'FLIGHTS',
tabText: 'Flights',
id: 'flights',
query: { tab: 'flights' },
},
{
autobotID: 'DASH_TAB_HOTEL + FLIGHT',
name: 'BUNDLE + SAVE',
tabText: 'Bundle & Save',
id: 'vacations',
query: { tab: 'vacations' },
},
{
autobotID: 'DASH_TAB_CARS',
name: 'CARS',
tabText: 'Cars',
id: 'cars',
query: { tab: 'cars' },
},
{
autobotID: 'DASH_TAB_CRUISES',
name: 'CRUISES',
tabText: 'Cruises',
id: 'cruises',
query: { tab: 'cruises' },
},
] as const

const Wrapper = styled(Flex)`
position: relative;
`
const IconWrapper = styled(Flex)<{ isActive: boolean }>`
background: ${(props) => (props.isActive ? 'transparent' : getPaletteColor('background.base'))};
`

const TabWithIcon = styled(Button)<{ highlightTab: boolean }>`
&:hover {
text-decoration: none;
}
z-index: 1;
position: relative;
border: 2px solid ${(props) => (props.highlightTab ? getPaletteColor('primary.base') : 'transparent')};
background-color: ${(props) => (props.highlightTab ? getPaletteColor('primary.light') : 'transparent')};
&:hover ${IconWrapper} {
border: 1px solid ${(props) => (props.isActive ? 'transparent' : getPaletteColor('primary.base'))};
}
`

const Slider = styled(Button)<{ showSlider: boolean }>`
position: absolute;
top: 0;
bottom: 0;
height: 44px;
z-index: 0;
border: 2px solid ${(props) => (props.showSlider ? getPaletteColor('primary.base') : 'transparent')};
background-color: ${(props) => (props.showSlider ? getPaletteColor('primary.light') : 'transparent')};
transition: margin-left 0.4s ease-in-out, width 0.4s ease-in-out;
`

const StyledButton = styled(Button)<{ highlightTab: boolean }>`
&:hover {
text-decoration: none;
}
position: relative;
border: 2px solid ${getPaletteColor('primary.base')};
background-color: ${getPaletteColor('primary.light')};
`
const BrokenButton = () => {
const [activeTab, setActiveTab] = useState('hotels')
const [hoveredTab, setHoverTab] = useState('')
const [sliderWidth, setSliderWidth] = useState(0)
const [sliderOffset, setSliderOffset] = useState(0)
const [showSlider, setShowSlider] = useState(false)
const [highlightTab, setHighlightTab] = useState(false)
useEffect(() => {
const currentTab = typeof activeTab === 'string' ? activeTab : 'hotels'
const currentTabElement = document.getElementById(`tab-${currentTab}`)
if (currentTabElement) {
setSliderOffset(currentTabElement.offsetLeft)
setSliderWidth(currentTabElement.offsetWidth)
}
}, [activeTab])

const handleOnClick = (tab: any) => {
setActiveTab(tab.id)
}
return (
<Wrapper role='tablist' aria-label='Types of travel' mx={3}>
<Slider
id='slider'
role='tab'
my='auto'
tabIndex={-1}
aria-hidden='true'
ml={sliderOffset}
width={sliderWidth}
borderRadius='full'
variation='link'
showSlider={showSlider}
onTransitionEnd={() => {
setShowSlider(false)
setHighlightTab(true)
}}
/>
{PRODUCT_TABS.map((tab) => {
const isActive = tab.id === activeTab
const isHoveredTab = tab.id === hoveredTab
return (
<TabWithIcon
mr={[0, null, null, 3]}
width={[1, null, null, 'auto']}
key={tab.id}
color={getPaletteColor('primary.base')}
variation='link'
role='tab'
pr={[2, null, null, 3]}
borderRadius='full'
isActive={isActive}
highlightTab={isActive && highlightTab}
aria-selected={isActive}
aria-label={`Search for ${tab.id}`}
id={`tab-${tab.id}`}
data-testid={tab.autobotID}
onMouseEnter={() => setHoverTab(tab.id)}
onMouseLeave={() => setHoverTab('')}
onClick={() => {
if (!isActive) {
handleOnClick(tab)
setShowSlider(true)
setHighlightTab(false)
}
}}
>
<Flex alignItems='center' justifyContent='center'>
<Box display={['none', null, 'block']}>
<IconWrapper
isActive={isActive}
alignItems='center'
justifyContent='center'
pt='2px'
borderRadius='50%'
width={40}
height={40}
bg='background'
>
<Check name={tab.id} isActive={isActive || isHoveredTab} size='24px' />
</IconWrapper>
</Box>
<Text ml={2} mb='2px' fontSize={1} fontWeight={isActive ? 'bold' : 100}>
{tab.tabText}
</Text>
</Flex>
</TabWithIcon>
)
})}
</Wrapper>
)
}

export default BrokenButton
25 changes: 22 additions & 3 deletions packages/core/src/Button/Button.stories.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,18 @@ import { linkTo } from '@storybook/addon-links'
import { Calendar, Check, ChevronLeft, ChevronRight, Search, User } from 'pcln-icons'
import React from 'react'

import { Box, Button, ButtonChip, CloseButton, Flex, Image, Link, Text, ThemeProvider } from '..'
import {
Box,
Button,
ButtonChip,
CloseButton,
Flex,
Image,
Link,
Text,
ThemeProvider,
getPaletteColor,
} from '..'
import {
DocTable,
DoDont,
Expand All @@ -29,6 +40,7 @@ import groupsImage from './Button.Image.Groups.png'
import heroImage from './Button.Image.Hero.png'
import responsiveLayoutImage from './Button.Image.ResponsiveLayout.png'
import buttonStates from './Button.Image.States.png'
import BrokenButton from './BrokenButton'

type ButtonStory = StoryObj<IButtonProps>

Expand Down Expand Up @@ -177,14 +189,21 @@ export const IconButtons: ButtonStory = {
),
}

export const BrokenButtons: ButtonStory = {
render: () => (
<StoryStage>
<BrokenButton />
</StoryStage>
),
}

const meta: Meta<typeof Button> = {
title: 'Actions/Button',
component: Button,
parameters: {
design: {
type: 'figma',
url:
'https://www.figma.com/file/1lLCo0ZnO1RyMDEbnnS0by/Web-Design-System?type=design&node-id=131-21304&t=wTmhDg2MwlPA9PGf-4',
url: 'https://www.figma.com/file/1lLCo0ZnO1RyMDEbnnS0by/Web-Design-System?type=design&node-id=131-21304&t=wTmhDg2MwlPA9PGf-4',
},

docs: {
Expand Down