Merge branch 'master' into feature/tracking
This commit is contained in:
@@ -5,6 +5,8 @@ import { useRef } from "react"
|
||||
import { ChevronDownIcon } from "@/components/Icons"
|
||||
import { getIconByIconName } from "@/components/Icons/get-icon-by-icon-name"
|
||||
|
||||
import Body from "../../Text/Body"
|
||||
import Subtitle from "../../Text/Subtitle"
|
||||
import { accordionItemVariants } from "./variants"
|
||||
|
||||
import styles from "./accordionItem.module.css"
|
||||
@@ -49,7 +51,23 @@ export default function AccordionItem({
|
||||
<details ref={detailsRef} onToggle={toggleAccordion}>
|
||||
<summary className={styles.summary}>
|
||||
{IconComp && <IconComp className={styles.icon} color="burgundy" />}
|
||||
<span className={styles.title}>{title}</span>
|
||||
{variant === "card" ? (
|
||||
<Body
|
||||
textTransform="bold"
|
||||
color="baseTextHighContrast"
|
||||
className={styles.title}
|
||||
>
|
||||
{title}
|
||||
</Body>
|
||||
) : (
|
||||
<Subtitle
|
||||
className={styles.title}
|
||||
type="two"
|
||||
color="baseTextHighContrast"
|
||||
>
|
||||
{title}
|
||||
</Subtitle>
|
||||
)}
|
||||
<ChevronDownIcon
|
||||
className={styles.chevron}
|
||||
color="burgundy"
|
||||
|
||||
@@ -20,7 +20,7 @@
|
||||
font-weight: 500;
|
||||
font-size: var(--typography-Caption-Bold-fontSize);
|
||||
line-height: var(--typography-Caption-Bold-lineHeight);
|
||||
letter-spacing: 0.6%;
|
||||
letter-spacing: 0.084px;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
font-size: var(--typography-Body-Bold-fontSize);
|
||||
font-weight: 500;
|
||||
line-height: var(--typography-Body-Bold-lineHeight);
|
||||
letter-spacing: 0.6%;
|
||||
letter-spacing: 0.084px;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
|
||||
@@ -13,7 +13,7 @@ export const dividerVariants = cva(styles.divider, {
|
||||
primaryLightSubtle: styles.primaryLightSubtle,
|
||||
subtle: styles.subtle,
|
||||
white: styles.white,
|
||||
baseSurfaceSutbleHover: styles.baseSurfaceSubtleHover,
|
||||
baseSurfaceSubtleHover: styles.baseSurfaceSubtleHover,
|
||||
},
|
||||
opacity: {
|
||||
100: styles.opacity100,
|
||||
|
||||
@@ -76,19 +76,17 @@ export default function DateSelect({ name, registerOptions = {} }: DateProps) {
|
||||
}
|
||||
}
|
||||
|
||||
if (year && month && day) {
|
||||
const newDate = dt()
|
||||
.year(Number(year))
|
||||
.month(Number(month) - 1)
|
||||
.date(Number(day))
|
||||
const newDate = dt()
|
||||
.year(Number(year))
|
||||
.month(Number(month) - 1)
|
||||
.date(Number(day))
|
||||
|
||||
if (newDate.isValid()) {
|
||||
setValue(name, newDate.format("YYYY-MM-DD"), {
|
||||
shouldDirty: true,
|
||||
shouldTouch: true,
|
||||
shouldValidate: true,
|
||||
})
|
||||
}
|
||||
if (newDate.isValid()) {
|
||||
setValue(name, newDate.format("YYYY-MM-DD"), {
|
||||
shouldDirty: true,
|
||||
shouldTouch: true,
|
||||
shouldValidate: true,
|
||||
})
|
||||
}
|
||||
}, [year, month, day, setValue, name, formState.isSubmitting])
|
||||
|
||||
@@ -106,6 +104,16 @@ export default function DateSelect({ name, registerOptions = {} }: DateProps) {
|
||||
console.warn("Known error for parse date in DateSelect: ", error)
|
||||
}
|
||||
|
||||
useEffect(() => {
|
||||
if (formState.isSubmitting) return
|
||||
|
||||
if (!(day && month && year) && dateValue) {
|
||||
setValue(DateName.day, Number(dateValue.day))
|
||||
setValue(DateName.month, Number(dateValue.month))
|
||||
setValue(DateName.year, Number(dateValue.year))
|
||||
}
|
||||
}, [setValue, formState.isSubmitting, dateValue, day, month, year])
|
||||
|
||||
return (
|
||||
<DatePicker
|
||||
aria-label={intl.formatMessage({ id: "Select date of birth" })}
|
||||
|
||||
@@ -12,17 +12,23 @@ import {
|
||||
} from "react-international-phone"
|
||||
import { useIntl } from "react-intl"
|
||||
|
||||
import { Lang } from "@/constants/languages"
|
||||
|
||||
import { ChevronDownIcon } from "@/components/Icons"
|
||||
import ErrorMessage from "@/components/TempDesignSystem/Form/ErrorMessage"
|
||||
import AriaInputWithLabel from "@/components/TempDesignSystem/Form/Input/AriaInputWithLabel"
|
||||
import Label from "@/components/TempDesignSystem/Form/Label"
|
||||
import Body from "@/components/TempDesignSystem/Text/Body"
|
||||
import useLang from "@/hooks/useLang"
|
||||
|
||||
import styles from "./phone.module.css"
|
||||
|
||||
import type { ChangeEvent } from "react"
|
||||
|
||||
import type { PhoneProps } from "./phone"
|
||||
import type {
|
||||
LowerCaseCountryCode,
|
||||
PhoneProps,
|
||||
} from "@/types/components/form/phone"
|
||||
|
||||
export default function Phone({
|
||||
ariaLabel = "Phone number input",
|
||||
@@ -37,6 +43,7 @@ export default function Phone({
|
||||
},
|
||||
}: PhoneProps) {
|
||||
const intl = useIntl()
|
||||
const lang = useLang()
|
||||
const { control, setValue, trigger } = useFormContext()
|
||||
const phone = useWatch({ name })
|
||||
|
||||
@@ -47,13 +54,17 @@ export default function Phone({
|
||||
rules: registerOptions,
|
||||
})
|
||||
|
||||
const defaultPhoneNumber = formState.defaultValues?.phoneNumber
|
||||
|
||||
// If defaultPhoneNumber exists and is valid, parse it to get the country code,
|
||||
// otherwise set the default country from the lang.
|
||||
const defaultCountry = isValidPhoneNumber(defaultPhoneNumber)
|
||||
? parsePhoneNumber(defaultPhoneNumber).country?.toLowerCase()
|
||||
: getDefaultCountryFromLang(lang)
|
||||
|
||||
const { country, handlePhoneValueChange, inputValue, setCountry } =
|
||||
usePhoneInput({
|
||||
defaultCountry: isValidPhoneNumber(formState.defaultValues?.phoneNumber)
|
||||
? parsePhoneNumber(
|
||||
formState.defaultValues?.phoneNumber
|
||||
).country?.toLowerCase()
|
||||
: "se",
|
||||
defaultCountry,
|
||||
disableDialCodeAndPrefix: true,
|
||||
forceDialCode: true,
|
||||
value: phone,
|
||||
@@ -142,3 +153,15 @@ export default function Phone({
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
function getDefaultCountryFromLang(lang: Lang): LowerCaseCountryCode {
|
||||
const countryMap: Record<Lang, LowerCaseCountryCode> = {
|
||||
sv: "se",
|
||||
da: "dk",
|
||||
fi: "fi",
|
||||
no: "no",
|
||||
de: "de",
|
||||
en: "se", // Default to Sweden for English
|
||||
}
|
||||
return countryMap[lang] || "se"
|
||||
}
|
||||
|
||||
@@ -1,12 +0,0 @@
|
||||
import type { RegisterOptions } from "react-hook-form"
|
||||
|
||||
export type PhoneProps = {
|
||||
ariaLabel?: string
|
||||
className?: string
|
||||
disabled?: boolean
|
||||
label: string
|
||||
name?: string
|
||||
placeholder?: string
|
||||
readOnly?: boolean
|
||||
registerOptions?: RegisterOptions
|
||||
}
|
||||
@@ -16,7 +16,8 @@
|
||||
.breadcrumb {
|
||||
font-family: var(--typography-Footnote-Bold-fontFamily);
|
||||
font-size: var(--typography-Footnote-Bold-fontSize);
|
||||
font-weight: 500; /* var(--typography-Footnote-Bold-fontWeight); */
|
||||
font-weight: 500;
|
||||
/* var(--typography-Footnote-Bold-fontWeight); */
|
||||
letter-spacing: var(--typography-Footnote-Bold-letterSpacing);
|
||||
line-height: var(--typography-Footnote-Bold-lineHeight);
|
||||
}
|
||||
@@ -24,7 +25,8 @@
|
||||
.link.breadcrumb {
|
||||
font-family: var(--typography-Footnote-Bold-fontFamily);
|
||||
font-size: var(--typography-Footnote-Bold-fontSize);
|
||||
font-weight: 500; /* var(--typography-Footnote-Bold-fontWeight); */
|
||||
font-weight: 500;
|
||||
/* var(--typography-Footnote-Bold-fontWeight); */
|
||||
letter-spacing: var(--typography-Footnote-Bold-letterSpacing);
|
||||
line-height: var(--typography-Footnote-Bold-lineHeight);
|
||||
}
|
||||
@@ -159,12 +161,15 @@
|
||||
color: var(--Scandic-Peach-50);
|
||||
}
|
||||
|
||||
.peach80 {
|
||||
.peach80,
|
||||
.baseTextMediumContrast {
|
||||
color: var(--Base-Text-Medium-contrast);
|
||||
}
|
||||
|
||||
.peach80:hover,
|
||||
.peach80:active {
|
||||
.peach80:active,
|
||||
.baseTextMediumContrast:hover,
|
||||
.baseTextMediumContrast:active {
|
||||
color: var(--Base-Text-High-contrast);
|
||||
}
|
||||
|
||||
@@ -235,6 +240,7 @@
|
||||
letter-spacing: var(--typography-Caption-Bold-letterSpacing);
|
||||
line-height: var(--typography-Caption-Bold-lineHeight);
|
||||
}
|
||||
|
||||
.bold {
|
||||
font-family: var(--typography-Body-Bold-fontFamily);
|
||||
font-size: var(--typography-Body-Bold-fontSize);
|
||||
|
||||
@@ -9,6 +9,7 @@ export const linkVariants = cva(styles.link, {
|
||||
},
|
||||
color: {
|
||||
baseButtonTextOnFillNormal: styles.baseButtonTextOnFillNormal,
|
||||
baseTextMediumContrast: styles.baseTextMediumContrast,
|
||||
black: styles.black,
|
||||
burgundy: styles.burgundy,
|
||||
none: "",
|
||||
|
||||
@@ -63,7 +63,7 @@
|
||||
color: var(--Scandic-Brand-Pale-Peach);
|
||||
}
|
||||
|
||||
.baseTextMediumContrast {
|
||||
.baseTextHighContrast {
|
||||
color: var(--Base-Text-High-contrast);
|
||||
}
|
||||
|
||||
@@ -86,3 +86,7 @@
|
||||
.baseTextDisabled {
|
||||
color: var(--Base-Text-Disabled);
|
||||
}
|
||||
|
||||
.mainGrey60 {
|
||||
color: var(--Main-Grey-60);
|
||||
}
|
||||
|
||||
@@ -9,11 +9,12 @@ const config = {
|
||||
burgundy: styles.burgundy,
|
||||
baseTextDisabled: styles.baseTextDisabled,
|
||||
pale: styles.pale,
|
||||
baseTextMediumContrast: styles.baseTextMediumContrast,
|
||||
baseTextHighContrast: styles.baseTextHighContrast,
|
||||
uiTextHighContrast: styles.uiTextHighContrast,
|
||||
uiTextMediumContrast: styles.uiTextMediumContrast,
|
||||
uiTextPlaceholder: styles.uiTextPlaceholder,
|
||||
red: styles.red,
|
||||
mainGrey60: styles.mainGrey60,
|
||||
},
|
||||
textAlign: {
|
||||
center: styles.center,
|
||||
|
||||
@@ -32,7 +32,7 @@ function getIcon(variant: ToastsProps["variant"]) {
|
||||
}
|
||||
}
|
||||
|
||||
export function Toast({ message, onClose, variant }: ToastsProps) {
|
||||
export function Toast({ children, message, onClose, variant }: ToastsProps) {
|
||||
const className = toastVariants({ variant })
|
||||
const Icon = getIcon(variant)
|
||||
return (
|
||||
@@ -40,10 +40,16 @@ export function Toast({ message, onClose, variant }: ToastsProps) {
|
||||
<div className={styles.iconContainer}>
|
||||
{Icon && <Icon color="white" height={24} width={24} />}
|
||||
</div>
|
||||
<Body className={styles.message}>{message}</Body>
|
||||
<Button onClick={onClose} variant="icon" intent="text">
|
||||
<CloseLargeIcon />
|
||||
</Button>
|
||||
{message ? (
|
||||
<Body className={styles.message}>{message}</Body>
|
||||
) : (
|
||||
<div className={styles.content}>{children}</div>
|
||||
)}
|
||||
{onClose ? (
|
||||
<Button onClick={onClose} variant="icon" intent="text">
|
||||
<CloseLargeIcon />
|
||||
</Button>
|
||||
) : null}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
@@ -8,6 +8,11 @@
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.content {
|
||||
padding: var(--Spacing-x-one-and-half) var(--Spacing-x3)
|
||||
var(--Spacing-x-one-and-half) var(--Spacing-x2);
|
||||
}
|
||||
|
||||
@media screen and (min-width: 768px) {
|
||||
.toast {
|
||||
width: var(--width);
|
||||
|
||||
@@ -2,9 +2,16 @@ import { toastVariants } from "./variants"
|
||||
|
||||
import type { VariantProps } from "class-variance-authority"
|
||||
|
||||
export interface ToastsProps
|
||||
extends Omit<React.AnchorHTMLAttributes<HTMLDivElement>, "color">,
|
||||
VariantProps<typeof toastVariants> {
|
||||
message: React.ReactNode
|
||||
onClose: () => void
|
||||
}
|
||||
export type ToastsProps = Omit<React.HTMLAttributes<HTMLDivElement>, "color"> &
|
||||
VariantProps<typeof toastVariants> & {
|
||||
onClose?: () => void
|
||||
} & (
|
||||
| {
|
||||
children: React.ReactNode
|
||||
message?: never
|
||||
}
|
||||
| {
|
||||
children?: never
|
||||
message: React.ReactNode
|
||||
}
|
||||
)
|
||||
|
||||
@@ -14,12 +14,20 @@ export function Tooltip<P extends TooltipPosition>({
|
||||
position,
|
||||
arrow,
|
||||
children,
|
||||
isTouchable = false,
|
||||
}: PropsWithChildren<TooltipProps<P>>) {
|
||||
const className = tooltipVariants({ position, arrow })
|
||||
const [isActive, setIsActive] = useState(false)
|
||||
|
||||
function handleToggle() {
|
||||
setIsActive(!isActive)
|
||||
setIsActive((prevState) => !prevState)
|
||||
}
|
||||
|
||||
function handleKeyDown(event: React.KeyboardEvent<HTMLDivElement>) {
|
||||
if (event.key === "Enter" || event.key === " ") {
|
||||
event.preventDefault()
|
||||
handleToggle()
|
||||
}
|
||||
}
|
||||
|
||||
return (
|
||||
@@ -27,8 +35,10 @@ export function Tooltip<P extends TooltipPosition>({
|
||||
className={styles.tooltipContainer}
|
||||
role="tooltip"
|
||||
aria-label={text}
|
||||
onClick={handleToggle}
|
||||
onTouchStart={handleToggle}
|
||||
tabIndex={0}
|
||||
onClick={isTouchable ? undefined : handleToggle}
|
||||
onTouchStart={isTouchable ? handleToggle : undefined}
|
||||
onKeyDown={handleKeyDown}
|
||||
data-active={isActive}
|
||||
>
|
||||
<div className={className}>
|
||||
|
||||
Reference in New Issue
Block a user