Merged in fix/3697-prettier-configs (pull request #3396)
fix(SW-3691): Setup one prettier config for whole repo * Setup prettierrc in root and remove other configs Approved-by: Joakim Jäderberg Approved-by: Linus Flood
This commit is contained in:
@@ -1,18 +1,18 @@
|
||||
import type { Meta, StoryObj } from '@storybook/nextjs-vite'
|
||||
import type { Meta, StoryObj } from "@storybook/nextjs-vite"
|
||||
|
||||
import Accordion from './index'
|
||||
import AccordionItem from './AccordionItem/index'
|
||||
import { MaterialIcon } from '../Icons/MaterialIcon'
|
||||
import { IconName } from '../Icons/iconName'
|
||||
import { Typography } from '../Typography'
|
||||
import Accordion from "./index"
|
||||
import AccordionItem from "./AccordionItem/index"
|
||||
import { MaterialIcon } from "../Icons/MaterialIcon"
|
||||
import { IconName } from "../Icons/iconName"
|
||||
import { Typography } from "../Typography"
|
||||
|
||||
const meta: Meta<typeof Accordion> = {
|
||||
title: 'Core Components/Accordion',
|
||||
title: "Core Components/Accordion",
|
||||
component: Accordion,
|
||||
argTypes: {
|
||||
type: {
|
||||
control: 'select',
|
||||
options: ['card', 'sidepeek', 'inline'],
|
||||
control: "select",
|
||||
options: ["card", "sidepeek", "inline"],
|
||||
},
|
||||
},
|
||||
}
|
||||
@@ -23,7 +23,7 @@ type Story = StoryObj<typeof Accordion>
|
||||
|
||||
export const Default: Story = {
|
||||
args: {
|
||||
type: 'card',
|
||||
type: "card",
|
||||
},
|
||||
render: (args) => (
|
||||
<Accordion {...args}>
|
||||
@@ -60,7 +60,7 @@ export const Default: Story = {
|
||||
|
||||
export const WithIcons: Story = {
|
||||
args: {
|
||||
type: 'card',
|
||||
type: "card",
|
||||
},
|
||||
render: (args) => (
|
||||
<Accordion {...args}>
|
||||
@@ -106,7 +106,7 @@ export const WithIcons: Story = {
|
||||
|
||||
export const WithSubtitle: Story = {
|
||||
args: {
|
||||
type: 'card',
|
||||
type: "card",
|
||||
},
|
||||
render: (args) => (
|
||||
<Accordion {...args}>
|
||||
@@ -140,7 +140,7 @@ export const WithSubtitle: Story = {
|
||||
|
||||
export const Inline: Story = {
|
||||
args: {
|
||||
type: 'inline',
|
||||
type: "inline",
|
||||
},
|
||||
render: () => (
|
||||
<Accordion type="inline">
|
||||
|
||||
@@ -1,23 +1,24 @@
|
||||
'use client'
|
||||
"use client"
|
||||
|
||||
import { type ReactNode, useEffect, useRef } from 'react'
|
||||
import { type ReactNode, useEffect, useRef } from "react"
|
||||
|
||||
import { IconByIconName } from '../../Icons/IconByIconName'
|
||||
import { MaterialIcon } from '../../Icons/MaterialIcon'
|
||||
import { IconByIconName } from "../../Icons/IconByIconName"
|
||||
import { MaterialIcon } from "../../Icons/MaterialIcon"
|
||||
|
||||
import { accordionItemVariants } from './variants'
|
||||
import { accordionItemVariants } from "./variants"
|
||||
|
||||
import styles from './accordionItem.module.css'
|
||||
import styles from "./accordionItem.module.css"
|
||||
|
||||
import type { VariantProps } from 'class-variance-authority'
|
||||
import type { IconName } from '../../Icons/iconName'
|
||||
import { Typography } from '../../Typography'
|
||||
import type { VariantProps } from "class-variance-authority"
|
||||
import type { IconName } from "../../Icons/iconName"
|
||||
import { Typography } from "../../Typography"
|
||||
|
||||
export interface AccordionItemProps
|
||||
extends React.HtmlHTMLAttributes<HTMLDetailsElement>,
|
||||
extends
|
||||
React.HtmlHTMLAttributes<HTMLDetailsElement>,
|
||||
VariantProps<typeof accordionItemVariants> {
|
||||
title: string
|
||||
titleLevel?: 'span' | 'p' | 'h1' | 'h2' | 'h3' | 'h4' | 'h5' | 'h6'
|
||||
titleLevel?: "span" | "p" | "h1" | "h2" | "h3" | "h4" | "h5" | "h6"
|
||||
iconName?: IconName
|
||||
icon?: ReactNode
|
||||
subtitle?: string
|
||||
@@ -31,7 +32,7 @@ export default function AccordionItem({
|
||||
icon,
|
||||
iconName,
|
||||
title,
|
||||
titleLevel = 'p',
|
||||
titleLevel = "p",
|
||||
type,
|
||||
className,
|
||||
subtitle,
|
||||
@@ -59,17 +60,17 @@ export default function AccordionItem({
|
||||
if (details.open) {
|
||||
content.style.maxHeight = `${content.scrollHeight}px`
|
||||
content.addEventListener(
|
||||
'transitionend',
|
||||
"transitionend",
|
||||
() => {
|
||||
// Remove maxHeight after transition to allow content to transition multiple times
|
||||
content.style.maxHeight = 'none'
|
||||
content.style.maxHeight = "none"
|
||||
},
|
||||
{ once: true }
|
||||
)
|
||||
|
||||
onOpen?.()
|
||||
} else {
|
||||
content.style.maxHeight = '0'
|
||||
content.style.maxHeight = "0"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -89,11 +90,11 @@ export default function AccordionItem({
|
||||
<details ref={detailsRef} onToggle={toggleAccordion}>
|
||||
<summary className={styles.summary}>
|
||||
{IconComp}
|
||||
{type === 'sidepeek' ? (
|
||||
{type === "sidepeek" ? (
|
||||
<Typography variant="Title/Subtitle/md">
|
||||
<p className={styles.title}>{title}</p>
|
||||
</Typography>
|
||||
) : type === 'inline' ? (
|
||||
) : type === "inline" ? (
|
||||
<Typography variant="Body/Supporting text (caption)/smBold">
|
||||
<p className={styles.title}>{title}</p>
|
||||
</Typography>
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { cva } from 'class-variance-authority'
|
||||
import { cva } from "class-variance-authority"
|
||||
|
||||
import styles from './accordionItem.module.css'
|
||||
import styles from "./accordionItem.module.css"
|
||||
|
||||
export const accordionItemVariants = cva(styles.accordionItem, {
|
||||
variants: {
|
||||
@@ -11,6 +11,6 @@ export const accordionItemVariants = cva(styles.accordionItem, {
|
||||
},
|
||||
},
|
||||
defaultVariants: {
|
||||
type: 'card',
|
||||
type: "card",
|
||||
},
|
||||
})
|
||||
|
||||
@@ -1,12 +1,13 @@
|
||||
import { Children, cloneElement, isValidElement } from 'react'
|
||||
import { Children, cloneElement, isValidElement } from "react"
|
||||
|
||||
import type { VariantProps } from 'class-variance-authority'
|
||||
import type { VariantProps } from "class-variance-authority"
|
||||
|
||||
import type { AccordionItemProps } from './AccordionItem'
|
||||
import { accordionVariants } from './variants'
|
||||
import type { AccordionItemProps } from "./AccordionItem"
|
||||
import { accordionVariants } from "./variants"
|
||||
|
||||
interface AccordionProps
|
||||
extends React.HtmlHTMLAttributes<HTMLUListElement>,
|
||||
extends
|
||||
React.HtmlHTMLAttributes<HTMLUListElement>,
|
||||
VariantProps<typeof accordionVariants> {}
|
||||
|
||||
export default function Accordion({
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { cva } from 'class-variance-authority'
|
||||
import { cva } from "class-variance-authority"
|
||||
|
||||
import styles from './accordion.module.css'
|
||||
import styles from "./accordion.module.css"
|
||||
|
||||
export const accordionVariants = cva(styles.accordion, {
|
||||
variants: {
|
||||
@@ -11,6 +11,6 @@ export const accordionVariants = cva(styles.accordion, {
|
||||
},
|
||||
},
|
||||
defaultVariants: {
|
||||
type: 'card',
|
||||
type: "card",
|
||||
},
|
||||
})
|
||||
|
||||
@@ -1,22 +1,22 @@
|
||||
import type { Meta, StoryObj } from '@storybook/nextjs-vite'
|
||||
import { Alert } from './index'
|
||||
import { AlertTypeEnum } from '@scandic-hotels/common/constants/alert'
|
||||
import { expect, fn } from 'storybook/test'
|
||||
import type { Meta, StoryObj } from "@storybook/nextjs-vite"
|
||||
import { Alert } from "./index"
|
||||
import { AlertTypeEnum } from "@scandic-hotels/common/constants/alert"
|
||||
import { expect, fn } from "storybook/test"
|
||||
|
||||
const meta: Meta<typeof Alert> = {
|
||||
title: 'Core Components/Alert',
|
||||
title: "Core Components/Alert",
|
||||
component: Alert,
|
||||
parameters: {
|
||||
layout: 'centered',
|
||||
layout: "centered",
|
||||
},
|
||||
tags: ['autodocs'],
|
||||
tags: ["autodocs"],
|
||||
argTypes: {
|
||||
variant: {
|
||||
control: { type: 'select' },
|
||||
options: ['banner', 'inline'],
|
||||
control: { type: "select" },
|
||||
options: ["banner", "inline"],
|
||||
},
|
||||
type: {
|
||||
control: { type: 'select' },
|
||||
control: { type: "select" },
|
||||
options: Object.values(AlertTypeEnum),
|
||||
},
|
||||
close: {
|
||||
@@ -32,43 +32,43 @@ type Story = StoryObj<typeof meta>
|
||||
|
||||
export const Default: Story = {
|
||||
args: {
|
||||
variant: 'inline',
|
||||
variant: "inline",
|
||||
type: AlertTypeEnum.Info,
|
||||
heading: 'Heading',
|
||||
text: 'Caramels danish jelly-o pudding tart croissant. Pie cotton candy jujubes carrot cake gummies. Apple pie cake chocolate bar halvah tootsie roll bonbon cheesecake. Brownie dessert macaroon bear claw pastry.',
|
||||
heading: "Heading",
|
||||
text: "Caramels danish jelly-o pudding tart croissant. Pie cotton candy jujubes carrot cake gummies. Apple pie cake chocolate bar halvah tootsie roll bonbon cheesecake. Brownie dessert macaroon bear claw pastry.",
|
||||
close: undefined,
|
||||
ariaRole: 'alert',
|
||||
ariaRole: "alert",
|
||||
},
|
||||
play: async ({ canvas }) => {
|
||||
canvas.findByRole('alert')
|
||||
canvas.findByRole("alert")
|
||||
},
|
||||
}
|
||||
|
||||
export const Closable: Story = {
|
||||
args: {
|
||||
variant: 'inline',
|
||||
variant: "inline",
|
||||
type: AlertTypeEnum.Info,
|
||||
heading: 'Heading',
|
||||
text: 'Caramels danish jelly-o pudding tart croissant. Pie cotton candy jujubes carrot cake gummies. Apple pie cake chocolate bar halvah tootsie roll bonbon cheesecake. Brownie dessert macaroon bear claw pastry.',
|
||||
heading: "Heading",
|
||||
text: "Caramels danish jelly-o pudding tart croissant. Pie cotton candy jujubes carrot cake gummies. Apple pie cake chocolate bar halvah tootsie roll bonbon cheesecake. Brownie dessert macaroon bear claw pastry.",
|
||||
close: fn(),
|
||||
},
|
||||
play: async ({ canvas, userEvent, args }) => {
|
||||
await userEvent.click(await canvas.findByRole('button'))
|
||||
await userEvent.click(await canvas.findByRole("button"))
|
||||
expect(args.close).toHaveBeenCalledTimes(1)
|
||||
},
|
||||
}
|
||||
|
||||
export const WithPhonenumber: Story = {
|
||||
args: {
|
||||
variant: 'inline',
|
||||
variant: "inline",
|
||||
type: AlertTypeEnum.Info,
|
||||
heading: 'Heading',
|
||||
text: 'Caramels danish jelly-o pudding tart croissant. Pie cotton candy jujubes carrot cake gummies. Apple pie cake chocolate bar halvah tootsie roll bonbon cheesecake. Brownie dessert macaroon bear claw pastry.',
|
||||
heading: "Heading",
|
||||
text: "Caramels danish jelly-o pudding tart croissant. Pie cotton candy jujubes carrot cake gummies. Apple pie cake chocolate bar halvah tootsie roll bonbon cheesecake. Brownie dessert macaroon bear claw pastry.",
|
||||
close: fn(),
|
||||
phoneContact: {
|
||||
displayText: 'Call us:',
|
||||
phoneNumber: '+4685551234',
|
||||
footnote: 'Available 24/7',
|
||||
displayText: "Call us:",
|
||||
phoneNumber: "+4685551234",
|
||||
footnote: "Available 24/7",
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
@@ -1,16 +1,16 @@
|
||||
'use client'
|
||||
"use client"
|
||||
|
||||
import { useState } from 'react'
|
||||
import { useIntl } from 'react-intl'
|
||||
import { useState } from "react"
|
||||
import { useIntl } from "react-intl"
|
||||
|
||||
import { Button } from '../../Button'
|
||||
import { MaterialIcon } from '../../Icons/MaterialIcon'
|
||||
import { JsonToHtml } from '../../JsonToHtml/JsonToHtml'
|
||||
import SidePeek from '../../SidePeek'
|
||||
import { Button } from "../../Button"
|
||||
import { MaterialIcon } from "../../Icons/MaterialIcon"
|
||||
import { JsonToHtml } from "../../JsonToHtml/JsonToHtml"
|
||||
import SidePeek from "../../SidePeek"
|
||||
|
||||
import styles from './sidepeek.module.css'
|
||||
import styles from "./sidepeek.module.css"
|
||||
|
||||
import type { AlertSidepeekProps } from './sidepeek'
|
||||
import type { AlertSidepeekProps } from "./sidepeek"
|
||||
|
||||
export default function AlertSidepeek({
|
||||
ctaText,
|
||||
@@ -37,8 +37,8 @@ export default function AlertSidepeek({
|
||||
isOpen={sidePeekIsOpen}
|
||||
handleClose={() => setSidePeekIsOpen(false)}
|
||||
closeLabel={intl.formatMessage({
|
||||
id: 'common.close',
|
||||
defaultMessage: 'Close',
|
||||
id: "common.close",
|
||||
defaultMessage: "Close",
|
||||
})}
|
||||
>
|
||||
<JsonToHtml
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import type { SidepeekContent } from '@scandic-hotels/common/constants/alert'
|
||||
import type { SidepeekContent } from "@scandic-hotels/common/constants/alert"
|
||||
|
||||
export interface AlertSidepeekProps {
|
||||
ctaText: string
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
import type {
|
||||
AlertTypeEnum,
|
||||
SidepeekContent,
|
||||
} from '@scandic-hotels/common/constants/alert'
|
||||
import type { VariantProps } from 'class-variance-authority'
|
||||
import type { AriaRole } from 'react'
|
||||
} from "@scandic-hotels/common/constants/alert"
|
||||
import type { VariantProps } from "class-variance-authority"
|
||||
import type { AriaRole } from "react"
|
||||
|
||||
import type { alertVariants } from './variants'
|
||||
import type { alertVariants } from "./variants"
|
||||
|
||||
export interface AlertProps extends VariantProps<typeof alertVariants> {
|
||||
className?: string
|
||||
@@ -26,5 +26,5 @@ export interface AlertProps extends VariantProps<typeof alertVariants> {
|
||||
} | null
|
||||
close?: () => void
|
||||
ariaRole?: AriaRole
|
||||
ariaLive?: 'off' | 'assertive' | 'polite'
|
||||
ariaLive?: "off" | "assertive" | "polite"
|
||||
}
|
||||
|
||||
@@ -1,17 +1,17 @@
|
||||
'use client'
|
||||
"use client"
|
||||
|
||||
import { Button } from '../Button'
|
||||
import { MaterialIcon } from '../Icons/MaterialIcon'
|
||||
import Link from '../OldDSLink'
|
||||
import { Typography } from '../Typography'
|
||||
import { Button } from "../Button"
|
||||
import { MaterialIcon } from "../Icons/MaterialIcon"
|
||||
import Link from "../OldDSLink"
|
||||
import { Typography } from "../Typography"
|
||||
|
||||
import AlertSidepeek from './Sidepeek'
|
||||
import { IconByAlertType } from './utils'
|
||||
import { alertVariants } from './variants'
|
||||
import AlertSidepeek from "./Sidepeek"
|
||||
import { IconByAlertType } from "./utils"
|
||||
import { alertVariants } from "./variants"
|
||||
|
||||
import styles from './alert.module.css'
|
||||
import styles from "./alert.module.css"
|
||||
|
||||
import type { AlertProps } from './alert'
|
||||
import type { AlertProps } from "./alert"
|
||||
|
||||
export function Alert({
|
||||
className,
|
||||
@@ -61,7 +61,7 @@ export function Alert({
|
||||
<>
|
||||
<span> {phoneContact.displayText} </span>
|
||||
<Link
|
||||
href={`tel:${phoneContact.phoneNumber.replace(/ /g, '')}`}
|
||||
href={`tel:${phoneContact.phoneNumber.replace(/ /g, "")}`}
|
||||
>
|
||||
{phoneContact.phoneNumber}
|
||||
</Link>
|
||||
|
||||
@@ -1,28 +1,28 @@
|
||||
import {
|
||||
MaterialIcon,
|
||||
type MaterialIconSetIconProps,
|
||||
} from '../Icons/MaterialIcon'
|
||||
import { AlertTypeEnum } from '@scandic-hotels/common/constants/alert'
|
||||
} from "../Icons/MaterialIcon"
|
||||
import { AlertTypeEnum } from "@scandic-hotels/common/constants/alert"
|
||||
|
||||
import type { JSX } from 'react'
|
||||
import type { JSX } from "react"
|
||||
|
||||
import type { AlertProps } from './alert'
|
||||
import type { AlertProps } from "./alert"
|
||||
|
||||
interface IconByAlertProps {
|
||||
alertType: AlertTypeEnum
|
||||
variant?: AlertProps['variant']
|
||||
variant?: AlertProps["variant"]
|
||||
}
|
||||
|
||||
export function IconByAlertType({
|
||||
alertType,
|
||||
variant = 'inline',
|
||||
variant = "inline",
|
||||
...props
|
||||
}: IconByAlertProps & MaterialIconSetIconProps): JSX.Element {
|
||||
switch (alertType) {
|
||||
case AlertTypeEnum.Alarm:
|
||||
return (
|
||||
<MaterialIcon
|
||||
color={variant === 'inline' ? 'Icon/Inverted' : 'Icon/Feedback/Error'}
|
||||
color={variant === "inline" ? "Icon/Inverted" : "Icon/Feedback/Error"}
|
||||
isFilled
|
||||
icon="error"
|
||||
{...props}
|
||||
@@ -33,7 +33,7 @@ export function IconByAlertType({
|
||||
<MaterialIcon
|
||||
icon="warning"
|
||||
color={
|
||||
variant === 'inline' ? 'Icon/Inverted' : 'Icon/Feedback/Warning'
|
||||
variant === "inline" ? "Icon/Inverted" : "Icon/Feedback/Warning"
|
||||
}
|
||||
isFilled
|
||||
{...props}
|
||||
@@ -44,7 +44,7 @@ export function IconByAlertType({
|
||||
<MaterialIcon
|
||||
icon="check_circle"
|
||||
color={
|
||||
variant === 'inline' ? 'Icon/Inverted' : 'Icon/Feedback/Success'
|
||||
variant === "inline" ? "Icon/Inverted" : "Icon/Feedback/Success"
|
||||
}
|
||||
isFilled
|
||||
{...props}
|
||||
@@ -55,7 +55,7 @@ export function IconByAlertType({
|
||||
return (
|
||||
<MaterialIcon
|
||||
color={
|
||||
variant === 'inline' ? 'Icon/Inverted' : 'Icon/Feedback/Information'
|
||||
variant === "inline" ? "Icon/Inverted" : "Icon/Feedback/Information"
|
||||
}
|
||||
isFilled
|
||||
icon="info"
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
import { cva } from 'class-variance-authority'
|
||||
import { cva } from "class-variance-authority"
|
||||
|
||||
import { AlertTypeEnum } from '@scandic-hotels/common/constants/alert'
|
||||
import { AlertTypeEnum } from "@scandic-hotels/common/constants/alert"
|
||||
|
||||
import styles from './alert.module.css'
|
||||
import styles from "./alert.module.css"
|
||||
|
||||
export const alertVariants = cva(styles.alert, {
|
||||
variants: {
|
||||
@@ -18,7 +18,7 @@ export const alertVariants = cva(styles.alert, {
|
||||
},
|
||||
},
|
||||
defaultVariants: {
|
||||
variant: 'inline',
|
||||
variant: "inline",
|
||||
type: AlertTypeEnum.Info,
|
||||
},
|
||||
})
|
||||
|
||||
@@ -1,17 +1,17 @@
|
||||
import type { Meta, StoryObj } from '@storybook/nextjs-vite'
|
||||
import type { Meta, StoryObj } from "@storybook/nextjs-vite"
|
||||
|
||||
import { Avatar } from '.'
|
||||
import { config } from './variants'
|
||||
import { Avatar } from "."
|
||||
import { config } from "./variants"
|
||||
|
||||
const meta: Meta<typeof Avatar> = {
|
||||
title: 'Core Components/Avatar',
|
||||
title: "Core Components/Avatar",
|
||||
component: Avatar,
|
||||
parameters: {
|
||||
layout: 'centered',
|
||||
layout: "centered",
|
||||
},
|
||||
argTypes: {
|
||||
size: {
|
||||
control: { type: 'select' },
|
||||
control: { type: "select" },
|
||||
options: Object.keys(config.variants.size),
|
||||
},
|
||||
},
|
||||
@@ -20,31 +20,31 @@ const meta: Meta<typeof Avatar> = {
|
||||
export default meta
|
||||
|
||||
type Story = StoryObj<typeof Avatar>
|
||||
const imageFile = './img/profile-picture.png' as const
|
||||
const imageFile = "./img/profile-picture.png" as const
|
||||
export const WithImage: Story = {
|
||||
args: {
|
||||
src: imageFile,
|
||||
alt: 'Profile photo',
|
||||
size: 'md',
|
||||
alt: "Profile photo",
|
||||
size: "md",
|
||||
},
|
||||
}
|
||||
|
||||
export const WithInitials: Story = {
|
||||
args: {
|
||||
initials: 'FR',
|
||||
size: 'md',
|
||||
initials: "FR",
|
||||
size: "md",
|
||||
},
|
||||
}
|
||||
|
||||
export const Fallback: Story = {
|
||||
args: {
|
||||
size: 'md',
|
||||
size: "md",
|
||||
},
|
||||
}
|
||||
|
||||
export const SmallSize: Story = {
|
||||
render: () => (
|
||||
<div style={{ display: 'flex', gap: '16px', alignItems: 'center' }}>
|
||||
<div style={{ display: "flex", gap: "16px", alignItems: "center" }}>
|
||||
<Avatar src={imageFile} alt="Profile photo" size="sm" />
|
||||
<Avatar initials="FR" size="sm" />
|
||||
<Avatar size="sm" />
|
||||
@@ -54,7 +54,7 @@ export const SmallSize: Story = {
|
||||
|
||||
export const MediumSize: Story = {
|
||||
render: () => (
|
||||
<div style={{ display: 'flex', gap: '16px', alignItems: 'center' }}>
|
||||
<div style={{ display: "flex", gap: "16px", alignItems: "center" }}>
|
||||
<Avatar src={imageFile} alt="Profile photo" size="md" />
|
||||
<Avatar initials="FR" size="md" />
|
||||
<Avatar size="md" />
|
||||
@@ -64,7 +64,7 @@ export const MediumSize: Story = {
|
||||
|
||||
export const LargeSize: Story = {
|
||||
render: () => (
|
||||
<div style={{ display: 'flex', gap: '16px', alignItems: 'center' }}>
|
||||
<div style={{ display: "flex", gap: "16px", alignItems: "center" }}>
|
||||
<Avatar src={imageFile} alt="Profile photo" size="lg" />
|
||||
<Avatar initials="FR" size="lg" />
|
||||
<Avatar size="lg" />
|
||||
@@ -74,39 +74,39 @@ export const LargeSize: Story = {
|
||||
|
||||
export const AllSizes: Story = {
|
||||
render: () => (
|
||||
<div style={{ display: 'flex', gap: '24px', alignItems: 'center' }}>
|
||||
<div style={{ display: "flex", gap: "24px", alignItems: "center" }}>
|
||||
<div
|
||||
style={{
|
||||
display: 'flex',
|
||||
flexDirection: 'column',
|
||||
gap: '8px',
|
||||
alignItems: 'center',
|
||||
display: "flex",
|
||||
flexDirection: "column",
|
||||
gap: "8px",
|
||||
alignItems: "center",
|
||||
}}
|
||||
>
|
||||
<Avatar initials="FR" size="sm" />
|
||||
<span style={{ fontSize: '12px' }}>Small (20px)</span>
|
||||
<span style={{ fontSize: "12px" }}>Small (20px)</span>
|
||||
</div>
|
||||
<div
|
||||
style={{
|
||||
display: 'flex',
|
||||
flexDirection: 'column',
|
||||
gap: '8px',
|
||||
alignItems: 'center',
|
||||
display: "flex",
|
||||
flexDirection: "column",
|
||||
gap: "8px",
|
||||
alignItems: "center",
|
||||
}}
|
||||
>
|
||||
<Avatar initials="FR" size="md" />
|
||||
<span style={{ fontSize: '12px' }}>Medium (32px)</span>
|
||||
<span style={{ fontSize: "12px" }}>Medium (32px)</span>
|
||||
</div>
|
||||
<div
|
||||
style={{
|
||||
display: 'flex',
|
||||
flexDirection: 'column',
|
||||
gap: '8px',
|
||||
alignItems: 'center',
|
||||
display: "flex",
|
||||
flexDirection: "column",
|
||||
gap: "8px",
|
||||
alignItems: "center",
|
||||
}}
|
||||
>
|
||||
<Avatar initials="FR" size="lg" />
|
||||
<span style={{ fontSize: '12px' }}>Large (55px)</span>
|
||||
<span style={{ fontSize: "12px" }}>Large (55px)</span>
|
||||
</div>
|
||||
</div>
|
||||
),
|
||||
|
||||
@@ -1,28 +1,28 @@
|
||||
import { MaterialIcon } from '../Icons/MaterialIcon'
|
||||
import { Typography } from '../Typography'
|
||||
import Image from '../Image'
|
||||
import { MaterialIcon } from "../Icons/MaterialIcon"
|
||||
import { Typography } from "../Typography"
|
||||
import Image from "../Image"
|
||||
|
||||
import { variants } from './variants'
|
||||
import type { AvatarProps } from './types'
|
||||
import { variants } from "./variants"
|
||||
import type { AvatarProps } from "./types"
|
||||
|
||||
export function Avatar({
|
||||
src,
|
||||
alt,
|
||||
initials,
|
||||
size = 'md',
|
||||
size = "md",
|
||||
className,
|
||||
}: AvatarProps) {
|
||||
const classNames = variants({ size, className })
|
||||
const pixelSize = size === 'sm' ? 24 : size === 'md' ? 32 : 55
|
||||
const iconSize = size === 'sm' ? 16 : 24
|
||||
const pixelSize = size === "sm" ? 24 : size === "md" ? 32 : 55
|
||||
const iconSize = size === "sm" ? 16 : 24
|
||||
|
||||
return (
|
||||
<div className={classNames}>
|
||||
{src ? (
|
||||
<Image src={src} alt={alt || ''} width={pixelSize} height={pixelSize} />
|
||||
<Image src={src} alt={alt || ""} width={pixelSize} height={pixelSize} />
|
||||
) : initials ? (
|
||||
<Typography
|
||||
variant={size === 'lg' ? 'Title/Overline/sm' : 'Tag/sm'}
|
||||
variant={size === "lg" ? "Title/Overline/sm" : "Tag/sm"}
|
||||
className={variants.initials}
|
||||
>
|
||||
<span data-hj-suppress>{initials}</span>
|
||||
|
||||
@@ -15,7 +15,7 @@ export interface AvatarProps {
|
||||
* Size of the avatar
|
||||
* @default 'md'
|
||||
*/
|
||||
size?: 'sm' | 'md' | 'lg'
|
||||
size?: "sm" | "md" | "lg"
|
||||
/**
|
||||
* Additional CSS class names
|
||||
*/
|
||||
|
||||
@@ -1,17 +1,17 @@
|
||||
import { cva } from 'class-variance-authority'
|
||||
import { cva } from "class-variance-authority"
|
||||
|
||||
import styles from './avatar.module.css'
|
||||
import styles from "./avatar.module.css"
|
||||
|
||||
export const config = {
|
||||
variants: {
|
||||
size: {
|
||||
sm: styles['size-sm'],
|
||||
md: styles['size-md'],
|
||||
lg: styles['size-lg'],
|
||||
sm: styles["size-sm"],
|
||||
md: styles["size-md"],
|
||||
lg: styles["size-lg"],
|
||||
},
|
||||
},
|
||||
defaultVariants: {
|
||||
size: 'md',
|
||||
size: "md",
|
||||
},
|
||||
} as const
|
||||
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
import type { Meta, StoryObj } from '@storybook/nextjs-vite'
|
||||
import type { Meta, StoryObj } from "@storybook/nextjs-vite"
|
||||
|
||||
import { expect, fn } from 'storybook/test'
|
||||
import { expect, fn } from "storybook/test"
|
||||
|
||||
import { BackToTopButton } from '.'
|
||||
import { config as backToTopButtonConfig } from './variants'
|
||||
import { BackToTopButton } from "."
|
||||
import { config as backToTopButtonConfig } from "./variants"
|
||||
|
||||
const meta: Meta<typeof BackToTopButton> = {
|
||||
title: 'Patterns/BackToTopButton',
|
||||
title: "Patterns/BackToTopButton",
|
||||
component: BackToTopButton,
|
||||
argTypes: {
|
||||
onPress: {
|
||||
@@ -15,13 +15,13 @@ const meta: Meta<typeof BackToTopButton> = {
|
||||
},
|
||||
},
|
||||
position: {
|
||||
control: 'select',
|
||||
control: "select",
|
||||
options: Object.keys(backToTopButtonConfig.variants.position),
|
||||
table: {
|
||||
type: {
|
||||
summary: 'string',
|
||||
summary: "string",
|
||||
detail: Object.keys(backToTopButtonConfig.variants.position).join(
|
||||
' | '
|
||||
" | "
|
||||
),
|
||||
},
|
||||
defaultValue: {
|
||||
@@ -30,7 +30,7 @@ const meta: Meta<typeof BackToTopButton> = {
|
||||
},
|
||||
},
|
||||
label: {
|
||||
control: 'text',
|
||||
control: "text",
|
||||
},
|
||||
},
|
||||
}
|
||||
@@ -40,16 +40,16 @@ export default meta
|
||||
type Story = StoryObj<typeof BackToTopButton>
|
||||
|
||||
const globalStoryPropsInverted = {
|
||||
backgrounds: { value: 'scandicPrimaryDark' },
|
||||
backgrounds: { value: "scandicPrimaryDark" },
|
||||
}
|
||||
|
||||
export const Default: Story = {
|
||||
args: {
|
||||
onPress: fn(),
|
||||
label: 'Back to top',
|
||||
label: "Back to top",
|
||||
},
|
||||
play: async ({ canvas, userEvent, args }) => {
|
||||
await userEvent.click(await canvas.findByRole('button'))
|
||||
await userEvent.click(await canvas.findByRole("button"))
|
||||
expect(args.onPress).toHaveBeenCalledTimes(1)
|
||||
},
|
||||
}
|
||||
@@ -57,10 +57,10 @@ export const Default: Story = {
|
||||
export const PositionLeft: Story = {
|
||||
args: {
|
||||
...Default.args,
|
||||
position: 'left',
|
||||
position: "left",
|
||||
},
|
||||
play: async ({ canvas, userEvent, args }) => {
|
||||
await userEvent.click(await canvas.findByRole('button'))
|
||||
await userEvent.click(await canvas.findByRole("button"))
|
||||
expect(args.onPress).toHaveBeenCalledTimes(1)
|
||||
},
|
||||
}
|
||||
@@ -68,10 +68,10 @@ export const PositionLeft: Story = {
|
||||
export const PositionCenter: Story = {
|
||||
args: {
|
||||
...Default.args,
|
||||
position: 'center',
|
||||
position: "center",
|
||||
},
|
||||
play: async ({ canvas, userEvent, args }) => {
|
||||
await userEvent.click(await canvas.findByRole('button'))
|
||||
await userEvent.click(await canvas.findByRole("button"))
|
||||
expect(args.onPress).toHaveBeenCalledTimes(1)
|
||||
},
|
||||
}
|
||||
@@ -79,10 +79,10 @@ export const PositionCenter: Story = {
|
||||
export const PositionRight: Story = {
|
||||
args: {
|
||||
...Default.args,
|
||||
position: 'right',
|
||||
position: "right",
|
||||
},
|
||||
play: async ({ canvas, userEvent, args }) => {
|
||||
await userEvent.click(await canvas.findByRole('button'))
|
||||
await userEvent.click(await canvas.findByRole("button"))
|
||||
expect(args.onPress).toHaveBeenCalledTimes(1)
|
||||
},
|
||||
}
|
||||
@@ -91,10 +91,10 @@ export const OnDarkBackground: Story = {
|
||||
globals: globalStoryPropsInverted,
|
||||
args: {
|
||||
onPress: fn(),
|
||||
label: 'Back to top',
|
||||
label: "Back to top",
|
||||
},
|
||||
play: async ({ canvas, userEvent, args }) => {
|
||||
await userEvent.click(await canvas.findByRole('button'))
|
||||
await userEvent.click(await canvas.findByRole("button"))
|
||||
expect(args.onPress).toHaveBeenCalledTimes(1)
|
||||
},
|
||||
}
|
||||
|
||||
@@ -31,7 +31,7 @@
|
||||
/* This button is able to be on top of dark background colors,
|
||||
so we need to create an illusion that it also has an inverted border on focus */
|
||||
&::before {
|
||||
content: '';
|
||||
content: "";
|
||||
position: absolute;
|
||||
inset: -4px;
|
||||
border: 2px solid var(--Border-Inverted);
|
||||
|
||||
@@ -1,20 +1,19 @@
|
||||
'use client'
|
||||
"use client"
|
||||
|
||||
import { Button as ButtonRAC } from 'react-aria-components'
|
||||
import { Button as ButtonRAC } from "react-aria-components"
|
||||
|
||||
import { MaterialIcon } from '../Icons/MaterialIcon'
|
||||
import { Typography } from '../Typography'
|
||||
import { MaterialIcon } from "../Icons/MaterialIcon"
|
||||
import { Typography } from "../Typography"
|
||||
|
||||
import { variants } from './variants'
|
||||
import { variants } from "./variants"
|
||||
|
||||
import styles from './backToTopButton.module.css'
|
||||
import styles from "./backToTopButton.module.css"
|
||||
|
||||
import type { VariantProps } from 'class-variance-authority'
|
||||
import type { ComponentProps } from 'react'
|
||||
import type { VariantProps } from "class-variance-authority"
|
||||
import type { ComponentProps } from "react"
|
||||
|
||||
interface BackToTopButtonProps
|
||||
extends ComponentProps<typeof ButtonRAC>,
|
||||
VariantProps<typeof variants> {
|
||||
extends ComponentProps<typeof ButtonRAC>, VariantProps<typeof variants> {
|
||||
label: string
|
||||
}
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { cva } from 'class-variance-authority'
|
||||
import { cva } from "class-variance-authority"
|
||||
|
||||
import styles from './backToTopButton.module.css'
|
||||
import styles from "./backToTopButton.module.css"
|
||||
|
||||
export const config = {
|
||||
variants: {
|
||||
@@ -11,7 +11,7 @@ export const config = {
|
||||
},
|
||||
},
|
||||
defaultVariants: {
|
||||
position: 'right',
|
||||
position: "right",
|
||||
},
|
||||
} as const
|
||||
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
import type { Meta, StoryObj } from '@storybook/nextjs-vite'
|
||||
import type { Meta, StoryObj } from "@storybook/nextjs-vite"
|
||||
|
||||
import { Badge } from './Badge.tsx'
|
||||
import { Badge } from "./Badge.tsx"
|
||||
|
||||
const meta: Meta<typeof Badge> = {
|
||||
title: 'Core Components/Badge',
|
||||
title: "Core Components/Badge",
|
||||
component: Badge,
|
||||
}
|
||||
|
||||
@@ -15,7 +15,7 @@ export const Default: Story = {}
|
||||
|
||||
export const XS: Story = {
|
||||
render: () => (
|
||||
<div style={{ display: 'flex', gap: '16px', alignItems: 'center' }}>
|
||||
<div style={{ display: "flex", gap: "16px", alignItems: "center" }}>
|
||||
<Badge number={3} color="primary" size="20" />
|
||||
<Badge number={3} color="green" size="20" />
|
||||
</div>
|
||||
@@ -24,7 +24,7 @@ export const XS: Story = {
|
||||
|
||||
export const Small: Story = {
|
||||
render: () => (
|
||||
<div style={{ display: 'flex', gap: '16px', alignItems: 'center' }}>
|
||||
<div style={{ display: "flex", gap: "16px", alignItems: "center" }}>
|
||||
<Badge number={3} color="primary" size="24" />
|
||||
<Badge number={3} color="green" size="24" />
|
||||
</div>
|
||||
@@ -32,7 +32,7 @@ export const Small: Story = {
|
||||
}
|
||||
export const Medium: Story = {
|
||||
render: () => (
|
||||
<div style={{ display: 'flex', gap: '16px', alignItems: 'center' }}>
|
||||
<div style={{ display: "flex", gap: "16px", alignItems: "center" }}>
|
||||
<Badge number={3} color="primary" size="28" />
|
||||
<Badge number={3} color="green" size="28" />
|
||||
</div>
|
||||
@@ -40,7 +40,7 @@ export const Medium: Story = {
|
||||
}
|
||||
export const Large: Story = {
|
||||
render: () => (
|
||||
<div style={{ display: 'flex', gap: '16px', alignItems: 'center' }}>
|
||||
<div style={{ display: "flex", gap: "16px", alignItems: "center" }}>
|
||||
<Badge number={3} color="primary" size="32" />
|
||||
<Badge number={3} color="green" size="32" />
|
||||
</div>
|
||||
@@ -49,7 +49,7 @@ export const Large: Story = {
|
||||
|
||||
export const XL: Story = {
|
||||
render: () => (
|
||||
<div style={{ display: 'flex', gap: '16px', alignItems: 'center' }}>
|
||||
<div style={{ display: "flex", gap: "16px", alignItems: "center" }}>
|
||||
<Badge number={3} color="primary" size="36" />
|
||||
<Badge number={3} color="green" size="36" />
|
||||
</div>
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
import { config } from './variants'
|
||||
import { config } from "./variants"
|
||||
|
||||
import { VariantProps } from 'class-variance-authority'
|
||||
import { Typography } from '../Typography'
|
||||
import { TypographyProps } from '../Typography/types'
|
||||
import { VariantProps } from "class-variance-authority"
|
||||
import { Typography } from "../Typography"
|
||||
import { TypographyProps } from "../Typography/types"
|
||||
|
||||
interface BadgeProps extends VariantProps<typeof config> {
|
||||
number: string | number
|
||||
@@ -21,15 +21,15 @@ export function Badge({ number, color, size }: BadgeProps) {
|
||||
)
|
||||
}
|
||||
|
||||
function getTypography(size: BadgeProps['size']): TypographyProps['variant'] {
|
||||
function getTypography(size: BadgeProps["size"]): TypographyProps["variant"] {
|
||||
switch (size) {
|
||||
case '36':
|
||||
case '32':
|
||||
return 'Body/Paragraph/mdBold'
|
||||
case '28':
|
||||
case '24':
|
||||
return 'Body/Supporting text (caption)/smBold'
|
||||
case '20':
|
||||
return 'Label/xsRegular'
|
||||
case "36":
|
||||
case "32":
|
||||
return "Body/Paragraph/mdBold"
|
||||
case "28":
|
||||
case "24":
|
||||
return "Body/Supporting text (caption)/smBold"
|
||||
case "20":
|
||||
return "Label/xsRegular"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1 +1 @@
|
||||
export { Badge } from './Badge'
|
||||
export { Badge } from "./Badge"
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { cva } from 'class-variance-authority'
|
||||
import { cva } from "class-variance-authority"
|
||||
|
||||
import styles from './badge.module.css'
|
||||
import styles from "./badge.module.css"
|
||||
|
||||
export const config = cva(styles.badge, {
|
||||
variants: {
|
||||
@@ -9,15 +9,15 @@ export const config = cva(styles.badge, {
|
||||
green: styles.green,
|
||||
},
|
||||
size: {
|
||||
'36': styles._36,
|
||||
'32': styles._32,
|
||||
'28': styles._28,
|
||||
'24': styles._24,
|
||||
'20': styles._20,
|
||||
"36": styles._36,
|
||||
"32": styles._32,
|
||||
"28": styles._28,
|
||||
"24": styles._24,
|
||||
"20": styles._20,
|
||||
},
|
||||
},
|
||||
defaultVariants: {
|
||||
color: 'primary',
|
||||
size: '28',
|
||||
color: "primary",
|
||||
size: "28",
|
||||
},
|
||||
})
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
import type { Meta, StoryObj } from '@storybook/nextjs-vite'
|
||||
import { fn } from 'storybook/test'
|
||||
import { BookingCodeChip } from './index'
|
||||
import type { Meta, StoryObj } from "@storybook/nextjs-vite"
|
||||
import { fn } from "storybook/test"
|
||||
import { BookingCodeChip } from "./index"
|
||||
|
||||
const meta = {
|
||||
title: 'Product Components/BookingCodeChip',
|
||||
title: "Product Components/BookingCodeChip",
|
||||
component: BookingCodeChip,
|
||||
parameters: {
|
||||
layout: 'centered',
|
||||
layout: "centered",
|
||||
},
|
||||
} satisfies Meta<typeof BookingCodeChip>
|
||||
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
import { useIntl } from 'react-intl'
|
||||
import { useIntl } from "react-intl"
|
||||
|
||||
import IconChip from '../IconChip'
|
||||
import { MaterialIcon } from '../Icons/MaterialIcon'
|
||||
import FilledDiscountIcon from '../Icons/Nucleo/Benefits/FilledDiscount'
|
||||
import { Typography } from '../Typography'
|
||||
import IconChip from "../IconChip"
|
||||
import { MaterialIcon } from "../Icons/MaterialIcon"
|
||||
import FilledDiscountIcon from "../Icons/Nucleo/Benefits/FilledDiscount"
|
||||
import { Typography } from "../Typography"
|
||||
|
||||
import { cx } from 'class-variance-authority'
|
||||
import { IconButton } from '../IconButton'
|
||||
import styles from './bookingCodeChip.module.css'
|
||||
import { cx } from "class-variance-authority"
|
||||
import { IconButton } from "../IconButton"
|
||||
import styles from "./bookingCodeChip.module.css"
|
||||
|
||||
type BaseBookingCodeChipProps = {
|
||||
alignCenter?: boolean
|
||||
@@ -47,11 +47,11 @@ export function BookingCodeChip({
|
||||
return null
|
||||
}
|
||||
|
||||
const color = isCampaignRate ? 'green' : 'blue'
|
||||
const color = isCampaignRate ? "green" : "blue"
|
||||
|
||||
const iconColor = isCampaignRate
|
||||
? 'Icon/Feedback/Success'
|
||||
: 'Icon/Feedback/Information'
|
||||
? "Icon/Feedback/Success"
|
||||
: "Icon/Feedback/Information"
|
||||
|
||||
const isUnavailableRate = isCampaignRate
|
||||
? isCampaignUnavailable
|
||||
@@ -59,12 +59,12 @@ export function BookingCodeChip({
|
||||
|
||||
const label = isCampaignRate
|
||||
? intl.formatMessage({
|
||||
id: 'booking.campaign',
|
||||
defaultMessage: 'Campaign',
|
||||
id: "booking.campaign",
|
||||
defaultMessage: "Campaign",
|
||||
})
|
||||
: intl.formatMessage({
|
||||
id: 'booking.bookingCode',
|
||||
defaultMessage: 'Booking code',
|
||||
id: "booking.bookingCode",
|
||||
defaultMessage: "Booking code",
|
||||
})
|
||||
|
||||
const icon = isCampaignRate ? (
|
||||
@@ -107,8 +107,8 @@ export function BookingCodeChip({
|
||||
className={styles.removeButton}
|
||||
onPress={onClose}
|
||||
aria-label={intl.formatMessage({
|
||||
id: 'booking.removeBookingCode',
|
||||
defaultMessage: 'Remove booking code',
|
||||
id: "booking.removeBookingCode",
|
||||
defaultMessage: "Remove booking code",
|
||||
})}
|
||||
iconName="close"
|
||||
/>
|
||||
|
||||
@@ -1,41 +1,41 @@
|
||||
import type { Meta, StoryObj } from '@storybook/nextjs-vite'
|
||||
import type { Meta, StoryObj } from "@storybook/nextjs-vite"
|
||||
|
||||
import { expect, fn } from 'storybook/test'
|
||||
import { expect, fn } from "storybook/test"
|
||||
|
||||
import { Button } from './Button'
|
||||
import { buttonIconNames } from './types'
|
||||
import { config as buttonConfig } from './variants'
|
||||
import { Button } from "./Button"
|
||||
import { buttonIconNames } from "./types"
|
||||
import { config as buttonConfig } from "./variants"
|
||||
|
||||
const meta: Meta<typeof Button> = {
|
||||
title: 'Core Components/Button',
|
||||
title: "Core Components/Button",
|
||||
component: Button,
|
||||
argTypes: {
|
||||
onPress: {
|
||||
table: {
|
||||
type: { summary: 'function' },
|
||||
defaultValue: { summary: 'undefined' },
|
||||
type: { summary: "function" },
|
||||
defaultValue: { summary: "undefined" },
|
||||
},
|
||||
description: 'Callback function to handle button press events.',
|
||||
description: "Callback function to handle button press events.",
|
||||
},
|
||||
variant: {
|
||||
control: 'select',
|
||||
control: "select",
|
||||
options: Object.keys(buttonConfig.variants.variant),
|
||||
default: 'Primary',
|
||||
default: "Primary",
|
||||
table: {
|
||||
defaultValue: {
|
||||
summary: buttonConfig.defaultVariants.variant,
|
||||
},
|
||||
type: {
|
||||
summary: Object.keys(buttonConfig.variants.variant).join(' | '),
|
||||
summary: Object.keys(buttonConfig.variants.variant).join(" | "),
|
||||
},
|
||||
},
|
||||
},
|
||||
color: {
|
||||
control: 'select',
|
||||
control: "select",
|
||||
options: Object.keys(buttonConfig.variants.color),
|
||||
table: {
|
||||
type: {
|
||||
summary: Object.keys(buttonConfig.variants.color).join(' | '),
|
||||
summary: Object.keys(buttonConfig.variants.color).join(" | "),
|
||||
},
|
||||
defaultValue: {
|
||||
summary: buttonConfig.defaultVariants.color,
|
||||
@@ -43,11 +43,11 @@ const meta: Meta<typeof Button> = {
|
||||
},
|
||||
},
|
||||
size: {
|
||||
control: 'select',
|
||||
control: "select",
|
||||
options: Object.keys(buttonConfig.variants.size),
|
||||
table: {
|
||||
type: {
|
||||
summary: Object.keys(buttonConfig.variants.size).join(' | '),
|
||||
summary: Object.keys(buttonConfig.variants.size).join(" | "),
|
||||
},
|
||||
defaultValue: {
|
||||
summary: buttonConfig.defaultVariants.size,
|
||||
@@ -55,63 +55,63 @@ const meta: Meta<typeof Button> = {
|
||||
},
|
||||
},
|
||||
wrapping: {
|
||||
control: 'boolean',
|
||||
control: "boolean",
|
||||
options: Object.keys(buttonConfig.variants.wrapping),
|
||||
type: 'boolean',
|
||||
type: "boolean",
|
||||
table: {
|
||||
defaultValue: {
|
||||
summary: buttonConfig.defaultVariants.wrapping.toString(),
|
||||
},
|
||||
},
|
||||
description:
|
||||
'Only applies to variant `Text`. If `false`, the button will use smaller padding.',
|
||||
"Only applies to variant `Text`. If `false`, the button will use smaller padding.",
|
||||
},
|
||||
leadingIconName: {
|
||||
control: 'select',
|
||||
control: "select",
|
||||
options: buttonIconNames,
|
||||
table: {
|
||||
type: { summary: buttonIconNames.join(' | ') },
|
||||
defaultValue: { summary: 'undefined' },
|
||||
type: { summary: buttonIconNames.join(" | ") },
|
||||
defaultValue: { summary: "undefined" },
|
||||
},
|
||||
description: 'Name of the Material Icon to use as leading icon.',
|
||||
description: "Name of the Material Icon to use as leading icon.",
|
||||
},
|
||||
trailingIconName: {
|
||||
control: 'select',
|
||||
control: "select",
|
||||
options: buttonIconNames,
|
||||
table: {
|
||||
type: { summary: buttonIconNames.join(' | ') },
|
||||
defaultValue: { summary: 'undefined' },
|
||||
type: { summary: buttonIconNames.join(" | ") },
|
||||
defaultValue: { summary: "undefined" },
|
||||
},
|
||||
description: 'Name of the Material Icon to use as trailing icon.',
|
||||
description: "Name of the Material Icon to use as trailing icon.",
|
||||
},
|
||||
isDisabled: {
|
||||
control: 'boolean',
|
||||
control: "boolean",
|
||||
table: {
|
||||
type: { summary: 'boolean' },
|
||||
defaultValue: { summary: 'false' },
|
||||
type: { summary: "boolean" },
|
||||
defaultValue: { summary: "false" },
|
||||
},
|
||||
},
|
||||
isPending: {
|
||||
control: 'boolean',
|
||||
control: "boolean",
|
||||
table: {
|
||||
type: { summary: 'boolean' },
|
||||
defaultValue: { summary: 'false' },
|
||||
type: { summary: "boolean" },
|
||||
defaultValue: { summary: "false" },
|
||||
},
|
||||
},
|
||||
fullWidth: {
|
||||
control: 'boolean',
|
||||
control: "boolean",
|
||||
table: {
|
||||
type: { summary: 'boolean' },
|
||||
defaultValue: { summary: 'false' },
|
||||
type: { summary: "boolean" },
|
||||
defaultValue: { summary: "false" },
|
||||
},
|
||||
description:
|
||||
'By default, the button width adjusts to its content. Set to true to make the button take the full width of its container.',
|
||||
"By default, the button width adjusts to its content. Set to true to make the button take the full width of its container.",
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
const globalStoryPropsInverted = {
|
||||
backgrounds: { value: 'scandicPrimaryDark' },
|
||||
backgrounds: { value: "scandicPrimaryDark" },
|
||||
}
|
||||
export default meta
|
||||
|
||||
@@ -120,10 +120,10 @@ type Story = StoryObj<typeof Button>
|
||||
export const Default: Story = {
|
||||
args: {
|
||||
onPress: fn(),
|
||||
children: 'Button',
|
||||
children: "Button",
|
||||
},
|
||||
play: async ({ canvas, userEvent, args }) => {
|
||||
await userEvent.click(await canvas.findByRole('button'))
|
||||
await userEvent.click(await canvas.findByRole("button"))
|
||||
expect(args.onPress).toHaveBeenCalledTimes(1)
|
||||
},
|
||||
}
|
||||
@@ -131,11 +131,11 @@ export const Default: Story = {
|
||||
export const PrimaryLarge: Story = {
|
||||
args: {
|
||||
...Default.args,
|
||||
variant: 'Primary',
|
||||
size: 'lg',
|
||||
variant: "Primary",
|
||||
size: "lg",
|
||||
},
|
||||
play: async ({ canvas, userEvent, args }) => {
|
||||
await userEvent.click(await canvas.findByRole('button'))
|
||||
await userEvent.click(await canvas.findByRole("button"))
|
||||
expect(args.onPress).toHaveBeenCalledTimes(1)
|
||||
},
|
||||
}
|
||||
@@ -143,10 +143,10 @@ export const PrimaryLarge: Story = {
|
||||
export const PrimaryMedium: Story = {
|
||||
args: {
|
||||
...PrimaryLarge.args,
|
||||
size: 'md',
|
||||
size: "md",
|
||||
},
|
||||
play: async ({ canvas, userEvent, args }) => {
|
||||
await userEvent.click(await canvas.findByRole('button'))
|
||||
await userEvent.click(await canvas.findByRole("button"))
|
||||
expect(args.onPress).toHaveBeenCalledTimes(1)
|
||||
},
|
||||
}
|
||||
@@ -154,10 +154,10 @@ export const PrimaryMedium: Story = {
|
||||
export const PrimarySmall: Story = {
|
||||
args: {
|
||||
...PrimaryLarge.args,
|
||||
size: 'sm',
|
||||
size: "sm",
|
||||
},
|
||||
play: async ({ canvas, userEvent, args }) => {
|
||||
await userEvent.click(await canvas.findByRole('button'))
|
||||
await userEvent.click(await canvas.findByRole("button"))
|
||||
expect(args.onPress).toHaveBeenCalledTimes(1)
|
||||
},
|
||||
}
|
||||
@@ -169,7 +169,7 @@ export const PrimaryDisabled: Story = {
|
||||
onPress: fn(), // Fresh spy instance for disabled test
|
||||
},
|
||||
play: async ({ canvas, userEvent, args }) => {
|
||||
await userEvent.click(await canvas.findByRole('button'))
|
||||
await userEvent.click(await canvas.findByRole("button"))
|
||||
expect(args.onPress).toHaveBeenCalledTimes(0)
|
||||
},
|
||||
}
|
||||
@@ -181,7 +181,7 @@ export const PrimaryLoading: Story = {
|
||||
onPress: fn(), // Fresh spy instance for loading test
|
||||
},
|
||||
play: async ({ canvas, userEvent, args }) => {
|
||||
await userEvent.click(await canvas.findByRole('button'))
|
||||
await userEvent.click(await canvas.findByRole("button"))
|
||||
expect(args.onPress).toHaveBeenCalledTimes(0)
|
||||
},
|
||||
}
|
||||
@@ -192,7 +192,7 @@ export const PrimaryOnDarkBackground: Story = {
|
||||
...PrimaryLarge.args,
|
||||
},
|
||||
play: async ({ canvas, userEvent, args }) => {
|
||||
await userEvent.click(await canvas.findByRole('button'))
|
||||
await userEvent.click(await canvas.findByRole("button"))
|
||||
expect(args.onPress).toHaveBeenCalledTimes(1)
|
||||
},
|
||||
}
|
||||
@@ -201,11 +201,11 @@ export const PrimaryInvertedLarge: Story = {
|
||||
globals: globalStoryPropsInverted,
|
||||
args: {
|
||||
...Default.args,
|
||||
size: 'lg',
|
||||
color: 'Inverted',
|
||||
size: "lg",
|
||||
color: "Inverted",
|
||||
},
|
||||
play: async ({ canvas, userEvent, args }) => {
|
||||
await userEvent.click(await canvas.findByRole('button'))
|
||||
await userEvent.click(await canvas.findByRole("button"))
|
||||
expect(args.onPress).toHaveBeenCalledTimes(1)
|
||||
},
|
||||
}
|
||||
@@ -214,10 +214,10 @@ export const PrimaryInvertedMedium: Story = {
|
||||
globals: globalStoryPropsInverted,
|
||||
args: {
|
||||
...PrimaryInvertedLarge.args,
|
||||
size: 'md',
|
||||
size: "md",
|
||||
},
|
||||
play: async ({ canvas, userEvent, args }) => {
|
||||
await userEvent.click(await canvas.findByRole('button'))
|
||||
await userEvent.click(await canvas.findByRole("button"))
|
||||
expect(args.onPress).toHaveBeenCalledTimes(1)
|
||||
},
|
||||
}
|
||||
@@ -226,10 +226,10 @@ export const PrimaryInvertedSmall: Story = {
|
||||
globals: globalStoryPropsInverted,
|
||||
args: {
|
||||
...PrimaryInvertedLarge.args,
|
||||
size: 'sm',
|
||||
size: "sm",
|
||||
},
|
||||
play: async ({ canvas, userEvent, args }) => {
|
||||
await userEvent.click(await canvas.findByRole('button'))
|
||||
await userEvent.click(await canvas.findByRole("button"))
|
||||
expect(args.onPress).toHaveBeenCalledTimes(1)
|
||||
},
|
||||
}
|
||||
@@ -242,7 +242,7 @@ export const PrimaryInvertedDisabled: Story = {
|
||||
onPress: fn(), // Fresh spy instance for disabled test
|
||||
},
|
||||
play: async ({ canvas, userEvent, args }) => {
|
||||
await userEvent.click(await canvas.findByRole('button'))
|
||||
await userEvent.click(await canvas.findByRole("button"))
|
||||
expect(args.onPress).toHaveBeenCalledTimes(0)
|
||||
},
|
||||
}
|
||||
@@ -255,7 +255,7 @@ export const PrimaryInvertedLoading: Story = {
|
||||
onPress: fn(), // Fresh spy instance for loading test
|
||||
},
|
||||
play: async ({ canvas, userEvent, args }) => {
|
||||
await userEvent.click(await canvas.findByRole('button'))
|
||||
await userEvent.click(await canvas.findByRole("button"))
|
||||
expect(args.onPress).toHaveBeenCalledTimes(0)
|
||||
},
|
||||
}
|
||||
@@ -263,11 +263,11 @@ export const PrimaryInvertedLoading: Story = {
|
||||
export const SecondaryLarge: Story = {
|
||||
args: {
|
||||
...Default.args,
|
||||
variant: 'Secondary',
|
||||
size: 'lg',
|
||||
variant: "Secondary",
|
||||
size: "lg",
|
||||
},
|
||||
play: async ({ canvas, userEvent, args }) => {
|
||||
await userEvent.click(await canvas.findByRole('button'))
|
||||
await userEvent.click(await canvas.findByRole("button"))
|
||||
expect(args.onPress).toHaveBeenCalledTimes(1)
|
||||
},
|
||||
}
|
||||
@@ -275,10 +275,10 @@ export const SecondaryLarge: Story = {
|
||||
export const SecondaryMedium: Story = {
|
||||
args: {
|
||||
...SecondaryLarge.args,
|
||||
size: 'md',
|
||||
size: "md",
|
||||
},
|
||||
play: async ({ canvas, userEvent, args }) => {
|
||||
await userEvent.click(await canvas.findByRole('button'))
|
||||
await userEvent.click(await canvas.findByRole("button"))
|
||||
expect(args.onPress).toHaveBeenCalledTimes(1)
|
||||
},
|
||||
}
|
||||
@@ -286,10 +286,10 @@ export const SecondaryMedium: Story = {
|
||||
export const SecondarySmall: Story = {
|
||||
args: {
|
||||
...SecondaryLarge.args,
|
||||
size: 'sm',
|
||||
size: "sm",
|
||||
},
|
||||
play: async ({ canvas, userEvent, args }) => {
|
||||
await userEvent.click(await canvas.findByRole('button'))
|
||||
await userEvent.click(await canvas.findByRole("button"))
|
||||
expect(args.onPress).toHaveBeenCalledTimes(1)
|
||||
},
|
||||
}
|
||||
@@ -301,7 +301,7 @@ export const SecondaryDisabled: Story = {
|
||||
onPress: fn(), // Fresh spy instance for disabled test
|
||||
},
|
||||
play: async ({ canvas, userEvent, args }) => {
|
||||
await userEvent.click(await canvas.findByRole('button'))
|
||||
await userEvent.click(await canvas.findByRole("button"))
|
||||
expect(args.onPress).toHaveBeenCalledTimes(0)
|
||||
},
|
||||
}
|
||||
@@ -313,7 +313,7 @@ export const SecondaryLoading: Story = {
|
||||
onPress: fn(), // Fresh spy instance for loading test
|
||||
},
|
||||
play: async ({ canvas, userEvent, args }) => {
|
||||
await userEvent.click(await canvas.findByRole('button'))
|
||||
await userEvent.click(await canvas.findByRole("button"))
|
||||
expect(args.onPress).toHaveBeenCalledTimes(0)
|
||||
},
|
||||
}
|
||||
@@ -322,12 +322,12 @@ export const SecondaryInvertedLarge: Story = {
|
||||
globals: globalStoryPropsInverted,
|
||||
args: {
|
||||
...Default.args,
|
||||
variant: 'Secondary',
|
||||
color: 'Inverted',
|
||||
size: 'lg',
|
||||
variant: "Secondary",
|
||||
color: "Inverted",
|
||||
size: "lg",
|
||||
},
|
||||
play: async ({ canvas, userEvent, args }) => {
|
||||
await userEvent.click(await canvas.findByRole('button'))
|
||||
await userEvent.click(await canvas.findByRole("button"))
|
||||
expect(args.onPress).toHaveBeenCalledTimes(1)
|
||||
},
|
||||
}
|
||||
@@ -336,10 +336,10 @@ export const SecondaryInvertedMedium: Story = {
|
||||
globals: globalStoryPropsInverted,
|
||||
args: {
|
||||
...SecondaryInvertedLarge.args,
|
||||
size: 'md',
|
||||
size: "md",
|
||||
},
|
||||
play: async ({ canvas, userEvent, args }) => {
|
||||
await userEvent.click(await canvas.findByRole('button'))
|
||||
await userEvent.click(await canvas.findByRole("button"))
|
||||
expect(args.onPress).toHaveBeenCalledTimes(1)
|
||||
},
|
||||
}
|
||||
@@ -348,10 +348,10 @@ export const SecondaryInvertedSmall: Story = {
|
||||
globals: globalStoryPropsInverted,
|
||||
args: {
|
||||
...SecondaryInvertedLarge.args,
|
||||
size: 'sm',
|
||||
size: "sm",
|
||||
},
|
||||
play: async ({ canvas, userEvent, args }) => {
|
||||
await userEvent.click(await canvas.findByRole('button'))
|
||||
await userEvent.click(await canvas.findByRole("button"))
|
||||
expect(args.onPress).toHaveBeenCalledTimes(1)
|
||||
},
|
||||
}
|
||||
@@ -364,7 +364,7 @@ export const SecondaryInvertedDisabled: Story = {
|
||||
onPress: fn(), // Fresh spy instance for disabled test
|
||||
},
|
||||
play: async ({ canvas, userEvent, args }) => {
|
||||
await userEvent.click(await canvas.findByRole('button'))
|
||||
await userEvent.click(await canvas.findByRole("button"))
|
||||
expect(args.onPress).toHaveBeenCalledTimes(0)
|
||||
},
|
||||
}
|
||||
@@ -377,7 +377,7 @@ export const SecondaryInvertedLoading: Story = {
|
||||
onPress: fn(), // Fresh spy instance for loading test
|
||||
},
|
||||
play: async ({ canvas, userEvent, args }) => {
|
||||
await userEvent.click(await canvas.findByRole('button'))
|
||||
await userEvent.click(await canvas.findByRole("button"))
|
||||
expect(args.onPress).toHaveBeenCalledTimes(0)
|
||||
},
|
||||
}
|
||||
@@ -385,11 +385,11 @@ export const SecondaryInvertedLoading: Story = {
|
||||
export const TertiaryLarge: Story = {
|
||||
args: {
|
||||
...Default.args,
|
||||
variant: 'Tertiary',
|
||||
size: 'lg',
|
||||
variant: "Tertiary",
|
||||
size: "lg",
|
||||
},
|
||||
play: async ({ canvas, userEvent, args }) => {
|
||||
await userEvent.click(await canvas.findByRole('button'))
|
||||
await userEvent.click(await canvas.findByRole("button"))
|
||||
expect(args.onPress).toHaveBeenCalledTimes(1)
|
||||
},
|
||||
}
|
||||
@@ -397,10 +397,10 @@ export const TertiaryLarge: Story = {
|
||||
export const TertiaryMedium: Story = {
|
||||
args: {
|
||||
...TertiaryLarge.args,
|
||||
size: 'md',
|
||||
size: "md",
|
||||
},
|
||||
play: async ({ canvas, userEvent, args }) => {
|
||||
await userEvent.click(await canvas.findByRole('button'))
|
||||
await userEvent.click(await canvas.findByRole("button"))
|
||||
expect(args.onPress).toHaveBeenCalledTimes(1)
|
||||
},
|
||||
}
|
||||
@@ -408,10 +408,10 @@ export const TertiaryMedium: Story = {
|
||||
export const TertiarySmall: Story = {
|
||||
args: {
|
||||
...TertiaryLarge.args,
|
||||
size: 'sm',
|
||||
size: "sm",
|
||||
},
|
||||
play: async ({ canvas, userEvent, args }) => {
|
||||
await userEvent.click(await canvas.findByRole('button'))
|
||||
await userEvent.click(await canvas.findByRole("button"))
|
||||
expect(args.onPress).toHaveBeenCalledTimes(1)
|
||||
},
|
||||
}
|
||||
@@ -423,7 +423,7 @@ export const TertiaryDisabled: Story = {
|
||||
onPress: fn(), // Fresh spy instance for disabled test
|
||||
},
|
||||
play: async ({ canvas, userEvent, args }) => {
|
||||
await userEvent.click(await canvas.findByRole('button'))
|
||||
await userEvent.click(await canvas.findByRole("button"))
|
||||
expect(args.onPress).toHaveBeenCalledTimes(0)
|
||||
},
|
||||
}
|
||||
@@ -435,7 +435,7 @@ export const TertiaryLoading: Story = {
|
||||
onPress: fn(), // Fresh spy instance for loading test
|
||||
},
|
||||
play: async ({ canvas, userEvent, args }) => {
|
||||
await userEvent.click(await canvas.findByRole('button'))
|
||||
await userEvent.click(await canvas.findByRole("button"))
|
||||
expect(args.onPress).toHaveBeenCalledTimes(0)
|
||||
},
|
||||
}
|
||||
@@ -443,11 +443,11 @@ export const TertiaryLoading: Story = {
|
||||
export const TextLarge: Story = {
|
||||
args: {
|
||||
...Default.args,
|
||||
variant: 'Text',
|
||||
size: 'lg',
|
||||
variant: "Text",
|
||||
size: "lg",
|
||||
},
|
||||
play: async ({ canvas, userEvent, args }) => {
|
||||
await userEvent.click(await canvas.findByRole('button'))
|
||||
await userEvent.click(await canvas.findByRole("button"))
|
||||
expect(args.onPress).toHaveBeenCalledTimes(1)
|
||||
},
|
||||
}
|
||||
@@ -455,11 +455,11 @@ export const TextLarge: Story = {
|
||||
export const TextMedium: Story = {
|
||||
args: {
|
||||
...TextLarge.args,
|
||||
size: 'md',
|
||||
size: "md",
|
||||
},
|
||||
|
||||
play: async ({ canvas, userEvent, args }) => {
|
||||
await userEvent.click(await canvas.findByRole('button'))
|
||||
await userEvent.click(await canvas.findByRole("button"))
|
||||
expect(args.onPress).toHaveBeenCalledTimes(1)
|
||||
},
|
||||
}
|
||||
@@ -467,11 +467,11 @@ export const TextMedium: Story = {
|
||||
export const TextSmall: Story = {
|
||||
args: {
|
||||
...TextLarge.args,
|
||||
size: 'sm',
|
||||
size: "sm",
|
||||
},
|
||||
|
||||
play: async ({ canvas, userEvent, args }) => {
|
||||
await userEvent.click(await canvas.findByRole('button'))
|
||||
await userEvent.click(await canvas.findByRole("button"))
|
||||
expect(args.onPress).toHaveBeenCalledTimes(1)
|
||||
},
|
||||
}
|
||||
@@ -483,7 +483,7 @@ export const TextDisabled: Story = {
|
||||
onPress: fn(), // Fresh spy instance for disabled test
|
||||
},
|
||||
play: async ({ canvas, userEvent, args }) => {
|
||||
await userEvent.click(await canvas.findByRole('button'))
|
||||
await userEvent.click(await canvas.findByRole("button"))
|
||||
expect(args.onPress).toHaveBeenCalledTimes(0)
|
||||
},
|
||||
}
|
||||
@@ -494,7 +494,7 @@ export const TextNoWrapping: Story = {
|
||||
wrapping: false,
|
||||
},
|
||||
play: async ({ canvas, userEvent, args }) => {
|
||||
await userEvent.click(await canvas.findByRole('button'))
|
||||
await userEvent.click(await canvas.findByRole("button"))
|
||||
expect(args.onPress).toHaveBeenCalledTimes(1)
|
||||
},
|
||||
}
|
||||
@@ -503,12 +503,12 @@ export const TextInvertedLarge: Story = {
|
||||
globals: globalStoryPropsInverted,
|
||||
args: {
|
||||
...Default.args,
|
||||
variant: 'Text',
|
||||
color: 'Inverted',
|
||||
size: 'lg',
|
||||
variant: "Text",
|
||||
color: "Inverted",
|
||||
size: "lg",
|
||||
},
|
||||
play: async ({ canvas, userEvent, args }) => {
|
||||
await userEvent.click(await canvas.findByRole('button'))
|
||||
await userEvent.click(await canvas.findByRole("button"))
|
||||
expect(args.onPress).toHaveBeenCalledTimes(1)
|
||||
},
|
||||
}
|
||||
@@ -517,10 +517,10 @@ export const TextInvertedMedium: Story = {
|
||||
globals: globalStoryPropsInverted,
|
||||
args: {
|
||||
...TextInvertedLarge.args,
|
||||
size: 'md',
|
||||
size: "md",
|
||||
},
|
||||
play: async ({ canvas, userEvent, args }) => {
|
||||
await userEvent.click(await canvas.findByRole('button'))
|
||||
await userEvent.click(await canvas.findByRole("button"))
|
||||
expect(args.onPress).toHaveBeenCalledTimes(1)
|
||||
},
|
||||
}
|
||||
@@ -529,10 +529,10 @@ export const TextInvertedSmall: Story = {
|
||||
globals: globalStoryPropsInverted,
|
||||
args: {
|
||||
...TextInvertedLarge.args,
|
||||
size: 'sm',
|
||||
size: "sm",
|
||||
},
|
||||
play: async ({ canvas, userEvent, args }) => {
|
||||
await userEvent.click(await canvas.findByRole('button'))
|
||||
await userEvent.click(await canvas.findByRole("button"))
|
||||
expect(args.onPress).toHaveBeenCalledTimes(1)
|
||||
},
|
||||
}
|
||||
@@ -545,7 +545,7 @@ export const TextInvertedDisabled: Story = {
|
||||
onPress: fn(), // Fresh spy instance for disabled test
|
||||
},
|
||||
play: async ({ canvas, userEvent, args }) => {
|
||||
await userEvent.click(await canvas.findByRole('button'))
|
||||
await userEvent.click(await canvas.findByRole("button"))
|
||||
expect(args.onPress).toHaveBeenCalledTimes(0)
|
||||
},
|
||||
}
|
||||
@@ -553,15 +553,15 @@ export const TextInvertedDisabled: Story = {
|
||||
export const TextWithIcon: Story = {
|
||||
args: {
|
||||
...TextLarge.args,
|
||||
children: 'Text with icon',
|
||||
trailingIconName: 'chevron_right',
|
||||
children: "Text with icon",
|
||||
trailingIconName: "chevron_right",
|
||||
},
|
||||
play: async ({ canvas, userEvent, args }) => {
|
||||
await userEvent.click(await canvas.findByRole('button'))
|
||||
await userEvent.click(await canvas.findByRole("button"))
|
||||
expect(args.onPress).toHaveBeenCalledTimes(1)
|
||||
|
||||
expect(canvas.getByText('Text with icon')).toBeDefined()
|
||||
expect(canvas.getByTestId('MaterialIcon')).toBeDefined()
|
||||
expect(canvas.getByText("Text with icon")).toBeDefined()
|
||||
expect(canvas.getByTestId("MaterialIcon")).toBeDefined()
|
||||
},
|
||||
}
|
||||
|
||||
@@ -569,13 +569,13 @@ export const TextWithIconInverted: Story = {
|
||||
globals: globalStoryPropsInverted,
|
||||
args: {
|
||||
...TextWithIcon.args,
|
||||
color: 'Inverted',
|
||||
color: "Inverted",
|
||||
},
|
||||
play: async ({ canvas, userEvent, args }) => {
|
||||
await userEvent.click(await canvas.findByRole('button'))
|
||||
await userEvent.click(await canvas.findByRole("button"))
|
||||
expect(args.onPress).toHaveBeenCalledTimes(1)
|
||||
|
||||
expect(canvas.getByText('Text with icon')).toBeDefined()
|
||||
expect(canvas.getByTestId('MaterialIcon')).toBeDefined()
|
||||
expect(canvas.getByText("Text with icon")).toBeDefined()
|
||||
expect(canvas.getByTestId("MaterialIcon")).toBeDefined()
|
||||
},
|
||||
}
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
import { Button as ButtonRAC } from 'react-aria-components'
|
||||
import { Loading } from '../Loading/Loading'
|
||||
import { Button as ButtonRAC } from "react-aria-components"
|
||||
import { Loading } from "../Loading/Loading"
|
||||
|
||||
import { MaterialIcon } from '../Icons/MaterialIcon'
|
||||
import { Typography } from '../Typography'
|
||||
import type { ButtonProps } from './types'
|
||||
import { variants } from './variants'
|
||||
import { MaterialIcon } from "../Icons/MaterialIcon"
|
||||
import { Typography } from "../Typography"
|
||||
import type { ButtonProps } from "./types"
|
||||
import { variants } from "./variants"
|
||||
|
||||
export function Button({
|
||||
variant,
|
||||
@@ -30,9 +30,9 @@ export function Button({
|
||||
return (
|
||||
<Typography
|
||||
variant={
|
||||
size === 'sm'
|
||||
? 'Body/Supporting text (caption)/smBold'
|
||||
: 'Body/Paragraph/mdBold'
|
||||
size === "sm"
|
||||
? "Body/Supporting text (caption)/smBold"
|
||||
: "Body/Paragraph/mdBold"
|
||||
}
|
||||
>
|
||||
<ButtonRAC {...props} className={classNames}>
|
||||
@@ -43,7 +43,7 @@ export function Button({
|
||||
<MaterialIcon
|
||||
icon={leadingIconName}
|
||||
color="CurrentColor"
|
||||
size={size === 'sm' ? 20 : 24}
|
||||
size={size === "sm" ? 20 : 24}
|
||||
/>
|
||||
) : null}
|
||||
{children}
|
||||
@@ -51,11 +51,11 @@ export function Button({
|
||||
<MaterialIcon
|
||||
icon={trailingIconName}
|
||||
color="CurrentColor"
|
||||
size={size === 'sm' ? 20 : 24}
|
||||
size={size === "sm" ? 20 : 24}
|
||||
/>
|
||||
) : null}
|
||||
{isPending ? (
|
||||
<Loading size={size === 'sm' ? 18 : 20} type="CurrentColor" />
|
||||
<Loading size={size === "sm" ? 18 : 20} type="CurrentColor" />
|
||||
) : null}
|
||||
</>
|
||||
)
|
||||
|
||||
@@ -27,7 +27,7 @@
|
||||
outline-offset: 2px;
|
||||
|
||||
&::before {
|
||||
content: '';
|
||||
content: "";
|
||||
position: absolute;
|
||||
inset: -4px;
|
||||
border: 2px solid var(--Border-Inverted);
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
export { Button } from './Button'
|
||||
export { type ButtonProps } from './types'
|
||||
export { Button } from "./Button"
|
||||
export { type ButtonProps } from "./types"
|
||||
// eslint-disable-next-line react-refresh/only-export-components
|
||||
export { variants as buttonVariants, withButton } from './variants'
|
||||
export { variants as buttonVariants, withButton } from "./variants"
|
||||
|
||||
@@ -1,28 +1,28 @@
|
||||
import { Button } from 'react-aria-components'
|
||||
import { Button } from "react-aria-components"
|
||||
|
||||
import type { VariantProps } from 'class-variance-authority'
|
||||
import type { ComponentProps } from 'react'
|
||||
import type { VariantProps } from "class-variance-authority"
|
||||
import type { ComponentProps } from "react"
|
||||
|
||||
import type { SymbolCodepoints } from '../Icons/MaterialIcon/MaterialSymbol/types'
|
||||
import type { variants } from './variants'
|
||||
import type { SymbolCodepoints } from "../Icons/MaterialIcon/MaterialSymbol/types"
|
||||
import type { variants } from "./variants"
|
||||
|
||||
export const buttonIconNames = [
|
||||
'add_circle',
|
||||
'open_in_new',
|
||||
'keyboard_arrow_down',
|
||||
'keyboard_arrow_up',
|
||||
'edit_square',
|
||||
'location_on',
|
||||
'link',
|
||||
'mail',
|
||||
'cancel',
|
||||
'calendar_month',
|
||||
'calendar_clock',
|
||||
'edit_calendar',
|
||||
'calendar_add_on',
|
||||
'delete',
|
||||
'chevron_right',
|
||||
'chevron_left',
|
||||
"add_circle",
|
||||
"open_in_new",
|
||||
"keyboard_arrow_down",
|
||||
"keyboard_arrow_up",
|
||||
"edit_square",
|
||||
"location_on",
|
||||
"link",
|
||||
"mail",
|
||||
"cancel",
|
||||
"calendar_month",
|
||||
"calendar_clock",
|
||||
"edit_calendar",
|
||||
"calendar_add_on",
|
||||
"delete",
|
||||
"chevron_right",
|
||||
"chevron_left",
|
||||
] as const
|
||||
|
||||
export type ButtonIconName = Extract<
|
||||
|
||||
@@ -1,38 +1,38 @@
|
||||
import { cva } from 'class-variance-authority'
|
||||
import { cva } from "class-variance-authority"
|
||||
|
||||
import { deepmerge } from 'deepmerge-ts'
|
||||
import styles from './button.module.css'
|
||||
import { deepmerge } from "deepmerge-ts"
|
||||
import styles from "./button.module.css"
|
||||
|
||||
export const config = {
|
||||
variants: {
|
||||
variant: {
|
||||
Primary: styles['variant-primary'],
|
||||
Secondary: styles['variant-secondary'],
|
||||
Tertiary: styles['variant-tertiary'],
|
||||
Text: styles['variant-text'],
|
||||
Primary: styles["variant-primary"],
|
||||
Secondary: styles["variant-secondary"],
|
||||
Tertiary: styles["variant-tertiary"],
|
||||
Text: styles["variant-text"],
|
||||
},
|
||||
color: {
|
||||
Primary: styles['color-primary'],
|
||||
Inverted: styles['color-inverted'],
|
||||
Primary: styles["color-primary"],
|
||||
Inverted: styles["color-inverted"],
|
||||
},
|
||||
size: {
|
||||
sm: styles['size-sm'],
|
||||
md: styles['size-md'],
|
||||
lg: styles['size-lg'],
|
||||
sm: styles["size-sm"],
|
||||
md: styles["size-md"],
|
||||
lg: styles["size-lg"],
|
||||
},
|
||||
wrapping: {
|
||||
true: undefined,
|
||||
false: styles['no-wrapping'],
|
||||
false: styles["no-wrapping"],
|
||||
},
|
||||
fullWidth: {
|
||||
true: styles['full-width'],
|
||||
true: styles["full-width"],
|
||||
false: undefined,
|
||||
},
|
||||
},
|
||||
defaultVariants: {
|
||||
variant: 'Primary',
|
||||
color: 'Primary',
|
||||
size: 'lg',
|
||||
variant: "Primary",
|
||||
color: "Primary",
|
||||
size: "lg",
|
||||
wrapping: true,
|
||||
},
|
||||
} as const
|
||||
|
||||
@@ -1,20 +1,20 @@
|
||||
import type { Meta, StoryObj } from '@storybook/nextjs-vite'
|
||||
import type { Meta, StoryObj } from "@storybook/nextjs-vite"
|
||||
|
||||
import { expect, fn } from 'storybook/test'
|
||||
import { expect, fn } from "storybook/test"
|
||||
|
||||
import ButtonLink from '.'
|
||||
import buttonMeta from '../Button/Button.stories'
|
||||
import ButtonLink from "."
|
||||
import buttonMeta from "../Button/Button.stories"
|
||||
|
||||
const meta: Meta<typeof ButtonLink> = {
|
||||
title: 'Core Components/ButtonLink',
|
||||
title: "Core Components/ButtonLink",
|
||||
component: ButtonLink,
|
||||
argTypes: {
|
||||
onClick: {
|
||||
table: {
|
||||
type: { summary: 'function' },
|
||||
defaultValue: { summary: 'undefined' },
|
||||
type: { summary: "function" },
|
||||
defaultValue: { summary: "undefined" },
|
||||
},
|
||||
description: 'Callback function to handle link click events.',
|
||||
description: "Callback function to handle link click events.",
|
||||
},
|
||||
variant: buttonMeta.argTypes?.variant,
|
||||
color: buttonMeta.argTypes?.color,
|
||||
@@ -25,16 +25,16 @@ const meta: Meta<typeof ButtonLink> = {
|
||||
fullWidth: buttonMeta.argTypes?.fullWidth,
|
||||
href: {
|
||||
table: {
|
||||
type: { summary: 'string' },
|
||||
defaultValue: { summary: 'undefined' },
|
||||
type: { summary: "string" },
|
||||
defaultValue: { summary: "undefined" },
|
||||
},
|
||||
description: 'The URL that the link points to.',
|
||||
description: "The URL that the link points to.",
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
const globalStoryPropsInverted = {
|
||||
backgrounds: { value: 'scandicPrimaryDark' },
|
||||
backgrounds: { value: "scandicPrimaryDark" },
|
||||
}
|
||||
export default meta
|
||||
|
||||
@@ -43,12 +43,12 @@ type Story = StoryObj<typeof ButtonLink>
|
||||
export const Default: Story = {
|
||||
args: {
|
||||
onClick: fn(),
|
||||
href: '#',
|
||||
children: 'Button link',
|
||||
href: "#",
|
||||
children: "Button link",
|
||||
},
|
||||
play: async ({ canvasElement }) => {
|
||||
const link = canvasElement.querySelector('a')
|
||||
if (!link) throw new Error('Link not found')
|
||||
const link = canvasElement.querySelector("a")
|
||||
if (!link) throw new Error("Link not found")
|
||||
expect(link).toBeInTheDocument()
|
||||
},
|
||||
}
|
||||
@@ -56,12 +56,12 @@ export const Default: Story = {
|
||||
export const PrimaryLarge: Story = {
|
||||
args: {
|
||||
...Default.args,
|
||||
variant: 'Primary',
|
||||
size: 'lg',
|
||||
variant: "Primary",
|
||||
size: "lg",
|
||||
},
|
||||
play: async ({ canvasElement }) => {
|
||||
const link = canvasElement.querySelector('a')
|
||||
if (!link) throw new Error('Link not found')
|
||||
const link = canvasElement.querySelector("a")
|
||||
if (!link) throw new Error("Link not found")
|
||||
expect(link).toBeInTheDocument()
|
||||
},
|
||||
}
|
||||
@@ -69,11 +69,11 @@ export const PrimaryLarge: Story = {
|
||||
export const PrimaryMedium: Story = {
|
||||
args: {
|
||||
...PrimaryLarge.args,
|
||||
size: 'md',
|
||||
size: "md",
|
||||
},
|
||||
play: async ({ canvasElement }) => {
|
||||
const link = canvasElement.querySelector('a')
|
||||
if (!link) throw new Error('Link not found')
|
||||
const link = canvasElement.querySelector("a")
|
||||
if (!link) throw new Error("Link not found")
|
||||
expect(link).toBeInTheDocument()
|
||||
},
|
||||
}
|
||||
@@ -81,11 +81,11 @@ export const PrimaryMedium: Story = {
|
||||
export const PrimarySmall: Story = {
|
||||
args: {
|
||||
...PrimaryLarge.args,
|
||||
size: 'sm',
|
||||
size: "sm",
|
||||
},
|
||||
play: async ({ canvasElement }) => {
|
||||
const link = canvasElement.querySelector('a')
|
||||
if (!link) throw new Error('Link not found')
|
||||
const link = canvasElement.querySelector("a")
|
||||
if (!link) throw new Error("Link not found")
|
||||
expect(link).toBeInTheDocument()
|
||||
},
|
||||
}
|
||||
@@ -94,12 +94,12 @@ export const PrimaryOnDarkBackground: Story = {
|
||||
globals: globalStoryPropsInverted,
|
||||
args: {
|
||||
...Default.args,
|
||||
variant: 'Primary',
|
||||
size: 'lg',
|
||||
variant: "Primary",
|
||||
size: "lg",
|
||||
},
|
||||
play: async ({ canvasElement }) => {
|
||||
const link = canvasElement.querySelector('a')
|
||||
if (!link) throw new Error('Link not found')
|
||||
const link = canvasElement.querySelector("a")
|
||||
if (!link) throw new Error("Link not found")
|
||||
expect(link).toBeInTheDocument()
|
||||
},
|
||||
}
|
||||
@@ -108,14 +108,14 @@ export const PrimaryInvertedLarge: Story = {
|
||||
globals: globalStoryPropsInverted,
|
||||
args: {
|
||||
...Default.args,
|
||||
variant: 'Primary',
|
||||
color: 'Inverted',
|
||||
size: 'lg',
|
||||
variant: "Primary",
|
||||
color: "Inverted",
|
||||
size: "lg",
|
||||
},
|
||||
|
||||
play: async ({ canvasElement }) => {
|
||||
const link = canvasElement.querySelector('a')
|
||||
if (!link) throw new Error('Link not found')
|
||||
const link = canvasElement.querySelector("a")
|
||||
if (!link) throw new Error("Link not found")
|
||||
expect(link).toBeInTheDocument()
|
||||
},
|
||||
}
|
||||
@@ -124,11 +124,11 @@ export const PrimaryInvertedMedium: Story = {
|
||||
globals: globalStoryPropsInverted,
|
||||
args: {
|
||||
...PrimaryInvertedLarge.args,
|
||||
size: 'md',
|
||||
size: "md",
|
||||
},
|
||||
play: async ({ canvasElement }) => {
|
||||
const link = canvasElement.querySelector('a')
|
||||
if (!link) throw new Error('Link not found')
|
||||
const link = canvasElement.querySelector("a")
|
||||
if (!link) throw new Error("Link not found")
|
||||
expect(link).toBeInTheDocument()
|
||||
},
|
||||
}
|
||||
@@ -137,11 +137,11 @@ export const PrimaryInvertedSmall: Story = {
|
||||
globals: globalStoryPropsInverted,
|
||||
args: {
|
||||
...PrimaryInvertedLarge.args,
|
||||
size: 'sm',
|
||||
size: "sm",
|
||||
},
|
||||
play: async ({ canvasElement }) => {
|
||||
const link = canvasElement.querySelector('a')
|
||||
if (!link) throw new Error('Link not found')
|
||||
const link = canvasElement.querySelector("a")
|
||||
if (!link) throw new Error("Link not found")
|
||||
expect(link).toBeInTheDocument()
|
||||
},
|
||||
}
|
||||
@@ -149,12 +149,12 @@ export const PrimaryInvertedSmall: Story = {
|
||||
export const SecondaryLarge: Story = {
|
||||
args: {
|
||||
...Default.args,
|
||||
variant: 'Secondary',
|
||||
size: 'lg',
|
||||
variant: "Secondary",
|
||||
size: "lg",
|
||||
},
|
||||
play: async ({ canvasElement }) => {
|
||||
const link = canvasElement.querySelector('a')
|
||||
if (!link) throw new Error('Link not found')
|
||||
const link = canvasElement.querySelector("a")
|
||||
if (!link) throw new Error("Link not found")
|
||||
expect(link).toBeInTheDocument()
|
||||
},
|
||||
}
|
||||
@@ -162,11 +162,11 @@ export const SecondaryLarge: Story = {
|
||||
export const SecondaryMedium: Story = {
|
||||
args: {
|
||||
...SecondaryLarge.args,
|
||||
size: 'md',
|
||||
size: "md",
|
||||
},
|
||||
play: async ({ canvasElement }) => {
|
||||
const link = canvasElement.querySelector('a')
|
||||
if (!link) throw new Error('Link not found')
|
||||
const link = canvasElement.querySelector("a")
|
||||
if (!link) throw new Error("Link not found")
|
||||
expect(link).toBeInTheDocument()
|
||||
},
|
||||
}
|
||||
@@ -174,11 +174,11 @@ export const SecondaryMedium: Story = {
|
||||
export const SecondarySmall: Story = {
|
||||
args: {
|
||||
...SecondaryLarge.args,
|
||||
size: 'sm',
|
||||
size: "sm",
|
||||
},
|
||||
play: async ({ canvasElement }) => {
|
||||
const link = canvasElement.querySelector('a')
|
||||
if (!link) throw new Error('Link not found')
|
||||
const link = canvasElement.querySelector("a")
|
||||
if (!link) throw new Error("Link not found")
|
||||
expect(link).toBeInTheDocument()
|
||||
},
|
||||
}
|
||||
@@ -187,13 +187,13 @@ export const SecondaryInvertedLarge: Story = {
|
||||
globals: globalStoryPropsInverted,
|
||||
args: {
|
||||
...Default.args,
|
||||
variant: 'Secondary',
|
||||
color: 'Inverted',
|
||||
size: 'lg',
|
||||
variant: "Secondary",
|
||||
color: "Inverted",
|
||||
size: "lg",
|
||||
},
|
||||
play: async ({ canvasElement }) => {
|
||||
const link = canvasElement.querySelector('a')
|
||||
if (!link) throw new Error('Link not found')
|
||||
const link = canvasElement.querySelector("a")
|
||||
if (!link) throw new Error("Link not found")
|
||||
expect(link).toBeInTheDocument()
|
||||
},
|
||||
}
|
||||
@@ -202,11 +202,11 @@ export const SecondaryInvertedMedium: Story = {
|
||||
globals: globalStoryPropsInverted,
|
||||
args: {
|
||||
...SecondaryInvertedLarge.args,
|
||||
size: 'md',
|
||||
size: "md",
|
||||
},
|
||||
play: async ({ canvasElement }) => {
|
||||
const link = canvasElement.querySelector('a')
|
||||
if (!link) throw new Error('Link not found')
|
||||
const link = canvasElement.querySelector("a")
|
||||
if (!link) throw new Error("Link not found")
|
||||
expect(link).toBeInTheDocument()
|
||||
},
|
||||
}
|
||||
@@ -215,11 +215,11 @@ export const SecondaryInvertedSmall: Story = {
|
||||
globals: globalStoryPropsInverted,
|
||||
args: {
|
||||
...SecondaryInvertedLarge.args,
|
||||
size: 'sm',
|
||||
size: "sm",
|
||||
},
|
||||
play: async ({ canvasElement }) => {
|
||||
const link = canvasElement.querySelector('a')
|
||||
if (!link) throw new Error('Link not found')
|
||||
const link = canvasElement.querySelector("a")
|
||||
if (!link) throw new Error("Link not found")
|
||||
expect(link).toBeInTheDocument()
|
||||
},
|
||||
}
|
||||
@@ -227,12 +227,12 @@ export const SecondaryInvertedSmall: Story = {
|
||||
export const TertiaryLarge: Story = {
|
||||
args: {
|
||||
...Default.args,
|
||||
variant: 'Tertiary',
|
||||
size: 'lg',
|
||||
variant: "Tertiary",
|
||||
size: "lg",
|
||||
},
|
||||
play: async ({ canvasElement }) => {
|
||||
const link = canvasElement.querySelector('a')
|
||||
if (!link) throw new Error('Link not found')
|
||||
const link = canvasElement.querySelector("a")
|
||||
if (!link) throw new Error("Link not found")
|
||||
expect(link).toBeInTheDocument()
|
||||
},
|
||||
}
|
||||
@@ -240,11 +240,11 @@ export const TertiaryLarge: Story = {
|
||||
export const TertiaryMedium: Story = {
|
||||
args: {
|
||||
...TertiaryLarge.args,
|
||||
size: 'md',
|
||||
size: "md",
|
||||
},
|
||||
play: async ({ canvasElement }) => {
|
||||
const link = canvasElement.querySelector('a')
|
||||
if (!link) throw new Error('Link not found')
|
||||
const link = canvasElement.querySelector("a")
|
||||
if (!link) throw new Error("Link not found")
|
||||
expect(link).toBeInTheDocument()
|
||||
},
|
||||
}
|
||||
@@ -252,11 +252,11 @@ export const TertiaryMedium: Story = {
|
||||
export const TertiarySmall: Story = {
|
||||
args: {
|
||||
...TertiaryLarge.args,
|
||||
size: 'sm',
|
||||
size: "sm",
|
||||
},
|
||||
play: async ({ canvasElement }) => {
|
||||
const link = canvasElement.querySelector('a')
|
||||
if (!link) throw new Error('Link not found')
|
||||
const link = canvasElement.querySelector("a")
|
||||
if (!link) throw new Error("Link not found")
|
||||
expect(link).toBeInTheDocument()
|
||||
},
|
||||
}
|
||||
@@ -264,12 +264,12 @@ export const TertiarySmall: Story = {
|
||||
export const TextLarge: Story = {
|
||||
args: {
|
||||
...Default.args,
|
||||
variant: 'Text',
|
||||
size: 'lg',
|
||||
variant: "Text",
|
||||
size: "lg",
|
||||
},
|
||||
play: async ({ canvasElement }) => {
|
||||
const link = canvasElement.querySelector('a')
|
||||
if (!link) throw new Error('Link not found')
|
||||
const link = canvasElement.querySelector("a")
|
||||
if (!link) throw new Error("Link not found")
|
||||
expect(link).toBeInTheDocument()
|
||||
},
|
||||
}
|
||||
@@ -277,11 +277,11 @@ export const TextLarge: Story = {
|
||||
export const TextMedium: Story = {
|
||||
args: {
|
||||
...TextLarge.args,
|
||||
size: 'md',
|
||||
size: "md",
|
||||
},
|
||||
play: async ({ canvasElement }) => {
|
||||
const link = canvasElement.querySelector('a')
|
||||
if (!link) throw new Error('Link not found')
|
||||
const link = canvasElement.querySelector("a")
|
||||
if (!link) throw new Error("Link not found")
|
||||
expect(link).toBeInTheDocument()
|
||||
},
|
||||
}
|
||||
@@ -289,11 +289,11 @@ export const TextMedium: Story = {
|
||||
export const TextSmall: Story = {
|
||||
args: {
|
||||
...TextLarge.args,
|
||||
size: 'sm',
|
||||
size: "sm",
|
||||
},
|
||||
play: async ({ canvasElement }) => {
|
||||
const link = canvasElement.querySelector('a')
|
||||
if (!link) throw new Error('Link not found')
|
||||
const link = canvasElement.querySelector("a")
|
||||
if (!link) throw new Error("Link not found")
|
||||
expect(link).toBeInTheDocument()
|
||||
},
|
||||
}
|
||||
@@ -301,12 +301,12 @@ export const TextSmall: Story = {
|
||||
export const TextNoWrapping: Story = {
|
||||
args: {
|
||||
...TextLarge.args,
|
||||
children: 'Text button with wrapping false',
|
||||
children: "Text button with wrapping false",
|
||||
wrapping: false,
|
||||
},
|
||||
play: async ({ canvasElement }) => {
|
||||
const link = canvasElement.querySelector('a')
|
||||
if (!link) throw new Error('Link not found')
|
||||
const link = canvasElement.querySelector("a")
|
||||
if (!link) throw new Error("Link not found")
|
||||
expect(link).toBeInTheDocument()
|
||||
},
|
||||
}
|
||||
@@ -315,13 +315,13 @@ export const TextInvertedLarge: Story = {
|
||||
globals: globalStoryPropsInverted,
|
||||
args: {
|
||||
...Default.args,
|
||||
variant: 'Text',
|
||||
color: 'Inverted',
|
||||
size: 'lg',
|
||||
variant: "Text",
|
||||
color: "Inverted",
|
||||
size: "lg",
|
||||
},
|
||||
play: async ({ canvasElement }) => {
|
||||
const link = canvasElement.querySelector('a')
|
||||
if (!link) throw new Error('Link not found')
|
||||
const link = canvasElement.querySelector("a")
|
||||
if (!link) throw new Error("Link not found")
|
||||
expect(link).toBeInTheDocument()
|
||||
},
|
||||
}
|
||||
@@ -330,11 +330,11 @@ export const TextInvertedMedium: Story = {
|
||||
globals: globalStoryPropsInverted,
|
||||
args: {
|
||||
...TextInvertedLarge.args,
|
||||
size: 'md',
|
||||
size: "md",
|
||||
},
|
||||
play: async ({ canvasElement }) => {
|
||||
const link = canvasElement.querySelector('a')
|
||||
if (!link) throw new Error('Link not found')
|
||||
const link = canvasElement.querySelector("a")
|
||||
if (!link) throw new Error("Link not found")
|
||||
expect(link).toBeInTheDocument()
|
||||
},
|
||||
}
|
||||
@@ -343,11 +343,11 @@ export const TextInvertedSmall: Story = {
|
||||
globals: globalStoryPropsInverted,
|
||||
args: {
|
||||
...TextInvertedLarge.args,
|
||||
size: 'sm',
|
||||
size: "sm",
|
||||
},
|
||||
play: async ({ canvasElement }) => {
|
||||
const link = canvasElement.querySelector('a')
|
||||
if (!link) throw new Error('Link not found')
|
||||
const link = canvasElement.querySelector("a")
|
||||
if (!link) throw new Error("Link not found")
|
||||
expect(link).toBeInTheDocument()
|
||||
},
|
||||
}
|
||||
@@ -355,13 +355,13 @@ export const TextInvertedSmall: Story = {
|
||||
export const TextWithIcon: Story = {
|
||||
args: {
|
||||
...Default.args,
|
||||
variant: 'Text',
|
||||
children: 'Text with icon',
|
||||
trailingIconName: 'chevron_right',
|
||||
variant: "Text",
|
||||
children: "Text with icon",
|
||||
trailingIconName: "chevron_right",
|
||||
},
|
||||
play: async ({ canvasElement }) => {
|
||||
const link = canvasElement.querySelector('a')
|
||||
if (!link) throw new Error('Link not found')
|
||||
const link = canvasElement.querySelector("a")
|
||||
if (!link) throw new Error("Link not found")
|
||||
expect(link).toBeInTheDocument()
|
||||
},
|
||||
}
|
||||
@@ -370,11 +370,11 @@ export const TextWithIconInverted: Story = {
|
||||
globals: globalStoryPropsInverted,
|
||||
args: {
|
||||
...TextWithIcon.args,
|
||||
color: 'Inverted',
|
||||
color: "Inverted",
|
||||
},
|
||||
play: async ({ canvasElement }) => {
|
||||
const link = canvasElement.querySelector('a')
|
||||
if (!link) throw new Error('Link not found')
|
||||
const link = canvasElement.querySelector("a")
|
||||
if (!link) throw new Error("Link not found")
|
||||
expect(link).toBeInTheDocument()
|
||||
},
|
||||
}
|
||||
|
||||
@@ -1,19 +1,19 @@
|
||||
'use client'
|
||||
"use client"
|
||||
|
||||
import { type ComponentProps } from 'react'
|
||||
import { type ComponentProps } from "react"
|
||||
|
||||
import { variants } from './variants'
|
||||
import { variants } from "./variants"
|
||||
|
||||
import type { VariantProps } from 'class-variance-authority'
|
||||
import Link from 'next/link'
|
||||
import { useIntl } from 'react-intl'
|
||||
import { ButtonIconName } from '../Button/types'
|
||||
import { MaterialIcon } from '../Icons/MaterialIcon'
|
||||
import { Typography } from '../Typography'
|
||||
import type { VariantProps } from "class-variance-authority"
|
||||
import Link from "next/link"
|
||||
import { useIntl } from "react-intl"
|
||||
import { ButtonIconName } from "../Button/types"
|
||||
import { MaterialIcon } from "../Icons/MaterialIcon"
|
||||
import { Typography } from "../Typography"
|
||||
|
||||
export interface ButtonLinkProps
|
||||
extends
|
||||
Omit<ComponentProps<typeof Link>, 'color'>,
|
||||
Omit<ComponentProps<typeof Link>, "color">,
|
||||
VariantProps<typeof variants> {
|
||||
leadingIconName?: ButtonIconName | null
|
||||
trailingIconName?: ButtonIconName | null
|
||||
@@ -44,30 +44,30 @@ export default function ButtonLink({
|
||||
|
||||
const intl = useIntl()
|
||||
const newTabText = intl.formatMessage({
|
||||
id: 'common.linkOpenInNewTab',
|
||||
defaultMessage: 'Opens in a new tab/window',
|
||||
id: "common.linkOpenInNewTab",
|
||||
defaultMessage: "Opens in a new tab/window",
|
||||
})
|
||||
|
||||
return (
|
||||
<Typography
|
||||
variant={
|
||||
size === 'sm'
|
||||
? 'Body/Supporting text (caption)/smBold'
|
||||
: 'Body/Paragraph/mdBold'
|
||||
size === "sm"
|
||||
? "Body/Supporting text (caption)/smBold"
|
||||
: "Body/Paragraph/mdBold"
|
||||
}
|
||||
>
|
||||
<Link
|
||||
className={classNames}
|
||||
href={href}
|
||||
target={target}
|
||||
title={target === '_blank' ? newTabText : ''}
|
||||
title={target === "_blank" ? newTabText : ""}
|
||||
{...props}
|
||||
>
|
||||
{leadingIconName ? (
|
||||
<MaterialIcon
|
||||
icon={leadingIconName}
|
||||
color="CurrentColor"
|
||||
size={size === 'sm' ? 20 : 24}
|
||||
size={size === "sm" ? 20 : 24}
|
||||
/>
|
||||
) : null}
|
||||
{children}
|
||||
@@ -75,7 +75,7 @@ export default function ButtonLink({
|
||||
<MaterialIcon
|
||||
icon={trailingIconName}
|
||||
color="CurrentColor"
|
||||
size={size === 'sm' ? 20 : 24}
|
||||
size={size === "sm" ? 20 : 24}
|
||||
/>
|
||||
) : null}
|
||||
</Link>
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { cva } from 'class-variance-authority'
|
||||
import { cva } from "class-variance-authority"
|
||||
|
||||
import { withButton } from '../Button'
|
||||
import buttonStyles from '../Button/button.module.css'
|
||||
import { withButton } from "../Button"
|
||||
import buttonStyles from "../Button/button.module.css"
|
||||
|
||||
export const variants = cva([buttonStyles.button], withButton({}))
|
||||
|
||||
@@ -1,10 +1,11 @@
|
||||
import { Slot } from '@radix-ui/react-slot'
|
||||
import { Slot } from "@radix-ui/react-slot"
|
||||
|
||||
import { captionVariants, fontOnlycaptionVariants } from './variants'
|
||||
import { VariantProps } from 'class-variance-authority'
|
||||
import { captionVariants, fontOnlycaptionVariants } from "./variants"
|
||||
import { VariantProps } from "class-variance-authority"
|
||||
|
||||
interface CaptionProps
|
||||
extends Omit<React.HTMLAttributes<HTMLHeadingElement>, 'color'>,
|
||||
extends
|
||||
Omit<React.HTMLAttributes<HTMLHeadingElement>, "color">,
|
||||
VariantProps<typeof captionVariants> {
|
||||
asChild?: boolean
|
||||
fontOnly?: boolean
|
||||
@@ -15,7 +16,7 @@ interface CaptionProps
|
||||
*/
|
||||
export default function Caption({
|
||||
asChild = false,
|
||||
className = '',
|
||||
className = "",
|
||||
color,
|
||||
fontOnly = false,
|
||||
textAlign,
|
||||
@@ -25,7 +26,7 @@ export default function Caption({
|
||||
type,
|
||||
...props
|
||||
}: CaptionProps) {
|
||||
const Comp = asChild ? Slot : 'p'
|
||||
const Comp = asChild ? Slot : "p"
|
||||
const classNames = fontOnly
|
||||
? fontOnlycaptionVariants({
|
||||
className,
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { cva } from 'class-variance-authority'
|
||||
import { cva } from "class-variance-authority"
|
||||
|
||||
import styles from './caption.module.css'
|
||||
import styles from "./caption.module.css"
|
||||
|
||||
const config = {
|
||||
variants: {
|
||||
@@ -44,8 +44,8 @@ const config = {
|
||||
},
|
||||
},
|
||||
defaultVariants: {
|
||||
color: 'black',
|
||||
type: 'regular',
|
||||
color: "black",
|
||||
type: "regular",
|
||||
},
|
||||
} as const
|
||||
|
||||
@@ -70,7 +70,7 @@ const fontOnlyConfig = {
|
||||
},
|
||||
},
|
||||
defaultVariants: {
|
||||
type: 'regular',
|
||||
type: "regular",
|
||||
},
|
||||
} as const
|
||||
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
import type { Meta, StoryObj } from '@storybook/nextjs-vite'
|
||||
import type { Meta, StoryObj } from "@storybook/nextjs-vite"
|
||||
|
||||
import { Card } from './Card.tsx'
|
||||
import { Card } from "./Card.tsx"
|
||||
|
||||
const meta: Meta<typeof Card> = {
|
||||
title: 'Core Components/Card',
|
||||
title: "Core Components/Card",
|
||||
component: Card,
|
||||
}
|
||||
|
||||
@@ -13,13 +13,13 @@ type Story = StoryObj<typeof Card>
|
||||
|
||||
export const Default: Story = {
|
||||
args: {
|
||||
as: 'Default',
|
||||
as: "Default",
|
||||
},
|
||||
}
|
||||
|
||||
export const Featured: Story = {
|
||||
args: {
|
||||
...Default.args,
|
||||
as: 'Featured',
|
||||
as: "Featured",
|
||||
},
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { variants } from './variants'
|
||||
import { variants } from "./variants"
|
||||
|
||||
import type { CardProps } from './types'
|
||||
import type { CardProps } from "./types"
|
||||
|
||||
export function Card({ as, className, children }: CardProps) {
|
||||
const classNames = variants({
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
import type { Meta, StoryObj } from '@storybook/nextjs-vite'
|
||||
import { fn } from 'storybook/test'
|
||||
import type { Meta, StoryObj } from "@storybook/nextjs-vite"
|
||||
import { fn } from "storybook/test"
|
||||
|
||||
import { themes } from '../../../../.storybook/preview'
|
||||
import { themes } from "../../../../.storybook/preview"
|
||||
|
||||
import { Card } from '../'
|
||||
import { Button } from '../../Button'
|
||||
import { Typography } from '../../Typography'
|
||||
import { Card } from "../"
|
||||
import { Button } from "../../Button"
|
||||
import { Typography } from "../../Typography"
|
||||
|
||||
type CompositionProps = React.ComponentPropsWithoutRef<typeof Card> & {
|
||||
_onPrimaryPress?: () => void
|
||||
@@ -18,18 +18,18 @@ type CompositionProps = React.ComponentPropsWithoutRef<typeof Card> & {
|
||||
}
|
||||
|
||||
const meta: Meta<CompositionProps> = {
|
||||
title: 'Compositions/Card',
|
||||
title: "Compositions/Card",
|
||||
component: Card,
|
||||
decorators: [
|
||||
(Story, context) => {
|
||||
if (context.name.toLowerCase().indexOf('all themes') >= 0) {
|
||||
if (context.name.toLowerCase().indexOf("all themes") >= 0) {
|
||||
return (
|
||||
<>
|
||||
<h1>{context.name}</h1>
|
||||
{Object.entries(themes.themes).map(([key, value], ix) => {
|
||||
return (
|
||||
<div key={ix} className={value} style={{ padding: '1em 0' }}>
|
||||
<h2 style={{ paddingBottom: '0.5em' }}>{key}</h2>
|
||||
<div key={ix} className={value} style={{ padding: "1em 0" }}>
|
||||
<h2 style={{ paddingBottom: "0.5em" }}>{key}</h2>
|
||||
<Story />
|
||||
</div>
|
||||
)
|
||||
@@ -39,7 +39,7 @@ const meta: Meta<CompositionProps> = {
|
||||
}
|
||||
|
||||
return (
|
||||
<div style={{ display: 'flex' }}>
|
||||
<div style={{ display: "flex" }}>
|
||||
<Story />
|
||||
</div>
|
||||
)
|
||||
@@ -47,19 +47,19 @@ const meta: Meta<CompositionProps> = {
|
||||
],
|
||||
argTypes: {
|
||||
inMainArea: {
|
||||
name: 'Is in main area',
|
||||
name: "Is in main area",
|
||||
},
|
||||
showTitle: {
|
||||
name: 'Composition: Show title',
|
||||
name: "Composition: Show title",
|
||||
},
|
||||
showPreamble: {
|
||||
name: 'Composition: Show preamble',
|
||||
name: "Composition: Show preamble",
|
||||
},
|
||||
showPrimaryButton: {
|
||||
name: 'Composition: Show primary button',
|
||||
name: "Composition: Show primary button",
|
||||
},
|
||||
showSecondaryButton: {
|
||||
name: 'Composition: Show secondary button',
|
||||
name: "Composition: Show secondary button",
|
||||
},
|
||||
_onPrimaryPress: {
|
||||
table: {
|
||||
@@ -110,7 +110,7 @@ const meta: Meta<CompositionProps> = {
|
||||
|
||||
{showSecondaryButton && (
|
||||
<Button
|
||||
size={inMainArea ? 'lg' : 'sm'}
|
||||
size={inMainArea ? "lg" : "sm"}
|
||||
variant="Secondary"
|
||||
onPress={args._onSecondaryPress}
|
||||
>
|
||||
@@ -127,7 +127,7 @@ type Story = StoryObj<CompositionProps>
|
||||
|
||||
export const ContentCardMainArea: Story = {
|
||||
args: {
|
||||
as: 'Default',
|
||||
as: "Default",
|
||||
inMainArea: true,
|
||||
showTitle: true,
|
||||
showPreamble: true,
|
||||
@@ -140,7 +140,7 @@ export const ContentCardMainArea: Story = {
|
||||
|
||||
export const ContentCardNonMainArea: Story = {
|
||||
args: {
|
||||
as: 'Default',
|
||||
as: "Default",
|
||||
inMainArea: false,
|
||||
showTitle: true,
|
||||
showPreamble: true,
|
||||
|
||||
@@ -1 +1 @@
|
||||
export { Card } from './Card'
|
||||
export { Card } from "./Card"
|
||||
|
||||
@@ -1,11 +1,10 @@
|
||||
import type { VariantProps } from 'class-variance-authority'
|
||||
import type { VariantProps } from "class-variance-authority"
|
||||
|
||||
import type { variants } from './variants'
|
||||
import type { variants } from "./variants"
|
||||
|
||||
type CardStyles = 'Default' | 'Featured'
|
||||
type CardStyles = "Default" | "Featured"
|
||||
|
||||
export interface CardProps
|
||||
extends React.HTMLAttributes<HTMLDivElement>,
|
||||
VariantProps<typeof variants> {
|
||||
extends React.HTMLAttributes<HTMLDivElement>, VariantProps<typeof variants> {
|
||||
as: CardStyles
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { cva } from 'class-variance-authority'
|
||||
import { cva } from "class-variance-authority"
|
||||
|
||||
import styles from './card.module.css'
|
||||
import styles from "./card.module.css"
|
||||
|
||||
const config = {
|
||||
variants: {
|
||||
@@ -10,7 +10,7 @@ const config = {
|
||||
},
|
||||
},
|
||||
defaultVariants: {
|
||||
as: 'Default',
|
||||
as: "Default",
|
||||
},
|
||||
} as const
|
||||
|
||||
|
||||
@@ -1,9 +1,10 @@
|
||||
import { VariantProps } from 'class-variance-authority'
|
||||
import { chipVariants } from './variants'
|
||||
import Footnote from '../Footnote'
|
||||
import { VariantProps } from "class-variance-authority"
|
||||
import { chipVariants } from "./variants"
|
||||
import Footnote from "../Footnote"
|
||||
|
||||
export interface ChipProps
|
||||
extends React.HtmlHTMLAttributes<HTMLDivElement>,
|
||||
extends
|
||||
React.HtmlHTMLAttributes<HTMLDivElement>,
|
||||
VariantProps<typeof chipVariants> {}
|
||||
|
||||
/**
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { cva } from 'class-variance-authority'
|
||||
import { cva } from "class-variance-authority"
|
||||
|
||||
import styles from './chip.module.css'
|
||||
import styles from "./chip.module.css"
|
||||
|
||||
export const chipVariants = cva(styles.chip, {
|
||||
variants: {
|
||||
@@ -17,7 +17,7 @@ export const chipVariants = cva(styles.chip, {
|
||||
},
|
||||
},
|
||||
defaultVariants: {
|
||||
size: 'medium',
|
||||
variant: 'default',
|
||||
size: "medium",
|
||||
variant: "default",
|
||||
},
|
||||
})
|
||||
|
||||
@@ -1,18 +1,18 @@
|
||||
import type { Meta, StoryObj } from '@storybook/nextjs-vite'
|
||||
import type { Meta, StoryObj } from "@storybook/nextjs-vite"
|
||||
|
||||
import { fn } from 'storybook/test'
|
||||
import { fn } from "storybook/test"
|
||||
|
||||
import { MaterialIcon } from '../Icons/MaterialIcon/MaterialIcon.tsx'
|
||||
import { ChipButton } from './ChipButton.tsx'
|
||||
import { config as chipButtonConfig } from './variants'
|
||||
import { MaterialIcon } from "../Icons/MaterialIcon/MaterialIcon.tsx"
|
||||
import { ChipButton } from "./ChipButton.tsx"
|
||||
import { config as chipButtonConfig } from "./variants"
|
||||
|
||||
const meta: Meta<typeof ChipButton> = {
|
||||
title: 'Core Components/ChipButton',
|
||||
title: "Core Components/ChipButton",
|
||||
component: ChipButton,
|
||||
argTypes: {
|
||||
variant: {
|
||||
control: 'select',
|
||||
type: 'string',
|
||||
control: "select",
|
||||
type: "string",
|
||||
options: Object.keys(chipButtonConfig.variants.variant),
|
||||
},
|
||||
onPress: {
|
||||
@@ -41,7 +41,7 @@ export const Default: Story = {
|
||||
|
||||
export const Outlined: Story = {
|
||||
args: {
|
||||
variant: 'Outlined',
|
||||
variant: "Outlined",
|
||||
onPress: fn(),
|
||||
children: (
|
||||
<>
|
||||
@@ -54,9 +54,9 @@ export const Outlined: Story = {
|
||||
|
||||
export const FilterRoundedLarge: Story = {
|
||||
args: {
|
||||
variant: 'FilterRounded',
|
||||
variant: "FilterRounded",
|
||||
onPress: fn(),
|
||||
size: 'Large',
|
||||
size: "Large",
|
||||
children: (
|
||||
<>
|
||||
<MaterialIcon icon="location_city" size={20} color="CurrentColor" />
|
||||
@@ -68,9 +68,9 @@ export const FilterRoundedLarge: Story = {
|
||||
|
||||
export const FilterRoundedLargeSelected: Story = {
|
||||
args: {
|
||||
variant: 'FilterRounded',
|
||||
variant: "FilterRounded",
|
||||
onPress: fn(),
|
||||
size: 'Large',
|
||||
size: "Large",
|
||||
selected: true,
|
||||
children: (
|
||||
<>
|
||||
@@ -83,9 +83,9 @@ export const FilterRoundedLargeSelected: Story = {
|
||||
|
||||
export const FilterRoundedMedium: Story = {
|
||||
args: {
|
||||
variant: 'FilterRounded',
|
||||
variant: "FilterRounded",
|
||||
onPress: fn(),
|
||||
size: 'Medium',
|
||||
size: "Medium",
|
||||
children: (
|
||||
<>
|
||||
<MaterialIcon icon="location_city" size={20} color="CurrentColor" />
|
||||
@@ -97,9 +97,9 @@ export const FilterRoundedMedium: Story = {
|
||||
|
||||
export const FilterRoundedMediumSelected: Story = {
|
||||
args: {
|
||||
variant: 'FilterRounded',
|
||||
variant: "FilterRounded",
|
||||
onPress: fn(),
|
||||
size: 'Medium',
|
||||
size: "Medium",
|
||||
selected: true,
|
||||
children: (
|
||||
<>
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
import { Button as ButtonRAC } from 'react-aria-components'
|
||||
import { Button as ButtonRAC } from "react-aria-components"
|
||||
|
||||
import { ChipButtonProps } from './types'
|
||||
import { variants } from './variants'
|
||||
import { ChipButtonProps } from "./types"
|
||||
import { variants } from "./variants"
|
||||
|
||||
export function ChipButton({
|
||||
children,
|
||||
variant,
|
||||
selected = false,
|
||||
size = 'Large',
|
||||
size = "Large",
|
||||
className,
|
||||
...props
|
||||
}: ChipButtonProps) {
|
||||
@@ -18,7 +18,7 @@ export function ChipButton({
|
||||
})
|
||||
|
||||
return (
|
||||
<ButtonRAC {...props} className={[className, classNames].join(' ')}>
|
||||
<ButtonRAC {...props} className={[className, classNames].join(" ")}>
|
||||
{children}
|
||||
</ButtonRAC>
|
||||
)
|
||||
|
||||
@@ -1 +1 @@
|
||||
export { ChipButton } from './ChipButton'
|
||||
export { ChipButton } from "./ChipButton"
|
||||
|
||||
@@ -1,10 +1,9 @@
|
||||
import { Button } from 'react-aria-components'
|
||||
import { Button } from "react-aria-components"
|
||||
|
||||
import type { VariantProps } from 'class-variance-authority'
|
||||
import type { ComponentProps } from 'react'
|
||||
import type { VariantProps } from "class-variance-authority"
|
||||
import type { ComponentProps } from "react"
|
||||
|
||||
import type { variants } from './variants'
|
||||
import type { variants } from "./variants"
|
||||
|
||||
export interface ChipButtonProps
|
||||
extends ComponentProps<typeof Button>,
|
||||
VariantProps<typeof variants> {}
|
||||
extends ComponentProps<typeof Button>, VariantProps<typeof variants> {}
|
||||
|
||||
@@ -1,22 +1,22 @@
|
||||
import { cva } from 'class-variance-authority'
|
||||
import { cva } from "class-variance-authority"
|
||||
|
||||
import { deepmerge } from 'deepmerge-ts'
|
||||
import styles from './chip-button.module.css'
|
||||
import { config as typographyConfig } from '../Typography/variants'
|
||||
import { deepmerge } from "deepmerge-ts"
|
||||
import styles from "./chip-button.module.css"
|
||||
import { config as typographyConfig } from "../Typography/variants"
|
||||
|
||||
const variantKeys = {
|
||||
variant: {
|
||||
Default: 'Default',
|
||||
Outlined: 'Outlined',
|
||||
FilterRounded: 'FilterRounded',
|
||||
Default: "Default",
|
||||
Outlined: "Outlined",
|
||||
FilterRounded: "FilterRounded",
|
||||
},
|
||||
style: {
|
||||
Medium: 'Medium',
|
||||
Large: 'Large',
|
||||
Medium: "Medium",
|
||||
Large: "Large",
|
||||
},
|
||||
typography: {
|
||||
Bold: 'Body/Supporting text (caption)/smBold',
|
||||
Regular: 'Body/Supporting text (caption)/smRegular',
|
||||
Bold: "Body/Supporting text (caption)/smBold",
|
||||
Regular: "Body/Supporting text (caption)/smRegular",
|
||||
},
|
||||
} as const
|
||||
|
||||
@@ -28,12 +28,12 @@ export const config = {
|
||||
[variantKeys.variant.FilterRounded]: styles.FilterRounded,
|
||||
},
|
||||
selected: {
|
||||
true: '',
|
||||
false: '',
|
||||
true: "",
|
||||
false: "",
|
||||
},
|
||||
size: {
|
||||
[variantKeys.style.Medium]: '',
|
||||
[variantKeys.style.Large]: '',
|
||||
[variantKeys.style.Medium]: "",
|
||||
[variantKeys.style.Large]: "",
|
||||
},
|
||||
},
|
||||
compoundVariants: [
|
||||
@@ -41,7 +41,7 @@ export const config = {
|
||||
variant: variantKeys.variant.Default,
|
||||
className: [
|
||||
typographyConfig.variants.variant[
|
||||
'Body/Supporting text (caption)/smBold'
|
||||
"Body/Supporting text (caption)/smBold"
|
||||
],
|
||||
],
|
||||
},
|
||||
@@ -49,7 +49,7 @@ export const config = {
|
||||
variant: variantKeys.variant.Outlined,
|
||||
className: [
|
||||
typographyConfig.variants.variant[
|
||||
'Body/Supporting text (caption)/smBold'
|
||||
"Body/Supporting text (caption)/smBold"
|
||||
],
|
||||
],
|
||||
},
|
||||
@@ -59,7 +59,7 @@ export const config = {
|
||||
selected: true,
|
||||
className: [
|
||||
typographyConfig.variants.variant[
|
||||
'Body/Supporting text (caption)/smRegular'
|
||||
"Body/Supporting text (caption)/smRegular"
|
||||
],
|
||||
styles.selected,
|
||||
styles.medium,
|
||||
@@ -71,7 +71,7 @@ export const config = {
|
||||
selected: false,
|
||||
className: [
|
||||
typographyConfig.variants.variant[
|
||||
'Body/Supporting text (caption)/smRegular'
|
||||
"Body/Supporting text (caption)/smRegular"
|
||||
],
|
||||
styles.medium,
|
||||
],
|
||||
@@ -82,7 +82,7 @@ export const config = {
|
||||
selected: true,
|
||||
className: [
|
||||
typographyConfig.variants.variant[
|
||||
'Body/Supporting text (caption)/smRegular'
|
||||
"Body/Supporting text (caption)/smRegular"
|
||||
],
|
||||
styles.selected,
|
||||
styles.large,
|
||||
@@ -94,7 +94,7 @@ export const config = {
|
||||
selected: false,
|
||||
className: [
|
||||
typographyConfig.variants.variant[
|
||||
'Body/Supporting text (caption)/smRegular'
|
||||
"Body/Supporting text (caption)/smRegular"
|
||||
],
|
||||
styles.large,
|
||||
],
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
import type { Meta, StoryObj } from '@storybook/nextjs-vite'
|
||||
import type { Meta, StoryObj } from "@storybook/nextjs-vite"
|
||||
|
||||
import { MaterialIcon } from '../Icons/MaterialIcon'
|
||||
import { ChipLink } from './ChipLink.tsx'
|
||||
import { MaterialIcon } from "../Icons/MaterialIcon"
|
||||
import { ChipLink } from "./ChipLink.tsx"
|
||||
|
||||
const meta: Meta<typeof ChipLink> = {
|
||||
title: 'Core Components/ChipLink',
|
||||
title: "Core Components/ChipLink",
|
||||
component: ChipLink,
|
||||
}
|
||||
|
||||
@@ -14,7 +14,7 @@ type Story = StoryObj<typeof ChipLink>
|
||||
|
||||
export const Default: Story = {
|
||||
args: {
|
||||
href: '/',
|
||||
href: "/",
|
||||
onPress: (e) => console.log(e),
|
||||
children: (
|
||||
<>
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
import { cx } from 'class-variance-authority'
|
||||
import { Typography } from '../Typography'
|
||||
import { cx } from "class-variance-authority"
|
||||
import { Typography } from "../Typography"
|
||||
|
||||
import styles from './chip-link.module.css'
|
||||
import styles from "./chip-link.module.css"
|
||||
|
||||
import type { PropsWithChildren } from 'react'
|
||||
import type { PropsWithChildren } from "react"
|
||||
import {
|
||||
Link as LinkRAC,
|
||||
LinkProps as LinkRACProps,
|
||||
} from 'react-aria-components'
|
||||
} from "react-aria-components"
|
||||
|
||||
export function ChipLink({
|
||||
children,
|
||||
|
||||
@@ -1 +1 @@
|
||||
export { ChipLink } from './ChipLink'
|
||||
export { ChipLink } from "./ChipLink"
|
||||
|
||||
@@ -1,19 +1,19 @@
|
||||
import type { Meta, StoryObj } from '@storybook/nextjs-vite'
|
||||
import { fn } from 'storybook/test'
|
||||
import type { Meta, StoryObj } from "@storybook/nextjs-vite"
|
||||
import { fn } from "storybook/test"
|
||||
|
||||
import { Chips } from './Chips.tsx'
|
||||
import { ChipLink } from '../ChipLink/ChipLink.tsx'
|
||||
import { ChipButton } from '../ChipButton/ChipButton.tsx'
|
||||
import { Chips } from "./Chips.tsx"
|
||||
import { ChipLink } from "../ChipLink/ChipLink.tsx"
|
||||
import { ChipButton } from "../ChipButton/ChipButton.tsx"
|
||||
|
||||
import { Default as ChipLinkDefault } from '../ChipLink/ChipLink.stories.tsx'
|
||||
import { Default as ChipButtonDefault } from '../ChipButton/ChipButton.stories.tsx'
|
||||
import { Default as ChipLinkDefault } from "../ChipLink/ChipLink.stories.tsx"
|
||||
import { Default as ChipButtonDefault } from "../ChipButton/ChipButton.stories.tsx"
|
||||
|
||||
type StoryProps = React.ComponentPropsWithoutRef<typeof Chips> & {
|
||||
onPress: () => void
|
||||
}
|
||||
|
||||
const meta: Meta<StoryProps> = {
|
||||
title: 'Compositions/Chips',
|
||||
title: "Compositions/Chips",
|
||||
component: Chips,
|
||||
argTypes: {
|
||||
onPress: {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import styles from './chips.module.css'
|
||||
import styles from "./chips.module.css"
|
||||
|
||||
import type { PropsWithChildren } from 'react'
|
||||
import type { PropsWithChildren } from "react"
|
||||
|
||||
export function Chips({ children }: PropsWithChildren) {
|
||||
return <div className={styles.chips}>{children}</div>
|
||||
|
||||
@@ -1 +1 @@
|
||||
export { Chips } from './Chips'
|
||||
export { Chips } from "./Chips"
|
||||
|
||||
@@ -2,6 +2,6 @@
|
||||
display: flex;
|
||||
}
|
||||
|
||||
div[data-rac][data-open='true'] .chevron {
|
||||
div[data-rac][data-open="true"] .chevron {
|
||||
transform: rotate(180deg);
|
||||
}
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
import { IconProps } from '../../Icons'
|
||||
import { MaterialIcon } from '../../Icons/MaterialIcon'
|
||||
import styles from './chevron.module.css'
|
||||
import { IconProps } from "../../Icons"
|
||||
import { MaterialIcon } from "../../Icons/MaterialIcon"
|
||||
import styles from "./chevron.module.css"
|
||||
|
||||
export default function SelectChevron(props: IconProps) {
|
||||
return (
|
||||
<span aria-hidden="true" className={styles.chevron}>
|
||||
<MaterialIcon
|
||||
icon="keyboard_arrow_down"
|
||||
color={props.color ?? 'Icon/Default'}
|
||||
color={props.color ?? "Icon/Default"}
|
||||
size={20}
|
||||
/>
|
||||
</span>
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
'use client'
|
||||
import { ReactElement, useState } from 'react'
|
||||
"use client"
|
||||
import { ReactElement, useState } from "react"
|
||||
import {
|
||||
Button,
|
||||
type Key,
|
||||
@@ -8,17 +8,17 @@ import {
|
||||
Popover,
|
||||
Select as ReactAriaSelect,
|
||||
SelectValue,
|
||||
} from 'react-aria-components'
|
||||
} from "react-aria-components"
|
||||
|
||||
import SelectChevron from './SelectChevron'
|
||||
import SelectChevron from "./SelectChevron"
|
||||
|
||||
import styles from './select.module.css'
|
||||
import { InputLabel } from '../InputLabel'
|
||||
import { Typography } from '../Typography'
|
||||
import styles from "./select.module.css"
|
||||
import { InputLabel } from "../InputLabel"
|
||||
import { Typography } from "../Typography"
|
||||
|
||||
interface SelectProps extends Omit<
|
||||
React.SelectHTMLAttributes<HTMLSelectElement>,
|
||||
'onSelect'
|
||||
"onSelect"
|
||||
> {
|
||||
defaultSelectedKey?: Key
|
||||
items: { label: string; value: Key }[]
|
||||
@@ -37,14 +37,14 @@ interface SelectProps extends Omit<
|
||||
type SelectPortalContainer = HTMLDivElement | undefined
|
||||
type SelectPortalContainerArgs = HTMLDivElement | null
|
||||
|
||||
const DELIMITER = ':'
|
||||
const DELIMITER = ":"
|
||||
|
||||
/**
|
||||
* @deprecated Do not use.
|
||||
*/
|
||||
export default function Select({
|
||||
className = '',
|
||||
'aria-label': ariaLabel,
|
||||
className = "",
|
||||
"aria-label": ariaLabel,
|
||||
defaultSelectedKey,
|
||||
items,
|
||||
label,
|
||||
@@ -78,16 +78,16 @@ export default function Select({
|
||||
let chevronProps = {}
|
||||
|
||||
if (discreet) {
|
||||
chevronProps = { color: 'baseButtonTextOnFillNormal' }
|
||||
chevronProps = { color: "baseButtonTextOnFillNormal" }
|
||||
} else if (disabled) {
|
||||
chevronProps = { color: 'disabled' }
|
||||
chevronProps = { color: "disabled" }
|
||||
}
|
||||
|
||||
return (
|
||||
<div className={`${styles.container} ${className}`} ref={setRef}>
|
||||
<ReactAriaSelect
|
||||
aria-label={ariaLabel}
|
||||
className={`${styles.select} ${discreet ? styles.discreet : ''} select-container`}
|
||||
className={`${styles.select} ${discreet ? styles.discreet : ""} select-container`}
|
||||
defaultSelectedKey={defaultSelectedKey}
|
||||
name={name}
|
||||
onSelectionChange={handleOnSelect}
|
||||
@@ -105,7 +105,7 @@ export default function Select({
|
||||
<>
|
||||
<InputLabel
|
||||
required={required}
|
||||
size={discreet ? 'discreet' : 'regular'}
|
||||
size={discreet ? "discreet" : "regular"}
|
||||
>
|
||||
{label}
|
||||
{discreet && DELIMITER}
|
||||
@@ -113,7 +113,7 @@ export default function Select({
|
||||
{selectedText && (
|
||||
<Typography
|
||||
variant="Body/Paragraph/mdRegular"
|
||||
className={optionsIcon ? styles.iconLabel : ''}
|
||||
className={optionsIcon ? styles.iconLabel : ""}
|
||||
>
|
||||
<p>
|
||||
{optionsIcon ? optionsIcon : null}
|
||||
@@ -165,9 +165,9 @@ export default function Select({
|
||||
function useSetOverflowVisibleOnRA(isNestedInModal?: boolean) {
|
||||
function setOverflowVisible(isOpen: boolean) {
|
||||
if (isOpen) {
|
||||
document.body.style.overflow = 'visible'
|
||||
document.body.style.overflow = "visible"
|
||||
} else if (!isNestedInModal) {
|
||||
document.body.style.overflow = ''
|
||||
document.body.style.overflow = ""
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -10,16 +10,16 @@
|
||||
gap: var(--Space-x05);
|
||||
}
|
||||
|
||||
.select[data-focused='true'] {
|
||||
.select[data-focused="true"] {
|
||||
border: 2px solid var(--Border-Interactive-Focus);
|
||||
outline: none;
|
||||
}
|
||||
|
||||
.select[data-focused='true'].discreet {
|
||||
.select[data-focused="true"].discreet {
|
||||
border: 1px solid transparent;
|
||||
outline: none;
|
||||
}
|
||||
.select[data-focus-visible='true'].discreet {
|
||||
.select[data-focus-visible="true"].discreet {
|
||||
border: 2px solid var(--Border-Interactive-Focus);
|
||||
}
|
||||
|
||||
@@ -97,8 +97,8 @@
|
||||
padding: var(--Space-x1);
|
||||
}
|
||||
|
||||
.listBoxItem[data-focused='true'],
|
||||
.listBoxItem[data-selected='true'] {
|
||||
.listBoxItem[data-focused="true"],
|
||||
.listBoxItem[data-selected="true"] {
|
||||
background: var(--UI-Input-Controls-Surface-Hover);
|
||||
border-radius: var(--Corner-radius-md);
|
||||
outline: none;
|
||||
@@ -111,7 +111,7 @@
|
||||
|
||||
.listBoxItem.showRadioButton:before {
|
||||
flex-shrink: 0;
|
||||
content: '';
|
||||
content: "";
|
||||
margin-right: var(--Space-x15);
|
||||
background-color: white;
|
||||
width: 24px;
|
||||
@@ -120,6 +120,6 @@
|
||||
box-shadow: inset 0 0 0 2px var(--Base-Border-Normal);
|
||||
}
|
||||
|
||||
.listBoxItem[data-selected='true'].showRadioButton:before {
|
||||
.listBoxItem[data-selected="true"].showRadioButton:before {
|
||||
box-shadow: inset 0 0 0 8px var(--Surface-UI-Fill-Active);
|
||||
}
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
import type { Meta, StoryObj } from '@storybook/nextjs-vite'
|
||||
import type { Meta, StoryObj } from "@storybook/nextjs-vite"
|
||||
|
||||
import { Divider } from './Divider'
|
||||
import { Divider } from "./Divider"
|
||||
|
||||
const meta: Meta<typeof Divider> = {
|
||||
title: 'Core Components/Divider',
|
||||
title: "Core Components/Divider",
|
||||
component: Divider,
|
||||
argTypes: {},
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { dividerVariants } from './variants'
|
||||
import { dividerVariants } from "./variants"
|
||||
|
||||
import type { DividerProps } from './types'
|
||||
import type { DividerProps } from "./types"
|
||||
|
||||
export function Divider({ className, color, variant }: DividerProps) {
|
||||
const classNames = dividerVariants({ className, color, variant })
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
export { Divider } from './Divider'
|
||||
export { Divider } from "./Divider"
|
||||
|
||||
// eslint-disable-next-line react-refresh/only-export-components
|
||||
export { dividerVariants } from './variants'
|
||||
export { dividerVariants } from "./variants"
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
import type { VariantProps } from 'class-variance-authority'
|
||||
import type { VariantProps } from "class-variance-authority"
|
||||
|
||||
import type { dividerVariants } from './variants'
|
||||
import type { dividerVariants } from "./variants"
|
||||
|
||||
export interface DividerProps
|
||||
extends Omit<React.HTMLAttributes<HTMLHRElement>, 'color'>,
|
||||
extends
|
||||
Omit<React.HTMLAttributes<HTMLHRElement>, "color">,
|
||||
VariantProps<typeof dividerVariants> {}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { cva } from 'class-variance-authority'
|
||||
import { cva } from "class-variance-authority"
|
||||
|
||||
import styles from './divider.module.css'
|
||||
import styles from "./divider.module.css"
|
||||
|
||||
export const dividerVariants = cva(styles.divider, {
|
||||
variants: {
|
||||
@@ -9,15 +9,15 @@ export const dividerVariants = cva(styles.divider, {
|
||||
pale: styles.pale,
|
||||
peach: styles.peach,
|
||||
white: styles.white,
|
||||
'Border/Divider/Accent': styles['Border-Divider-Accent'],
|
||||
'Border/Divider/Default': styles['Border-Divider-Default'],
|
||||
'Border/Divider/Brand/OnPrimary 3/Default':
|
||||
styles['Border-Divider-Brand-OnPrimary-3-Default'],
|
||||
'Border/Divider/Subtle': styles['Border-Divider-Subtle'],
|
||||
'Surface/Brand/Primary 1/OnSurface/Accent Secondary':
|
||||
styles['Surface-Brand-Primary-1-OnSurface-Accent-Secondary'],
|
||||
'Border/Divider/Brand/OnAccent/Default':
|
||||
styles['Border-Divider-Brand-OnAccent-Default'],
|
||||
"Border/Divider/Accent": styles["Border-Divider-Accent"],
|
||||
"Border/Divider/Default": styles["Border-Divider-Default"],
|
||||
"Border/Divider/Brand/OnPrimary 3/Default":
|
||||
styles["Border-Divider-Brand-OnPrimary-3-Default"],
|
||||
"Border/Divider/Subtle": styles["Border-Divider-Subtle"],
|
||||
"Surface/Brand/Primary 1/OnSurface/Accent Secondary":
|
||||
styles["Surface-Brand-Primary-1-OnSurface-Accent-Secondary"],
|
||||
"Border/Divider/Brand/OnAccent/Default":
|
||||
styles["Border-Divider-Brand-OnAccent-Default"],
|
||||
},
|
||||
variant: {
|
||||
horizontal: styles.horizontal,
|
||||
@@ -25,7 +25,7 @@ export const dividerVariants = cva(styles.divider, {
|
||||
},
|
||||
},
|
||||
defaultVariants: {
|
||||
color: 'Border/Divider/Default',
|
||||
variant: 'horizontal',
|
||||
color: "Border/Divider/Default",
|
||||
variant: "horizontal",
|
||||
},
|
||||
})
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
import type { Meta, StoryObj } from '@storybook/nextjs-vite'
|
||||
import type { Meta, StoryObj } from "@storybook/nextjs-vite"
|
||||
|
||||
import { FacilityEnum } from '@scandic-hotels/common/constants/facilities'
|
||||
import { FacilityEnum } from "@scandic-hotels/common/constants/facilities"
|
||||
|
||||
import { FacilityToIcon } from '.'
|
||||
import { iconVariantConfig } from '../Icons/variants'
|
||||
import { FacilityToIcon } from "."
|
||||
import { iconVariantConfig } from "../Icons/variants"
|
||||
|
||||
const facilityMapping: Record<string, FacilityEnum> = Object.fromEntries(
|
||||
Object.entries(FacilityEnum).filter(([k]) => isNaN(Number(k)))
|
||||
@@ -12,26 +12,26 @@ const facilityMapping: Record<string, FacilityEnum> = Object.fromEntries(
|
||||
const colorOptions = Object.keys(iconVariantConfig.variants.color)
|
||||
|
||||
const meta: Meta<typeof FacilityToIcon> = {
|
||||
title: 'Core Components/Facility To Icon',
|
||||
title: "Core Components/Facility To Icon",
|
||||
component: FacilityToIcon,
|
||||
argTypes: {
|
||||
id: {
|
||||
control: 'select',
|
||||
control: "select",
|
||||
options: Object.keys(FacilityEnum)
|
||||
.map((key) => FacilityEnum[key as keyof typeof FacilityEnum])
|
||||
.filter((x) => typeof x === 'string')
|
||||
.filter((x) => typeof x === "string")
|
||||
.toSorted(),
|
||||
mapping: facilityMapping,
|
||||
description: 'Facility identifier (mapped to the corresponding icon)',
|
||||
description: "Facility identifier (mapped to the corresponding icon)",
|
||||
},
|
||||
color: {
|
||||
control: 'select',
|
||||
control: "select",
|
||||
options: colorOptions,
|
||||
description: 'Icon color variant',
|
||||
description: "Icon color variant",
|
||||
},
|
||||
size: {
|
||||
control: 'number',
|
||||
description: 'Icon pixel size',
|
||||
control: "number",
|
||||
description: "Icon pixel size",
|
||||
},
|
||||
},
|
||||
}
|
||||
@@ -44,7 +44,7 @@ export const Playground: Story = {
|
||||
args: {
|
||||
id: FacilityEnum.Bar,
|
||||
size: 24,
|
||||
color: 'Icon/Default',
|
||||
color: "Icon/Default",
|
||||
},
|
||||
}
|
||||
|
||||
@@ -65,13 +65,13 @@ const exampleFacilities = [
|
||||
export const Examples: Story = {
|
||||
args: {
|
||||
size: 24,
|
||||
color: 'Icon/Default',
|
||||
color: "Icon/Default",
|
||||
},
|
||||
render: (args) => (
|
||||
<div
|
||||
style={{
|
||||
display: 'grid',
|
||||
gridTemplateColumns: 'repeat(auto-fill, minmax(180px, 1fr))',
|
||||
display: "grid",
|
||||
gridTemplateColumns: "repeat(auto-fill, minmax(180px, 1fr))",
|
||||
gap: 16,
|
||||
}}
|
||||
>
|
||||
@@ -79,12 +79,12 @@ export const Examples: Story = {
|
||||
<div
|
||||
key={key}
|
||||
style={{
|
||||
display: 'flex',
|
||||
alignItems: 'center',
|
||||
display: "flex",
|
||||
alignItems: "center",
|
||||
gap: 12,
|
||||
padding: 8,
|
||||
borderRadius: 8,
|
||||
background: 'var(--ds-color-surface-subtle, #F2ECE6)',
|
||||
background: "var(--ds-color-surface-subtle, #F2ECE6)",
|
||||
}}
|
||||
>
|
||||
<FacilityToIcon id={key} size={args.size} color={args.color} />
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
import { FacilityEnum } from '@scandic-hotels/common/constants/facilities'
|
||||
import { FacilityEnum } from "@scandic-hotels/common/constants/facilities"
|
||||
|
||||
import type { JSX } from 'react'
|
||||
import { IconProps, NucleoIconProps } from '../Icons'
|
||||
import { IconByIconName } from '../Icons/IconByIconName'
|
||||
import { IconName } from '../Icons/iconName'
|
||||
import { MaterialIconSetIconProps } from '../Icons/MaterialIcon'
|
||||
import type { JSX } from "react"
|
||||
import { IconProps, NucleoIconProps } from "../Icons"
|
||||
import { IconByIconName } from "../Icons/IconByIconName"
|
||||
import { IconName } from "../Icons/iconName"
|
||||
import { MaterialIconSetIconProps } from "../Icons/MaterialIcon"
|
||||
|
||||
interface mapFacilityToIconProps {
|
||||
id: FacilityEnum
|
||||
|
||||
@@ -1,14 +1,14 @@
|
||||
'use client'
|
||||
"use client"
|
||||
|
||||
import { variants } from './variants'
|
||||
import { variants } from "./variants"
|
||||
|
||||
import { cx, type VariantProps } from 'class-variance-authority'
|
||||
import type { HTMLAttributes } from 'react'
|
||||
import { Typography } from '../Typography'
|
||||
import { cx, type VariantProps } from "class-variance-authority"
|
||||
import type { HTMLAttributes } from "react"
|
||||
import { Typography } from "../Typography"
|
||||
|
||||
interface FakeButtonProps
|
||||
extends
|
||||
Omit<HTMLAttributes<HTMLSpanElement>, 'color'>,
|
||||
Omit<HTMLAttributes<HTMLSpanElement>, "color">,
|
||||
VariantProps<typeof variants> {
|
||||
isDisabled?: boolean
|
||||
}
|
||||
@@ -36,9 +36,9 @@ export function FakeButton({
|
||||
return (
|
||||
<Typography
|
||||
variant={
|
||||
size === 'sm'
|
||||
? 'Body/Supporting text (caption)/smBold'
|
||||
: 'Body/Paragraph/mdBold'
|
||||
size === "sm"
|
||||
? "Body/Supporting text (caption)/smBold"
|
||||
: "Body/Paragraph/mdBold"
|
||||
}
|
||||
>
|
||||
<span
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
import { cva } from 'class-variance-authority'
|
||||
import { cva } from "class-variance-authority"
|
||||
|
||||
import { withButton } from '../Button'
|
||||
import { withButton } from "../Button"
|
||||
|
||||
import buttonStyles from '../Button/button.module.css'
|
||||
import buttonStyles from "../Button/button.module.css"
|
||||
|
||||
export const variants = cva(
|
||||
buttonStyles.button,
|
||||
|
||||
@@ -1,11 +1,12 @@
|
||||
import { Slot } from '@radix-ui/react-slot'
|
||||
import { Slot } from "@radix-ui/react-slot"
|
||||
|
||||
import { footnoteFontOnlyVariants, footnoteVariants } from './variants'
|
||||
import { footnoteFontOnlyVariants, footnoteVariants } from "./variants"
|
||||
|
||||
import type { VariantProps } from 'class-variance-authority'
|
||||
import type { VariantProps } from "class-variance-authority"
|
||||
|
||||
interface FootnoteProps
|
||||
extends Omit<React.HTMLAttributes<HTMLParagraphElement>, 'color'>,
|
||||
extends
|
||||
Omit<React.HTMLAttributes<HTMLParagraphElement>, "color">,
|
||||
VariantProps<typeof footnoteVariants> {
|
||||
asChild?: boolean
|
||||
fontOnly?: boolean
|
||||
@@ -16,7 +17,7 @@ interface FootnoteProps
|
||||
*/
|
||||
export default function Footnote({
|
||||
asChild = false,
|
||||
className = '',
|
||||
className = "",
|
||||
color,
|
||||
fontOnly = false,
|
||||
textAlign,
|
||||
@@ -24,7 +25,7 @@ export default function Footnote({
|
||||
type,
|
||||
...props
|
||||
}: FootnoteProps) {
|
||||
const Comp = asChild ? Slot : 'p'
|
||||
const Comp = asChild ? Slot : "p"
|
||||
const classNames = fontOnly
|
||||
? footnoteFontOnlyVariants({
|
||||
className,
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { cva } from 'class-variance-authority'
|
||||
import { cva } from "class-variance-authority"
|
||||
|
||||
import styles from './footnote.module.css'
|
||||
import styles from "./footnote.module.css"
|
||||
|
||||
const config = {
|
||||
variants: {
|
||||
@@ -29,7 +29,7 @@ const config = {
|
||||
},
|
||||
},
|
||||
defaultVariants: {
|
||||
type: 'regular',
|
||||
type: "regular",
|
||||
},
|
||||
} as const
|
||||
|
||||
@@ -51,7 +51,7 @@ const fontOnlyConfig = {
|
||||
},
|
||||
},
|
||||
defaultVariants: {
|
||||
type: 'regular',
|
||||
type: "regular",
|
||||
},
|
||||
} as const
|
||||
|
||||
|
||||
@@ -1,16 +1,16 @@
|
||||
'use client'
|
||||
"use client"
|
||||
|
||||
import { forwardRef } from 'react'
|
||||
import { Checkbox as AriaCheckbox } from 'react-aria-components'
|
||||
import { forwardRef } from "react"
|
||||
import { Checkbox as AriaCheckbox } from "react-aria-components"
|
||||
import {
|
||||
type RegisterOptions,
|
||||
useController,
|
||||
useFormContext,
|
||||
} from 'react-hook-form'
|
||||
} from "react-hook-form"
|
||||
|
||||
import styles from './checkbox.module.css'
|
||||
import { MaterialIcon } from '../../Icons/MaterialIcon'
|
||||
import { ErrorMessage } from '../ErrorMessage'
|
||||
import styles from "./checkbox.module.css"
|
||||
import { MaterialIcon } from "../../Icons/MaterialIcon"
|
||||
import { ErrorMessage } from "../ErrorMessage"
|
||||
|
||||
interface CheckboxProps extends React.InputHTMLAttributes<HTMLInputElement> {
|
||||
name: string
|
||||
@@ -25,7 +25,7 @@ const CheckboxComponent = forwardRef<
|
||||
React.PropsWithChildren<CheckboxProps>
|
||||
>(function Checkbox(
|
||||
{
|
||||
className = '',
|
||||
className = "",
|
||||
name,
|
||||
children,
|
||||
registerOptions,
|
||||
@@ -55,7 +55,7 @@ const CheckboxComponent = forwardRef<
|
||||
{({ isSelected }) => (
|
||||
<>
|
||||
<span
|
||||
className={`${styles.checkboxContainer} ${topAlign ? styles.topAlign : ''}`}
|
||||
className={`${styles.checkboxContainer} ${topAlign ? styles.topAlign : ""}`}
|
||||
>
|
||||
<span
|
||||
className={styles.checkbox}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
'use client'
|
||||
"use client"
|
||||
|
||||
import { type SyntheticEvent, useMemo, useState } from 'react'
|
||||
import { type SyntheticEvent, useMemo, useState } from "react"
|
||||
import {
|
||||
Button,
|
||||
ComboBox,
|
||||
@@ -10,33 +10,33 @@ import {
|
||||
ListBoxItem,
|
||||
Popover,
|
||||
useFilter,
|
||||
} from 'react-aria-components'
|
||||
import { useController } from 'react-hook-form'
|
||||
} from "react-aria-components"
|
||||
import { useController } from "react-hook-form"
|
||||
|
||||
import { MaterialIcon } from '../../Icons/MaterialIcon'
|
||||
import { Typography } from '../../Typography'
|
||||
import { ErrorMessage } from '../ErrorMessage'
|
||||
import { MaterialIcon } from "../../Icons/MaterialIcon"
|
||||
import { Typography } from "../../Typography"
|
||||
import { ErrorMessage } from "../ErrorMessage"
|
||||
|
||||
import styles from './country.module.css'
|
||||
import styles from "./country.module.css"
|
||||
|
||||
import type { CountryProps } from './country'
|
||||
import type { CountryProps } from "./country"
|
||||
|
||||
const prioCountryCode = ['DE', 'DK', 'FI', 'NO', 'SE']
|
||||
const prioCountryCode = ["DE", "DK", "FI", "NO", "SE"]
|
||||
|
||||
export default function CountryCombobox({
|
||||
// hack used since chrome does not respect autocomplete="off"
|
||||
autoComplete = 'nope',
|
||||
className = '',
|
||||
autoComplete = "nope",
|
||||
className = "",
|
||||
errorMessage,
|
||||
label,
|
||||
lang = 'en',
|
||||
lang = "en",
|
||||
countries,
|
||||
name = 'country',
|
||||
name = "country",
|
||||
disabled = false,
|
||||
registerOptions = {},
|
||||
}: CountryProps) {
|
||||
const { startsWith } = useFilter({ sensitivity: 'base' })
|
||||
const [filterValue, setFilterValue] = useState('')
|
||||
const { startsWith } = useFilter({ sensitivity: "base" })
|
||||
const [filterValue, setFilterValue] = useState("")
|
||||
const { field, formState, fieldState } = useController({
|
||||
name,
|
||||
rules: registerOptions,
|
||||
@@ -68,7 +68,7 @@ export default function CountryCombobox({
|
||||
|
||||
function handleOnInput(evt: SyntheticEvent<HTMLInputElement>) {
|
||||
setFilterValue(evt.currentTarget.value)
|
||||
const isAutoCompleteEvent = !('inputType' in evt.nativeEvent)
|
||||
const isAutoCompleteEvent = !("inputType" in evt.nativeEvent)
|
||||
if (isAutoCompleteEvent) {
|
||||
const { value } = evt.currentTarget
|
||||
const cc = countries.find((c) => c.name === value || c.code === value)
|
||||
@@ -89,7 +89,7 @@ export default function CountryCombobox({
|
||||
isInvalid={fieldState.invalid}
|
||||
name={name}
|
||||
onBlur={field.onBlur}
|
||||
onSelectionChange={(c) => field.onChange(c ?? '')}
|
||||
onSelectionChange={(c) => field.onChange(c ?? "")}
|
||||
selectedKey={field.value}
|
||||
menuTrigger="focus"
|
||||
>
|
||||
@@ -142,8 +142,8 @@ export default function CountryCombobox({
|
||||
<Typography
|
||||
variant={
|
||||
isSelected
|
||||
? 'Body/Paragraph/mdBold'
|
||||
: 'Body/Paragraph/mdRegular'
|
||||
? "Body/Paragraph/mdBold"
|
||||
: "Body/Paragraph/mdRegular"
|
||||
}
|
||||
>
|
||||
<span>{item.label}</span>
|
||||
|
||||
@@ -1,23 +1,23 @@
|
||||
'use client'
|
||||
"use client"
|
||||
|
||||
import { useMemo } from 'react'
|
||||
import { useController } from 'react-hook-form'
|
||||
import { useMemo } from "react"
|
||||
import { useController } from "react-hook-form"
|
||||
|
||||
import { Select } from '../../Select'
|
||||
import { Select } from "../../Select"
|
||||
|
||||
import { ErrorMessage } from '../ErrorMessage'
|
||||
import { ErrorMessage } from "../ErrorMessage"
|
||||
|
||||
import type { CountryProps } from './country'
|
||||
import type { CountryProps } from "./country"
|
||||
|
||||
const prioCountryCode = ['DE', 'DK', 'FI', 'NO', 'SE']
|
||||
const prioCountryCode = ["DE", "DK", "FI", "NO", "SE"]
|
||||
|
||||
export default function CountrySelect({
|
||||
className = '',
|
||||
className = "",
|
||||
errorMessage,
|
||||
label,
|
||||
countries,
|
||||
lang = 'en',
|
||||
name = 'country',
|
||||
lang = "en",
|
||||
name = "country",
|
||||
disabled = false,
|
||||
registerOptions = {},
|
||||
}: CountryProps) {
|
||||
@@ -58,7 +58,7 @@ export default function CountrySelect({
|
||||
isInvalid={fieldState.invalid}
|
||||
name={name}
|
||||
onBlur={field.onBlur}
|
||||
onSelectionChange={(c) => field.onChange(c ?? '')}
|
||||
onSelectionChange={(c) => field.onChange(c ?? "")}
|
||||
selectedKey={field.value}
|
||||
data-testid={name}
|
||||
/>
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
height: 56px;
|
||||
|
||||
&[data-required] .label::after {
|
||||
content: ' *';
|
||||
content: " *";
|
||||
}
|
||||
|
||||
&[data-open] {
|
||||
@@ -92,12 +92,12 @@
|
||||
}
|
||||
}
|
||||
|
||||
.inner:has(input:placeholder-shown, input[data-focused='true'], input:valid)
|
||||
.inner:has(input:placeholder-shown, input[data-focused="true"], input:valid)
|
||||
.labelValue {
|
||||
display: initial;
|
||||
}
|
||||
|
||||
.inner:has(input[value='']:not([data-focused='true'])) .labelEmpty {
|
||||
.inner:has(input[value=""]:not([data-focused="true"])) .labelEmpty {
|
||||
display: initial;
|
||||
}
|
||||
|
||||
@@ -110,7 +110,7 @@
|
||||
transition: min-height 150ms ease;
|
||||
width: 100%;
|
||||
|
||||
&[value]:not([value='']) {
|
||||
&[value]:not([value=""]) {
|
||||
min-height: 18px;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import type { RegisterOptions } from 'react-hook-form'
|
||||
import type { RegisterOptions } from "react-hook-form"
|
||||
|
||||
export type CountryProps = {
|
||||
autoComplete?: string
|
||||
|
||||
@@ -1,14 +1,14 @@
|
||||
'use client'
|
||||
"use client"
|
||||
|
||||
import { useMediaQuery } from 'usehooks-ts'
|
||||
import { useMediaQuery } from "usehooks-ts"
|
||||
|
||||
import CountryCombobox from './CountryCombobox'
|
||||
import CountrySelect from './CountrySelect'
|
||||
import CountryCombobox from "./CountryCombobox"
|
||||
import CountrySelect from "./CountrySelect"
|
||||
|
||||
import type { CountryProps } from './country'
|
||||
import type { CountryProps } from "./country"
|
||||
|
||||
export default function Country(props: CountryProps) {
|
||||
const isDesktop = useMediaQuery('(min-width: 768px)', {
|
||||
const isDesktop = useMediaQuery("(min-width: 768px)", {
|
||||
initializeWithValue: false,
|
||||
})
|
||||
|
||||
|
||||
@@ -1,14 +1,13 @@
|
||||
import { Lang } from '@scandic-hotels/common/constants/language'
|
||||
import type { RegisterOptions } from 'react-hook-form'
|
||||
import { Lang } from "@scandic-hotels/common/constants/language"
|
||||
import type { RegisterOptions } from "react-hook-form"
|
||||
|
||||
export const enum DateName {
|
||||
date = 'date',
|
||||
day = 'day',
|
||||
month = 'month',
|
||||
year = 'year',
|
||||
date = "date",
|
||||
day = "day",
|
||||
month = "month",
|
||||
year = "year",
|
||||
}
|
||||
export interface DateProps
|
||||
extends React.SelectHTMLAttributes<HTMLSelectElement> {
|
||||
export interface DateProps extends React.SelectHTMLAttributes<HTMLSelectElement> {
|
||||
labels: {
|
||||
day: string
|
||||
month: string
|
||||
|
||||
@@ -1,19 +1,19 @@
|
||||
'use client'
|
||||
import { parseDate } from '@internationalized/date'
|
||||
import { useEffect } from 'react'
|
||||
import { useController, useFormContext, useWatch } from 'react-hook-form'
|
||||
import { useMediaQuery } from 'usehooks-ts'
|
||||
"use client"
|
||||
import { parseDate } from "@internationalized/date"
|
||||
import { useEffect } from "react"
|
||||
import { useController, useFormContext, useWatch } from "react-hook-form"
|
||||
import { useMediaQuery } from "usehooks-ts"
|
||||
|
||||
import { dt } from '@scandic-hotels/common/dt'
|
||||
import { logger } from '@scandic-hotels/common/logger'
|
||||
import { getLocalizedMonthName } from '@scandic-hotels/common/utils/dateFormatting'
|
||||
import { rangeArray } from '@scandic-hotels/common/utils/rangeArray'
|
||||
import { ErrorMessage } from '../../Form/ErrorMessage'
|
||||
import { Select } from '../../Select'
|
||||
import { dt } from "@scandic-hotels/common/dt"
|
||||
import { logger } from "@scandic-hotels/common/logger"
|
||||
import { getLocalizedMonthName } from "@scandic-hotels/common/utils/dateFormatting"
|
||||
import { rangeArray } from "@scandic-hotels/common/utils/rangeArray"
|
||||
import { ErrorMessage } from "../../Form/ErrorMessage"
|
||||
import { Select } from "../../Select"
|
||||
|
||||
import { DateName, type DateProps } from './date'
|
||||
import { DateName, type DateProps } from "./date"
|
||||
|
||||
import styles from './date.module.css'
|
||||
import styles from "./date.module.css"
|
||||
|
||||
export default function DateSelect({
|
||||
labels,
|
||||
@@ -21,7 +21,7 @@ export default function DateSelect({
|
||||
name,
|
||||
registerOptions = {},
|
||||
}: DateProps) {
|
||||
const isDesktop = useMediaQuery('(min-width: 768px)', {
|
||||
const isDesktop = useMediaQuery("(min-width: 768px)", {
|
||||
initializeWithValue: false,
|
||||
})
|
||||
|
||||
@@ -37,7 +37,7 @@ export default function DateSelect({
|
||||
const month = watch(DateName.month)
|
||||
const day = watch(DateName.day)
|
||||
|
||||
const minAgeDate = dt().subtract(18, 'year').toDate() // age 18
|
||||
const minAgeDate = dt().subtract(18, "year").toDate() // age 18
|
||||
const minAgeYear = minAgeDate.getFullYear()
|
||||
const minAgeMonth = year === minAgeYear ? minAgeDate.getMonth() + 1 : null
|
||||
const minAgeDay =
|
||||
@@ -86,7 +86,7 @@ export default function DateSelect({
|
||||
.date(Number(day))
|
||||
|
||||
if (newDate.isValid()) {
|
||||
setValue(name, newDate.format('YYYY-MM-DD'), {
|
||||
setValue(name, newDate.format("YYYY-MM-DD"), {
|
||||
shouldDirty: true,
|
||||
shouldTouch: true,
|
||||
shouldValidate: true,
|
||||
@@ -105,7 +105,7 @@ export default function DateSelect({
|
||||
? parseDate(currentDateValue)
|
||||
: null
|
||||
} catch (error) {
|
||||
logger.warn('Known error for parse date in DateSelect: ', error)
|
||||
logger.warn("Known error for parse date in DateSelect: ", error)
|
||||
}
|
||||
|
||||
useEffect(() => {
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import { MaterialIcon } from '../../Icons/MaterialIcon'
|
||||
import { MaterialIcon } from "../../Icons/MaterialIcon"
|
||||
|
||||
import styles from './error.module.css'
|
||||
import { Typography } from '../../Typography'
|
||||
import styles from "./error.module.css"
|
||||
import { Typography } from "../../Typography"
|
||||
|
||||
export function Error({ children }: React.PropsWithChildren) {
|
||||
return (
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
import type { FieldValuesFromFieldErrors } from '@hookform/error-message'
|
||||
import type { FieldValuesFromFieldErrors } from "@hookform/error-message"
|
||||
import type {
|
||||
FieldErrors,
|
||||
FieldName,
|
||||
FieldValues,
|
||||
Message,
|
||||
MultipleFieldErrors,
|
||||
} from 'react-hook-form'
|
||||
} from "react-hook-form"
|
||||
|
||||
export type ErrorMessageProps<TFieldErrors> = {
|
||||
errors?: FieldErrors<FieldValues>
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
import { ErrorMessage as RHFErrorMessage } from '@hookform/error-message'
|
||||
import { ErrorMessage as RHFErrorMessage } from "@hookform/error-message"
|
||||
|
||||
import { Error } from './Error'
|
||||
import { Error } from "./Error"
|
||||
|
||||
import type { ErrorMessageProps } from './errorMessage'
|
||||
import type { ErrorMessageProps } from "./errorMessage"
|
||||
|
||||
export function ErrorMessage<T>({
|
||||
errors,
|
||||
|
||||
@@ -1,45 +1,45 @@
|
||||
'use client'
|
||||
"use client"
|
||||
|
||||
import { forwardRef, type HTMLAttributes, type WheelEvent } from 'react'
|
||||
import { Text, TextField } from 'react-aria-components'
|
||||
import { Controller, useFormContext } from 'react-hook-form'
|
||||
import { useIntl, type IntlShape } from 'react-intl'
|
||||
import { cx } from 'class-variance-authority'
|
||||
import { forwardRef, type HTMLAttributes, type WheelEvent } from "react"
|
||||
import { Text, TextField } from "react-aria-components"
|
||||
import { Controller, useFormContext } from "react-hook-form"
|
||||
import { useIntl, type IntlShape } from "react-intl"
|
||||
import { cx } from "class-variance-authority"
|
||||
|
||||
import { Error } from '../ErrorMessage/Error'
|
||||
import { mergeRefs } from '../utils/mergeRefs'
|
||||
import { MaterialIcon, MaterialIconProps } from '../../Icons/MaterialIcon'
|
||||
import { Input } from '../../Input'
|
||||
import { Error } from "../ErrorMessage/Error"
|
||||
import { mergeRefs } from "../utils/mergeRefs"
|
||||
import { MaterialIcon, MaterialIconProps } from "../../Icons/MaterialIcon"
|
||||
import { Input } from "../../Input"
|
||||
|
||||
import styles from './input.module.css'
|
||||
import styles from "./input.module.css"
|
||||
|
||||
import type { FormInputProps } from './input'
|
||||
import type { FormInputProps } from "./input"
|
||||
|
||||
const defaultErrorFormatter = (
|
||||
_intl: IntlShape,
|
||||
errorMessage?: string
|
||||
): string => errorMessage ?? ''
|
||||
): string => errorMessage ?? ""
|
||||
|
||||
export const FormInput = forwardRef<HTMLInputElement, FormInputProps>(
|
||||
function FormInput(
|
||||
{
|
||||
autoComplete,
|
||||
className = '',
|
||||
description = '',
|
||||
descriptionIcon = 'info' as MaterialIconProps['icon'],
|
||||
className = "",
|
||||
description = "",
|
||||
descriptionIcon = "info" as MaterialIconProps["icon"],
|
||||
disabled = false,
|
||||
errorFormatter,
|
||||
hideError,
|
||||
inputMode,
|
||||
label,
|
||||
labelPosition = 'floating',
|
||||
labelPosition = "floating",
|
||||
maxLength,
|
||||
name,
|
||||
id,
|
||||
placeholder,
|
||||
readOnly = false,
|
||||
registerOptions = {},
|
||||
type = 'text',
|
||||
type = "text",
|
||||
validationState,
|
||||
...props
|
||||
},
|
||||
@@ -52,7 +52,7 @@ export const FormInput = forwardRef<HTMLInputElement, FormInputProps>(
|
||||
|
||||
// Number input: prevent scroll from changing value
|
||||
const numberAttributes: HTMLAttributes<HTMLInputElement> =
|
||||
type === 'number'
|
||||
type === "number"
|
||||
? {
|
||||
onWheel: (evt: WheelEvent<HTMLInputElement>) => {
|
||||
evt.currentTarget.blur()
|
||||
@@ -87,7 +87,7 @@ export const FormInput = forwardRef<HTMLInputElement, FormInputProps>(
|
||||
name={field.name}
|
||||
onBlur={field.onBlur}
|
||||
onChange={field.onChange}
|
||||
value={field.value ?? ''}
|
||||
value={field.value ?? ""}
|
||||
autoComplete={autoComplete}
|
||||
id={id ?? field.name}
|
||||
label={label}
|
||||
@@ -123,4 +123,4 @@ export const FormInput = forwardRef<HTMLInputElement, FormInputProps>(
|
||||
}
|
||||
)
|
||||
|
||||
FormInput.displayName = 'FormInput'
|
||||
FormInput.displayName = "FormInput"
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
gap: var(--Space-x05);
|
||||
margin-top: var(--Space-x1);
|
||||
font-size: var(--Body-Supporting-text-Size);
|
||||
font-family: var(--Body-Supporting-text-Font-family, 'Fira Sans');
|
||||
font-family: var(--Body-Supporting-text-Font-family, "Fira Sans");
|
||||
font-style: normal;
|
||||
font-weight: var(--Body-Supporting-text-Font-weight);
|
||||
letter-spacing: var(--Body-Supporting-text-Letter-spacing);
|
||||
|
||||
@@ -1,14 +1,14 @@
|
||||
import type { RegisterOptions } from 'react-hook-form'
|
||||
import type { IntlShape } from 'react-intl'
|
||||
import type { RegisterOptions } from "react-hook-form"
|
||||
import type { IntlShape } from "react-intl"
|
||||
|
||||
import type { MaterialIconProps } from '../../Icons/MaterialIcon'
|
||||
import type { InputProps } from '../../Input/types'
|
||||
import type { MaterialIconProps } from "../../Icons/MaterialIcon"
|
||||
import type { InputProps } from "../../Input/types"
|
||||
|
||||
export interface FormInputProps extends InputProps {
|
||||
/** Helper text displayed below the input (hidden when there's an error) */
|
||||
description?: string
|
||||
/** Icon to display with the description text. Defaults to 'info' */
|
||||
descriptionIcon?: MaterialIconProps['icon']
|
||||
descriptionIcon?: MaterialIconProps["icon"]
|
||||
/** Field id for react-hook-form registration */
|
||||
id?: string
|
||||
/** Field name for react-hook-form registration */
|
||||
@@ -24,5 +24,5 @@ export interface FormInputProps extends InputProps {
|
||||
* - 'warning': Shows warning styling (yellow background, focus ring)
|
||||
* - Note: Error state is automatically derived from form validation
|
||||
*/
|
||||
validationState?: 'warning'
|
||||
validationState?: "warning"
|
||||
}
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
'use client'
|
||||
"use client"
|
||||
|
||||
import { useController } from 'react-hook-form'
|
||||
import { useController } from "react-hook-form"
|
||||
|
||||
import { Select } from '../../Select'
|
||||
import { Select } from "../../Select"
|
||||
|
||||
import { SelectProps } from '../../Select/types'
|
||||
import { SelectProps } from "../../Select/types"
|
||||
|
||||
export function FormSelect({ label, items, name }: SelectProps) {
|
||||
const { field, fieldState } = useController({
|
||||
@@ -17,7 +17,7 @@ export function FormSelect({ label, items, name }: SelectProps) {
|
||||
isInvalid={fieldState.invalid}
|
||||
name={name}
|
||||
onBlur={field.onBlur}
|
||||
onSelectionChange={(c) => field.onChange(c ?? '')}
|
||||
onSelectionChange={(c) => field.onChange(c ?? "")}
|
||||
selectedKey={field.value}
|
||||
data-testid={name}
|
||||
/>
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
import { cx } from 'class-variance-authority'
|
||||
import { Label, Radio } from 'react-aria-components'
|
||||
import { cx } from "class-variance-authority"
|
||||
import { Label, Radio } from "react-aria-components"
|
||||
|
||||
import styles from './paymentOption.module.css'
|
||||
import styles from "./paymentOption.module.css"
|
||||
|
||||
import type { PaymentMethodEnum } from '@scandic-hotels/common/constants/paymentMethod'
|
||||
import type { PaymentMethodEnum } from "@scandic-hotels/common/constants/paymentMethod"
|
||||
|
||||
import { PaymentMethodIcon } from '../../Payment/PaymentMethodIcon'
|
||||
import { Typography } from '../../Typography'
|
||||
import { PaymentMethodIcon } from "../../Payment/PaymentMethodIcon"
|
||||
import { Typography } from "../../Typography"
|
||||
|
||||
export type PaymentOptionProps = {
|
||||
value: string
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
import type { Meta, StoryObj } from '@storybook/nextjs-vite'
|
||||
import { expect, fn } from 'storybook/test'
|
||||
import type { Meta, StoryObj } from "@storybook/nextjs-vite"
|
||||
import { expect, fn } from "storybook/test"
|
||||
|
||||
import { PaymentOptionsGroup } from './PaymentOptionsGroup'
|
||||
import { PaymentOption } from './PaymentOption'
|
||||
import { PaymentMethodEnum } from '@scandic-hotels/common/constants/paymentMethod'
|
||||
import { FormDecorator } from '../../../../.storybook/decorators/FormDecorator'
|
||||
import { PaymentOptionsGroup } from "./PaymentOptionsGroup"
|
||||
import { PaymentOption } from "./PaymentOption"
|
||||
import { PaymentMethodEnum } from "@scandic-hotels/common/constants/paymentMethod"
|
||||
import { FormDecorator } from "../../../../.storybook/decorators/FormDecorator"
|
||||
|
||||
const meta: Meta<typeof PaymentOptionsGroup> = {
|
||||
title: 'Patterns/Form/Payment/PaymentOptionsGroup',
|
||||
title: "Patterns/Form/Payment/PaymentOptionsGroup",
|
||||
component: PaymentOptionsGroup,
|
||||
decorators: [FormDecorator],
|
||||
}
|
||||
@@ -17,8 +17,8 @@ type Story = StoryObj<typeof PaymentOptionsGroup>
|
||||
|
||||
export const Default: Story = {
|
||||
args: {
|
||||
label: 'Select Payment Method',
|
||||
name: 'paymentMethod',
|
||||
label: "Select Payment Method",
|
||||
name: "paymentMethod",
|
||||
onChange: fn(),
|
||||
children: (
|
||||
<>
|
||||
@@ -42,11 +42,11 @@ export const Default: Story = {
|
||||
),
|
||||
},
|
||||
play: async ({ canvas, userEvent, args }) => {
|
||||
const visaOption = await canvas.findByRole('radio', { name: 'Visa' })
|
||||
const visaOption = await canvas.findByRole("radio", { name: "Visa" })
|
||||
expect(visaOption).toBeInTheDocument()
|
||||
|
||||
expect(args.onChange).not.toHaveBeenCalled()
|
||||
await userEvent.click(visaOption)
|
||||
expect(args.onChange).toHaveBeenCalledWith('visa')
|
||||
expect(args.onChange).toHaveBeenCalledWith("visa")
|
||||
},
|
||||
}
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
'use client'
|
||||
"use client"
|
||||
|
||||
import { Label, RadioGroup } from 'react-aria-components'
|
||||
import { useController, useFormContext } from 'react-hook-form'
|
||||
import type { ReactNode } from 'react'
|
||||
import { Typography } from '../../../components/Typography'
|
||||
import { Label, RadioGroup } from "react-aria-components"
|
||||
import { useController, useFormContext } from "react-hook-form"
|
||||
import type { ReactNode } from "react"
|
||||
import { Typography } from "../../../components/Typography"
|
||||
|
||||
interface PaymentOptionsGroupProps {
|
||||
name: string
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
'use client'
|
||||
import 'react-international-phone/style.css'
|
||||
"use client"
|
||||
import "react-international-phone/style.css"
|
||||
|
||||
import { useEffect, useMemo } from 'react'
|
||||
import { TextField } from 'react-aria-components'
|
||||
import { useFormContext, useWatch } from 'react-hook-form'
|
||||
import { useEffect, useMemo } from "react"
|
||||
import { TextField } from "react-aria-components"
|
||||
import { useFormContext, useWatch } from "react-hook-form"
|
||||
import {
|
||||
buildCountryData,
|
||||
CountrySelector,
|
||||
@@ -12,29 +12,29 @@ import {
|
||||
parseCountry,
|
||||
type ParsedCountry,
|
||||
usePhoneInput,
|
||||
} from 'react-international-phone'
|
||||
} from "react-international-phone"
|
||||
|
||||
import { ErrorMessage } from '../ErrorMessage'
|
||||
import { MaterialIcon } from '../../Icons/MaterialIcon'
|
||||
import { Input } from '../../Input'
|
||||
import { InputLabel } from '../../InputLabel'
|
||||
import { ErrorMessage } from "../ErrorMessage"
|
||||
import { MaterialIcon } from "../../Icons/MaterialIcon"
|
||||
import { Input } from "../../Input"
|
||||
import { InputLabel } from "../../InputLabel"
|
||||
|
||||
import styles from './phone.module.css'
|
||||
import styles from "./phone.module.css"
|
||||
|
||||
import type { PhoneProps } from './phone'
|
||||
import { Typography } from '../../Typography'
|
||||
import type { PhoneProps } from "./phone"
|
||||
import { Typography } from "../../Typography"
|
||||
|
||||
export default function Phone({
|
||||
ariaLabel = 'Phone number input',
|
||||
className = '',
|
||||
countryLabel = 'Country code',
|
||||
countrySelectorName = 'phoneNumberCC',
|
||||
ariaLabel = "Phone number input",
|
||||
className = "",
|
||||
countryLabel = "Country code",
|
||||
countrySelectorName = "phoneNumberCC",
|
||||
countriesWithTranslatedName,
|
||||
defaultCountryCode,
|
||||
disabled = false,
|
||||
errorMessage,
|
||||
label,
|
||||
name = 'phoneNumber',
|
||||
name = "phoneNumber",
|
||||
placeholder,
|
||||
registerOptions = {
|
||||
required: true,
|
||||
@@ -90,7 +90,7 @@ export default function Phone({
|
||||
dropdownArrowClassName={styles.arrow}
|
||||
flagClassName={styles.flag}
|
||||
onSelect={handleSelectCountry}
|
||||
preferredCountries={['de', 'dk', 'fi', 'no', 'se', 'gb']}
|
||||
preferredCountries={["de", "dk", "fi", "no", "se", "gb"]}
|
||||
selectedCountry={country.iso2}
|
||||
renderButtonWrapper={(props) => (
|
||||
<button
|
||||
|
||||
@@ -90,7 +90,7 @@
|
||||
}
|
||||
}
|
||||
|
||||
.select[aria-expanded='true'] .chevron {
|
||||
.select[aria-expanded="true"] .chevron {
|
||||
transform: rotate(180deg);
|
||||
}
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import type { RegisterOptions } from 'react-hook-form'
|
||||
import type { RegisterOptions } from "react-hook-form"
|
||||
|
||||
export interface PhoneProps {
|
||||
ariaLabel?: string
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
'use client'
|
||||
"use client"
|
||||
|
||||
import { cx } from 'class-variance-authority'
|
||||
import { Label, Radio, RadioGroup, Text } from 'react-aria-components'
|
||||
import { cx } from "class-variance-authority"
|
||||
import { Label, Radio, RadioGroup, Text } from "react-aria-components"
|
||||
|
||||
import { Divider } from '../../Divider'
|
||||
import { Typography } from '../../Typography'
|
||||
import { Divider } from "../../Divider"
|
||||
import { Typography } from "../../Typography"
|
||||
|
||||
import styles from './radioButtonsGroup.module.css'
|
||||
import styles from "./radioButtonsGroup.module.css"
|
||||
interface Option {
|
||||
value: string
|
||||
title: string
|
||||
|
||||
@@ -1,15 +1,15 @@
|
||||
'use client'
|
||||
"use client"
|
||||
|
||||
import { cx } from 'class-variance-authority'
|
||||
import { useFormContext } from 'react-hook-form'
|
||||
import { cx } from "class-variance-authority"
|
||||
import { useFormContext } from "react-hook-form"
|
||||
|
||||
import { Divider } from '../../Divider'
|
||||
import { MaterialIcon } from '../../Icons/MaterialIcon'
|
||||
import { Typography } from '../../Typography'
|
||||
import { Divider } from "../../Divider"
|
||||
import { MaterialIcon } from "../../Icons/MaterialIcon"
|
||||
import { Typography } from "../../Typography"
|
||||
|
||||
import styles from './radioCard.module.css'
|
||||
import styles from "./radioCard.module.css"
|
||||
|
||||
import type { RadioCardProps } from './types'
|
||||
import type { RadioCardProps } from "./types"
|
||||
|
||||
export default function RadioCard({
|
||||
Icon,
|
||||
@@ -37,7 +37,7 @@ export default function RadioCard({
|
||||
function onKeyDown(event: React.KeyboardEvent) {
|
||||
if (disabled) return
|
||||
|
||||
if (event.key === 'Enter') {
|
||||
if (event.key === "Enter") {
|
||||
setValue(name, value)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,8 +5,8 @@
|
||||
grid-template-columns: 1fr auto;
|
||||
grid-auto-rows: min-content;
|
||||
grid-template-areas:
|
||||
'icon subtitleSecondary'
|
||||
'title subtitle';
|
||||
"icon subtitleSecondary"
|
||||
"title subtitle";
|
||||
border-radius: var(--Corner-radius-md);
|
||||
border: 1px solid var(--Border-Strong);
|
||||
background: var(--Surface-Primary-Default);
|
||||
|
||||
@@ -1,8 +1,10 @@
|
||||
import type { IconProps } from '../../Icons'
|
||||
import type { JSX } from 'react'
|
||||
import type { IconProps } from "../../Icons"
|
||||
import type { JSX } from "react"
|
||||
|
||||
export interface RadioCardProps
|
||||
extends Omit<React.LabelHTMLAttributes<HTMLLabelElement>, 'title'> {
|
||||
export interface RadioCardProps extends Omit<
|
||||
React.LabelHTMLAttributes<HTMLLabelElement>,
|
||||
"title"
|
||||
> {
|
||||
Icon?: (props: IconProps) => JSX.Element
|
||||
iconHeight?: number
|
||||
name: string
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
import type { ComponentProps } from 'react'
|
||||
import type { Meta, StoryObj } from '@storybook/nextjs-vite'
|
||||
import { fn, expect } from 'storybook/test'
|
||||
import { SelectPaymentMethod } from './index'
|
||||
import { PaymentMethodEnum } from '@scandic-hotels/common/constants/paymentMethod'
|
||||
import { FormDecorator } from '../../../../.storybook/decorators/FormDecorator'
|
||||
import type { ComponentProps } from "react"
|
||||
import type { Meta, StoryObj } from "@storybook/nextjs-vite"
|
||||
import { fn, expect } from "storybook/test"
|
||||
import { SelectPaymentMethod } from "./index"
|
||||
import { PaymentMethodEnum } from "@scandic-hotels/common/constants/paymentMethod"
|
||||
import { FormDecorator } from "../../../../.storybook/decorators/FormDecorator"
|
||||
|
||||
const meta: Meta<typeof SelectPaymentMethod> = {
|
||||
title: 'Patterns/Form/Payment/SelectCreditCard',
|
||||
title: "Patterns/Form/Payment/SelectCreditCard",
|
||||
component: SelectPaymentMethod,
|
||||
argTypes: {},
|
||||
decorators: [FormDecorator],
|
||||
@@ -18,30 +18,30 @@ type Story = StoryObj<typeof SelectPaymentMethod>
|
||||
|
||||
export const PrimaryDefault: Story = {
|
||||
args: {
|
||||
formName: 'paymentMethod',
|
||||
formName: "paymentMethod",
|
||||
onChange: fn(),
|
||||
paymentMethods: [
|
||||
{
|
||||
id: 'klarna',
|
||||
alias: 'Card 1',
|
||||
id: "klarna",
|
||||
alias: "Card 1",
|
||||
cardType: PaymentMethodEnum.klarna,
|
||||
truncatedNumber: '1234',
|
||||
truncatedNumber: "1234",
|
||||
},
|
||||
{
|
||||
id: 'applePay',
|
||||
alias: 'Card 2',
|
||||
id: "applePay",
|
||||
alias: "Card 2",
|
||||
cardType: PaymentMethodEnum.applePay,
|
||||
truncatedNumber: '1234',
|
||||
truncatedNumber: "1234",
|
||||
},
|
||||
],
|
||||
} satisfies ComponentProps<typeof SelectPaymentMethod>,
|
||||
|
||||
play: async ({ canvas, userEvent, args }) => {
|
||||
const options = await canvas.findAllByRole('radio')
|
||||
const options = await canvas.findAllByRole("radio")
|
||||
expect(options[0]).toBeInTheDocument()
|
||||
|
||||
expect(args.onChange).not.toHaveBeenCalled()
|
||||
await userEvent.click(options[0])
|
||||
expect(args.onChange).toHaveBeenCalledWith('klarna')
|
||||
expect(args.onChange).toHaveBeenCalledWith("klarna")
|
||||
},
|
||||
}
|
||||
|
||||
@@ -1,16 +1,16 @@
|
||||
import { useIntl } from 'react-intl'
|
||||
import { Label } from 'react-aria-components'
|
||||
import { useIntl } from "react-intl"
|
||||
import { Label } from "react-aria-components"
|
||||
|
||||
import { PaymentOptionsGroup } from '../PaymentOption/PaymentOptionsGroup'
|
||||
import { PaymentOption } from '../PaymentOption/PaymentOption'
|
||||
import { Typography } from '../../../components/Typography'
|
||||
import { PaymentOptionsGroup } from "../PaymentOption/PaymentOptionsGroup"
|
||||
import { PaymentOption } from "../PaymentOption/PaymentOption"
|
||||
import { Typography } from "../../../components/Typography"
|
||||
|
||||
import styles from './selectPaymentMethod.module.css'
|
||||
import styles from "./selectPaymentMethod.module.css"
|
||||
|
||||
import {
|
||||
PAYMENT_METHOD_TITLES,
|
||||
PaymentMethodEnum,
|
||||
} from '@scandic-hotels/common/constants/paymentMethod'
|
||||
} from "@scandic-hotels/common/constants/paymentMethod"
|
||||
|
||||
type PaymentMethod = {
|
||||
id: string
|
||||
@@ -39,15 +39,15 @@ export function SelectPaymentMethod({
|
||||
|
||||
const mySavedCardsLabel = paymentMethods.length
|
||||
? intl.formatMessage({
|
||||
id: 'payment.mySavedCards',
|
||||
defaultMessage: 'My saved cards',
|
||||
id: "payment.mySavedCards",
|
||||
defaultMessage: "My saved cards",
|
||||
})
|
||||
: undefined
|
||||
|
||||
const otherCardLabel = paymentMethods.length
|
||||
? intl.formatMessage({
|
||||
id: 'common.other',
|
||||
defaultMessage: 'Other',
|
||||
id: "common.other",
|
||||
defaultMessage: "Other",
|
||||
})
|
||||
: undefined
|
||||
|
||||
@@ -64,8 +64,8 @@ export function SelectPaymentMethod({
|
||||
>
|
||||
<Label className="sr-only">
|
||||
{intl.formatMessage({
|
||||
id: 'enterDetails.guarantee.cardOptions',
|
||||
defaultMessage: 'Card options',
|
||||
id: "enterDetails.guarantee.cardOptions",
|
||||
defaultMessage: "Card options",
|
||||
})}
|
||||
</Label>
|
||||
<Typography variant="Title/Overline/sm">
|
||||
@@ -94,8 +94,8 @@ export function SelectPaymentMethod({
|
||||
value={PaymentMethodEnum.card}
|
||||
type={PaymentMethodEnum.card}
|
||||
label={intl.formatMessage({
|
||||
id: 'common.creditCard',
|
||||
defaultMessage: 'Credit card',
|
||||
id: "common.creditCard",
|
||||
defaultMessage: "Credit card",
|
||||
})}
|
||||
/>
|
||||
</PaymentOptionsGroup>
|
||||
|
||||
@@ -1 +1 @@
|
||||
export { mergeRefs } from './mergeRefs'
|
||||
export { mergeRefs } from "./mergeRefs"
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import type { Ref, RefCallback } from 'react'
|
||||
import type { Ref, RefCallback } from "react"
|
||||
|
||||
/**
|
||||
* Merges multiple refs into a single ref callback.
|
||||
@@ -14,7 +14,7 @@ export function mergeRefs<T>(
|
||||
): RefCallback<T> {
|
||||
return (node: T | null) => {
|
||||
refs.forEach((ref) => {
|
||||
if (typeof ref === 'function') {
|
||||
if (typeof ref === "function") {
|
||||
ref(node)
|
||||
} else if (ref) {
|
||||
ref.current = node
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user