diff --git a/.changeset/shiny-dryers-count.md b/.changeset/shiny-dryers-count.md new file mode 100644 index 0000000000..727a9af1e1 --- /dev/null +++ b/.changeset/shiny-dryers-count.md @@ -0,0 +1,8 @@ +--- +"@digdir/designsystemet-css": major +"@digdir/designsystemet-react": major +--- + +Radio + Checkbox: +- Use `label` prop instead of `children` as label text +- Remove `Radio.Group` and `Checkbox.Group` and use `Fieldset` instead diff --git a/.changeset/shy-cameras-approve.md b/.changeset/shy-cameras-approve.md new file mode 100644 index 0000000000..2cd77f78aa --- /dev/null +++ b/.changeset/shy-cameras-approve.md @@ -0,0 +1,6 @@ +--- +"@digdir/designsystemet-css": patch +"@digdir/designsystemet-react": patch +--- + +Chip: Use correct `32px` height to align nicely with `` diff --git a/.changeset/slow-news-act.md b/.changeset/slow-news-act.md new file mode 100644 index 0000000000..360ddb79dd --- /dev/null +++ b/.changeset/slow-news-act.md @@ -0,0 +1,26 @@ +--- +"@digdir/designsystemet-theme": minor +"@digdir/designsystemet": minor +--- + +CSS variables: `--ds-color-*-{1,2,...,13,contrast-1,contrast-2}`, which were generated from the `primitives` layer of design tokens, have been removed since they are always 1-to-1 with the semantic layer. Use the equivalent variables from the semantic layer instead + +Example, for the `neutral` scale: +```css + var(--ds-color-neutral-background-default); /* instead of: var(--ds-color-neutral-1) */ + var(--ds-color-neutral-background-subtle); /* instead of: var(--ds-color-neutral-2) */ + var(--ds-color-neutral-surface-default); /* instead of: var(--ds-color-neutral-3) */ + var(--ds-color-neutral-surface-hover); /* instead of: var(--ds-color-neutral-4) */ + var(--ds-color-neutral-surface-active); /* instead of: var(--ds-color-neutral-5) */ + var(--ds-color-neutral-border-subtle); /* instead of: var(--ds-color-neutral-6) */ + var(--ds-color-neutral-border-default); /* instead of: var(--ds-color-neutral-7) */ + var(--ds-color-neutral-border-strong); /* instead of: var(--ds-color-neutral-8) */ + var(--ds-color-neutral-base-default); /* instead of: var(--ds-color-neutral-9) */ + var(--ds-color-neutral-base-hover); /* instead of: var(--ds-color-neutral-10) */ + var(--ds-color-neutral-base-active); /* instead of: var(--ds-color-neutral-11) */ + var(--ds-color-neutral-text-subtle); /* instead of: var(--ds-color-neutral-12) */ + var(--ds-color-neutral-text-default); /* instead of: var(--ds-color-neutral-13) */ + var(--ds-color-neutral-contrast-default); /* instead of: var(--ds-color-neutral-contrast-1) */ + var(--ds-color-neutral-contrast-subtle); /* instead of: var(--ds-color-neutral-contrast-2) */ +``` +...and similarly for `accent`, `brand1`, `brand2` and `brand3`. diff --git a/.changeset/wet-scissors-tickle.md b/.changeset/wet-scissors-tickle.md new file mode 100644 index 0000000000..6280a26b3e --- /dev/null +++ b/.changeset/wet-scissors-tickle.md @@ -0,0 +1,5 @@ +--- +"@digdir/designsystemet-react": patch +--- + +Spinner: `aria-label` required instead of `title` prop diff --git a/apps/_components/src/ClipboardButton/ClipboardButton.tsx b/apps/_components/src/ClipboardButton/ClipboardButton.tsx index 52d4b07a1b..d21df7faa1 100644 --- a/apps/_components/src/ClipboardButton/ClipboardButton.tsx +++ b/apps/_components/src/ClipboardButton/ClipboardButton.tsx @@ -35,7 +35,7 @@ export const ClipboardButton = ({ icon={!text} variant='tertiary' color='neutral' - size='sm' + data-size='sm' > {text && {text}} diff --git a/apps/_components/src/CodeSnippet/CodeSnippet.tsx b/apps/_components/src/CodeSnippet/CodeSnippet.tsx index 4f729ffa7d..790a7d5da2 100644 --- a/apps/_components/src/CodeSnippet/CodeSnippet.tsx +++ b/apps/_components/src/CodeSnippet/CodeSnippet.tsx @@ -88,7 +88,7 @@ const CodeSnippet = ({ aria-label='Kopier' icon color='neutral' - size='sm' + data-size='sm' > diff --git a/apps/_components/src/ColorModal/ColorModal.tsx b/apps/_components/src/ColorModal/ColorModal.tsx index 5c970ad6ce..3953845126 100644 --- a/apps/_components/src/ColorModal/ColorModal.tsx +++ b/apps/_components/src/ColorModal/ColorModal.tsx @@ -26,11 +26,11 @@ const Field = ({ return (
{label && ( - + {label} )} - + {value} {copyBtn && } @@ -61,7 +61,7 @@ export const ColorModal = ({ backdropClose > - + {`${capitalizeFirstLetter(namespace)} ${capitalizeFirstLetter(getColorNameFromNumber(weight))}`} diff --git a/apps/_components/src/ColorModal/components/ContrastBoxes.tsx b/apps/_components/src/ColorModal/components/ContrastBoxes.tsx index a26854910c..e3097d65f3 100644 --- a/apps/_components/src/ColorModal/components/ContrastBoxes.tsx +++ b/apps/_components/src/ColorModal/components/ContrastBoxes.tsx @@ -4,7 +4,6 @@ import type { ColorNumber } from '@digdir/designsystemet/color'; import { areColorsContrasting, getApcaContrastLc, - getColorNameFromNumber, } from '@digdir/designsystemet/color'; import { CheckmarkCircleFillIcon, diff --git a/apps/_components/src/Footer/Footer.tsx b/apps/_components/src/Footer/Footer.tsx index 6b3ce3492e..d3068152bb 100644 --- a/apps/_components/src/Footer/Footer.tsx +++ b/apps/_components/src/Footer/Footer.tsx @@ -1,6 +1,5 @@ import { Button, Heading, Link, Paragraph } from '@digdir/designsystemet-react'; import cl from 'clsx/lite'; -import Image from 'next/image'; import NextLink from 'next/link'; import { type ReactNode, forwardRef } from 'react'; import { Container } from '../'; @@ -56,7 +55,7 @@ export const Footer = forwardRef(function Footer(
- + Lages på tvers av offentlige etater:
@@ -65,7 +64,7 @@ export const Footer = forwardRef(function Footer(
-
- + Om nettstedet {LinkList(centerLinks)}
- + Kom i kontakt med oss {LinkList(rightLinks)} @@ -90,7 +89,9 @@ export const Footer = forwardRef(function Footer(
- © {getCurrentYear()} Designsystemet + + © {getCurrentYear()} Designsystemet +
diff --git a/apps/_components/src/Header/Header.module.css b/apps/_components/src/Header/Header.module.css index 70fdcc6c6f..b1bdc39d7b 100644 --- a/apps/_components/src/Header/Header.module.css +++ b/apps/_components/src/Header/Header.module.css @@ -91,11 +91,11 @@ } .linkIcon.figma path { - stroke: var(--ds-color-neutral-8); + stroke: var(--ds-color-neutral-border-strong); } .linkIcon.github path { - fill: var(--ds-color-neutral-8); + fill: var(--ds-color-neutral-border-strong); } .linkIcon.figma:hover path { diff --git a/apps/_components/src/Header/Header.tsx b/apps/_components/src/Header/Header.tsx index ef257177c4..9d6dd2202f 100644 --- a/apps/_components/src/Header/Header.tsx +++ b/apps/_components/src/Header/Header.tsx @@ -108,7 +108,7 @@ const Header = ({ menu, betaTag, skipLink = true }: HeaderProps) => { > {menu.map((item, index) => (
  • - + {
    Next
    - + Designsystemet hjelper deg å lage gode digitale tjenester
    diff --git a/apps/storefront/app/bloggen/_components/Card/BlogCard.module.css b/apps/storefront/app/bloggen/_components/Card/BlogCard.module.css index f06ae9bca0..d70a211e00 100644 --- a/apps/storefront/app/bloggen/_components/Card/BlogCard.module.css +++ b/apps/storefront/app/bloggen/_components/Card/BlogCard.module.css @@ -34,6 +34,6 @@ height: 7px; transform: rotate(45deg); border-radius: 1px; - background-color: var(--ds-color-brand1-6); + background-color: var(--ds-color-brand1-border-subtle); margin: auto; } diff --git a/apps/storefront/app/bloggen/_components/Card/BlogCard.tsx b/apps/storefront/app/bloggen/_components/Card/BlogCard.tsx index 066a80af59..df9cec33da 100644 --- a/apps/storefront/app/bloggen/_components/Card/BlogCard.tsx +++ b/apps/storefront/app/bloggen/_components/Card/BlogCard.tsx @@ -48,15 +48,15 @@ export const BlogCard = ({ {tagText && ( - + {tagText} )} - + {title} - {desc} - + {desc} + {author || (date && ( <> diff --git a/apps/storefront/app/bloggen/_components/Contributors/Contributors.module.css b/apps/storefront/app/bloggen/_components/Contributors/Contributors.module.css index cef6e16010..297ca1f43b 100644 --- a/apps/storefront/app/bloggen/_components/Contributors/Contributors.module.css +++ b/apps/storefront/app/bloggen/_components/Contributors/Contributors.module.css @@ -55,7 +55,7 @@ height: 7px; transform: rotate(45deg); border-radius: 1px; - background-color: var(--ds-color-brand1-7); + background-color: var(--ds-color-brand1-border-default); margin: auto 0; break-after: avoid; } diff --git a/apps/storefront/app/bloggen/_components/Contributors/Contributors.tsx b/apps/storefront/app/bloggen/_components/Contributors/Contributors.tsx index e013c4fb69..b0059b204a 100644 --- a/apps/storefront/app/bloggen/_components/Contributors/Contributors.tsx +++ b/apps/storefront/app/bloggen/_components/Contributors/Contributors.tsx @@ -17,10 +17,10 @@ export const Contributors = ({ authors }: ContributorsProps) => { className={classes.logoImage} />
  • - + Bidragsytere - + {authors?.map((author, index) => ( {index !== 0 && } diff --git a/apps/storefront/app/bloggen/_components/PostLayout/PostLayout.module.css b/apps/storefront/app/bloggen/_components/PostLayout/PostLayout.module.css index 2ebce015ab..48e353efb9 100644 --- a/apps/storefront/app/bloggen/_components/PostLayout/PostLayout.module.css +++ b/apps/storefront/app/bloggen/_components/PostLayout/PostLayout.module.css @@ -40,7 +40,7 @@ height: 7px; transform: rotate(45deg); border-radius: 1px; - background-color: var(--ds-color-brand1-7); + background-color: var(--ds-color-brand1-border-default); margin: auto 0; } diff --git a/apps/storefront/app/bloggen/_components/PostLayout/PostLayout.tsx b/apps/storefront/app/bloggen/_components/PostLayout/PostLayout.tsx index a1c575b450..991902b447 100644 --- a/apps/storefront/app/bloggen/_components/PostLayout/PostLayout.tsx +++ b/apps/storefront/app/bloggen/_components/PostLayout/PostLayout.tsx @@ -52,7 +52,7 @@ function PostLayout({ {ingress} - + {date} {author} @@ -67,10 +67,10 @@ function PostLayout({ {content}
    - + Ønsker du å skrive for bloggen? - + Ta kontakt med oss på{' '} Gjeldende regelverk, WCAG 2.1 @@ -63,7 +63,7 @@ Alle brukerne, også de med svekket syn, skal kunne se innholdet i digitale tjen Fremtidig eller strengere: diff --git a/apps/storefront/app/grunnleggende/for-designere/terskel.txt b/apps/storefront/app/grunnleggende/for-designere/terskel.txt index 7cbcf86cbe..c530d7d3f8 100644 --- a/apps/storefront/app/grunnleggende/for-designere/terskel.txt +++ b/apps/storefront/app/grunnleggende/for-designere/terskel.txt @@ -7,7 +7,7 @@ Skriv noe om HSL, Om du ønsker å lage dine egne farger, kan du bruke tabellen under for å passe på at du holder deg innenfor terkskelverdiene for den gitte fargen. - +
    Navn @@ -31,4 +31,4 @@ Om du ønsker å lage dine egne farger, kan du bruke tabellen under for å passe #### Kontrastfarger -med eksempler \ No newline at end of file +med eksempler diff --git a/apps/storefront/app/komponenter/page.tsx b/apps/storefront/app/komponenter/page.tsx index 82e2888c95..8a2188dbf0 100644 --- a/apps/storefront/app/komponenter/page.tsx +++ b/apps/storefront/app/komponenter/page.tsx @@ -1,5 +1,4 @@ import { ComponentCard } from '@components'; -import React from 'react'; import { data } from './component-list'; diff --git a/apps/storefront/app/not-found.tsx b/apps/storefront/app/not-found.tsx index 0c69eae555..fa61caa59f 100644 --- a/apps/storefront/app/not-found.tsx +++ b/apps/storefront/app/not-found.tsx @@ -25,7 +25,7 @@ const NotFound = ({ children }: { children: React.ReactNode }) => { />
    - Denne siden finnes ikke + Denne siden finnes ikke Beklager, vi finner ikke siden du ba om. Siden kan være flyttet eller slettet. diff --git a/apps/storefront/components/Banner/Banner.module.css b/apps/storefront/components/Banner/Banner.module.css index d3e1feae28..95fc8c26ef 100644 --- a/apps/storefront/components/Banner/Banner.module.css +++ b/apps/storefront/components/Banner/Banner.module.css @@ -25,7 +25,7 @@ display: grid; place-items: center; transform: rotate(45deg); - background-color: var(--ds-color-brand2-6); + background-color: var(--ds-color-brand2-border-subtle); border-radius: 3px; margin-top: var(--ds-spacing-2); margin-bottom: var(--ds-spacing-2); @@ -38,15 +38,15 @@ } .red { - background-color: var(--ds-color-brand1-7); + background-color: var(--ds-color-brand1-border-default); } .yellow { - background-color: var(--ds-color-brand2-6); + background-color: var(--ds-color-brand2-border-subtle); } .blue { - background-color: var(--ds-color-brand3-7); + background-color: var(--ds-color-brand3-border-default); } .logo { @@ -77,13 +77,13 @@ } .logo.svg-red path { - fill: var(--ds-color-brand1-6); + fill: var(--ds-color-brand1-border-subtle); } .logo.svg-yellow path { - fill: var(--ds-color-brand2-6); + fill: var(--ds-color-brand2-border-subtle); } .logo.svg-blue path { - fill: var(--ds-color-brand3-6); + fill: var(--ds-color-brand3-border-subtle); } diff --git a/apps/storefront/components/Banner/Banner.tsx b/apps/storefront/components/Banner/Banner.tsx index d4fab70795..90475a7df8 100644 --- a/apps/storefront/components/Banner/Banner.tsx +++ b/apps/storefront/components/Banner/Banner.tsx @@ -37,7 +37,7 @@ const BannerRoot = ({ type BannerHeadingProps = Omit; const BannerHeading = ({ ...props }: BannerHeadingProps) => { - return ; + return ; }; type BannerIngressProps = HTMLAttributes; diff --git a/apps/storefront/components/ComponentCard/ComponentCard.tsx b/apps/storefront/components/ComponentCard/ComponentCard.tsx index 83309805d9..2b7eee02b8 100644 --- a/apps/storefront/components/ComponentCard/ComponentCard.tsx +++ b/apps/storefront/components/ComponentCard/ComponentCard.tsx @@ -18,7 +18,7 @@ const ComponentCard = ({ title, image, url }: ComponentCardProps) => { alt={title} className={classes.image} /> - + {title} diff --git a/apps/storefront/components/Image/Image.tsx b/apps/storefront/components/Image/Image.tsx index 11578de899..63d221afa3 100644 --- a/apps/storefront/components/Image/Image.tsx +++ b/apps/storefront/components/Image/Image.tsx @@ -30,7 +30,7 @@ const Image = ({ aria-label={alt} > {caption && ( - +
    {caption}
    )} diff --git a/apps/storefront/components/ImageBanner/ImageBanner.module.css b/apps/storefront/components/ImageBanner/ImageBanner.module.css index 017c407d5c..48063e58f8 100644 --- a/apps/storefront/components/ImageBanner/ImageBanner.module.css +++ b/apps/storefront/components/ImageBanner/ImageBanner.module.css @@ -4,15 +4,15 @@ } .blue { - background-color: var(--ds-color-brand3-3); + background-color: var(--ds-color-brand3-surface-default); } .red { - background-color: var(--ds-color-brand1-3); + background-color: var(--ds-color-brand1-surface-default); } .yellow { - background-color: var(--ds-color-brand2-3); + background-color: var(--ds-color-brand2-surface-default); } .grey { diff --git a/apps/storefront/components/ImageBanner/ImageBanner.tsx b/apps/storefront/components/ImageBanner/ImageBanner.tsx index 567e0367f4..50b9d92d3c 100644 --- a/apps/storefront/components/ImageBanner/ImageBanner.tsx +++ b/apps/storefront/components/ImageBanner/ImageBanner.tsx @@ -89,11 +89,11 @@ const ImageBanner = ({
    {title ? ( - + {title} ) : null} - {description && {description}} + {description && {description}} {content && content} {link && ( diff --git a/apps/storefront/components/NavigationCard/NavigationCard.module.css b/apps/storefront/components/NavigationCard/NavigationCard.module.css index 714584ad33..29f3472683 100644 --- a/apps/storefront/components/NavigationCard/NavigationCard.module.css +++ b/apps/storefront/components/NavigationCard/NavigationCard.module.css @@ -41,17 +41,17 @@ } .red { - background-color: var(--ds-color-brand1-5); + background-color: var(--ds-color-brand1-surface-active); color: var(--ds-color-brand1-text-default); } .blue { - background-color: var(--ds-color-brand3-4); + background-color: var(--ds-color-brand3-surface-hover); color: var(--ds-color-brand3-text-default); } .yellow { - background-color: var(--ds-color-brand2-4); + background-color: var(--ds-color-brand2-surface-hover); color: var(--ds-color-brand2-text-default); } diff --git a/apps/storefront/components/NavigationCard/NavigationCard.tsx b/apps/storefront/components/NavigationCard/NavigationCard.tsx index c3c64d4d2f..06bbb0d031 100644 --- a/apps/storefront/components/NavigationCard/NavigationCard.tsx +++ b/apps/storefront/components/NavigationCard/NavigationCard.tsx @@ -33,11 +33,11 @@ const NavigationCard = ({
    {icon}
    - + {title} - + {description} diff --git a/apps/storefront/components/Section/Section.tsx b/apps/storefront/components/Section/Section.tsx index f64b90aea4..a21c71854c 100644 --- a/apps/storefront/components/Section/Section.tsx +++ b/apps/storefront/components/Section/Section.tsx @@ -24,7 +24,7 @@ const Section = ({
    {title && ( - + {title} )} diff --git a/apps/storefront/components/SidebarMenu/SidebarMenu.tsx b/apps/storefront/components/SidebarMenu/SidebarMenu.tsx index f53bf9010a..3b3293c0f9 100644 --- a/apps/storefront/components/SidebarMenu/SidebarMenu.tsx +++ b/apps/storefront/components/SidebarMenu/SidebarMenu.tsx @@ -40,7 +40,7 @@ const SidebarMenu = ({ routerPath }: SidebarMenuProps) => { <>
    - +

    {SiteConfig.menu[activeIndex].name}

    @@ -66,14 +66,14 @@ const SidebarMenu = ({ routerPath }: SidebarMenuProps) => { > {item.children && ( <> - +
    {item.name}
      {item.children.map( (item2: PageMenuItemType, index2) => (
    • - + { )} {!item.children && ( - + { return ( - + {title}

      {description}

      diff --git a/apps/storefront/components/Tokens/TokenList/TokenList.tsx b/apps/storefront/components/Tokens/TokenList/TokenList.tsx index 4ec7f48c9b..8314ae75d5 100644 --- a/apps/storefront/components/Tokens/TokenList/TokenList.tsx +++ b/apps/storefront/components/Tokens/TokenList/TokenList.tsx @@ -97,7 +97,7 @@ const TokenCards = ({ tokens, cols, hideValue, type }: TokenCardsProps) => { return tokens.map(([group, tokens]) => { return (
      - + {capitalizeString(group)}
      @@ -144,7 +144,7 @@ const TokenCard = ({ token, type, hideValue, ...rest }: TokenCardProps) => {
      - + {weight ? getColorNameFromNumber(weight) : capitalizeString(title)}   - @digdir/designsystemet-theme + @digdir/designsystemet-theme
      {(showThemePicker || showModeSwitcher) && (
      diff --git a/apps/storefront/components/VersionBanner/VersionBanner.tsx b/apps/storefront/components/VersionBanner/VersionBanner.tsx index 226db8f58b..c7052daba6 100644 --- a/apps/storefront/components/VersionBanner/VersionBanner.tsx +++ b/apps/storefront/components/VersionBanner/VersionBanner.tsx @@ -1,5 +1,4 @@ import cl from 'clsx/lite'; -import React from 'react'; import classes from './VersionBanner.module.css'; function VersionBanner() { diff --git a/apps/storefront/layouts/MenuPageLayout/MenuPageLayout.module.css b/apps/storefront/layouts/MenuPageLayout/MenuPageLayout.module.css index b4568a209a..be84dd2669 100644 --- a/apps/storefront/layouts/MenuPageLayout/MenuPageLayout.module.css +++ b/apps/storefront/layouts/MenuPageLayout/MenuPageLayout.module.css @@ -55,15 +55,15 @@ } .iconContainer.red { - border-color: var(--ds-color-brand1-4); + border-color: var(--ds-color-brand1-surface-hover); } .iconContainer.blue { - border-color: var(--ds-color-brand3-4); + border-color: var(--ds-color-brand3-surface-hover); } .iconContainer.yellow { - border-color: var(--ds-color-brand2-4); + border-color: var(--ds-color-brand2-surface-hover); } .iconContainer svg { @@ -76,15 +76,15 @@ } .iconContainer.red svg { - color: var(--ds-color-brand1-6); + color: var(--ds-color-brand1-border-subtle); } .iconContainer.blue svg { - color: var(--ds-color-brand3-6); + color: var(--ds-color-brand3-border-subtle); } .iconContainer.yellow svg { - color: var(--ds-color-brand2-6); + color: var(--ds-color-brand2-border-subtle); } .content { diff --git a/apps/storefront/layouts/MenuPageLayout/MenuPageLayout.tsx b/apps/storefront/layouts/MenuPageLayout/MenuPageLayout.tsx index 7953a78d05..03dccb2f6b 100644 --- a/apps/storefront/layouts/MenuPageLayout/MenuPageLayout.tsx +++ b/apps/storefront/layouts/MenuPageLayout/MenuPageLayout.tsx @@ -54,7 +54,7 @@ const MenuPageLayout = ({ content, data, banner }: PageLayoutProps) => { {data && (
      - {data.title} + {data.title} {data.date &&
      {data.date}
      }
      { {data.backText} - +
      {data.author && {data.author}} - {data.date &&
      {data.date}
      }
      - + {data.title}
      diff --git a/apps/storefront/mdx-components.tsx b/apps/storefront/mdx-components.tsx index c9de35f72f..fdf1c769f1 100644 --- a/apps/storefront/mdx-components.tsx +++ b/apps/storefront/mdx-components.tsx @@ -34,17 +34,27 @@ export function useMDXComponents(components: MDXComponents): MDXComponents { ), - h2: (props: HeadingProps) => , - h3: (props: HeadingProps) => , - h4: (props: HeadingProps) => , - h5: (props: HeadingProps) => , - h6: (props: HeadingProps) => , + h2: (props: HeadingProps) => ( + + ), + h3: (props: HeadingProps) => ( + + ), + h4: (props: HeadingProps) => ( + + ), + h5: (props: HeadingProps) => ( + + ), + h6: (props: HeadingProps) => ( + + ), table: (props) =>
    , thead: (props) => , tbody: (props) => , diff --git a/apps/storybook/.storybook/manager-head.html b/apps/storybook/.storybook/manager-head.html index fe1fee6b6c..725e760882 100644 --- a/apps/storybook/.storybook/manager-head.html +++ b/apps/storybook/.storybook/manager-head.html @@ -132,11 +132,11 @@ } .header__linkIcon.header__figma path { - stroke: var(--ds-color-neutral-8); + stroke: var(--ds-color-neutral-border-strong); } .header__linkIcon.header__github path { - fill: var(--ds-color-neutral-8); + fill: var(--ds-color-neutral-border-strong); } .header__linkIcon.header__figma:hover path { diff --git a/apps/storybook/.storybook/preview.tsx b/apps/storybook/.storybook/preview.tsx index 4fce15c045..eca851977a 100644 --- a/apps/storybook/.storybook/preview.tsx +++ b/apps/storybook/.storybook/preview.tsx @@ -1,8 +1,6 @@ import './style.css'; import '../../../packages/css/index.css'; import '@digdir/designsystemet-theme/digdir.css'; - -import { withThemeByDataAttribute } from '@storybook/addon-themes'; import type { Preview } from '@storybook/react'; import type { LinkProps } from '@digdir/designsystemet-react'; diff --git a/apps/storybook/docs-components/DoAndDont/DoAndDont.tsx b/apps/storybook/docs-components/DoAndDont/DoAndDont.tsx index c06578c84a..4a474d78c1 100644 --- a/apps/storybook/docs-components/DoAndDont/DoAndDont.tsx +++ b/apps/storybook/docs-components/DoAndDont/DoAndDont.tsx @@ -18,7 +18,7 @@ const Wrapper = ({ variant, description, image, alt }: WrapperProps) => {
    {icon}
    { return ( {textData.title && ( - + {textData.title} )} diff --git a/apps/theme/app/page.tsx b/apps/theme/app/page.tsx index b910d544cd..a7730cbc6a 100644 --- a/apps/theme/app/page.tsx +++ b/apps/theme/app/page.tsx @@ -1,7 +1,7 @@ 'use client'; import type { CssColor } from '@adobe/leonardo-contrast-colors'; -import { Heading, Paragraph } from '@digdir/designsystemet-react'; +import { Heading } from '@digdir/designsystemet-react'; import type { ColorError, ColorInfo, @@ -269,7 +269,7 @@ export default function Home() {
    Temabygger
    - + Sett opp temaet ditt diff --git a/apps/theme/app/slik-bruker-du-verktoyet/page.tsx b/apps/theme/app/slik-bruker-du-verktoyet/page.tsx index 52719dd51d..ea953833d9 100644 --- a/apps/theme/app/slik-bruker-du-verktoyet/page.tsx +++ b/apps/theme/app/slik-bruker-du-verktoyet/page.tsx @@ -1,5 +1,5 @@ 'use client'; -import { Alert, Heading, Link, Paragraph } from '@digdir/designsystemet-react'; +import { Heading, Link, Paragraph } from '@digdir/designsystemet-react'; import { Container } from '@repo/components'; import classes from './page.module.css'; @@ -10,7 +10,7 @@ export default function Home() {
    - + Slik bruker du verktøyet @@ -21,7 +21,7 @@ export default function Home() { temabyggeren blir ferdigstilt. - + Hva er et tema? @@ -35,7 +35,7 @@ export default function Home() { skulle trenge det. - + Farger og WCAG @@ -66,7 +66,7 @@ export default function Home() { bakgrunnsfargene om Base fargene skal brukes på aktive brukergrensesnittkomponenter eller meningsbærende grafikk. - + Valg av Accentfarge diff --git a/apps/theme/app/testside/BackgroundSurface/BackgroundSurface.tsx b/apps/theme/app/testside/BackgroundSurface/BackgroundSurface.tsx index a4ad4cc344..61f8bd38d7 100644 --- a/apps/theme/app/testside/BackgroundSurface/BackgroundSurface.tsx +++ b/apps/theme/app/testside/BackgroundSurface/BackgroundSurface.tsx @@ -81,7 +81,7 @@ type ColumnProps = { const Column = ({ title, scales }: ColumnProps) => { return (
    - + {title}
    diff --git a/apps/theme/app/testside/Backgrounds/Backgrounds.tsx b/apps/theme/app/testside/Backgrounds/Backgrounds.tsx index 08b522b3bf..101c92a62a 100644 --- a/apps/theme/app/testside/Backgrounds/Backgrounds.tsx +++ b/apps/theme/app/testside/Backgrounds/Backgrounds.tsx @@ -24,7 +24,7 @@ export const Backgrounds = ({ > Light @@ -54,7 +54,7 @@ export const Backgrounds = ({ > Dark @@ -84,7 +84,7 @@ export const Backgrounds = ({ > Contrast diff --git a/apps/theme/app/testside/BaseContrast/BaseContrast.tsx b/apps/theme/app/testside/BaseContrast/BaseContrast.tsx index 7e8f8bf98f..2966324526 100644 --- a/apps/theme/app/testside/BaseContrast/BaseContrast.tsx +++ b/apps/theme/app/testside/BaseContrast/BaseContrast.tsx @@ -33,7 +33,7 @@ type BaseColumnProps = { const BaseColumn = ({ colorTheme, title }: BaseColumnProps) => { return (
    - {title} + {title}
    @@ -51,7 +51,7 @@ type BaseBoxProps = { const BaseBox = ({ colorScale, title }: BaseBoxProps) => { return (
    - + {title}
    { > {title} diff --git a/apps/theme/app/testside/page.tsx b/apps/theme/app/testside/page.tsx index f6a4b307ff..fb28b05849 100644 --- a/apps/theme/app/testside/page.tsx +++ b/apps/theme/app/testside/page.tsx @@ -33,7 +33,7 @@ const Box = (name: string, color1: CssColor, color2: CssColor) => { const Row = (title: string, colors: ColorInfo[], whiteText = false) => { return (
    - + {title}
    @@ -41,7 +41,7 @@ const Row = (title: string, colors: ColorInfo[], whiteText = false) => { className={classes.column} style={{ backgroundColor: colors[0].hex }} > - + Background default {Box('Border subtle', colors[5].hex, colors[0].hex)} @@ -54,7 +54,7 @@ const Row = (title: string, colors: ColorInfo[], whiteText = false) => { className={classes.column} style={{ backgroundColor: colors[1].hex }} > - + Background subtle {Box('Border subtle', colors[5].hex, colors[1].hex)} @@ -67,7 +67,7 @@ const Row = (title: string, colors: ColorInfo[], whiteText = false) => { className={classes.column} style={{ backgroundColor: colors[2].hex }} > - + Surface default {Box('Border subtle', colors[5].hex, colors[2].hex)} @@ -80,7 +80,7 @@ const Row = (title: string, colors: ColorInfo[], whiteText = false) => { className={classes.column} style={{ backgroundColor: colors[3].hex }} > - + Surface hover {Box('Border subtle', colors[5].hex, colors[3].hex)} @@ -93,7 +93,7 @@ const Row = (title: string, colors: ColorInfo[], whiteText = false) => { className={classes.column} style={{ backgroundColor: colors[4].hex }} > - + Surface active {Box('Border subtle', colors[5].hex, colors[4].hex)} @@ -131,7 +131,7 @@ export default function Dev() { return (
    - + Fargekontrast og visuell vurdering
    @@ -154,7 +154,7 @@ export default function Dev() {
    Under dekorativ
    - + Background Default og Subtle - + Background Subtle mot Surface Default - + Surface og Base interaksjon
    @@ -198,7 +198,7 @@ export default function Dev() { theme11={theme11} theme12={theme12} /> - + Kontrastfarger mot Base
      @@ -291,7 +291,7 @@ export default function Dev() { }, ]} /> - + Background og Surface mot Border og Tekst
        @@ -321,11 +321,11 @@ export default function Dev() { {Row('Light', theme1.light)} {Row('Dark', theme1.dark, true)} {Row('Contrast', theme1.contrast, true)} - + Overgangen fra svart til hvit kontrastfarge på ulike Base farger - + Viser blå base farger i et spekter av lightness verdier og om kontrastfargen er hvit eller svart per mode diff --git a/apps/theme/components/ColorPicker/ColorPicker.tsx b/apps/theme/components/ColorPicker/ColorPicker.tsx index e48d936e16..aa6271a8fb 100644 --- a/apps/theme/components/ColorPicker/ColorPicker.tsx +++ b/apps/theme/components/ColorPicker/ColorPicker.tsx @@ -1,6 +1,6 @@ import type { CssColor } from '@adobe/leonardo-contrast-colors'; import { Link, Popover } from '@digdir/designsystemet-react'; -import { CheckmarkIcon, ExclamationmarkIcon } from '@navikt/aksel-icons'; +import { ExclamationmarkIcon } from '@navikt/aksel-icons'; import { useClickOutside } from '@react-awesome/use-click-outside'; import cl from 'clsx/lite'; import { useEffect, useId, useRef, useState } from 'react'; @@ -60,7 +60,7 @@ export const ColorPicker = ({ style={{ width: '900px' }} id={popoverId} placement='top' - size='sm' + data-size='sm' variant={colorError === 'none' ? 'default' : 'warning'} >
        diff --git a/apps/theme/components/Previews/Components/Components.tsx b/apps/theme/components/Previews/Components/Components.tsx index 5cb80a806c..c41b84e2f7 100644 --- a/apps/theme/components/Previews/Components/Components.tsx +++ b/apps/theme/components/Previews/Components/Components.tsx @@ -35,7 +35,6 @@ import { useState } from 'react'; import classes from './Components.module.css'; export const Components = () => { - const [radioValue, setRadioValue] = useState('vanilje'); const [currentPage, setCurrentPage] = useState(1); const pagination = usePagination({ currentPage, @@ -47,37 +46,34 @@ export const Components = () => { return (
        - - En kilo poteter - To liter Farris - - Blomkål - - - Pizza - - - Tre liter lettmelk - - 2kg smågodt - 10 poser med Smash - +
        + + + + + + + +
        - + Opprett ny bruker @@ -86,35 +82,35 @@ export const Components = () => { Glemt passord? -
        - + Alle brukere
        - Velg handling Dupliser Slett Oppdater -
        -
    +
    @@ -153,7 +149,7 @@ export const Components = () => {
    - + @@ -174,12 +170,12 @@ export const Components = () => {
    - + Hva kan vi hjelpe deg med?
    - + Sikkerhet og drift @@ -187,7 +183,7 @@ export const Components = () => { - + Skole og utdanning @@ -195,7 +191,7 @@ export const Components = () => { - + Mat og helse @@ -205,47 +201,44 @@ export const Components = () => {
    - setRadioValue(e)} + data-size='sm' > - Vanilje - Jordbær - Sjokolade - Jeg spiser ikke iskrem - + + + + +
    - + Emner
    - + Data og IKT - + Mat og ernæring - + Sport og Idrett - + Politikk og samfunn - + Utenriks - + Helse og velvære - + PC Gaming - + Trening og livsstil
    @@ -254,7 +247,7 @@ export const Components = () => {
    TV-visning @@ -266,35 +259,35 @@ export const Components = () => {
    - Hvor er du fra? - Svar under så finner vi flyreise + Hvor er du fra? + Svar under så finner vi flyreise
    - + Norge Sverige Utlandet
    - + Filtrer på språk
    - + Bokmål - + Nynorsk - + Engelsk
    - + Hvor skal du reise? - + Fant ingen treff Leikanger Oslo @@ -313,18 +306,18 @@ export const Components = () => { cols={100} id='my-textarea' rows={4} - size='sm' + data-size='sm' />
    - + Min profil Tjenester Innstillinger - + For å kunne bli registrert i{' '} Frivillighetsregisteret @@ -344,7 +337,7 @@ export const Components = () => {
    - + Ofte stillte spørsmål @@ -353,7 +346,7 @@ export const Components = () => { Hvem kan registrere seg i Frivillighetsregisteret? - + For å kunne bli registrert i Frivillighetsregisteret, må organisasjonen drive frivillig virksomhet. Det er bare foreninger, stiftelser og aksjeselskap som kan registreres. @@ -367,7 +360,7 @@ export const Components = () => { Hvordan går jeg fram for å registrere i Frivillighetsregisteret? - + Virksomheten må være registrert i Enhetsregisteret før den kan bli registrert i Frivillighetsregisteret. Du kan registrere i begge registrene samtidig i Samordnet registermelding. @@ -379,7 +372,7 @@ export const Components = () => { Hvordan går jeg fram for å registrere i Frivillighetsregisteret? - + Virksomheten må være registrert i Enhetsregisteret før den kan bli registrert i Frivillighetsregisteret. Du kan registrere i begge registrene samtidig i Samordnet registermelding. @@ -389,24 +382,24 @@ export const Components = () => {
    - + Dette er informasjon som du bør lese for å forstå hva som skjer - + Dette er en advarsel om at noe kan gå galt hvis du ikke følger med - + Dette er en melding om at noe har gått galt og du bør gjøre noe med det - + Dette er en melding om at noe har gått bra og du kan fortsette
    - Velg språk - + Velg språk + Norsk Engelsk Spansk @@ -425,8 +418,8 @@ export const Components = () => {
    - - + +
    diff --git a/apps/theme/components/Previews/Dashboard/ColorCard/ColorCard.tsx b/apps/theme/components/Previews/Dashboard/ColorCard/ColorCard.tsx index 248f14d486..be0966c292 100644 --- a/apps/theme/components/Previews/Dashboard/ColorCard/ColorCard.tsx +++ b/apps/theme/components/Previews/Dashboard/ColorCard/ColorCard.tsx @@ -33,10 +33,10 @@ export const ColorCard = ({ brand, icon }: ColorCardProps) => { brand === 'three' && classes.textThree, )} > - + Grafikk one - + Her er ein beskrivelse diff --git a/apps/theme/components/Previews/Dashboard/Dashboard.tsx b/apps/theme/components/Previews/Dashboard/Dashboard.tsx index 4147381ef7..27e3a20d14 100644 --- a/apps/theme/components/Previews/Dashboard/Dashboard.tsx +++ b/apps/theme/components/Previews/Dashboard/Dashboard.tsx @@ -43,89 +43,91 @@ export const Dashboard = () => {
    - + Dashboard
    - + Grafikk one - + Her er ein stor beskrivelse
    } + icon={ + + } /> } + icon={} /> } + icon={} />
    - + Siste brukere
    @@ -157,19 +159,19 @@ export const Dashboard = () => {
    - + Vekst de siste 3 årene
    - + Sideklikk siste 6 mnd
    - + Antall innlogginger diff --git a/apps/theme/components/Previews/Landing/Landing.tsx b/apps/theme/components/Previews/Landing/Landing.tsx index b8bb6f0201..ceb1252ad6 100644 --- a/apps/theme/components/Previews/Landing/Landing.tsx +++ b/apps/theme/components/Previews/Landing/Landing.tsx @@ -52,12 +52,12 @@ export const Landing = () => {
    Here is a sub heading
    - + A need explain have out been making it Multitude a hung structure return her belt of fixed had because a diff --git a/apps/theme/components/Previews/Previews.module.css b/apps/theme/components/Previews/Previews.module.css index d0260b37f6..2a38f0d755 100644 --- a/apps/theme/components/Previews/Previews.module.css +++ b/apps/theme/components/Previews/Previews.module.css @@ -24,11 +24,11 @@ .menuItem:hover { cursor: pointer; - background-color: var(--ds-color-accent-4); + background-color: var(--ds-color-accent-surface-hover); } .menuItemActive { - background-color: var(--ds-color-accent-3); + background-color: var(--ds-color-accent-surface-default); } .menuItem[aria-disabled] { @@ -58,11 +58,11 @@ .toggle:hover { cursor: pointer; - background-color: var(--ds-color-accent-4); + background-color: var(--ds-color-accent-surface-hover); } .active { - background-color: var(--ds-color-accent-3); + background-color: var(--ds-color-accent-surface-default); } .toggle img { diff --git a/apps/theme/components/ThemeToolbar/ThemeToolbar.tsx b/apps/theme/components/ThemeToolbar/ThemeToolbar.tsx index cadec80de3..7dbf394205 100644 --- a/apps/theme/components/ThemeToolbar/ThemeToolbar.tsx +++ b/apps/theme/components/ThemeToolbar/ThemeToolbar.tsx @@ -1,5 +1,5 @@ import type { CssColor } from '@adobe/leonardo-contrast-colors'; -import { Button, Label, Select, Tooltip } from '@digdir/designsystemet-react'; +import { Button, Tooltip } from '@digdir/designsystemet-react'; import type { ColorError, ContrastMode, @@ -110,7 +110,7 @@ export const ThemeToolbar = ({ onBorderRadiusChanged(e.target.value)} style={{ diff --git a/apps/theme/components/TokenModal/TokenModal.tsx b/apps/theme/components/TokenModal/TokenModal.tsx index 2ab2041493..b8423e9512 100644 --- a/apps/theme/components/TokenModal/TokenModal.tsx +++ b/apps/theme/components/TokenModal/TokenModal.tsx @@ -92,8 +92,8 @@ export const TokenModal = ({
    - {title} - {desc} + {title} + {desc}
    @@ -116,7 +116,7 @@ export const TokenModal = ({ ref={modalRef} backdropClose={true} > - + Ta i bruk tema @@ -127,7 +127,7 @@ export const TokenModal = ({ label='Navn på tema' description="Kun bokstaver, tall og bindestrek. Eks: 'mitt-tema'" value={themeName} - size='sm' + data-size='sm' onChange={(e) => { const value = e.currentTarget.value .replace(/\s+/g, '-') @@ -188,8 +188,8 @@ export const TokenModal = ({
    - Noe som ikke fungerer? - + Noe som ikke fungerer? + Send oss en melding på{' '} @@ -46,7 +46,7 @@ som kan brukes til å videreutvikle og lage mer avanserte og sammensatte kompone @@ -64,7 +64,7 @@ som kan brukes til å videreutvikle og lage mer avanserte og sammensatte kompone @@ -83,7 +83,7 @@ som kan brukes til å videreutvikle og lage mer avanserte og sammensatte kompone diff --git a/packages/cli/src/tokens/build/configs.ts b/packages/cli/src/tokens/build/configs.ts index 76311a9b81..8e0184c925 100644 --- a/packages/cli/src/tokens/build/configs.ts +++ b/packages/cli/src/tokens/build/configs.ts @@ -99,7 +99,7 @@ const colorModeVariables: GetStyleDictionaryConfig = ({ mode = 'light', theme }, ], options: { fileHeader, - outputReferences: (token, options) => outputColorReferences(token) && outputReferencesFilter(token, options), + outputReferences: false, }, }, }, diff --git a/packages/cli/src/tokens/build/formats/css.ts b/packages/cli/src/tokens/build/formats/css.ts index 520713b33e..894b4b513f 100644 --- a/packages/cli/src/tokens/build/formats/css.ts +++ b/packages/cli/src/tokens/build/formats/css.ts @@ -4,7 +4,7 @@ import type { Format } from 'style-dictionary/types'; import { createPropertyFormatter, fileHeader, usesReferences } from 'style-dictionary/utils'; import type { IsCalculatedToken } from '../types.js'; -import { getValue } from '../utils/utils.js'; +import { getValue, isColorCategoryToken, isGlobalColorToken, isSemanticToken } from '../utils/utils.js'; const prefersColorScheme = (mode: string, content: string) => ` @media (prefers-color-scheme: ${mode}) { @@ -32,7 +32,19 @@ export const colormode: Format = { const colorSchemeProperty = mode_ === 'dark' || mode_ === 'light' ? `\n color-scheme: ${mode_};\n` : ''; - const formattedTokens = dictionary.allTokens.map(format).join('\n'); + const filteredAllTokens = allTokens.filter( + R.allPass([ + R.anyPass([ + // Include semantic tokens in the output + isSemanticToken, + // Include global color tokens + isGlobalColorToken, + ]), + // Don't include color category tokens -- they are exported separately + (t) => !isColorCategoryToken(t), + ]), + ); + const formattedTokens = filteredAllTokens.map(format).join('\n'); const content = `{\n${formattedTokens}\n${colorSchemeProperty}}\n`; const autoSelectorContent = ['light', 'dark'].includes(mode_) ? prefersColorScheme(mode_, content) : ''; const body = R.isNotNil(layer) diff --git a/packages/cli/src/tokens/build/formats/js-tokens.ts b/packages/cli/src/tokens/build/formats/js-tokens.ts index 972ff41239..e0416a1a2e 100644 --- a/packages/cli/src/tokens/build/formats/js-tokens.ts +++ b/packages/cli/src/tokens/build/formats/js-tokens.ts @@ -2,13 +2,14 @@ import * as R from 'ramda'; import type { Format, TransformedToken } from 'style-dictionary/types'; import { createPropertyFormatter, fileHeader } from 'style-dictionary/utils'; -import { getType } from '../utils/utils.js'; +import { getType, isColorCategoryToken } from '../utils/utils.js'; const groupByType = R.groupBy((token: TransformedToken) => getType(token)); /** Add token name with prefix to list for removal */ const removeUnwatedTokens = R.filter( - (token: TransformedToken) => !['ds-base-spacing', 'ds-base-sizing'].includes(token.name), + (token: TransformedToken) => + !['ds-base-spacing', 'ds-base-sizing'].includes(token.name) && !isColorCategoryToken(token), ); const dissocExtensions = R.pipe(R.dissoc('$extensions'), R.dissocPath(['original', '$extensions'])); diff --git a/packages/cli/src/tokens/build/types.ts b/packages/cli/src/tokens/build/types.ts index f1319d48a5..a23f1fd760 100644 --- a/packages/cli/src/tokens/build/types.ts +++ b/packages/cli/src/tokens/build/types.ts @@ -6,6 +6,8 @@ import type { GetStyleDictionaryConfig } from './configs'; */ export type ThemePermutation = { mode: string; + 'main-color': string; + 'support-color': string; semantic: string; size: string; theme: string; diff --git a/packages/cli/src/tokens/build/utils/entryfile.ts b/packages/cli/src/tokens/build/utils/entryfile.ts index 3f316ad1b8..6dc86d9c2f 100644 --- a/packages/cli/src/tokens/build/utils/entryfile.ts +++ b/packages/cli/src/tokens/build/utils/entryfile.ts @@ -1,4 +1,3 @@ -import path from 'node:path'; import chalk from 'chalk'; import glob from 'fast-glob'; import fs from 'fs-extra'; diff --git a/packages/cli/src/tokens/build/utils/getMultidimensionalThemes.ts b/packages/cli/src/tokens/build/utils/getMultidimensionalThemes.ts index c3c66432d4..a9ea14e071 100644 --- a/packages/cli/src/tokens/build/utils/getMultidimensionalThemes.ts +++ b/packages/cli/src/tokens/build/utils/getMultidimensionalThemes.ts @@ -117,6 +117,8 @@ function permutateThemes(groups: GroupedThemes): PermutatedTheme[] { selectedTokenSets: [], permutation: { mode: 'unknown', + 'main-color': 'unknown', + 'support-color': 'unknown', theme: 'unknown', semantic: 'unknown', size: 'unknown', diff --git a/packages/cli/src/tokens/build/utils/utils.ts b/packages/cli/src/tokens/build/utils/utils.ts index 92fa5702d6..c71e58e0b5 100644 --- a/packages/cli/src/tokens/build/utils/utils.ts +++ b/packages/cli/src/tokens/build/utils/utils.ts @@ -46,3 +46,18 @@ export const pathStartsWithOneOf = R.curry((paths: string[], token: TransformedT return hasAnyTruth(matchPathsStartingWith); }); + +export function isSemanticToken(token: TransformedToken): boolean { + return token.filePath.includes('semantic/'); +} + +export function isGlobalColorToken(token: TransformedToken): boolean { + return typeEquals('color', token) && pathStartsWithOneOf(['global'], token); +} + +export function isColorCategoryToken(token: TransformedToken, category?: 'main' | 'support'): boolean { + if (!category) { + return (['main', 'support'] as const).some((c) => isColorCategoryToken(token, c)); + } + return R.startsWith(['color', category], token.path); +} diff --git a/packages/cli/src/tokens/write/generate$themes.ts b/packages/cli/src/tokens/write/generate$themes.ts index 5c4c814b4a..e7b2728880 100644 --- a/packages/cli/src/tokens/write/generate$themes.ts +++ b/packages/cli/src/tokens/write/generate$themes.ts @@ -4,8 +4,6 @@ import { type ThemeObject, TokenSetStatus } from '@tokens-studio/types'; import type { ColorMode } from '../../colors/types.js'; -import * as R from 'ramda'; - const capitalize = (word: string) => word.charAt(0).toUpperCase() + word.slice(1); const createHash = (text: string) => crypto.hash('sha1', text); diff --git a/packages/css/avatar.css b/packages/css/avatar.css index 3e37c02b1a..05ce7ec1bb 100644 --- a/packages/css/avatar.css +++ b/packages/css/avatar.css @@ -6,12 +6,12 @@ --dsc-avatar-border-radius: var(--ds-border-radius-full); align-items: center; - aspect-ratio: 1 / 1; background: var(--dsc-avatar-background); border-radius: var(--dsc-avatar-border-radius); box-sizing: border-box; color: var(--dsc-avatar-color); display: inline-flex; + flex-shrink: 0; font-weight: var(--ds-font-weight-medium); height: var(--dsc-avatar-size); justify-content: center; @@ -19,6 +19,7 @@ text-decoration: none; text-transform: uppercase; user-select: none; + width: var(--dsc-avatar-size); &:not(:has(> img)) { padding: var(--dsc-avatar-padding); @@ -84,14 +85,14 @@ } &[data-size='sm'] { - @composes ds-heading-text--2xs from './base/base.css'; + font-size: var(--ds-heading-2xs-font-size); } &[data-size='md'] { - @composes ds-heading-text--sm from './base/base.css'; + font-size: var(--ds-heading-sm-font-size); } &[data-size='lg'] { - @composes ds-heading-text--md from './base/base.css'; + font-size: var(--ds-heading-md-font-size); } } diff --git a/packages/css/base/base.css b/packages/css/base/base.css index 37ce955b0f..c7b8553192 100644 --- a/packages/css/base/base.css +++ b/packages/css/base/base.css @@ -45,9 +45,17 @@ * We use both box-shadow and outline to ensure that the focus style is visible, * in case box-shadow is overridden. */ - box-shadow: var(--dsc-focus-boxShadow); - outline: var(--dsc-focus-outline); - outline-offset: var(--dsc-focus-border-width); + box-shadow: var(--ds--focus, var(--dsc-focus-boxShadow)); + outline: var(--ds--focus, var(--dsc-focus-outline)); + outline-offset: var(--ds--focus, var(--dsc-focus-border-width)); + + /** + * Using CSS custom properties toggle trick to ensure focus-visible is only shown on outermost element + * https://css-tricks.com/the-css-custom-property-toggle-trick/ + */ + * { + --ds--focus: ; + } } [data-size='xs'] { @@ -86,112 +94,3 @@ body, font-size: var(--ds-body-xl-font-size); letter-spacing: var(--ds-body-xl-letter-spacing); } - -/** Heading */ -.ds-heading-text--2xs { - font-weight: var(--ds-heading-2xs-font-weight); - line-height: var(--ds-heading-2xs-line-height); - font-size: var(--ds-heading-2xs-font-size); - letter-spacing: var(--ds-heading-2xs-letter-spacing); -} - -.ds-heading-text--xs { - font-weight: var(--ds-heading-xs-font-weight); - line-height: var(--ds-heading-xs-line-height); - font-size: var(--ds-heading-xs-font-size); - letter-spacing: var(--ds-heading-xs-letter-spacing); -} - -.ds-heading-text--sm { - font-weight: var(--ds-heading-sm-font-weight); - line-height: var(--ds-heading-sm-line-height); - font-size: var(--ds-heading-sm-font-size); - letter-spacing: var(--ds-heading-sm-letter-spacing); -} - -.ds-heading-text--md { - font-size: var(--ds-heading-md-font-size); - font-weight: var(--ds-heading-md-font-weight); - letter-spacing: var(--ds-heading-md-letter-spacing); - line-height: var(--ds-heading-md-line-height); -} - -.ds-heading-text--lg { - font-weight: var(--ds-heading-lg-font-weight); - line-height: var(--ds-heading-lg-line-height); - font-size: var(--ds-heading-lg-font-size); - letter-spacing: var(--ds-heading-lg-letter-spacing); -} - -.ds-heading-text--xl { - font-weight: var(--ds-heading-xl-font-weight); - line-height: var(--ds-heading-xl-line-height); - font-size: var(--ds-heading-xl-font-size); - letter-spacing: var(--ds-heading-xl-letter-spacing); -} - -.ds-heading-text--2xl { - font-weight: var(--ds-heading-2xl-font-weight); - line-height: var(--ds-heading-2xl-line-height); - font-size: var(--ds-heading-2xl-font-size); - letter-spacing: var(--ds-heading-2xl-letter-spacing); -} - -/* TODO: Maybe remove label sizes after sync with design */ -.ds-label--md { - font-size: var(--ds-label-md-font-size); - font-weight: var(--ds-label-md-font-weight); - letter-spacing: var(--ds-label-md-letter-spacing); - line-height: var(--ds-label-md-line-height); -} - -.ds-label--xs { - font-weight: var(--ds-label-xs-font-weight); - line-height: var(--ds-label-xs-line-height); - font-size: var(--ds-label-xs-font-size); - letter-spacing: var(--ds-label-xs-letter-spacing); -} - -.ds-label--sm { - font-weight: var(--ds-label-sm-font-weight); - line-height: var(--ds-label-sm-line-height); - font-size: var(--ds-label-sm-font-size); - letter-spacing: var(--ds-label-sm-letter-spacing); -} - -.ds-label--lg { - font-weight: var(--ds-label-lg-font-weight); - line-height: var(--ds-label-lg-line-height); - font-size: var(--ds-label-lg-font-size); - letter-spacing: var(--ds-label-lg-letter-spacing); -} - -/* TODO: Maybe remove validation sizes after sync with design */ -.ds-validation-message--xs { - font-weight: var(--ds-validation-message-xs-font-weight); - line-height: var(--ds-validation-message-xs-line-height); - font-size: var(--ds-validation-message-xs-font-size); - letter-spacing: var(--ds-validation-message-xs-letter-spacing); -} - -.ds-validation-message--sm { - font-weight: var(--ds-validation-message-sm-font-weight); - line-height: var(--ds-validation-message-sm-line-height); - font-size: var(--ds-validation-message-sm-font-size); - letter-spacing: var(--ds-validation-message-sm-letter-spacing); -} - -.ds-validation-message--md { - font-size: var(--ds-validation-message-md-font-size); - font-weight: var(--ds-validation-message-md-font-weight); - letter-spacing: var(--ds-validation-message-md-letter-spacing); - line-height: var(--ds-validation-message-md-line-height); - margin: 0; -} - -.ds-validation-message--lg { - font-weight: var(--ds-validation-message-lg-font-weight); - line-height: var(--ds-validation-message-lg-line-height); - font-size: var(--ds-validation-message-lg-font-size); - letter-spacing: var(--ds-validation-message-lg-letter-spacing); -} diff --git a/packages/css/checkbox.css b/packages/css/checkbox.css deleted file mode 100644 index 4303a4a2fc..0000000000 --- a/packages/css/checkbox.css +++ /dev/null @@ -1,221 +0,0 @@ -.ds-checkbox { - --dsc-checkbox-size: 1.75rem; - --dsc-checkbox-focus-border-width: 3px; - --dsc-checkbox-background: var(--ds-color-neutral-background-default); - --dsc-checkbox-border-color: var(--ds-color-neutral-border-default); - --dsc-checkbox-border__hover--size: calc(var(--ds-spacing-3) / 2); - --dsc-checkbox-border__hover: 0 0 0 var(--dsc-checkbox-border__hover--size) var(--ds-color-accent-surface-hover); - --dsc-checkbox-check_color: transparent; - - display: grid; -} - -.ds-checkbox:has(.ds-checkbox__label) { - grid-template-columns: var(--dsc-checkbox-size) auto; - gap: var(--ds-spacing-2); -} - -/* Checkbox */ -.ds-checkbox__input { - position: relative; - width: var(--dsc-checkbox-size); - height: var(--dsc-checkbox-size); - z-index: 1; - appearance: none; - margin: 0; - align-self: center; - outline: none; - cursor: pointer; - box-shadow: inset 0 0 0 2px var(--dsc-checkbox-border-color); - background: var(--dsc-checkbox-background); - border-radius: var(--ds-border-radius-sm); -} - -.ds-checkbox__input::before { - position: absolute; - content: ''; - display: block; - width: 2.75rem; - height: 2.75rem; - transform: translate(-50%, -50%); - top: 50%; - left: 50%; - cursor: pointer; - border-radius: var(--ds-border-radius-sm); -} - -.ds-checkbox__label { - /* min-height: var(--ds-sizing-10); */ - min-width: min-content; - display: inline-flex; - flex-direction: row; - gap: var(--ds-spacing-1); - align-items: center; - cursor: pointer; -} - -.ds-checkbox__description { - margin-top: calc(var(--ds-spacing-2) * -1); - color: var(--ds-color-neutral-text-subtle); - grid-column: 2; -} - -.ds-checkbox--readonly > .ds-checkbox__label, -.ds-checkbox--readonly > .ds-checkbox__input, -.ds-checkbox--readonly > .ds-checkbox__input::before { - cursor: default; -} - -.ds-checkbox__input:disabled, -.ds-checkbox__input:disabled ~ .ds-checkbox__label, -.ds-checkbox__input:disabled::before { - cursor: not-allowed; -} - -/* .ds-checkbox__input:focus-visible { - outline-offset: 3px; - outline: var(--dsc-checkbox-focus-border-width) solid var(--ds-color-focus-outer); - box-shadow: - 0 0 0 var(--dsc-checkbox-focus-border-width) var(--ds-color-focus-inner), - inset 0 0 0 2px var(--dsc-checkbox-border-color); - } */ - -.ds-checkbox__input::after { - content: ''; - width: 100%; - height: 100%; - position: absolute; - top: 50%; - left: 50%; - transform: translate(-50%, -50%); - background-color: var(--dsc-checkbox-check_color); - mask-image: url("data:image/svg+xml,%3Csvg viewBox='0 0 23 23' fill='none' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath fill-rule='evenodd' clip-rule='evenodd' d='M18.5509 6.32414C18.9414 6.71467 18.9414 7.34783 18.5509 7.73836L10.5821 15.7071C10.1916 16.0976 9.55842 16.0976 9.16789 15.7071L4.94914 11.4884C4.55862 11.0978 4.55862 10.4647 4.94914 10.0741C5.33967 9.68362 5.97283 9.68362 6.36336 10.0741L9.875 13.5858L17.1366 6.32414C17.5272 5.93362 18.1603 5.93362 18.5509 6.32414Z' fill='white'/%3E%3C/svg%3E%0A"); -} - -.ds-checkbox__input:checked { - --dsc-checkbox-border-color: var(--ds-color-accent-base-default); - --dsc-checkbox-background: var(--ds-color-accent-base-default); - --dsc-checkbox-check_color: var(--ds-color-accent-contrast-1); - - background: var(--dsc-checkbox-background); -} - -.ds-checkbox__input:indeterminate { - --dsc-checkbox-border-color: var(--ds-color-accent-base-default); - --dsc-checkbox-background: var(--ds-color-accent-base-default); - --dsc-checkbox-check_color: var(--ds-color-accent-contrast-1); -} - -.ds-checkbox__input:indeterminate::after { - mask-image: url("data:image/svg+xml,%3Csvg viewBox='0 0 23 23' fill='none' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M4.25 11.25C4.25 10.4216 4.92157 9.75 5.75 9.75H16.75C17.5784 9.75 18.25 10.4216 18.25 11.25C18.25 12.0784 17.5784 12.75 16.75 12.75H5.75C4.92157 12.75 4.25 12.0784 4.25 11.25Z' fill='white' /%3E%3C/svg%3E%0A"); -} - -.ds-checkbox--readonly > .ds-checkbox__input { - --dsc-checkbox-border-color: var(--ds-color-neutral-border-subtle); - --dsc-checkbox-background: var(--ds-color-neutral-background-subtle); -} - -.ds-checkbox__input:disabled, -.ds-checkbox__input:disabled ~ .ds-checkbox__label, -.ds-checkbox__input:disabled ~ .ds-checkbox__description { - opacity: var(--ds-disabled-opacity); -} - -/* .ds-checkbox__input:checked:not(:focus-visible) { - box-shadow: inset 0 0 0 2px var(--dsc-checkbox-border-color); - } */ - -.ds-checkbox:has(.ds-checkbox__input:focus-visible) { - --dsc-focus-border-width: 3px; - - outline: var(--dsc-focus-border-width) solid var(--ds-color-focus-outer); - outline-offset: var(--dsc-focus-border-width); - box-shadow: 0 0 0 var(--dsc-focus-border-width) var(--ds-color-focus-inner); - border-radius: var(--ds-border-radius-sm); -} - -.ds-checkbox--readonly > .ds-checkbox__input:checked { - --dsc-checkbox-check_color: var(--ds-color-neutral-text-subtle); - - background: var(--dsc-checkbox-background); -} - -.ds-checkbox--readonly > .ds-checkbox__input:indeterminate { - --dsc-checkbox-check_color: var(--ds-color-neutral-text-subtle); - - background: var(--dsc-checkbox-background); -} - -.ds-checkbox--error > .ds-checkbox__input:not(:disabled, :focus-visible) { - --dsc-checkbox-border-color: var(--ds-color-danger-border-default); -} - -/* Only use hover for non-touch devices to prevent sticky-hovering - "input:not(:read-only)" does not work so using ".container:not(.readonly) >" instead */ -@media (hover: hover) and (pointer: fine) { - .ds-checkbox:not(.ds-checkbox--readonly) .ds-checkbox__input:not(:disabled) ~ .ds-checkbox__label:hover, - .ds-checkbox:not(.ds-checkbox--readonly) .ds-checkbox__input:hover:not(:disabled) ~ .ds-checkbox__label { - color: var(--ds-color-accent-text-subtle); - } - - .ds-checkbox:not(.ds-checkbox--readonly) .ds-checkbox__input:hover:not(:checked, :disabled, :focus-visible) { - --dsc-checkbox-border-color: var(--ds-color-accent-border-strong); - - box-shadow: var(--dsc-checkbox-border__hover), inset 0 0 0 2px var(--dsc-checkbox-border-color); - } - - .ds-checkbox:not(.ds-checkbox--readonly) .ds-checkbox__input:indeterminate:hover:not(:focus-visible) { - --dsc-checkbox-border-color: var(--ds-color-accent-border-strong); - - box-shadow: var(--dsc-checkbox-border__hover); - } - - .ds-checkbox:not(.ds-checkbox--readonly) .ds-checkbox__input:hover:checked:not(:disabled, :focus-visible) { - box-shadow: var(--dsc-checkbox-border__hover); - } -} - -/** Sizing */ - -.ds-checkbox--sm { - --dsc-checkbox-size: var(--ds-sizing-5); - - /* min-height: var(--ds-sizing-10); */ -} - -.ds-checkbox--md { - --dsc-checkbox-size: var(--ds-sizing-6); - - /* min-height: var(--ds-sizing-11); */ -} - -.ds-checkbox--lg { - --dsc-checkbox-size: var(--ds-sizing-7); - - /* min-height: var(--ds-sizing-12); */ -} - -.ds-checkbox__group { - --dsc-checkbox-group-gap: var(--ds-spacing-4); - - display: flex; - flex-direction: column; - gap: var(--dsc-checkbox-group-gap); - width: fit-content; -} - -.ds-checkbox__group--sm { - --dsc-checkbox-group-gap: var(--ds-spacing-3); - - margin-top: calc(var(--ds-spacing-1) * -1); -} - -.ds-checkbox__group--md { - --dsc-checkbox-group-gap: var(--ds-spacing-4); -} - -.ds-checkbox__group--lg { - --dsc-checkbox-group-gap: var(--ds-spacing-5); - - margin-top: var(--ds-spacing-1); -} diff --git a/packages/css/chip.css b/packages/css/chip.css index 5d9506eea9..bebb17a79c 100644 --- a/packages/css/chip.css +++ b/packages/css/chip.css @@ -1,15 +1,23 @@ .ds-chip { --dsc-chip-background: var(--ds-color-accent-surface-default); + --dsc-chip-background--hover: var(--ds-color-accent-surface-hover); + --dsc-chip-background--active: var(--ds-color-accent-surface-active); + --dsc-chip-background--checked: var(--ds-color-accent-base-default); + --dsc-chip-background--checked--hover: var(--ds-color-accent-base-hover); + --dsc-chip-background--checked--active: var(--ds-color-accent-base-active); --dsc-chip-border-color: var(--ds-color-accent-border-subtle); - --dsc-chip-border-radius: var(--ds-border-radius-full); + --dsc-chip-border-color--checked: transparent; --dsc-chip-color: var(--ds-color-accent-text-default); - --dsc-chip-height: var(--ds-sizing-8); - --dsc-chip-icon-size: var(--ds-spacing-6); - --dsc-chip-input-color: var(--ds-color-accent-border-default); - --dsc-chip-input-size: var(--ds-spacing-5); - --dsc-chip-padding: 0 var(--ds-spacing-3); + --dsc-chip-color--checked: var(--ds-color-accent-contrast-default); + --dsc-chip-input-color: var(--ds-color-accent-border-strong); + --dsc-chip-input-color--checked: var(--ds-color-accent-base-default); - @composes ds-focus from './base/base.css'; + --dsc-chip-border-radius: var(--ds-border-radius-full); + --dsc-chip-height: var(--ds-sizing-9); + --dsc-chip-icon-size: var(--ds-spacing-7); + --dsc-chip-icon-url: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='1em' height='1em' fill='none' viewBox='0 0 24 24' focusable='false' role='img'%3E%3Cpath fill='currentColor' d='M6.53 5.47a.75.75 0 0 0-1.06 1.06L10.94 12l-5.47 5.47a.75.75 0 1 0 1.06 1.06L12 13.06l5.47 5.47a.75.75 0 1 0 1.06-1.06L13.06 12l5.47-5.47a.75.75 0 0 0-1.06-1.06L12 10.94z'%3E%3C/path%3E%3C/svg%3E"); + --dsc-chip-input-size: var(--ds-spacing-6); + --gap: calc((var(--dsc-chip-height) - var(--dsc-chip-input-size)) / 2); /* Distance between edge of input and chip */ align-items: center; background: var(--dsc-chip-background); @@ -20,15 +28,20 @@ cursor: pointer; display: inline-flex; font-family: inherit; + gap: var(--gap); + line-height: var(--ds-line-height-sm); + margin: 0; min-height: var(--dsc-chip-height); - padding: var(--dsc-chip-padding); + padding: 0 var(--ds-spacing-3); text-decoration: none; + @composes ds-focus from './base/base.css'; + &:not([data-size]) { font-size: var(--ds-font-size-minus-1); } - /* Make focus ring also when input inside is focused */ + /* Show focus ring when input inside is focused by keyboard interaction */ &:has(:focus-visible) { @composes ds-focus--visible from './base/base.css'; } @@ -40,92 +53,54 @@ opacity: var(--ds-disabled-opacity); } - &:has(input[type='checkbox']) { - --dsc-chip-border-radius: var(--ds-border-radius-md); - --dsc-chip-padding: 0 var(--ds-spacing-2) 0 var(--ds-spacing-3); + &[data-removable] { + padding-inline-end: var(--gap); + + &::after { + content: ''; + background: currentcolor; + height: var(--dsc-chip-icon-size); + mask: center / contain no-repeat var(--dsc-chip-icon-url); + width: var(--dsc-chip-icon-size); + } } - &[data-removable]::after { - --gap: calc((var(--dsc-chip-height) - var(--dsc-chip-icon-size)) / 2); /* Gap is based on remaining space between icon and edge */ + &:has(input[type='radio']) { + padding-inline-start: var(--gap); + } - background: currentcolor; - content: ''; - height: var(--dsc-chip-icon-size); - margin: 0 calc(var(--gap) * -1) 0 var(--gap); - mask: center / contain no-repeat - url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='1em' height='1em' fill='none' viewBox='0 0 24 24' focusable='false' role='img'%3E%3Cpath fill='currentColor' d='M6.53 5.47a.75.75 0 0 0-1.06 1.06L10.94 12l-5.47 5.47a.75.75 0 1 0 1.06 1.06L12 13.06l5.47 5.47a.75.75 0 1 0 1.06-1.06L13.06 12l5.47-5.47a.75.75 0 0 0-1.06-1.06L12 10.94z'%3E%3C/path%3E%3C/svg%3E"); - width: var(--dsc-chip-icon-size); + &:has(input[type='checkbox']) { + --dsc-chip-border-radius: var(--ds-border-radius-md); + padding-inline: var(--gap); } & > input { - --gap: calc((var(--dsc-chip-height) - var(--dsc-chip-input-size)) / 2); /* Gap is based on remaining space between input and edge */ - - appearance: none; - background: none; - border: 2px solid; - box-sizing: border-box; - color: var(--dsc-chip-input-color); - height: var(--dsc-chip-input-size); - margin: 0 var(--gap) 0 calc(var(--gap) * -1); - outline: none; - width: var(--dsc-chip-input-size); - - &[type='radio'] { - border-radius: var(--ds-border-radius-full); - } - - &[type='radio']:checked { - border-width: calc(var(--dsc-chip-input-size) / 3.5); /* Matches Figma */ - } - - &[type='checkbox'] { - border-radius: var(--ds-border-radius-sm); - } - - &[type='checkbox']:checked { - background: currentcolor; - mask: center / cover no-repeat - url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath fill-rule='evenodd' d='M24 0H0v24h24V0Zm-4.44 8.56a1.5 1.5 0 0 0-2.12-2.12L10 13.88l-3.44-3.44a1.5 1.5 0 0 0-2.12 2.12l4.5 4.5a1.5 1.5 0 0 0 2.12 0l8.5-8.5Z'/%3E%3C/svg%3E"); - } + --dsc-input-background--checked: var(--dsc-chip-color); + --dsc-input-background: transparent; + --dsc-input-border-color--checked: var(--dsc-chip-color); + --dsc-input-border-color: var(--dsc-chip-input-color); + --dsc-input-color--checked: var(--dsc-chip-input-color--checked); + --dsc-input-size--toggle: var(--dsc-chip-input-size); } &:has(input:checked), &[data-removable] { - --dsc-chip-background: var(--ds-color-accent-base-default); - --dsc-chip-border-color: transparent; - --dsc-chip-color: var(--ds-color-accent-contrast-default); - --dsc-chip-input-color: currentcolor; + --dsc-chip-color: var(--dsc-chip-color--checked); + --dsc-chip-background: var(--dsc-chip-background--checked); + --dsc-chip-border-color: var(--dsc-chip-border-color--checked); + --dsc-chip-background--hover: var(--dsc-chip-background--checked--hover); + --dsc-chip-background--active: var(--dsc-chip-background--checked--active); } /* Only use hover for non-touch devices to prevent sticky-hovering */ @media (hover: hover) and (pointer: fine) { - &:where(:not(:disabled, :has(input:disabled), [aria-disabled='true'])) { + &:not(:has(:disabled, [aria-disabled='true'])) { &:hover { - --dsc-chip-background: var(--ds-color-accent-surface-hover); - --dsc-chip-border-color: var(--ds-color-accent-border-default); - --dsc-chip-color: var(--ds-color-accent-text-default); - --dsc-chip-input-color: var(--ds-color-accent-border-strong); + --dsc-chip-background: var(--dsc-chip-background--hover); } &:active { - --dsc-chip-background: var(--ds-color-accent-surface-active); - --dsc-chip-border-color: var(--ds-color-accent-border-strong); - --dsc-chip-input-color: var(--ds-color-accent-border-strong); - } - - &[data-removable]:hover, - &:has(input:checked):hover { - --dsc-chip-background: var(--ds-color-accent-base-hover); - --dsc-chip-border-color: transparent; - --dsc-chip-color: var(--ds-color-accent-contrast-default); - --dsc-chip-input-color: currentcolor; - } - - &[data-removable]:active, - &:has(input:checked):active { - --dsc-chip-background: var(--ds-color-accent-base-active); - --dsc-chip-border-color: transparent; - --dsc-chip-color: var(--ds-color-accent-contrast-default); + --dsc-chip-background: var(--dsc-chip-background--active); } } } diff --git a/packages/css/field.css b/packages/css/field.css index 14d1368623..1c6f3c39b1 100644 --- a/packages/css/field.css +++ b/packages/css/field.css @@ -1,7 +1,69 @@ .ds-field { - display: contents; + align-items: start; + display: flex; + flex-direction: column; + gap: var(--ds-spacing-2); - & > * + * { - margin-top: var(--ds-spacing-2); + @composes ds-body-text--md from './base/base.css'; + + &[data-size='sm'] { + @composes ds-body-text--sm from './base/base.css'; + } + + &[data-size='lg'] { + @composes ds-body-text--lg from './base/base.css'; + } + + & [data-field='description'] { + color: var(--ds-color-neutral-text-subtle); /* TODO: Change to opacity or color-mix(currentColor, trasparent) to ensure contrast when parent element color changes? */ + } + + /** + * States + */ + &:has([aria-disabled='true'], :disabled) > * { + cursor: not-allowed; + opacity: var(--ds-disabled-opacity); + } + + &:has([aria-readonly='true'], [readonly]) label { + --dsc-label--readonly: ; /* Activate lock icon for label when readonly */ + } + + /** + * Toggle inputs + */ + &:has(input:is([type='radio'], [type='checkbox'])) { + border-radius: var(--ds-border-radius-md); + display: grid; + grid-template-columns: auto 1fr; + row-gap: 0; + width: fit-content; /* Rather do display: grid + width: fit-content than display: inline-grid to encourage stacked radios */ + + & > * { + grid-column: 2; /* Only allow input in column 1 */ + } + + & label { + --dsc-label--readonly: initial; /* Never show lock icon on toggle inputs */ + font-weight: var(--ds-font-weight-regular); + } + + & input { + grid-column: 1; /* Always place input in column 1 */ + grid-row: 1; /* Always place input in row 1 */ + } + + &:not(:has([readonly], [aria-disabled='true'], :disabled)) label { + cursor: pointer; + } + + &:has(input:focus-visible) { + @composes ds-focus--visible from './base/base.css'; + } + + &:has(input:only-child) { + gap: 0; /* No gap only with aria-label/aria-labelledby */ + } } } diff --git a/packages/css/fieldset.css b/packages/css/fieldset.css index 6413d4a5dd..27b704e518 100644 --- a/packages/css/fieldset.css +++ b/packages/css/fieldset.css @@ -1,44 +1,31 @@ .ds-fieldset { - --dsc-fieldset-icon-size: 1.2em; - --dsc-fieldset-gap: var(--ds-spacing-2); - - margin: 0; - padding: 0; border: 0; + margin: 0; min-width: 0; - - & > :not(:last-child) { - margin-bottom: var(--ds-spacing-2); /* Use margin as fieldset does not play nice with display: flex */ - } - - & > legend { - display: inline-flex; - } - - & > legend:empty { - display: none; - } + padding: 0; &[data-hidelegend] > legend, &[data-hidelegend] > legend + p { @composes ds-sr-only from './base/base.css'; } - &[data-readonly] > legend::before { - content: ''; - background: currentcolor; - height: var(--dsc-fieldset-icon-size); - mask: center / contain no-repeat - url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' aria-hidden='true' viewBox='0 0 24 24'%3E%3Cpath fill-rule='evenodd' d='M12 2.25A4.75 4.75 0 0 0 7.25 7v2.25H7A1.75 1.75 0 0 0 5.25 11v9c0 .41.34.75.75.75h12a.75.75 0 0 0 .75-.75v-9A1.75 1.75 0 0 0 17 9.25h-.25V7A4.75 4.75 0 0 0 12 2.25m3.25 7V7a3.25 3.25 0 0 0-6.5 0v2.25zM12 13a1.5 1.5 0 0 0-.75 2.8V17a.75.75 0 0 0 1.5 0v-1.2A1.5 1.5 0 0 0 12 13'/%3E%3C/svg%3E"); - width: var(--dsc-fieldset-icon-size); + /* Add lock icon to legend when only containing readonly inputs */ + &:has([readonly]):not(:has(:read-write)) > legend { + --dsc-label--readonly: ; /* Using technique https://css-tricks.com/the-css-custom-property-toggle-trick/ */ + } + + /* Stack everything that is not directly after legend */ + & > * + * { + margin-block-start: var(--ds-spacing-4); } & > legend + p { color: var(--ds-color-neutral-text-subtle); + margin-block: 0; } &:disabled > legend, &:disabled > legend + p { - color: var(--ds-color-neutral-border-subtle); + opacity: var(--ds-disabled-opacity); } } diff --git a/packages/css/heading.css b/packages/css/heading.css index d86475f08f..a9466b3053 100644 --- a/packages/css/heading.css +++ b/packages/css/heading.css @@ -1,36 +1,55 @@ .ds-heading { - @composes ds-heading-text--md from './base/base.css'; - - margin: 0; font-size: 1.3em; /* Fallback if not supporting round() */ font-size: round(down, 1.3em, 0.0625rem); /* Default to 130% */ + font-weight: var(--ds-heading-md-font-weight); + letter-spacing: var(--ds-heading-md-letter-spacing); + line-height: var(--ds-heading-md-line-height); + margin: 0; /* Using font-size to ensure consistent size when explicitly setting data-size */ &[data-size='2xs'] { - @composes ds-heading-text--2xs from './base/base.css'; + font-weight: var(--ds-heading-2xs-font-weight); + line-height: var(--ds-heading-2xs-line-height); + font-size: var(--ds-heading-2xs-font-size); + letter-spacing: var(--ds-heading-2xs-letter-spacing); } &[data-size='xs'] { - @composes ds-heading-text--xs from './base/base.css'; + font-weight: var(--ds-heading-xs-font-weight); + line-height: var(--ds-heading-xs-line-height); + font-size: var(--ds-heading-xs-font-size); + letter-spacing: var(--ds-heading-xs-letter-spacing); } &[data-size='sm'] { - @composes ds-heading-text--sm from './base/base.css'; + font-weight: var(--ds-heading-sm-font-weight); + line-height: var(--ds-heading-sm-line-height); + font-size: var(--ds-heading-sm-font-size); + letter-spacing: var(--ds-heading-sm-letter-spacing); } &[data-size='md'] { - @composes ds-heading-text--md from './base/base.css'; + font-size: var(--ds-heading-md-font-size); } &[data-size='lg'] { - @composes ds-heading-text--lg from './base/base.css'; + font-weight: var(--ds-heading-lg-font-weight); + line-height: var(--ds-heading-lg-line-height); + font-size: var(--ds-heading-lg-font-size); + letter-spacing: var(--ds-heading-lg-letter-spacing); } &[data-size='xl'] { - @composes ds-heading-text--xl from './base/base.css'; + font-weight: var(--ds-heading-xl-font-weight); + line-height: var(--ds-heading-xl-line-height); + font-size: var(--ds-heading-xl-font-size); + letter-spacing: var(--ds-heading-xl-letter-spacing); } &[data-size='2xl'] { - @composes ds-heading-text--2xl from './base/base.css'; + font-weight: var(--ds-heading-2xl-font-weight); + line-height: var(--ds-heading-2xl-line-height); + font-size: var(--ds-heading-2xl-font-size); + letter-spacing: var(--ds-heading-2xl-letter-spacing); } } diff --git a/packages/css/index.css b/packages/css/index.css index 77adbf78c7..ad4f21ace8 100644 --- a/packages/css/index.css +++ b/packages/css/index.css @@ -10,17 +10,15 @@ @import url('./paragraph.css') layer(ds.typography); @import url('./validation-message.css') layer(ds.typography); @import url('./button.css') layer(ds.components); +@import url('./field.css') layer(ds.components); +@import url('./input.css') layer(ds.components); @import url('./alert.css') layer(ds.components); @import url('./popover.css') layer(ds.components); @import url('./skiplink.css') layer(ds.components); @import url('./accordion.css') layer(ds.components); -@import url('./field.css') layer(ds.components); @import url('./switch.css') layer(ds.components); -@import url('./checkbox.css') layer(ds.components); -@import url('./radio.css') layer(ds.components); @import url('./search.css') layer(ds.components); @import url('./textfield.css') layer(ds.components); -@import url('./input.css') layer(ds.components); @import url('./helptext.css') layer(ds.components); @import url('./modal.css') layer(ds.components); @import url('./list.css') layer(ds.components); diff --git a/packages/css/input.css b/packages/css/input.css index fe0f25421b..7d7fc2aac2 100644 --- a/packages/css/input.css +++ b/packages/css/input.css @@ -39,7 +39,7 @@ color: var(--dsc-input-color); font-family: inherit; height: var(--dsc-input-size); - line-height: var(--ds-line-height-sm); + line-height: inherit; margin: 0; /* Reset native margin on checkbox and radio */ max-width: 100%; /* Ensure input does not grow outside bounds even with a high value in size="" or cols="" */ padding: var(--dsc-input-padding); @@ -107,12 +107,15 @@ } /** - * Toggle inputs + * Toggle inputs and select */ &:read-only:not([readonly], [aria-disabled='true'], :disabled) { cursor: pointer; } + /** + * Toggle inputs + */ &[type='checkbox'], &[type='radio'] { --dsc-input-border-width: var(--dsc-input-border-width--toggle); @@ -120,6 +123,8 @@ --dsc-input-size: var(--dsc-input-size--toggle); flex-shrink: 0; /* Never shrink a toggle input */ + line-height: inherit; /* Inherit line height so we can use 1lh to align with first line of label */ + translate: 0 calc((1lh - var(--dsc-input-size)) / 2); /* Align with first line of label text */ width: var(--dsc-input-size); } @@ -173,11 +178,6 @@ } } -/* Change cursor on wrapping