fix(LOY-128): add rounded filter chip variant
This commit is contained in:
@@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
import { cx } from "class-variance-authority"
|
import { cx } from "class-variance-authority"
|
||||||
|
|
||||||
import { Typography } from "@scandic-hotels/design-system/Typography"
|
import { ChipButton } from "@scandic-hotels/design-system/ChipButton"
|
||||||
|
|
||||||
import useScrollShadows from "@/hooks/useScrollShadows"
|
import useScrollShadows from "@/hooks/useScrollShadows"
|
||||||
|
|
||||||
@@ -32,29 +32,23 @@ export default function TabFilters({
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<div
|
<div
|
||||||
className={cx(
|
className={cx(styles.containerWrapper, {
|
||||||
styles.containerWrapper,
|
[styles.showLeftShadow]: showLeftShadow,
|
||||||
showLeftShadow && styles.showLeftShadow,
|
[styles.showRightShadow]: showRightShadow,
|
||||||
showRightShadow && styles.showRightShadow
|
})}
|
||||||
)}
|
|
||||||
>
|
>
|
||||||
<div className={styles.container} ref={containerRef}>
|
<div className={styles.container} ref={containerRef}>
|
||||||
{categories.map((category) => (
|
{categories.map((category) => (
|
||||||
<Typography
|
<ChipButton
|
||||||
key={category.identifier}
|
key={category.identifier}
|
||||||
variant="Body/Supporting text (caption)/smRegular"
|
onPress={() => onFilterSelect(category.identifier)}
|
||||||
|
variant="FilterRounded"
|
||||||
|
selected={selectedFilter === category.identifier}
|
||||||
|
className={styles.filter}
|
||||||
>
|
>
|
||||||
<button
|
<IconByCSSelect identifier={category.iconIdentifier} />
|
||||||
onClick={() => onFilterSelect(category.identifier)}
|
{category.label}
|
||||||
className={cx(styles.filter, {
|
</ChipButton>
|
||||||
[styles.selected]: selectedFilter === category.identifier,
|
|
||||||
})}
|
|
||||||
type="button"
|
|
||||||
>
|
|
||||||
<IconByCSSelect identifier={category.iconIdentifier} />
|
|
||||||
{category.label}
|
|
||||||
</button>
|
|
||||||
</Typography>
|
|
||||||
))}
|
))}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -38,25 +38,10 @@
|
|||||||
scrollbar-width: none;
|
scrollbar-width: none;
|
||||||
position: relative;
|
position: relative;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
|
padding: var(--Space-x05);
|
||||||
}
|
}
|
||||||
|
|
||||||
.filter {
|
.filter {
|
||||||
display: flex;
|
scroll-snap-align: center;
|
||||||
align-items: center;
|
|
||||||
gap: var(--Space-x1);
|
|
||||||
background-color: transparent;
|
|
||||||
border: 1px solid var(--Border-Interactive-Selected);
|
|
||||||
border-radius: var(--Corner-radius-rounded);
|
|
||||||
padding: var(--Space-x1) var(--Space-x2);
|
|
||||||
transition: all 0.2s ease-in-out;
|
|
||||||
scroll-snap-align: start;
|
|
||||||
flex-shrink: 0;
|
flex-shrink: 0;
|
||||||
cursor: pointer;
|
|
||||||
color: var(--Text-Default);
|
|
||||||
}
|
|
||||||
|
|
||||||
.filter.selected {
|
|
||||||
border-color: transparent;
|
|
||||||
background-color: var(--Base-Button-Tertiary-Fill-Normal);
|
|
||||||
color: var(--Text-Inverted);
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -51,3 +51,61 @@ export const Outlined: Story = {
|
|||||||
),
|
),
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export const FilterRoundedLarge: Story = {
|
||||||
|
args: {
|
||||||
|
variant: 'FilterRounded',
|
||||||
|
onPress: fn(),
|
||||||
|
size: 'Large',
|
||||||
|
children: (
|
||||||
|
<>
|
||||||
|
<MaterialIcon icon="location_city" size={20} color="CurrentColor" />
|
||||||
|
Button Chip
|
||||||
|
</>
|
||||||
|
),
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
export const FilterRoundedLargeSelected: Story = {
|
||||||
|
args: {
|
||||||
|
variant: 'FilterRounded',
|
||||||
|
onPress: fn(),
|
||||||
|
size: 'Large',
|
||||||
|
selected: true,
|
||||||
|
children: (
|
||||||
|
<>
|
||||||
|
<MaterialIcon icon="location_city" size={20} color="CurrentColor" />
|
||||||
|
Button Chip
|
||||||
|
</>
|
||||||
|
),
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
export const FilterRoundedMedium: Story = {
|
||||||
|
args: {
|
||||||
|
variant: 'FilterRounded',
|
||||||
|
onPress: fn(),
|
||||||
|
size: 'Medium',
|
||||||
|
children: (
|
||||||
|
<>
|
||||||
|
<MaterialIcon icon="location_city" size={20} color="CurrentColor" />
|
||||||
|
Button Chip
|
||||||
|
</>
|
||||||
|
),
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
export const FilterRoundedMediumSelected: Story = {
|
||||||
|
args: {
|
||||||
|
variant: 'FilterRounded',
|
||||||
|
onPress: fn(),
|
||||||
|
size: 'Medium',
|
||||||
|
selected: true,
|
||||||
|
children: (
|
||||||
|
<>
|
||||||
|
<MaterialIcon icon="location_city" size={20} color="CurrentColor" />
|
||||||
|
Button Chip
|
||||||
|
</>
|
||||||
|
),
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|||||||
@@ -1,24 +1,25 @@
|
|||||||
import { Button as ButtonRAC } from 'react-aria-components'
|
import { Button as ButtonRAC } from 'react-aria-components'
|
||||||
|
|
||||||
import { Typography } from '../Typography'
|
|
||||||
import { ChipButtonProps } from './types'
|
import { ChipButtonProps } from './types'
|
||||||
import { variants } from './variants'
|
import { variants } from './variants'
|
||||||
|
|
||||||
export function ChipButton({
|
export function ChipButton({
|
||||||
children,
|
children,
|
||||||
variant,
|
variant,
|
||||||
|
selected = false,
|
||||||
|
size = 'Large',
|
||||||
className,
|
className,
|
||||||
...props
|
...props
|
||||||
}: ChipButtonProps) {
|
}: ChipButtonProps) {
|
||||||
const classNames = variants({
|
const classNames = variants({
|
||||||
variant,
|
variant,
|
||||||
|
selected,
|
||||||
|
size,
|
||||||
})
|
})
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Typography variant="Body/Supporting text (caption)/smBold">
|
<ButtonRAC {...props} className={[className, classNames].join(' ')}>
|
||||||
<ButtonRAC {...props} className={[className, classNames].join(' ')}>
|
{children}
|
||||||
{children}
|
</ButtonRAC>
|
||||||
</ButtonRAC>
|
|
||||||
</Typography>
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,6 +7,7 @@
|
|||||||
align-items: center;
|
align-items: center;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
|
gap: var(--Space-x05);
|
||||||
}
|
}
|
||||||
|
|
||||||
.Default {
|
.Default {
|
||||||
@@ -30,8 +31,31 @@
|
|||||||
border-color: var(--Border-Interactive-Selected);
|
border-color: var(--Border-Interactive-Selected);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.FilterRounded {
|
||||||
|
background-color: transparent;
|
||||||
|
border: 1px solid var(--Border-Interactive-Selected);
|
||||||
|
border-radius: var(--Corner-radius-rounded);
|
||||||
|
padding: var(--Space-x025) var(--Space-x2);
|
||||||
|
color: var(--Text-Default);
|
||||||
|
}
|
||||||
|
|
||||||
|
.selected {
|
||||||
|
border-color: transparent;
|
||||||
|
background-color: var(--Surface-Brand-Primary-3-Default);
|
||||||
|
color: var(--Text-Inverted);
|
||||||
|
}
|
||||||
|
|
||||||
|
.large {
|
||||||
|
height: 40px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.medium {
|
||||||
|
height: 32px;
|
||||||
|
}
|
||||||
|
|
||||||
.Default:focus,
|
.Default:focus,
|
||||||
.Outlined:focus {
|
.Outlined:focus,
|
||||||
|
.FilterRounded:focus {
|
||||||
outline-offset: 4px;
|
outline-offset: 4px;
|
||||||
outline-color: var(--Border-Interactive-Focus);
|
outline-color: var(--Border-Interactive-Focus);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,24 +2,114 @@ import { cva } from 'class-variance-authority'
|
|||||||
|
|
||||||
import { deepmerge } from 'deepmerge-ts'
|
import { deepmerge } from 'deepmerge-ts'
|
||||||
import styles from './chip-button.module.css'
|
import styles from './chip-button.module.css'
|
||||||
|
import { config as typographyConfig } from '../Typography/variants'
|
||||||
|
|
||||||
|
const variantKeys = {
|
||||||
|
variant: {
|
||||||
|
Default: 'Default',
|
||||||
|
Outlined: 'Outlined',
|
||||||
|
FilterRounded: 'FilterRounded',
|
||||||
|
},
|
||||||
|
style: {
|
||||||
|
Medium: 'Medium',
|
||||||
|
Large: 'Large',
|
||||||
|
},
|
||||||
|
typography: {
|
||||||
|
Bold: 'Body/Supporting text (caption)/smBold',
|
||||||
|
Regular: 'Body/Supporting text (caption)/smRegular',
|
||||||
|
},
|
||||||
|
} as const
|
||||||
|
|
||||||
export const config = {
|
export const config = {
|
||||||
variants: {
|
variants: {
|
||||||
variant: {
|
variant: {
|
||||||
Default: styles.Default,
|
[variantKeys.variant.Default]: styles.Default,
|
||||||
Outlined: styles.Outlined,
|
[variantKeys.variant.Outlined]: styles.Outlined,
|
||||||
|
[variantKeys.variant.FilterRounded]: styles.FilterRounded,
|
||||||
|
},
|
||||||
|
selected: {
|
||||||
|
true: '',
|
||||||
|
false: '',
|
||||||
|
},
|
||||||
|
size: {
|
||||||
|
[variantKeys.style.Medium]: '',
|
||||||
|
[variantKeys.style.Large]: '',
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
compoundVariants: [
|
||||||
|
{
|
||||||
|
variant: variantKeys.variant.Default,
|
||||||
|
className: [
|
||||||
|
typographyConfig.variants.variant[
|
||||||
|
'Body/Supporting text (caption)/smBold'
|
||||||
|
],
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
variant: variantKeys.variant.Outlined,
|
||||||
|
className: [
|
||||||
|
typographyConfig.variants.variant[
|
||||||
|
'Body/Supporting text (caption)/smBold'
|
||||||
|
],
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
variant: variantKeys.variant.FilterRounded,
|
||||||
|
size: variantKeys.style.Medium,
|
||||||
|
selected: true,
|
||||||
|
className: [
|
||||||
|
typographyConfig.variants.variant[
|
||||||
|
'Body/Supporting text (caption)/smRegular'
|
||||||
|
],
|
||||||
|
styles.selected,
|
||||||
|
styles.medium,
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
variant: variantKeys.variant.FilterRounded,
|
||||||
|
size: variantKeys.style.Medium,
|
||||||
|
selected: false,
|
||||||
|
className: [
|
||||||
|
typographyConfig.variants.variant[
|
||||||
|
'Body/Supporting text (caption)/smRegular'
|
||||||
|
],
|
||||||
|
styles.medium,
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
variant: variantKeys.variant.FilterRounded,
|
||||||
|
size: variantKeys.style.Large,
|
||||||
|
selected: true,
|
||||||
|
className: [
|
||||||
|
typographyConfig.variants.variant[
|
||||||
|
'Body/Supporting text (caption)/smRegular'
|
||||||
|
],
|
||||||
|
styles.selected,
|
||||||
|
styles.large,
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
variant: variantKeys.variant.FilterRounded,
|
||||||
|
size: variantKeys.style.Large,
|
||||||
|
selected: false,
|
||||||
|
className: [
|
||||||
|
typographyConfig.variants.variant[
|
||||||
|
'Body/Supporting text (caption)/smRegular'
|
||||||
|
],
|
||||||
|
styles.large,
|
||||||
|
],
|
||||||
|
},
|
||||||
|
],
|
||||||
defaultVariants: {
|
defaultVariants: {
|
||||||
variant: 'Default',
|
variant: variantKeys.variant.Default,
|
||||||
},
|
},
|
||||||
} as const
|
}
|
||||||
|
|
||||||
export const variants = cva(styles.chip, config)
|
export const variants = cva(styles.chip, config)
|
||||||
|
|
||||||
const chipConfig = {
|
const chipConfig = {
|
||||||
variants: {
|
variants: {
|
||||||
typography: config.variants.variant,
|
...config.variants,
|
||||||
},
|
},
|
||||||
defaultVariants: config.defaultVariants,
|
defaultVariants: config.defaultVariants,
|
||||||
} as const
|
} as const
|
||||||
|
|||||||
Reference in New Issue
Block a user