Merge branch 'develop'
This commit is contained in:
@@ -18,16 +18,13 @@
|
||||
font-weight: var(--typography-Body-Bold-fontWeight);
|
||||
transition: background-color 0.3s;
|
||||
}
|
||||
.summary:hover,
|
||||
.accordionItem details[open] .summary {
|
||||
background-color: var(--Base-Surface-Primary-light-Hover-alt, #f2ece6);
|
||||
.summary:hover {
|
||||
background-color: var(--Base-Surface-Primary-light-Hover-alt);
|
||||
}
|
||||
.accordionItem.light .summary:hover,
|
||||
.accordionItem.light details[open] .summary {
|
||||
background-color: var(--Base-Surface-Primary-light-Hover, #f9f6f4);
|
||||
.accordionItem.light .summary:hover {
|
||||
background-color: var(--Base-Surface-Primary-light-Hover);
|
||||
}
|
||||
.accordionItem.subtle .summary:hover,
|
||||
.accordionItem.subtle details[open] .summary {
|
||||
.accordionItem.subtle .summary:hover {
|
||||
background-color: var(--Base-Surface-Primary-light-Normal);
|
||||
}
|
||||
|
||||
|
||||
@@ -16,3 +16,10 @@
|
||||
.accordion li:last-child {
|
||||
border: none;
|
||||
}
|
||||
|
||||
.accordion details > summary {
|
||||
list-style: none;
|
||||
}
|
||||
.accordion details > summary::-webkit-details-marker {
|
||||
display: none;
|
||||
}
|
||||
|
||||
@@ -15,6 +15,7 @@
|
||||
|
||||
.imageWrapper {
|
||||
display: flex;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.imageWrapper::after {
|
||||
@@ -41,6 +42,7 @@
|
||||
|
||||
.content {
|
||||
margin: var(--Spacing-x0) var(--Spacing-x4);
|
||||
position: absolute;
|
||||
display: grid;
|
||||
gap: var(--Spacing-x2);
|
||||
}
|
||||
|
||||
@@ -33,12 +33,12 @@ export default function Checkbox({
|
||||
>
|
||||
{({ isSelected }) => (
|
||||
<>
|
||||
<div className={styles.checkboxContainer}>
|
||||
<div className={styles.checkbox}>
|
||||
<span className={styles.checkboxContainer}>
|
||||
<span className={styles.checkbox}>
|
||||
{isSelected && <CheckIcon color="white" />}
|
||||
</div>
|
||||
</span>
|
||||
{children}
|
||||
</div>
|
||||
</span>
|
||||
{fieldState.error ? (
|
||||
<Caption className={styles.error} fontOnly>
|
||||
<InfoCircleIcon color="red" />
|
||||
|
||||
@@ -26,7 +26,12 @@ interface TextCardProps extends BaseCardProps {
|
||||
text: React.ReactNode
|
||||
}
|
||||
|
||||
export type CardProps = ListCardProps | TextCardProps
|
||||
interface CleanCardProps extends BaseCardProps {
|
||||
list?: never
|
||||
text?: never
|
||||
}
|
||||
|
||||
export type CardProps = ListCardProps | TextCardProps | CleanCardProps
|
||||
|
||||
export type CheckboxProps =
|
||||
| Omit<ListCardProps, "type">
|
||||
@@ -34,6 +39,7 @@ export type CheckboxProps =
|
||||
export type RadioProps =
|
||||
| Omit<ListCardProps, "type">
|
||||
| Omit<TextCardProps, "type">
|
||||
| Omit<CleanCardProps, "type">
|
||||
|
||||
export interface ListProps extends Pick<ListCardProps, "declined"> {
|
||||
list?: ListCardProps["list"]
|
||||
|
||||
@@ -18,3 +18,12 @@
|
||||
.year {
|
||||
grid-area: year;
|
||||
}
|
||||
|
||||
/* TODO: Handle this in Select component.
|
||||
- out of scope for now.
|
||||
*/
|
||||
.day.invalid > div > div,
|
||||
.month.invalid > div > div,
|
||||
.year.invalid > div > div {
|
||||
border-color: var(--Scandic-Red-60);
|
||||
}
|
||||
|
||||
@@ -2,6 +2,7 @@ import type { RegisterOptions } from "react-hook-form"
|
||||
|
||||
export const enum DateName {
|
||||
date = "date",
|
||||
day = "day",
|
||||
month = "month",
|
||||
year = "year",
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
"use client"
|
||||
import { parseDate } from "@internationalized/date"
|
||||
import { useState } from "react"
|
||||
import { useEffect } from "react"
|
||||
import { DateInput, DatePicker, Group } from "react-aria-components"
|
||||
import { useController, useFormContext, useWatch } from "react-hook-form"
|
||||
import { useIntl } from "react-intl"
|
||||
@@ -8,8 +8,11 @@ import { useIntl } from "react-intl"
|
||||
import { dt } from "@/lib/dt"
|
||||
|
||||
import Select from "@/components/TempDesignSystem/Select"
|
||||
import useLang from "@/hooks/useLang"
|
||||
import { getLocalizedMonthName } from "@/utils/dateFormatting"
|
||||
import { rangeArray } from "@/utils/rangeArray"
|
||||
|
||||
import ErrorMessage from "../ErrorMessage"
|
||||
import { DateName } from "./date"
|
||||
|
||||
import styles from "./date.module.css"
|
||||
@@ -20,51 +23,75 @@ import type { DateProps } from "./date"
|
||||
|
||||
export default function DateSelect({ name, registerOptions = {} }: DateProps) {
|
||||
const intl = useIntl()
|
||||
const currentValue = useWatch({ name })
|
||||
const { control, setValue, trigger } = useFormContext()
|
||||
const { field } = useController({
|
||||
const { control, setValue, formState, watch } = useFormContext()
|
||||
const { field, fieldState } = useController({
|
||||
control,
|
||||
name,
|
||||
rules: registerOptions,
|
||||
})
|
||||
|
||||
const currentYear = new Date().getFullYear()
|
||||
const currentDateValue = useWatch({ name })
|
||||
const year = watch(DateName.year)
|
||||
const month = watch(DateName.month)
|
||||
const day = watch(DateName.day)
|
||||
|
||||
const lang = useLang()
|
||||
const months = rangeArray(1, 12).map((month) => ({
|
||||
value: month,
|
||||
label: `${month}`,
|
||||
label: getLocalizedMonthName(month, lang),
|
||||
}))
|
||||
|
||||
const currentYear = new Date().getFullYear()
|
||||
const years = rangeArray(1900, currentYear - 18)
|
||||
.reverse()
|
||||
.map((year) => ({ value: year, label: year.toString() }))
|
||||
|
||||
// Ensure the user can't select a date that doesn't exist.
|
||||
const daysInMonth = dt(currentValue).daysInMonth()
|
||||
// Calculate available days based on selected year and month
|
||||
const daysInMonth = getDaysInMonth(
|
||||
year ? Number(year) : null,
|
||||
month ? Number(month) - 1 : null
|
||||
)
|
||||
|
||||
const days = rangeArray(1, daysInMonth).map((day) => ({
|
||||
value: day,
|
||||
label: `${day}`,
|
||||
}))
|
||||
|
||||
function createOnSelect(selector: DateName) {
|
||||
/**
|
||||
* Months are 0 index based and therefore we
|
||||
* must subtract by 1 to get the selected month
|
||||
*/
|
||||
return (select: Key) => {
|
||||
if (selector === DateName.month) {
|
||||
select = Number(select) - 1
|
||||
}
|
||||
const newDate = dt(currentValue).set(selector, Number(select))
|
||||
setValue(name, newDate.format("YYYY-MM-DD"))
|
||||
trigger(name)
|
||||
}
|
||||
}
|
||||
|
||||
const dayLabel = intl.formatMessage({ id: "Day" })
|
||||
const monthLabel = intl.formatMessage({ id: "Month" })
|
||||
const yearLabel = intl.formatMessage({ id: "Year" })
|
||||
|
||||
useEffect(() => {
|
||||
if (formState.isSubmitting) return
|
||||
|
||||
if (month && day) {
|
||||
const maxDays = getDaysInMonth(
|
||||
year ? Number(year) : null,
|
||||
Number(month) - 1
|
||||
)
|
||||
const adjustedDay = Number(day) > maxDays ? maxDays : Number(day)
|
||||
|
||||
if (adjustedDay !== Number(day)) {
|
||||
setValue(DateName.day, adjustedDay)
|
||||
}
|
||||
}
|
||||
|
||||
if (year && month && 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,
|
||||
})
|
||||
}
|
||||
}
|
||||
}, [year, month, day, setValue, name, formState.isSubmitting])
|
||||
|
||||
let dateValue = null
|
||||
try {
|
||||
/**
|
||||
@@ -72,7 +99,9 @@ export default function DateSelect({ name, registerOptions = {} }: DateProps) {
|
||||
* date, but we can't check isNan since
|
||||
* we recieve the date as "1999-01-01"
|
||||
*/
|
||||
dateValue = dt(currentValue).isValid() ? parseDate(currentValue) : null
|
||||
dateValue = dt(currentDateValue).isValid()
|
||||
? parseDate(currentDateValue)
|
||||
: null
|
||||
} catch (error) {
|
||||
console.warn("Known error for parse date in DateSelect: ", error)
|
||||
}
|
||||
@@ -81,6 +110,7 @@ export default function DateSelect({ name, registerOptions = {} }: DateProps) {
|
||||
<DatePicker
|
||||
aria-label={intl.formatMessage({ id: "Select date of birth" })}
|
||||
isRequired={!!registerOptions.required}
|
||||
isInvalid={!formState.isValid}
|
||||
name={name}
|
||||
ref={field.ref}
|
||||
value={dateValue}
|
||||
@@ -92,57 +122,60 @@ export default function DateSelect({ name, registerOptions = {} }: DateProps) {
|
||||
switch (segment.type) {
|
||||
case "day":
|
||||
return (
|
||||
<div className={styles.day}>
|
||||
<div
|
||||
className={`${styles.day} ${fieldState.invalid ? styles.invalid : ""}`}
|
||||
>
|
||||
<Select
|
||||
aria-label={dayLabel}
|
||||
items={days}
|
||||
label={dayLabel}
|
||||
name={DateName.date}
|
||||
onSelect={createOnSelect(DateName.date)}
|
||||
placeholder="DD"
|
||||
name={DateName.day}
|
||||
onSelect={(key: Key) =>
|
||||
setValue(DateName.day, Number(key))
|
||||
}
|
||||
placeholder={dayLabel}
|
||||
required
|
||||
tabIndex={3}
|
||||
defaultSelectedKey={
|
||||
segment.isPlaceholder ? undefined : segment.value
|
||||
}
|
||||
value={segment.isPlaceholder ? undefined : segment.value}
|
||||
/>
|
||||
</div>
|
||||
)
|
||||
case "month":
|
||||
return (
|
||||
<div className={styles.month}>
|
||||
<div
|
||||
className={`${styles.month} ${fieldState.invalid ? styles.invalid : ""}`}
|
||||
>
|
||||
<Select
|
||||
aria-label={monthLabel}
|
||||
items={months}
|
||||
label={monthLabel}
|
||||
name={DateName.month}
|
||||
onSelect={createOnSelect(DateName.month)}
|
||||
placeholder="MM"
|
||||
onSelect={(key: Key) =>
|
||||
setValue(DateName.month, Number(key))
|
||||
}
|
||||
placeholder={monthLabel}
|
||||
required
|
||||
tabIndex={2}
|
||||
defaultSelectedKey={
|
||||
segment.isPlaceholder ? undefined : segment.value
|
||||
}
|
||||
value={segment.isPlaceholder ? undefined : segment.value}
|
||||
/>
|
||||
</div>
|
||||
)
|
||||
case "year":
|
||||
return (
|
||||
<div className={styles.year}>
|
||||
<div
|
||||
className={`${styles.year} ${fieldState.invalid ? styles.invalid : ""}`}
|
||||
>
|
||||
<Select
|
||||
aria-label={yearLabel}
|
||||
items={years}
|
||||
label={yearLabel}
|
||||
name={DateName.year}
|
||||
onSelect={createOnSelect(DateName.year)}
|
||||
placeholder="YYYY"
|
||||
onSelect={(key: Key) =>
|
||||
setValue(DateName.year, Number(key))
|
||||
}
|
||||
placeholder={yearLabel}
|
||||
required
|
||||
tabIndex={1}
|
||||
defaultSelectedKey={
|
||||
segment.isPlaceholder ? undefined : segment.value
|
||||
}
|
||||
value={segment.isPlaceholder ? undefined : segment.value}
|
||||
/>
|
||||
</div>
|
||||
@@ -154,6 +187,21 @@ export default function DateSelect({ name, registerOptions = {} }: DateProps) {
|
||||
}}
|
||||
</DateInput>
|
||||
</Group>
|
||||
<ErrorMessage errors={formState.errors} name={field.name} />
|
||||
</DatePicker>
|
||||
)
|
||||
}
|
||||
|
||||
function getDaysInMonth(year: number | null, month: number | null): number {
|
||||
if (month === null) {
|
||||
return 31
|
||||
}
|
||||
|
||||
// If month is February and no year selected, return minimum.
|
||||
if (month === 1 && !year) {
|
||||
return 28
|
||||
}
|
||||
|
||||
const yearToUse = year ?? new Date().getFullYear()
|
||||
return dt(`${yearToUse}-${month + 1}-01`).daysInMonth()
|
||||
}
|
||||
|
||||
@@ -58,8 +58,14 @@ export default function Phone({
|
||||
forceDialCode: true,
|
||||
value: phone,
|
||||
onChange: (value) => {
|
||||
setValue(name, value.phone)
|
||||
trigger(name)
|
||||
// If not checked trigger(name) forces validation on mount
|
||||
// which shows error message before user even can see the form
|
||||
if (value.inputValue) {
|
||||
setValue(name, value.phone)
|
||||
trigger(name)
|
||||
} else {
|
||||
setValue(name, "")
|
||||
}
|
||||
},
|
||||
})
|
||||
|
||||
|
||||
@@ -21,6 +21,14 @@
|
||||
line-height: var(--typography-Footnote-Bold-lineHeight);
|
||||
}
|
||||
|
||||
.link.breadcrumb {
|
||||
font-family: var(--typography-Footnote-Bold-fontFamily);
|
||||
font-size: var(--typography-Footnote-Bold-fontSize);
|
||||
font-weight: var(--typography-Footnote-Bold-fontWeight);
|
||||
letter-spacing: var(--typography-Footnote-Bold-letterSpacing);
|
||||
line-height: var(--typography-Footnote-Bold-lineHeight);
|
||||
}
|
||||
|
||||
.icon {
|
||||
align-items: center;
|
||||
display: flex;
|
||||
|
||||
@@ -35,7 +35,7 @@ export default function LoyaltyCard({
|
||||
focalPoint={image.focalPoint}
|
||||
/>
|
||||
) : null}
|
||||
<Title as="h5" level="h3" textAlign="center">
|
||||
<Title as="h4" level="h3" textAlign="center">
|
||||
{heading}
|
||||
</Title>
|
||||
{bodyText ? <Body textAlign="center">{bodyText}</Body> : null}
|
||||
|
||||
@@ -6,7 +6,7 @@ import { Dialog, Modal, ModalOverlay } from "react-aria-components"
|
||||
import { useIntl } from "react-intl"
|
||||
|
||||
import { CloseLargeIcon } from "@/components/Icons"
|
||||
import { SidePeekContext } from "@/components/SidePeekProvider"
|
||||
import { SidePeekContext } from "@/components/SidePeeks/SidePeekProvider"
|
||||
|
||||
import Button from "../Button"
|
||||
import Title from "../Text/Title"
|
||||
@@ -41,7 +41,7 @@ function SidePeek({
|
||||
|
||||
if (isSSR) {
|
||||
return (
|
||||
<div>
|
||||
<div className={styles.visuallyHidden}>
|
||||
<h2>{title}</h2>
|
||||
{children}
|
||||
</div>
|
||||
|
||||
@@ -21,6 +21,12 @@
|
||||
}
|
||||
}
|
||||
|
||||
.visuallyHidden {
|
||||
position: absolute;
|
||||
opacity: 0;
|
||||
visibility: hidden;
|
||||
}
|
||||
|
||||
.overlay {
|
||||
position: fixed;
|
||||
top: 0;
|
||||
@@ -40,7 +46,7 @@
|
||||
height: 100vh;
|
||||
background-color: var(--Base-Background-Primary-Normal);
|
||||
z-index: var(--sidepeek-z-index);
|
||||
box-shadow: 0 0 10px rgba(0, 0, 0, 0.85);
|
||||
outline: none;
|
||||
}
|
||||
|
||||
.modal[data-entering] {
|
||||
|
||||
@@ -21,7 +21,7 @@ export default function TeaserCardSidepeek({
|
||||
const { heading, content, primary_button, secondary_button } = sidePeekContent
|
||||
|
||||
return (
|
||||
<>
|
||||
<div>
|
||||
<Button
|
||||
onPress={() => setSidePeekIsOpen(true)}
|
||||
theme="base"
|
||||
@@ -77,6 +77,6 @@ export default function TeaserCardSidepeek({
|
||||
)}
|
||||
</div>
|
||||
</SidePeek>
|
||||
</>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
@@ -19,25 +19,23 @@ export default function TeaserCard({
|
||||
sidePeekButton,
|
||||
sidePeekContent,
|
||||
image,
|
||||
style = "default",
|
||||
intent,
|
||||
alwaysStack = false,
|
||||
className,
|
||||
}: TeaserCardProps) {
|
||||
const cardClasses = teaserCardVariants({ style, alwaysStack, className })
|
||||
const classNames = teaserCardVariants({ intent, alwaysStack, className })
|
||||
|
||||
return (
|
||||
<article className={cardClasses}>
|
||||
<article className={classNames}>
|
||||
{image && (
|
||||
<div className={styles.imageContainer}>
|
||||
<Image
|
||||
src={image.url}
|
||||
alt={image.meta?.alt || ""}
|
||||
className={styles.backgroundImage}
|
||||
width={399}
|
||||
height={201}
|
||||
focalPoint={image.focalPoint}
|
||||
/>
|
||||
</div>
|
||||
<Image
|
||||
src={image.url}
|
||||
alt={image.meta?.alt || ""}
|
||||
className={styles.image}
|
||||
width={Math.ceil(image.dimensions.aspectRatio * 200)}
|
||||
height={200}
|
||||
focalPoint={image.focalPoint}
|
||||
/>
|
||||
)}
|
||||
<div className={styles.content}>
|
||||
<Subtitle textAlign="left" type="two" color="black">
|
||||
|
||||
@@ -18,24 +18,17 @@
|
||||
border: 1px solid var(--Base-Border-Subtle);
|
||||
}
|
||||
|
||||
.imageContainer {
|
||||
.image {
|
||||
width: 100%;
|
||||
height: 12.58625rem; /* 201.38px / 16 = 12.58625rem */
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.backgroundImage {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
object-fit: cover;
|
||||
height: 12.5rem; /* 200px */
|
||||
}
|
||||
|
||||
.content {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
display: grid;
|
||||
gap: var(--Spacing-x-one-and-half);
|
||||
align-items: flex-start;
|
||||
padding: var(--Spacing-x2) var(--Spacing-x3);
|
||||
grid-template-rows: auto 1fr auto;
|
||||
flex-grow: 1;
|
||||
}
|
||||
|
||||
.description {
|
||||
@@ -53,17 +46,6 @@
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.body {
|
||||
display: -webkit-box;
|
||||
-webkit-box-orient: vertical;
|
||||
-webkit-line-clamp: 3;
|
||||
line-clamp: 3;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
/* line-height variables are in %, so using the value in rem instead */
|
||||
max-height: calc(3 * 1.5rem);
|
||||
}
|
||||
|
||||
@media (min-width: 1367px) {
|
||||
.card:not(.alwaysStack) .ctaContainer {
|
||||
grid-template-columns: repeat(auto-fit, minmax(0, 1fr));
|
||||
|
||||
@@ -4,7 +4,7 @@ import styles from "./teaserCard.module.css"
|
||||
|
||||
export const teaserCardVariants = cva(styles.card, {
|
||||
variants: {
|
||||
style: {
|
||||
intent: {
|
||||
default: styles.default,
|
||||
featured: styles.featured,
|
||||
},
|
||||
@@ -14,7 +14,7 @@ export const teaserCardVariants = cva(styles.card, {
|
||||
},
|
||||
},
|
||||
defaultVariants: {
|
||||
style: "default",
|
||||
intent: "default",
|
||||
alwaysStack: false,
|
||||
},
|
||||
})
|
||||
|
||||
@@ -92,7 +92,7 @@
|
||||
color: var(--Primary-Dark-On-Surface-Accent);
|
||||
}
|
||||
|
||||
.peach80 {
|
||||
.baseTextMediumContrast {
|
||||
color: var(--Base-Text-Medium-contrast);
|
||||
}
|
||||
|
||||
|
||||
@@ -16,7 +16,6 @@ const config = {
|
||||
textHighContrast: styles.textHighContrast,
|
||||
white: styles.white,
|
||||
peach50: styles.peach50,
|
||||
peach80: styles.peach80,
|
||||
uiTextHighContrast: styles.uiTextHighContrast,
|
||||
uiTextMediumContrast: styles.uiTextMediumContrast,
|
||||
uiTextPlaceholder: styles.uiTextPlaceholder,
|
||||
|
||||
@@ -4,7 +4,9 @@
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
.h1 {
|
||||
/* Temporarily remove h1 styling until design tokens är updated */
|
||||
|
||||
/* .h1 {
|
||||
font-family: var(--typography-Title-1-fontFamily);
|
||||
font-size: clamp(
|
||||
var(--typography-Title-1-Mobile-fontSize),
|
||||
@@ -14,9 +16,9 @@
|
||||
letter-spacing: var(--typography-Title-1-letterSpacing);
|
||||
line-height: var(--typography-Title-1-lineHeight);
|
||||
text-decoration: var(--typography-Title-1-textDecoration);
|
||||
}
|
||||
} */
|
||||
|
||||
.h2 {
|
||||
.h1 {
|
||||
font-family: var(--typography-Title-2-fontFamily);
|
||||
font-size: clamp(
|
||||
var(--typography-Title-2-Mobile-fontSize),
|
||||
@@ -26,9 +28,10 @@
|
||||
letter-spacing: var(--typography-Title-2-letterSpacing);
|
||||
line-height: var(--typography-Title-2-lineHeight);
|
||||
text-decoration: var(--typography-Title-2-textDecoration);
|
||||
font-weight: var(--typography-Title-2-fontWeight);
|
||||
}
|
||||
|
||||
.h3 {
|
||||
.h2 {
|
||||
font-family: var(--typography-Title-3-fontFamily);
|
||||
font-size: clamp(
|
||||
var(--typography-Title-3-Mobile-fontSize),
|
||||
@@ -38,9 +41,10 @@
|
||||
letter-spacing: var(--typography-Title-3-letterSpacing);
|
||||
line-height: var(--typography-Title-3-lineHeight);
|
||||
text-decoration: var(--typography-Title-3-textDecoration);
|
||||
font-weight: var(--typography-Title-3-fontWeight);
|
||||
}
|
||||
|
||||
.h4 {
|
||||
.h3 {
|
||||
font-family: var(--typography-Title-4-fontFamily);
|
||||
font-size: clamp(
|
||||
var(--typography-Title-4-Mobile-fontSize),
|
||||
@@ -50,9 +54,10 @@
|
||||
letter-spacing: var(--typography-Title-4-letterSpacing);
|
||||
line-height: var(--typography-Title-4-lineHeight);
|
||||
text-decoration: var(--typography-Title-4-textDecoration);
|
||||
font-weight: var(--typography-Title-4-fontWeight);
|
||||
}
|
||||
|
||||
.h5 {
|
||||
.h4 {
|
||||
font-family: var(--typography-Title-5-fontFamily);
|
||||
font-size: clamp(
|
||||
var(--typography-Title-5-Mobile-fontSize),
|
||||
@@ -62,6 +67,7 @@
|
||||
letter-spacing: var(--typography-Title-5-letterSpacing);
|
||||
line-height: var(--typography-Title-5-lineHeight);
|
||||
text-decoration: var(--typography-Title-5-textDecoration);
|
||||
font-weight: var(--typography-Title-5-fontWeight);
|
||||
}
|
||||
|
||||
.capitalize {
|
||||
|
||||
@@ -26,7 +26,7 @@ const config = {
|
||||
h2: styles.h2,
|
||||
h3: styles.h3,
|
||||
h4: styles.h4,
|
||||
h5: styles.h5,
|
||||
h5: styles.h4,
|
||||
},
|
||||
},
|
||||
defaultVariants: {
|
||||
|
||||
Reference in New Issue
Block a user