Compare commits

...

3 Commits

Author SHA1 Message Date
doryan 5dc93fe8a6 Merge pull request 'experimental' (#3) from experimental into main
мать ебал ридми
2024-02-18 21:55:50 +03:00
doryan04 ead00b5ae9 CHANGES: Added unoptimized progress bar inside <Slider> component
FIXED: Some styles
2024-02-18 22:39:34 +04:00
doryan04 f736f73a1f DONE: Full typography
CHANGES: Everywhere change <span> labels to <Typography>
FIXED: Imports in SASS files
2024-02-17 21:11:14 +04:00
22 changed files with 1057 additions and 256 deletions

View File

@ -9,24 +9,25 @@ This repository is including and will be including components, enumerates in tab
- [x] Icon - [x] Icon
- [x] FAB - [x] FAB
- [X] Radio - [X] Radio
- [ ] Segmented (WIP) - [X] Segmented
- [X] Checkbox - [X] Checkbox
- [x] Text fields - [x] Text fields
- [X] Switches - [X] Switches
- [ ] Chips
- [x] Icon - [x] Icon
- [x] Ripple Effect - [x] Ripple Effect
- [X] Dividers - [X] Dividers
- [x] Badges - [x] Badges
- [ ] Select field
- [ ] Bottom sheets
- [X] Cards - [X] Cards
- [X] Typography
- [ ] Chips
- [ ] Select field (WIP)
- [ ] Bottom sheets
- [ ] Menus - [ ] Menus
- [ ] Navigation - [ ] Navigation
- [ ] Bars - [ ] Bars
- [ ] Drawer - [ ] Drawer
- [ ] Rail - [ ] Rail
- [ ] Sliders - [ ] Sliders (WIP)
- [ ] Snackbar - [ ] Snackbar
- [ ] Tabs - [ ] Tabs
- [ ] Bottom sheets - [ ] Bottom sheets

View File

@ -1,7 +1,7 @@
import React from 'react'; import React from 'react';
import testImage1 from './test-images/test-image-1.jpg'; import testImage1 from './test-images/test-image-1.jpg';
import { Card } from '../src/primitive-components/card/card'; import { Card } from '../src/primitive-components/card/card';
import {Checkbox, Radio} from '../src/primitive-components/components'; import { Checkbox } from '../src/primitive-components/components';
import { CardBody } from '../src/primitive-components/card/card-body'; import { CardBody } from '../src/primitive-components/card/card-body';
import { CardMedia } from '../src/primitive-components/card/card-media'; import { CardMedia } from '../src/primitive-components/card/card-media';
import { CardFooter } from '../src/primitive-components/card/card-footer'; import { CardFooter } from '../src/primitive-components/card/card-footer';
@ -25,15 +25,22 @@ export default function Page() {
padding: '8px', padding: '8px',
}} }}
> >
<div style={{ display: 'flex', gap: '8px', maxWidth: '1024px' }}> <div
style={{ display: 'flex', gap: '8px', maxWidth: '1024px' }}
>
<Card variant={'outlined'}> <Card variant={'outlined'}>
<CardHeader> <CardHeader>
<Typography.h3> Header-3 </Typography.h3> <Typography role={'headline'} size={'large'}>
Welcome to Material You for Next.js!
</Typography>
<Typography role={'body'} size={'large'}>
{"It's UI kit for fast frontend development!"}
</Typography>
</CardHeader> </CardHeader>
<CardActionArea> <CardActionArea>
<CardMedia src={testImage1.src} type={'img'} /> <CardMedia src={testImage1.src} type={'img'} />
<CardBody> <CardBody>
<p> <Typography role={'body'} size={'large'}>
Lorem ipsum dolor sit amet, consecrate Lorem ipsum dolor sit amet, consecrate
adipiscing elit, sed do eiusmod tempor adipiscing elit, sed do eiusmod tempor
incididunt ut labore et dolore magna aliqua. incididunt ut labore et dolore magna aliqua.
@ -45,7 +52,7 @@ export default function Page() {
Excepteur sint occaecat cupidatat non Excepteur sint occaecat cupidatat non
proident, sunt in culpa qui officia deserunt proident, sunt in culpa qui officia deserunt
mollit anim id est laborum. mollit anim id est laborum.
</p> </Typography>
</CardBody> </CardBody>
</CardActionArea> </CardActionArea>
<CardFooter> <CardFooter>
@ -54,7 +61,7 @@ export default function Page() {
<Button icon={'add'} iconPlace={'right'}> <Button icon={'add'} iconPlace={'right'}>
Label 2 Label 2
</Button> </Button>
<SegmentedButtons> <SegmentedButtons toggled={true}>
<SegmentButton <SegmentButton
fillIcon={1} fillIcon={1}
icon={'change_history'} icon={'change_history'}
@ -73,8 +80,26 @@ export default function Page() {
</SegmentButton> </SegmentButton>
</SegmentedButtons> </SegmentedButtons>
<Checkbox /> <Checkbox />
<Radio /> <Slider
<Slider /> defaultValue={0}
max={100}
min={0}
options={[0, 10, 20, 100]}
/>
<Slider defaultValue={0} max={100} min={0} />
<div>
<input
list={'lol'}
max={100}
min={0}
type={'range'}
/>
<datalist id={'lol'}>
<option value={0} />
<option value={50} />
<option value={100} />
</datalist>
</div>
</div> </div>
</CardFooter> </CardFooter>
</Card> </Card>

View File

@ -5,6 +5,7 @@ import { ButtonProps } from './button.types';
import { bool, oneOf, string } from 'prop-types'; import { bool, oneOf, string } from 'prop-types';
import { ButtonLayout } from '../button-layout/button-layout'; import { ButtonLayout } from '../button-layout/button-layout';
import { IconWrapper } from '../../icon/icon-wrapper'; import { IconWrapper } from '../../icon/icon-wrapper';
import { Typography } from '../../typography/typography';
/** /**
* Button component * Button component
@ -32,7 +33,13 @@ export const Button = forwardRef<HTMLButtonElement, ButtonProps>(
ref={ref} ref={ref}
> >
<IconWrapper icon={icon} iconPlace={iconPlace}> <IconWrapper icon={icon} iconPlace={iconPlace}>
<span className={'label-large'}>{props.children}</span> <Typography
className={'label-large'}
role={'label'}
size={'large'}
>
{props.children}
</Typography>
</IconWrapper> </IconWrapper>
</ButtonLayout> </ButtonLayout>
), ),

View File

@ -1,9 +1,10 @@
'use client'; 'use client';
import { forwardRef } from 'react';
import { Icon } from '../../components';
import { FABProps } from './fab.types'; import { FABProps } from './fab.types';
import { Icon } from '../../components';
import React, { forwardRef } from 'react';
import { bool, oneOf, string } from 'prop-types'; import { bool, oneOf, string } from 'prop-types';
import { Typography } from '../../typography/typography';
import { ButtonLayout } from '../button-layout/button-layout'; import { ButtonLayout } from '../button-layout/button-layout';
/** /**
@ -21,6 +22,7 @@ const sizes = {
export const FAB = forwardRef<HTMLButtonElement, FABProps>( export const FAB = forwardRef<HTMLButtonElement, FABProps>(
( (
{ {
children,
icon = 'edit', icon = 'edit',
className = '', className = '',
size = 'default', size = 'default',
@ -43,7 +45,13 @@ export const FAB = forwardRef<HTMLButtonElement, FABProps>(
{icon} {icon}
</Icon> </Icon>
{size === 'extended' ? ( {size === 'extended' ? (
<span className={'label-large'}>{props.children}</span> <Typography
className={'label-large'}
role={'label'}
size={'large'}
>
{children}
</Typography>
) : ( ) : (
<></> <></>
)} )}

View File

@ -3,10 +3,8 @@
import { string } from 'prop-types'; import { string } from 'prop-types';
import React, { forwardRef, useState } from 'react'; import React, { forwardRef, useState } from 'react';
import { IconWrapper } from '../../icon/icon-wrapper'; import { IconWrapper } from '../../icon/icon-wrapper';
import { Typography } from '../../typography/typography';
import { SegmentedButton } from './segmented-buttons.types'; import { SegmentedButton } from './segmented-buttons.types';
import { ButtonLayout } from '../button-layout/button-layout';
import { ButtonLayoutProps } from '../button-layout/button-layout.types';
export const SegmentButton = forwardRef< export const SegmentButton = forwardRef<
HTMLButtonElement, HTMLButtonElement,
ButtonLayoutProps & SegmentedButton ButtonLayoutProps & SegmentedButton
@ -19,6 +17,7 @@ export const SegmentButton = forwardRef<
weight, weight,
svgSize, svgSize,
fillIcon, fillIcon,
children,
iconSize, iconSize,
opticalSize, opticalSize,
toggled = false, toggled = false,
@ -58,13 +57,22 @@ export const SegmentButton = forwardRef<
type={type} type={type}
weight={weight} weight={weight}
> >
<span className={'label-large'}>{props.children}</span> <Typography
className={'label-large'}
role={'label'}
size={'large'}
>
{children}
</Typography>
</IconWrapper> </IconWrapper>
<span className={'m3 m3-button-segment-state-layer'} /> <span className={'m3 m3-button-segment-state-layer'} />
</ButtonLayout> </ButtonLayout>
); );
}, },
); );
import { ButtonLayout } from '../button-layout/button-layout';
import { ButtonLayoutProps } from '../button-layout/button-layout.types';
SegmentButton.propTypes = { SegmentButton.propTypes = {
children: string, children: string,

View File

@ -1,11 +1,10 @@
import { HTMLAttributes, ReactElement } from 'react'; import { HTMLAttributes, ReactElement } from 'react';
import { IconProps, IconWrapperProps } from '../../icon/icon.types'; import { IconWrapperProps } from '../../icon/icon.types';
export type SegmentedButton = IconWrapperProps & { export type SegmentedButton = IconWrapperProps & {
icon?: string; icon?: string;
toggled?: boolean; toggled?: boolean;
centralRipple?: boolean; centralRipple?: boolean;
children?: string | ReactElement<IconProps>;
}; };
export interface SegmentedButtons { export interface SegmentedButtons {

View File

@ -20,7 +20,4 @@ export type IconWrapperProps = IconPlacement &
icon?: string; icon?: string;
}; };
export type IconProps = SVGProps<SVGSVGElement> & export type IconProps = SVGProps<SVGSVGElement> & GeneralIconProps;
GeneralIconProps & {
children?: string | undefined;
};

View File

@ -3,8 +3,8 @@
import { bool } from 'prop-types'; import { bool } from 'prop-types';
import { CheckboxProps } from './checkbox.types'; import { CheckboxProps } from './checkbox.types';
import { RippleEffect } from '../../ripple/ripple-effect'; import { RippleEffect } from '../../ripple/ripple-effect';
import useRippleEffect from '../../ripple/hooks/useRippleEffect';
import { InputLayout } from '../input-layout/input-layout'; import { InputLayout } from '../input-layout/input-layout';
import useRippleEffect from '../../ripple/hooks/useRippleEffect';
import { import {
forwardRef, forwardRef,
useEffect, useEffect,
@ -51,7 +51,6 @@ export const Checkbox = forwardRef<HTMLInputElement, CheckboxProps>(
className={'m3-checkbox-ripple-layer'} className={'m3-checkbox-ripple-layer'}
ref={ripplesRef} ref={ripplesRef}
/> />
{props.children}
</div> </div>
); );
}, },

View File

@ -6,7 +6,3 @@ export interface InputLayoutProps
typeInput?: string; typeInput?: string;
type?: string; type?: string;
} }
export interface LabelPlacement {
labelPlacement?: 'left' | 'right';
}

View File

@ -1,18 +1,46 @@
import React, { forwardRef, HTMLAttributes } from 'react'; 'use client';
import { InputLayout } from '../input-layout/input-layout';
export const Slider = forwardRef< import { InputLayout } from '../input-layout/input-layout';
HTMLInputElement, import React, { forwardRef, InputHTMLAttributes, useId, useState } from 'react';
HTMLAttributes<HTMLInputElement>
>((props, ref) => { interface SliderProps extends InputHTMLAttributes<HTMLInputElement> {
return ( options?: number[];
<div className={'m3 m3-slider-container'}> }
<InputLayout
className={props.className} export const Slider = forwardRef<HTMLInputElement, SliderProps>(
ref={ref} ({ options, ...props }, ref) => {
type={'range'} const sliderId = useId();
typeInput={'slider'} const [progress, setProgress] = useState<number>(0);
/>
</div> return (
); <div className={'m3 m3-slider-container'}>
}); <InputLayout
{...props}
className={props.className}
list={sliderId}
onChange={(event: React.ChangeEvent<HTMLInputElement>) => {
setProgress(
(parseInt(event.target.value) /
parseInt(event.target.max)) *
100,
);
}}
ref={ref}
style={{
...props.style,
background: `linear-gradient(to right, var(--md-sys-color-primary) ${progress}%, var(--md-sys-color-surface-container-highest) ${progress}%)`,
}}
type={'range'}
typeInput={'slider'}
/>
{options && (
<datalist id={sliderId}>
{options.map((option, index) => (
<option key={index} value={option} />
))}
</datalist>
)}
</div>
);
},
);

View File

@ -4,37 +4,41 @@ import { bool } from 'prop-types';
import React, { forwardRef } from 'react'; import React, { forwardRef } from 'react';
import { SwitchMainProps } from './switch.types'; import { SwitchMainProps } from './switch.types';
import { InputLayout } from '../input-layout/input-layout'; import { InputLayout } from '../input-layout/input-layout';
import { LabelPlacement } from '../input-layout/input-layout.types';
/** /**
* Switch component * Switch component
** description ** description
*/ */
export const Switch = forwardRef< export const Switch = forwardRef<HTMLInputElement, SwitchMainProps>(
HTMLInputElement, ({ icon, selected = false, ...props }, ref) => (
SwitchMainProps & LabelPlacement <>
>(({ icon, selected = false, ...props }, ref) => ( <div className={'m3 m3-switch'}>
<div className={'m3 m3-switch'}> <InputLayout
<InputLayout {...props}
{...props} className={`m3 ${props.className ?? ''}`.trimEnd()}
className={`m3 ${props.className ?? ''}`.trimEnd()} ref={ref}
ref={ref} type={'checkbox'}
type={'checkbox'} />
/> <svg>
<svg> <rect className={'m3 m3-switch-track'} />
<rect className={'m3 m3-switch-track'} /> <circle className={'m3 m3-switch-handler'} />
<circle className={'m3 m3-switch-handler'} /> <circle className={'m3 m3-switch-handler-state-layer'} />
<circle className={'m3 m3-switch-handler-state-layer'} /> <g>
<g> {icon && !selected && (
{icon && !selected && ( <text className={'m3 m3-icon-unchecked'}>
<text className={'m3 m3-icon-unchecked'}>close</text> close
)} </text>
{icon && <text className={'m3 m3-icon-checked'}>check</text>} )}
</g> {icon && (
</svg> <text className={'m3 m3-icon-checked'}>check</text>
</div> )}
)); </g>
</svg>
</div>
</>
),
);
Switch.propTypes = { Switch.propTypes = {
icon: bool, icon: bool,

View File

@ -1,76 +1,25 @@
import { forwardRef, HTMLAttributes } from 'react'; import { createElement, forwardRef } from 'react';
import { getTypographyRole } from './utils/get-typography-role';
import {
TypographyProps,
Typography as TypographyTargetRef,
} from './typography.types';
export const Typography = { export const Typography = forwardRef<TypographyTargetRef, TypographyProps>(
h1: forwardRef<HTMLHeadingElement, HTMLAttributes<HTMLHeadingElement>>( ({ size, role, children, ...props }, ref) => {
(props, ref) => { const typeElement = getTypographyRole(role, size);
return (
<h1 const extraClasses =
className={`m3 m3-typography display-hero ${props.className}`} `m3 m3-typography ${size && role ? `${role}-${size}` : ''}`.trimEnd();
ref={ref}
> return createElement(
{props.children} typeElement,
</h1> {
); ...props,
}, ref: ref,
), className: extraClasses,
h2: forwardRef<HTMLHeadingElement, HTMLAttributes<HTMLHeadingElement>>( },
(props, ref) => { children,
return ( );
<h2 },
className={`m3 m3-typography display-large ${props.className}`} );
ref={ref}
>
{props.children}
</h2>
);
},
),
h3: forwardRef<HTMLHeadingElement, HTMLAttributes<HTMLHeadingElement>>(
(props, ref) => {
return (
<h3
className={`m3 m3-typography headline-medium ${props.className}`}
ref={ref}
>
{props.children}
</h3>
);
},
),
h4: forwardRef<HTMLHeadingElement, HTMLAttributes<HTMLHeadingElement>>(
(props, ref) => {
return (
<h4
className={`m3 m3-typography headline-small ${props.className}`}
ref={ref}
>
{props.children}
</h4>
);
},
),
h5: forwardRef<HTMLHeadingElement, HTMLAttributes<HTMLHeadingElement>>(
(props, ref) => {
return (
<h5
className={`m3 m3-typography title-medium ${props.className}`}
ref={ref}
>
{props.children}
</h5>
);
},
),
h6: forwardRef<HTMLHeadingElement, HTMLAttributes<HTMLHeadingElement>>(
(props, ref) => {
return (
<h6
className={`m3 m3-typography title-small ${props.className}`}
ref={ref}
>
{props.children}
</h6>
);
},
),
};

View File

@ -0,0 +1,21 @@
import { HTMLAttributes } from 'react';
export type Typography =
| HTMLLabelElement
| HTMLHeadingElement
| HTMLSpanElement
| HTMLParagraphElement;
export type TypographySize = 'hero' | 'xl' | 'small' | 'medium' | 'large';
export type TypographyRole =
| 'display'
| 'headline'
| 'title'
| 'body'
| 'label';
export interface TypographyProps extends HTMLAttributes<Typography> {
size: TypographySize;
role: TypographyRole;
}

View File

@ -0,0 +1,32 @@
import { TypographyRole, TypographySize } from '../typography.types';
export function getTypographyRole(role: TypographyRole, size: TypographySize) {
switch (role) {
case 'display':
return 'h1';
case 'headline':
switch (size) {
case 'large' || 'hero' || 'xl':
return 'h2';
case 'medium':
return 'h3';
case 'small':
return 'h4';
}
break;
case 'title':
switch (size) {
case 'large' || 'hero' || 'xl':
return 'h4';
case 'medium':
return 'h5';
case 'small':
return 'h6';
}
break;
case 'body':
return 'p';
case 'label':
return 'label';
}
}

View File

@ -1,6 +1,3 @@
@import "./themes/tokens.css";
@import "./themes/colors.module.css";
@import "./themes/typography.module.css";
@import "./themes/theme.dark.css" (prefers-color-scheme: dark); @import "./themes/theme.dark.css" (prefers-color-scheme: dark);
@import "./themes/theme.light.css" (prefers-color-scheme: light); @import "./themes/theme.light.css" (prefers-color-scheme: light);
div.m3.m3-card > :is(div.m3-card-footer, header.m3-card-header, section.m3-card-body) > .m3-card-media:first-child, div.m3.m3-card > .m3-card-media:first-child, div.m3.m3-card > .m3-card-action-area:first-child > .m3-card-action-area-content > .m3-card-media:first-child { div.m3.m3-card > :is(div.m3-card-footer, header.m3-card-header, section.m3-card-body) > .m3-card-media:first-child, div.m3.m3-card > .m3-card-media:first-child, div.m3.m3-card > .m3-card-action-area:first-child > .m3-card-action-area-content > .m3-card-media:first-child {
@ -793,12 +790,16 @@ div.m3.m3-radio-container {
display: inline-flex; display: inline-flex;
justify-content: center; justify-content: center;
} }
div.m3.m3-radio-container + label.m3.m3-radio-label {
margin-inline: 3px;
}
div.m3.m3-radio-container > span.m3-checkbox-ripple-layer, div.m3.m3-radio-container span.m3.m3-radio-state-layer { div.m3.m3-radio-container > span.m3-checkbox-ripple-layer, div.m3.m3-radio-container span.m3.m3-radio-state-layer {
z-index: 5; z-index: 5;
width: 40px;
height: 40px;
aspect-ratio: 1;
} }
div.m3.m3-radio-container > span.m3.m3-radio-state-layer { div.m3.m3-radio-container > span.m3.m3-radio-state-layer {
width: 40px;
aspect-ratio: 1;
border-radius: 50%; border-radius: 50%;
position: absolute; position: absolute;
pointer-events: none; pointer-events: none;
@ -880,36 +881,39 @@ div.m3.m3-slider-container {
display: flex; display: flex;
align-items: center; align-items: center;
} }
div.m3.m3-slider-container > datalist {
display: none;
}
input[type=range].m3.m3-slider { input[type=range].m3.m3-slider {
margin: 0; margin: 0;
height: 4px;
appearance: none; appearance: none;
overflow: visible;
border-radius: 2px; border-radius: 2px;
margin-inline: 10px; margin-inline: 8px;
background-color: var(--md-sys-color-surface-container-highest); background: linear-gradient(to right, var(--md-sys-color-primary) 0%, var(--md-sys-color-surface-container-highest) 0%);
} }
input[type=range].m3.m3-slider::-webkit-slider-container { input[type=range].m3.m3-slider::-webkit-slider-container {
margin-inline: -8px; appearance: none;
box-shadow: none;
border-radius: 2px;
min-block-size: 4px;
height: 4px !important;
}
input[type=range].m3.m3-slider::-webkit-slider-runnable-track {
height: 4px;
} }
input[type=range].m3.m3-slider::-webkit-slider-thumb { input[type=range].m3.m3-slider::-webkit-slider-thumb {
box-shadow: 0 1px 3px 1px rgba(0, 0, 0, 0.15), 0 1px 2px 0 rgba(0, 0, 0, 0.3); box-shadow: 0 1px 3px 1px rgba(0, 0, 0, 0.15), 0 1px 2px 0 rgba(0, 0, 0, 0.3);
width: 20px; width: 20px;
aspect-ratio: 1; aspect-ratio: 1;
appearance: none; appearance: none;
overflow: visible;
border-radius: 50%; border-radius: 50%;
margin-top: -8px;
box-sizing: border-box; box-sizing: border-box;
outline: 10px solid transparent; outline: 10px solid transparent;
background: var(--md-sys-color-primary); background: var(--md-sys-color-primary);
transition: 0.2s cubic-bezier(0.2, 0, 0, 1); transition: 0.2s cubic-bezier(0.2, 0, 0, 1);
} }
input[type=range].m3.m3-slider::-webkit-slider-thumb::after {
width: 40px;
aspect-ratio: 1;
background-color: transparent;
}
input[type=range].m3.m3-slider::-webkit-slider-thumb:hover { input[type=range].m3.m3-slider::-webkit-slider-thumb:hover {
outline: 10px solid color-mix(in srgb, var(--md-sys-color-primary) 8%, transparent); outline: 10px solid color-mix(in srgb, var(--md-sys-color-primary) 8%, transparent);
} }
@ -918,33 +922,32 @@ input[type=range].m3.m3-slider::-webkit-slider-thumb:is(:active, :focus-visible)
} }
div.m3.m3-switch { div.m3.m3-switch {
margin: 4px;
gap: 20px; gap: 20px;
box-sizing: content-box; margin: 4px;
height: 32px;
display: flex; display: flex;
align-items: center; align-items: center;
justify-content: center; justify-content: left;
width: 52px; box-sizing: content-box;
height: 32px;
} }
div.m3.m3-switch > svg { div.m3.m3-switch > svg {
overflow: visible;
transition: 0.2s cubic-bezier(0.175, 0.885, 0.32, 1.275);
width: 52px; width: 52px;
height: 32px; height: 32px;
overflow: visible;
transition: 0.2s cubic-bezier(0.175, 0.885, 0.32, 1.275);
} }
div.m3.m3-switch > svg > g { div.m3.m3-switch > svg > g {
transform: translate(11.5%, 81%); transform: translate(11.5%, 81%);
transition: 0.2s cubic-bezier(0.175, 0.885, 0.32, 1.275); transition: 0.2s cubic-bezier(0.175, 0.885, 0.32, 1.275);
} }
div.m3.m3-switch > svg > g > text { div.m3.m3-switch > svg > g > text {
font-family: Material-Symbols-Outlined-Regular;
font-size: 20px; font-size: 20px;
font-family: Material-Symbols-Outlined-Regular;
} }
div.m3.m3-switch > svg > circle.m3.m3-switch-handler-state-layer, div.m3.m3-switch > svg > circle.m3.m3-switch-handler { div.m3.m3-switch > svg > circle.m3.m3-switch-handler-state-layer, div.m3.m3-switch > svg > circle.m3.m3-switch-handler {
transition: 0.2s cubic-bezier(0.175, 0.885, 0.32, 1.275);
cy: 50%; cy: 50%;
cx: 16px; cx: 16px;
transition: 0.2s cubic-bezier(0.175, 0.885, 0.32, 1.275);
} }
div.m3.m3-switch > svg > circle.m3.m3-switch-handler-state-layer { div.m3.m3-switch > svg > circle.m3.m3-switch-handler-state-layer {
r: 20px; r: 20px;
@ -962,13 +965,13 @@ div.m3.m3-switch > svg > rect.m3.m3-switch-track {
height: 30px; height: 30px;
} }
div.m3.m3-switch > input.m3 { div.m3.m3-switch > input.m3 {
cursor: pointer;
appearance: none;
opacity: 0 !important;
margin: 0; margin: 0;
width: 52px; width: 52px;
height: 32px; height: 32px;
cursor: pointer;
appearance: none;
position: absolute; position: absolute;
opacity: 0 !important;
} }
div.m3.m3-switch > input.m3:disabled { div.m3.m3-switch > input.m3:disabled {
cursor: not-allowed; cursor: not-allowed;
@ -1007,30 +1010,30 @@ div.m3.m3-switch > input.m3:is(div.m3.m3-switch > input.m3:checked, div.m3.m3-sw
r: 14px; r: 14px;
} }
div.m3.m3-switch > input.m3:not(:checked):disabled + svg > circle.m3.m3-switch-handler { div.m3.m3-switch > input.m3:not(:checked):disabled + svg > circle.m3.m3-switch-handler {
fill: var(--md-sys-color-on-surface);
fill-opacity: 38%; fill-opacity: 38%;
fill: var(--md-sys-color-on-surface);
} }
div.m3.m3-switch > input.m3:hover:not(:disabled):checked + svg > circle.m3.m3-switch-handler { div.m3.m3-switch > input.m3:hover:not(:disabled):checked + svg > circle.m3.m3-switch-handler {
fill: var(--md-sys-color-primary-container); fill: var(--md-sys-color-primary-container);
} }
div.m3.m3-switch > input.m3:hover:not(:disabled):checked + svg > circle.m3.m3-switch-handler-state-layer { div.m3.m3-switch > input.m3:hover:not(:disabled):checked + svg > circle.m3.m3-switch-handler-state-layer {
fill: var(--md-sys-color-primary);
fill-opacity: 8%; fill-opacity: 8%;
fill: var(--md-sys-color-primary);
} }
div.m3.m3-switch > input.m3:hover:not(:disabled):not(:checked) + svg > circle.m3.m3-switch-handler { div.m3.m3-switch > input.m3:hover:not(:disabled):not(:checked) + svg > circle.m3.m3-switch-handler {
fill: var(--md-sys-color-on-surface-variant); fill: var(--md-sys-color-on-surface-variant);
} }
div.m3.m3-switch > input.m3:hover:not(:disabled):not(:checked) + svg > circle.m3.m3-switch-handler-state-layer { div.m3.m3-switch > input.m3:hover:not(:disabled):not(:checked) + svg > circle.m3.m3-switch-handler-state-layer {
fill: var(--md-sys-color-on-surface);
fill-opacity: 8%; fill-opacity: 8%;
fill: var(--md-sys-color-on-surface);
} }
div.m3.m3-switch > input.m3:active:not(:disabled):checked + svg > circle.m3.m3-switch-handler-state-layer { div.m3.m3-switch > input.m3:active:not(:disabled):checked + svg > circle.m3.m3-switch-handler-state-layer {
fill: var(--md-sys-color-primary);
fill-opacity: 12%; fill-opacity: 12%;
fill: var(--md-sys-color-primary);
} }
div.m3.m3-switch > input.m3:active:not(:disabled):not(:checked) + svg > circle.m3.m3-switch-handler-state-layer { div.m3.m3-switch > input.m3:active:not(:disabled):not(:checked) + svg > circle.m3.m3-switch-handler-state-layer {
fill: var(--md-sys-color-on-surface);
fill-opacity: 12%; fill-opacity: 12%;
fill: var(--md-sys-color-on-surface);
} }
div.m3.m3-switch > input.m3:is(:checked, :checked:disabled) + svg > rect.m3.m3-switch-track { div.m3.m3-switch > input.m3:is(:checked, :checked:disabled) + svg > rect.m3.m3-switch-track {
rx: 16px; rx: 16px;
@ -1047,8 +1050,8 @@ div.m3.m3-switch > input.m3:not(:checked) + svg > rect.m3.m3-switch-track {
fill: var(--md-sys-color-surface-container-highest); fill: var(--md-sys-color-surface-container-highest);
} }
div.m3.m3-switch > input.m3:checked + svg > rect.m3.m3-switch-track { div.m3.m3-switch > input.m3:checked + svg > rect.m3.m3-switch-track {
stroke: var(--md-sys-color-primary);
fill: var(--md-sys-color-primary); fill: var(--md-sys-color-primary);
stroke: var(--md-sys-color-primary);
} }
div.m3.m3-switch > input.m3:disabled + svg > g > text.m3 { div.m3.m3-switch > input.m3:disabled + svg > g > text.m3 {
fill: color-mix(in srgb, var(--md-sys-color-surface-container-highest) 38%, transparent); fill: color-mix(in srgb, var(--md-sys-color-surface-container-highest) 38%, transparent);
@ -1062,28 +1065,27 @@ div.m3.m3-switch > input.m3:checked:disabled + svg > g > text.m3 {
fill: color-mix(in srgb, var(--md-sys-color-on-surface) 38%, transparent); fill: color-mix(in srgb, var(--md-sys-color-on-surface) 38%, transparent);
} }
div.m3.m3-switch > input.m3:checked:disabled + svg > rect.m3.m3-switch-track { div.m3.m3-switch > input.m3:checked:disabled + svg > rect.m3.m3-switch-track {
stroke: color-mix(in srgb, var(--md-sys-color-on-surface) 0%, transparent);
fill: color-mix(in srgb, var(--md-sys-color-on-surface) 12%, transparent); fill: color-mix(in srgb, var(--md-sys-color-on-surface) 12%, transparent);
stroke: color-mix(in srgb, var(--md-sys-color-on-surface) 0%, transparent);
} }
div.m3.m3-checkbox-container { div.m3.m3-checkbox-container {
gap: 16px;
height: 40px;
display: flex; display: flex;
aspect-ratio: 1;
position: relative; position: relative;
align-items: center; align-items: center;
justify-content: center; justify-content: center;
aspect-ratio: 1;
width: 18px;
height: 18px;
} }
div.m3.m3-checkbox-container > span.m3.m3-checkbox-state-layer { div.m3.m3-checkbox-container > span.m3.m3-checkbox-state-layer {
position: absolute; width: 40px;
width: 2.5rem; aspect-ratio: 1;
aspect-ratio: inherit;
border-radius: 50%; border-radius: 50%;
position: absolute;
transition: background-color 0.2s cubic-bezier(0.2, 0, 0, 1); transition: background-color 0.2s cubic-bezier(0.2, 0, 0, 1);
} }
div.m3.m3-checkbox-container > span.m3.m3-checkbox-ripple-layer {
span.m3.m3-checkbox-ripple-layer {
z-index: 20; z-index: 20;
width: 2.5rem; width: 2.5rem;
height: 2.5rem; height: 2.5rem;
@ -1093,7 +1095,6 @@ span.m3.m3-checkbox-ripple-layer {
} }
input[type=checkbox].m3.m3-checkbox { input[type=checkbox].m3.m3-checkbox {
margin: 0;
z-index: 10; z-index: 10;
display: flex; display: flex;
width: 1.125rem; width: 1.125rem;
@ -1107,6 +1108,7 @@ input[type=checkbox].m3.m3-checkbox {
transition: background-color 0.2s cubic-bezier(0.2, 0, 0, 1); transition: background-color 0.2s cubic-bezier(0.2, 0, 0, 1);
} }
input[type=checkbox].m3.m3-checkbox ~ span.m3-checkbox-state { input[type=checkbox].m3.m3-checkbox ~ span.m3-checkbox-state {
position: absolute;
color: var(--md-sys-color-on-surface-variant); color: var(--md-sys-color-on-surface-variant);
transition: color 0.2s cubic-bezier(0.2, 0, 0, 1); transition: color 0.2s cubic-bezier(0.2, 0, 0, 1);
} }
@ -1132,13 +1134,13 @@ input[type=checkbox].m3.m3-checkbox:disabled ~ *:is(:hover, input[type=checkbox]
opacity: 38%; opacity: 38%;
} }
input[type=checkbox].m3.m3-checkbox ~ span.m3-checkbox-state { input[type=checkbox].m3.m3-checkbox ~ span.m3-checkbox-state {
pointer-events: none;
z-index: 10; z-index: 10;
display: flex; display: flex;
font-size: 24px; font-size: 24px;
font-weight: 700; font-weight: 700;
line-height: 24px; line-height: 24px;
align-items: center; align-items: center;
pointer-events: none;
justify-content: center; justify-content: center;
font-family: Material-Symbols-Outlined-Regular, sans-serif; font-family: Material-Symbols-Outlined-Regular, sans-serif;
font-variation-settings: "FILL" 1, "wght" 300, "GRAD" 0, "opsz" 24; font-variation-settings: "FILL" 1, "wght" 300, "GRAD" 0, "opsz" 24;
@ -1394,16 +1396,733 @@ div.m3.m3-text-field.outlined:hover:not(div.m3.m3-text-field.outlined:hover:has(
border-color: var(--md-sys-color-on-surface); border-color: var(--md-sys-color-on-surface);
} }
:root {
/* display - hero */
--md-sys-typescale-display-hero-font-family-name: Roboto;
--md-sys-typescale-display-hero-font-family-style: Regular;
--md-sys-typescale-display-hero-font-weight: 475;
--md-sys-typescale-display-hero-font-size: 112px;
--md-sys-typescale-display-hero-line-height: 1;
--md-sys-typescale-display-hero-letter-spacing: 0;
/* display - xl */
--md-sys-typescale-display-xl-font-family-name: Roboto;
--md-sys-typescale-display-xl-font-family-style: Regular;
--md-sys-typescale-display-xl-font-weight: 475;
--md-sys-typescale-display-xl-font-size: 88px;
--md-sys-typescale-display-xl-line-height: 96px;
--md-sys-typescale-display-xl-letter-spacing: 0;
/* display - large */
--md-sys-typescale-display-large-font-family-name: Roboto;
--md-sys-typescale-display-large-font-family-style: Regular;
--md-sys-typescale-display-large-font-weight: 400;
--md-sys-typescale-display-large-font-size: 57px;
--md-sys-typescale-display-large-line-height: 64px;
--md-sys-typescale-display-large-letter-spacing: -0.25px;
/* display - medium */
--md-sys-typescale-display-medium-font-family-name: Roboto;
--md-sys-typescale-display-medium-font-family-style: Regular;
--md-sys-typescale-display-medium-font-weight: 400;
--md-sys-typescale-display-medium-font-size: 45px;
--md-sys-typescale-display-medium-line-height: 52px;
--md-sys-typescale-display-medium-letter-spacing: 0px;
/* display - small */
--md-sys-typescale-display-small-font-family-name: Roboto;
--md-sys-typescale-display-small-font-family-style: Regular;
--md-sys-typescale-display-small-font-weight: 400;
--md-sys-typescale-display-small-font-size: 36px;
--md-sys-typescale-display-small-line-height: 44px;
--md-sys-typescale-display-small-letter-spacing: 0px;
/* headline - large */
--md-sys-typescale-headline-large-font-family-name: Roboto;
--md-sys-typescale-headline-large-font-family-style: Regular;
--md-sys-typescale-headline-large-font-weight: 400;
--md-sys-typescale-headline-large-font-size: 32px;
--md-sys-typescale-headline-large-line-height: 40px;
--md-sys-typescale-headline-large-letter-spacing: 0px;
/* headline - medium */
--md-sys-typescale-headline-medium-font-family-name: Roboto;
--md-sys-typescale-headline-medium-font-family-style: Regular;
--md-sys-typescale-headline-medium-font-weight: 400;
--md-sys-typescale-headline-medium-font-size: 28px;
--md-sys-typescale-headline-medium-line-height: 36px;
--md-sys-typescale-headline-medium-letter-spacing: 0px;
/* headline - small */
--md-sys-typescale-headline-small-font-family-name: Roboto;
--md-sys-typescale-headline-small-font-family-style: Regular;
--md-sys-typescale-headline-small-font-weight: 400;
--md-sys-typescale-headline-small-font-size: 24px;
--md-sys-typescale-headline-small-line-height: 32px;
--md-sys-typescale-headline-small-letter-spacing: 0px;
/* title - large */
--md-sys-typescale-title-large-font-family-name: Roboto;
--md-sys-typescale-title-large-font-family-style: Regular;
--md-sys-typescale-title-large-font-weight: 400;
--md-sys-typescale-title-large-font-size: 22px;
--md-sys-typescale-title-large-line-height: 28px;
--md-sys-typescale-title-large-letter-spacing: 0px;
/* title - medium */
--md-sys-typescale-title-medium-font-family-name: Roboto;
--md-sys-typescale-title-medium-font-family-style: Medium;
--md-sys-typescale-title-medium-font-weight: 500;
--md-sys-typescale-title-medium-font-size: 16px;
--md-sys-typescale-title-medium-line-height: 24px;
--md-sys-typescale-title-medium-letter-spacing: 0.15px;
/* title - small */
--md-sys-typescale-title-small-font-family-name: Roboto;
--md-sys-typescale-title-small-font-family-style: Medium;
--md-sys-typescale-title-small-font-weight: 500;
--md-sys-typescale-title-small-font-size: 14px;
--md-sys-typescale-title-small-line-height: 20px;
--md-sys-typescale-title-small-letter-spacing: 0.1px;
/* body - large */
--md-sys-typescale-body-large-font-family-name: Roboto;
--md-sys-typescale-body-large-font-family-style: Regular;
--md-sys-typescale-body-large-font-weight: 400;
--md-sys-typescale-body-large-font-size: 16px;
--md-sys-typescale-body-large-line-height: 24px;
--md-sys-typescale-body-large-letter-spacing: 0.5px;
/* body - medium */
--md-sys-typescale-body-medium-font-family-name: Roboto;
--md-sys-typescale-body-medium-font-family-style: Regular;
--md-sys-typescale-body-medium-font-weight: 400;
--md-sys-typescale-body-medium-font-size: 14px;
--md-sys-typescale-body-medium-line-height: 20px;
--md-sys-typescale-body-medium-letter-spacing: 0.25px;
/* body - small */
--md-sys-typescale-body-small-font-family-name: Roboto;
--md-sys-typescale-body-small-font-family-style: Regular;
--md-sys-typescale-body-small-font-weight: 400;
--md-sys-typescale-body-small-font-size: 12px;
--md-sys-typescale-body-small-line-height: 16px;
--md-sys-typescale-body-small-letter-spacing: 0.4px;
/* label - large */
--md-sys-typescale-label-large-font-family-name: Roboto;
--md-sys-typescale-label-large-font-family-style: Medium;
--md-sys-typescale-label-large-font-weight: 500;
--md-sys-typescale-label-large-font-size: 14px;
--md-sys-typescale-label-large-line-height: 20px;
--md-sys-typescale-label-large-letter-spacing: 0.1px;
/* label - medium */
--md-sys-typescale-label-medium-font-family-name: Roboto;
--md-sys-typescale-label-medium-font-family-style: Medium;
--md-sys-typescale-label-medium-font-weight: 500;
--md-sys-typescale-label-medium-font-size: 12px;
--md-sys-typescale-label-medium-line-height: 16px;
--md-sys-typescale-label-medium-letter-spacing: 0.5px;
/* label - small */
--md-sys-typescale-label-small-font-family-name: Roboto;
--md-sys-typescale-label-small-font-family-style: Medium;
--md-sys-typescale-label-small-font-weight: 500;
--md-sys-typescale-label-small-font-size: 11px;
--md-sys-typescale-label-small-line-height: 16px;
--md-sys-typescale-label-small-letter-spacing: 0.5px;
/* shape - extra large top rounding */
--md-sys-shape-extra-large-top-rounding: 28px 28px 0 0;
/* shape - extra large rounding */
--md-sys-shape-extra-large-rounding: 28px;
/* shape - large top rounding */
--md-sys-shape-large-top-rounding: 16px 16px 0 0;
/* shape - large end rounding */
--md-sys-shape-large-end-rounding: 0 16px 16px 0;
/* shape - large start rounding */
--md-sys-shape-large-start-rounding: 16px 0 0 16px;
/* shape - large rounding */
--md-sys-shape-large-rounding: 16px;
/* shape - medium rounding */
--md-sys-shape-medium-rounding: 12px;
/* shape - small rounding */
--md-sys-shape-small-rounding: 8px;
/* shape - extra small top rounding */
--md-sys-shape-extra-small-top-rounding: 4px 4px 0 0;
/* shape - extra small rounding */
--md-sys-shape-extra-small-rounding: 4px;
}
.primary {
background-color: var(--md-sys-color-primary);
}
.primary-text {
color: var(--md-sys-color-primary);
}
.on-primary {
background-color: var(--md-sys-color-on-primary);
}
.on-primary-text {
color: var(--md-sys-color-on-primary);
}
.primary-container {
background-color: var(--md-sys-color-primary-container);
}
.primary-container-text {
color: var(--md-sys-color-primary-container);
}
.on-primary-container {
background-color: var(--md-sys-color-on-primary-container);
}
.on-primary-container-text {
color: var(--md-sys-color-on-primary-container);
}
.primary-fixed {
background-color: var(--md-sys-color-primary-fixed);
}
.primary-fixed-text {
color: var(--md-sys-color-primary-fixed);
}
.on-primary-fixed {
background-color: var(--md-sys-color-on-primary-fixed);
}
.on-primary-fixed-text {
color: var(--md-sys-color-on-primary-fixed);
}
.primary-fixed-dim {
background-color: var(--md-sys-color-primary-fixed-dim);
}
.primary-fixed-dim-text {
color: var(--md-sys-color-primary-fixed-dim);
}
.on-primary-fixed-variant {
background-color: var(--md-sys-color-on-primary-fixed-variant);
}
.on-primary-fixed-variant-text {
color: var(--md-sys-color-on-primary-fixed-variant);
}
.secondary {
background-color: var(--md-sys-color-secondary);
}
.secondary-text {
color: var(--md-sys-color-secondary);
}
.on-secondary {
background-color: var(--md-sys-color-on-secondary);
}
.on-secondary-text {
color: var(--md-sys-color-on-secondary);
}
.secondary-container {
background-color: var(--md-sys-color-secondary-container);
}
.secondary-container-text {
color: var(--md-sys-color-secondary-container);
}
.on-secondary-container {
background-color: var(--md-sys-color-on-secondary-container);
}
.on-secondary-container-text {
color: var(--md-sys-color-on-secondary-container);
}
.secondary-fixed {
background-color: var(--md-sys-color-secondary-fixed);
}
.secondary-fixed-text {
color: var(--md-sys-color-secondary-fixed);
}
.on-secondary-fixed {
background-color: var(--md-sys-color-on-secondary-fixed);
}
.on-secondary-fixed-text {
color: var(--md-sys-color-on-secondary-fixed);
}
.secondary-fixed-dim {
background-color: var(--md-sys-color-secondary-fixed-dim);
}
.secondary-fixed-dim-text {
color: var(--md-sys-color-secondary-fixed-dim);
}
.on-secondary-fixed-variant {
background-color: var(--md-sys-color-on-secondary-fixed-variant);
}
.on-secondary-fixed-variant-text {
color: var(--md-sys-color-on-secondary-fixed-variant);
}
.tertiary {
background-color: var(--md-sys-color-tertiary);
}
.tertiary-text {
color: var(--md-sys-color-tertiary);
}
.on-tertiary {
background-color: var(--md-sys-color-on-tertiary);
}
.on-tertiary-text {
color: var(--md-sys-color-on-tertiary);
}
.tertiary-container {
background-color: var(--md-sys-color-tertiary-container);
}
.tertiary-container-text {
color: var(--md-sys-color-tertiary-container);
}
.on-tertiary-container {
background-color: var(--md-sys-color-on-tertiary-container);
}
.on-tertiary-container-text {
color: var(--md-sys-color-on-tertiary-container);
}
.tertiary-fixed {
background-color: var(--md-sys-color-tertiary-fixed);
}
.tertiary-fixed-text {
color: var(--md-sys-color-tertiary-fixed);
}
.on-tertiary-fixed {
background-color: var(--md-sys-color-on-tertiary-fixed);
}
.on-tertiary-fixed-text {
color: var(--md-sys-color-on-tertiary-fixed);
}
.tertiary-fixed-dim {
background-color: var(--md-sys-color-tertiary-fixed-dim);
}
.tertiary-fixed-dim-text {
color: var(--md-sys-color-tertiary-fixed-dim);
}
.on-tertiary-fixed-variant {
background-color: var(--md-sys-color-on-tertiary-fixed-variant);
}
.on-tertiary-fixed-variant-text {
color: var(--md-sys-color-on-tertiary-fixed-variant);
}
.error {
background-color: var(--md-sys-color-error);
}
.error-text {
color: var(--md-sys-color-error);
}
.error-container {
background-color: var(--md-sys-color-error-container);
}
.error-container-text {
color: var(--md-sys-color-error-container);
}
.on-error {
background-color: var(--md-sys-color-on-error);
}
.on-error-text {
color: var(--md-sys-color-on-error);
}
.on-error-container {
background-color: var(--md-sys-color-on-error-container);
}
.on-error-container-text {
color: var(--md-sys-color-on-error-container);
}
.background {
background-color: var(--md-sys-color-background);
}
.background-text {
color: var(--md-sys-color-background);
}
.on-background {
background-color: var(--md-sys-color-on-background);
}
.on-background-text {
color: var(--md-sys-color-on-background);
}
.outline {
background-color: var(--md-sys-color-outline);
}
.outline-text {
color: var(--md-sys-color-outline);
}
.inverse-on-surface {
background-color: var(--md-sys-color-inverse-on-surface);
}
.inverse-on-surface-text {
color: var(--md-sys-color-inverse-on-surface);
}
.inverse-surface {
background-color: var(--md-sys-color-inverse-surface);
}
.inverse-surface-text {
color: var(--md-sys-color-inverse-surface);
}
.inverse-primary {
background-color: var(--md-sys-color-inverse-primary);
}
.inverse-primary-text {
color: var(--md-sys-color-inverse-primary);
}
.shadow {
background-color: var(--md-sys-color-shadow);
}
.shadow-text {
color: var(--md-sys-color-shadow);
}
.surface-tint {
background-color: var(--md-sys-color-surface-tint);
}
.surface-tint-text {
color: var(--md-sys-color-surface-tint);
}
.outline-variant {
background-color: var(--md-sys-color-outline-variant);
}
.outline-variant-text {
color: var(--md-sys-color-outline-variant);
}
.scrim {
background-color: var(--md-sys-color-scrim);
}
.scrim-text {
color: var(--md-sys-color-scrim);
}
.surface {
background-color: var(--md-sys-color-surface);
}
.surface-text {
color: var(--md-sys-color-surface);
}
.on-surface {
background-color: var(--md-sys-color-on-surface);
}
.on-surface-text {
color: var(--md-sys-color-on-surface);
}
.surface-variant {
background-color: var(--md-sys-color-surface-variant);
}
.surface-variant-text {
color: var(--md-sys-color-surface-variant);
}
.on-surface-variant {
background-color: var(--md-sys-color-on-surface-variant);
}
.on-surface-variant-text {
color: var(--md-sys-color-on-surface-variant);
}
.surface-container-highest {
background-color: var(--md-sys-color-surface-container-highest);
}
.surface-container-highest-text {
color: var(--md-sys-color-surface-container-highest);
}
.surface-container-high {
background-color: var(--md-sys-color-surface-container-high);
}
.surface-container-high-text {
color: var(--md-sys-color-surface-container-high);
}
.surface-container {
background-color: var(--md-sys-color-surface-container);
}
.surface-container-text {
color: var(--md-sys-color-surface-container);
}
.surface-container-low {
background-color: var(--md-sys-color-surface-container-low);
}
.surface-container-low-text {
color: var(--md-sys-color-surface-container-low);
}
.surface-container-lowest {
background-color: var(--md-sys-color-surface-container-lowest);
}
.surface-container-lowest-text {
color: var(--md-sys-color-surface-container-lowest);
}
.surface-dim {
background-color: var(--md-sys-color-surface-dim);
}
.surface-dim-text {
color: var(--md-sys-color-surface-dim);
}
.surface-bright {
background-color: var(--md-sys-color-surface-bright);
}
.surface-bright-text {
color: var(--md-sys-color-surface-bright);
}
.display-hero {
font-family: var(--md-sys-typescale-display-hero-font-family-name);
font-style: var(--md-sys-typescale-display-hero-font-family-style);
font-weight: var(--md-sys-typescale-display-hero-font-weight);
font-size: var(--md-sys-typescale-display-hero-font-size);
letter-spacing: var(--md-sys-typescale-display-hero-letter-spacing);
line-height: var(--md-sys-typescale-display-hero-line-height);
text-transform: var(--md-sys-typescale-display-hero-text-transform);
text-decoration: var(--md-sys-typescale-display-hero-text-decoration);
}
.display-xl {
font-family: var(--md-sys-typescale-display-xl-font-family-name);
font-style: var(--md-sys-typescale-display-xl-font-family-style);
font-weight: var(--md-sys-typescale-display-xl-font-weight);
font-size: var(--md-sys-typescale-display-xl-font-size);
letter-spacing: var(--md-sys-typescale-display-xl-letter-spacing);
line-height: var(--md-sys-typescale-display-xl-line-height);
text-transform: var(--md-sys-typescale-display-xl-text-transform);
text-decoration: var(--md-sys-typescale-display-xl-text-decoration);
}
.display-large {
font-family: var(--md-sys-typescale-display-large-font-family-name);
font-style: var(--md-sys-typescale-display-large-font-family-style);
font-weight: var(--md-sys-typescale-display-large-font-weight);
font-size: var(--md-sys-typescale-display-large-font-size);
letter-spacing: var(--md-sys-typescale-display-large-letter-spacing);
line-height: var(--md-sys-typescale-display-large-line-height);
text-transform: var(--md-sys-typescale-display-large-text-transform);
text-decoration: var(--md-sys-typescale-display-large-text-decoration);
}
.display-medium {
font-family: var(--md-sys-typescale-display-medium-font-family-name);
font-style: var(--md-sys-typescale-display-medium-font-family-style);
font-weight: var(--md-sys-typescale-display-medium-font-weight);
font-size: var(--md-sys-typescale-display-medium-font-size);
letter-spacing: var(--md-sys-typescale-display-medium-letter-spacing);
line-height: var(--md-sys-typescale-display-medium-line-height);
text-transform: var(--md-sys-typescale-display-medium-text-transform);
text-decoration: var(--md-sys-typescale-display-medium-text-decoration);
}
.display-small {
font-family: var(--md-sys-typescale-display-small-font-family-name);
font-style: var(--md-sys-typescale-display-small-font-family-style);
font-weight: var(--md-sys-typescale-display-small-font-weight);
font-size: var(--md-sys-typescale-display-small-font-size);
letter-spacing: var(--md-sys-typescale-display-small-letter-spacing);
line-height: var(--md-sys-typescale-display-small-line-height);
text-transform: var(--md-sys-typescale-display-small-text-transform);
text-decoration: var(--md-sys-typescale-display-small-text-decoration);
}
.headline-large {
font-family: var(--md-sys-typescale-headline-large-font-family-name);
font-style: var(--md-sys-typescale-headline-large-font-family-style);
font-weight: var(--md-sys-typescale-headline-large-font-weight);
font-size: var(--md-sys-typescale-headline-large-font-size);
letter-spacing: var(--md-sys-typescale-headline-large-letter-spacing);
line-height: var(--md-sys-typescale-headline-large-line-height);
text-transform: var(--md-sys-typescale-headline-large-text-transform);
text-decoration: var(--md-sys-typescale-headline-large-text-decoration);
}
.headline-medium {
font-family: var(--md-sys-typescale-headline-medium-font-family-name);
font-style: var(--md-sys-typescale-headline-medium-font-family-style);
font-weight: var(--md-sys-typescale-headline-medium-font-weight);
font-size: var(--md-sys-typescale-headline-medium-font-size);
letter-spacing: var(--md-sys-typescale-headline-medium-letter-spacing);
line-height: var(--md-sys-typescale-headline-medium-line-height);
text-transform: var(--md-sys-typescale-headline-medium-text-transform);
text-decoration: var(--md-sys-typescale-headline-medium-text-decoration);
}
.headline-small {
font-family: var(--md-sys-typescale-headline-small-font-family-name);
font-style: var(--md-sys-typescale-headline-small-font-family-style);
font-weight: var(--md-sys-typescale-headline-small-font-weight);
font-size: var(--md-sys-typescale-headline-small-font-size);
letter-spacing: var(--md-sys-typescale-headline-small-letter-spacing);
line-height: var(--md-sys-typescale-headline-small-line-height);
text-transform: var(--md-sys-typescale-headline-small-text-transform);
text-decoration: var(--md-sys-typescale-headline-small-text-decoration);
}
.body-large {
font-family: var(--md-sys-typescale-body-large-font-family-name);
font-style: var(--md-sys-typescale-body-large-font-family-style);
font-weight: var(--md-sys-typescale-body-large-font-weight);
font-size: var(--md-sys-typescale-body-large-font-size);
letter-spacing: var(--md-sys-typescale-body-large-letter-spacing);
line-height: var(--md-sys-typescale-body-large-line-height);
text-transform: var(--md-sys-typescale-body-large-text-transform);
text-decoration: var(--md-sys-typescale-body-large-text-decoration);
}
.body-medium {
font-family: var(--md-sys-typescale-body-medium-font-family-name);
font-style: var(--md-sys-typescale-body-medium-font-family-style);
font-weight: var(--md-sys-typescale-body-medium-font-weight);
font-size: var(--md-sys-typescale-body-medium-font-size);
letter-spacing: var(--md-sys-typescale-body-medium-letter-spacing);
line-height: var(--md-sys-typescale-body-medium-line-height);
text-transform: var(--md-sys-typescale-body-medium-text-transform);
text-decoration: var(--md-sys-typescale-body-medium-text-decoration);
}
.body-small {
font-family: var(--md-sys-typescale-body-small-font-family-name);
font-style: var(--md-sys-typescale-body-small-font-family-style);
font-weight: var(--md-sys-typescale-body-small-font-weight);
font-size: var(--md-sys-typescale-body-small-font-size);
letter-spacing: var(--md-sys-typescale-body-small-letter-spacing);
line-height: var(--md-sys-typescale-body-small-line-height);
text-transform: var(--md-sys-typescale-body-small-text-transform);
text-decoration: var(--md-sys-typescale-body-small-text-decoration);
}
.label-large {
font-family: var(--md-sys-typescale-label-large-font-family-name);
font-style: var(--md-sys-typescale-label-large-font-family-style);
font-weight: var(--md-sys-typescale-label-large-font-weight);
font-size: var(--md-sys-typescale-label-large-font-size);
letter-spacing: var(--md-sys-typescale-label-large-letter-spacing);
line-height: var(--md-sys-typescale-label-large-line-height);
text-transform: var(--md-sys-typescale-label-large-text-transform);
text-decoration: var(--md-sys-typescale-label-large-text-decoration);
}
.label-medium {
font-family: var(--md-sys-typescale-label-medium-font-family-name);
font-style: var(--md-sys-typescale-label-medium-font-family-style);
font-weight: var(--md-sys-typescale-label-medium-font-weight);
font-size: var(--md-sys-typescale-label-medium-font-size);
letter-spacing: var(--md-sys-typescale-label-medium-letter-spacing);
line-height: var(--md-sys-typescale-label-medium-line-height);
text-transform: var(--md-sys-typescale-label-medium-text-transform);
text-decoration: var(--md-sys-typescale-label-medium-text-decoration);
}
.label-small {
font-family: var(--md-sys-typescale-label-small-font-family-name);
font-style: var(--md-sys-typescale-label-small-font-family-style);
font-weight: var(--md-sys-typescale-label-small-font-weight);
font-size: var(--md-sys-typescale-label-small-font-size);
letter-spacing: var(--md-sys-typescale-label-small-letter-spacing);
line-height: var(--md-sys-typescale-label-small-line-height);
text-transform: var(--md-sys-typescale-label-small-text-transform);
text-decoration: var(--md-sys-typescale-label-small-text-decoration);
}
.title-large {
font-family: var(--md-sys-typescale-title-large-font-family-name);
font-style: var(--md-sys-typescale-title-large-font-family-style);
font-weight: var(--md-sys-typescale-title-large-font-weight);
font-size: var(--md-sys-typescale-title-large-font-size);
letter-spacing: var(--md-sys-typescale-title-large-letter-spacing);
line-height: var(--md-sys-typescale-title-large-line-height);
text-transform: var(--md-sys-typescale-title-large-text-transform);
text-decoration: var(--md-sys-typescale-title-large-text-decoration);
}
.title-medium {
font-family: var(--md-sys-typescale-title-medium-font-family-name);
font-style: var(--md-sys-typescale-title-medium-font-family-style);
font-weight: var(--md-sys-typescale-title-medium-font-weight);
font-size: var(--md-sys-typescale-title-medium-font-size);
letter-spacing: var(--md-sys-typescale-title-medium-letter-spacing);
line-height: var(--md-sys-typescale-title-medium-line-height);
text-transform: var(--md-sys-typescale-title-medium-text-transform);
text-decoration: var(--md-sys-typescale-title-medium-text-decoration);
}
.title-small {
font-family: var(--md-sys-typescale-title-small-font-family-name);
font-style: var(--md-sys-typescale-title-small-font-family-style);
font-weight: var(--md-sys-typescale-title-small-font-weight);
font-size: var(--md-sys-typescale-title-small-font-size);
letter-spacing: var(--md-sys-typescale-title-small-letter-spacing);
line-height: var(--md-sys-typescale-title-small-line-height);
text-transform: var(--md-sys-typescale-title-small-text-transform);
text-decoration: var(--md-sys-typescale-title-small-text-decoration);
}
html { html {
font-family: Roboto, serif; font-family: Roboto, serif;
color: var(--md-sys-color-on-surface); color: var(--md-sys-color-on-surface);
background-color: var(--md-sys-color-surface-container); background-color: var(--md-sys-color-surface-container);
} }
.m3 {
user-select: none;
}
.m3.m3-wrapper { .m3.m3-wrapper {
position: relative; position: relative;
display: block; display: block;

File diff suppressed because one or more lines are too long

View File

@ -19,9 +19,9 @@
@import "input-styles/checkbox" @import "input-styles/checkbox"
@import "input-styles/text-field" @import "input-styles/text-field"
@import "./themes/tokens.css" @import "./themes/tokens"
@import "./themes/colors.module.css" @import "./themes/colors.module"
@import "./themes/typography.module.css" @import "./themes/typography.module"
@import "./themes/theme.dark.css" (prefers-color-scheme: dark) @import "./themes/theme.dark.css" (prefers-color-scheme: dark)
@import "./themes/theme.light.css" (prefers-color-scheme: light) @import "./themes/theme.light.css" (prefers-color-scheme: light)
@ -30,9 +30,6 @@ html
color: var(--md-sys-color-on-surface) color: var(--md-sys-color-on-surface)
background-color: var(--md-sys-color-surface-container) background-color: var(--md-sys-color-surface-container)
.m3
user-select: none
.m3.m3-wrapper .m3.m3-wrapper
position: relative position: relative
display: block display: block

View File

@ -1,20 +1,18 @@
div.m3.m3-checkbox-container div.m3.m3-checkbox-container
@include m3-label-mixin @include m3-checkbox-container-mixin
width: 18px
height: 18px
& > span.m3.m3-checkbox-state-layer & > span.m3.m3-checkbox-state-layer
@include m3-state-layer-mixin @include m3-state-layer-mixin
span.m3.m3-checkbox-ripple-layer & > span.m3.m3-checkbox-ripple-layer
z-index: 20 z-index: 20
width: 2.5rem width: 2.5rem
height: 2.5rem height: 2.5rem
contain: content contain: content
border-radius: 50% border-radius: 50%
position: absolute position: absolute
input[type="checkbox"].m3.m3-checkbox input[type="checkbox"].m3.m3-checkbox
margin: 0
z-index: 10 z-index: 10
display: flex display: flex
width: 1.125rem width: 1.125rem
@ -28,6 +26,7 @@ input[type="checkbox"].m3.m3-checkbox
transition: background-color .2s cubic-bezier(0.2, 0, 0, 1) transition: background-color .2s cubic-bezier(0.2, 0, 0, 1)
& ~ span.m3-checkbox-state & ~ span.m3-checkbox-state
position: absolute
color: var(--md-sys-color-on-surface-variant) color: var(--md-sys-color-on-surface-variant)
transition: color .2s cubic-bezier(0.2, 0, 0, 1) transition: color .2s cubic-bezier(0.2, 0, 0, 1)
@ -55,13 +54,13 @@ input[type="checkbox"].m3.m3-checkbox
opacity: 38% opacity: 38%
& ~ span.m3-checkbox-state & ~ span.m3-checkbox-state
pointer-events: none
z-index: 10 z-index: 10
display: flex display: flex
font-size: 24px font-size: 24px
font-weight: 700 font-weight: 700
line-height: 24px line-height: 24px
align-items: center align-items: center
pointer-events: none
justify-content: center justify-content: center
font-family: Material-Symbols-Outlined-Regular, sans-serif font-family: Material-Symbols-Outlined-Regular, sans-serif
font-variation-settings: 'FILL' 1, 'wght' 300, 'GRAD' 0, 'opsz' 24 font-variation-settings: 'FILL' 1, 'wght' 300, 'GRAD' 0, 'opsz' 24
@ -83,6 +82,7 @@ input[type="checkbox"].m3.m3-checkbox
&:is(:user-invalid:is(:active, :indeterminate:active), .m3.m3-error:active) ~ span.m3.m3-checkbox-state-layer &:is(:user-invalid:is(:active, :indeterminate:active), .m3.m3-error:active) ~ span.m3.m3-checkbox-state-layer
background-color: color-mix(in srgb, var(--md-sys-color-error) 12%, transparent) background-color: color-mix(in srgb, var(--md-sys-color-error) 12%, transparent)
& ~ span.m3-ripple-domain > .m3.ripple & ~ span.m3-ripple-domain > .m3.ripple
background-color: color-mix(in srgb, var(--md-sys-color-error) 20%, transparent) background-color: color-mix(in srgb, var(--md-sys-color-error) 20%, transparent)
@ -91,6 +91,7 @@ input[type="checkbox"].m3.m3-checkbox
&:is(:checked:active, :indeterminate:active) ~ span.m3.m3-checkbox-state-layer &:is(:checked:active, :indeterminate:active) ~ span.m3.m3-checkbox-state-layer
background-color: color-mix(in srgb, var(--md-sys-color-primary) 12%, transparent) background-color: color-mix(in srgb, var(--md-sys-color-primary) 12%, transparent)
& ~ span.m3-ripple-domain > .m3.ripple & ~ span.m3-ripple-domain > .m3.ripple
background-color: color-mix(in srgb, var(--md-sys-color-on-surface) 20%, transparent) background-color: color-mix(in srgb, var(--md-sys-color-on-surface) 20%, transparent)
@ -100,6 +101,7 @@ input[type="checkbox"].m3.m3-checkbox
&:active ~ span.m3.m3-checkbox-state-layer &:active ~ span.m3.m3-checkbox-state-layer
background-color: color-mix(in srgb, var(--md-sys-color-on-surface) 12%, transparent) background-color: color-mix(in srgb, var(--md-sys-color-on-surface) 12%, transparent)
& ~ span.m3-ripple-domain > .m3.ripple & ~ span.m3-ripple-domain > .m3.ripple
background-color: color-mix(in srgb, var(--md-sys-color-primary) 20%, transparent) background-color: color-mix(in srgb, var(--md-sys-color-primary) 20%, transparent)

View File

@ -5,12 +5,16 @@ div.m3.m3-radio-container
display: inline-flex display: inline-flex
justify-content: center justify-content: center
& + label.m3.m3-radio-label
margin-inline: 3px
& > span.m3-checkbox-ripple-layer, span.m3.m3-radio-state-layer & > span.m3-checkbox-ripple-layer, span.m3.m3-radio-state-layer
z-index: 5 z-index: 5
width: 40px
height: 40px
aspect-ratio: 1
& > span.m3.m3-radio-state-layer & > span.m3.m3-radio-state-layer
width: 40px
aspect-ratio: 1
border-radius: 50% border-radius: 50%
position: absolute position: absolute
pointer-events: none pointer-events: none

View File

@ -3,26 +3,30 @@ div.m3.m3-slider-container
display: flex display: flex
align-items: center align-items: center
& > datalist
display: none
input[type="range"].m3.m3-slider input[type="range"].m3.m3-slider
margin: 0 margin: 0
height: 4px
appearance: none appearance: none
overflow: visible
border-radius: 2px border-radius: 2px
margin-inline: 10px margin-inline: 8px
background-color: var(--md-sys-color-surface-container-highest) background: linear-gradient(to right, var(--md-sys-color-primary) 0%, var(--md-sys-color-surface-container-highest) 0%)
&::-webkit-slider-container &::-webkit-slider-container
margin-inline: -8px appearance: none
box-shadow: none
border-radius: 2px
min-block-size: 4px
height: 4px !important
&::-webkit-slider-runnable-track
height: 4px
&::-webkit-slider-thumb &::-webkit-slider-thumb
@include elevation-1(false) @include elevation-1(false)
&::after
width: 40px
aspect-ratio: 1
background-color: transparent
&:hover &:hover
outline: 10px solid color-mix(in srgb, var(--md-sys-color-primary) 8%, transparent) outline: 10px solid color-mix(in srgb, var(--md-sys-color-primary) 8%, transparent)
@ -32,8 +36,8 @@ input[type="range"].m3.m3-slider
width: 20px width: 20px
aspect-ratio: 1 aspect-ratio: 1
appearance: none appearance: none
overflow: visible
border-radius: 50% border-radius: 50%
margin-top: -8px
box-sizing: border-box box-sizing: border-box
outline: 10px solid transparent outline: 10px solid transparent
background: var(--md-sys-color-primary) background: var(--md-sys-color-primary)

View File

@ -1,30 +1,29 @@
div.m3.m3-switch div.m3.m3-switch
margin: 4px
gap: 20px gap: 20px
box-sizing: content-box margin: 4px
height: 32px
display: flex display: flex
align-items: center align-items: center
justify-content: center justify-content: left
width: 52px box-sizing: content-box
height: 32px
& > svg & > svg
overflow: visible
transition: .2s cubic-bezier(0.175, 0.885, 0.32, 1.275)
width: 52px width: 52px
height: 32px height: 32px
overflow: visible
transition: .2s cubic-bezier(0.175, 0.885, 0.32, 1.275)
& > g & > g
transform: translate(11.5%, 81%) transform: translate(11.5%, 81%)
transition: .2s cubic-bezier(0.175, 0.885, 0.32, 1.275) transition: .2s cubic-bezier(0.175, 0.885, 0.32, 1.275)
& > text & > text
font-family: Material-Symbols-Outlined-Regular
font-size: 20px font-size: 20px
font-family: Material-Symbols-Outlined-Regular
& > circle.m3.m3-switch-handler-state-layer, & > circle.m3.m3-switch-handler & > circle.m3.m3-switch-handler-state-layer, & > circle.m3.m3-switch-handler
transition: .2s cubic-bezier(0.175, 0.885, 0.32, 1.275)
cy: 50% cy: 50%
cx: 16px cx: 16px
transition: .2s cubic-bezier(0.175, 0.885, 0.32, 1.275)
& > circle.m3.m3-switch-handler-state-layer & > circle.m3.m3-switch-handler-state-layer
r: 20px r: 20px
@ -42,13 +41,13 @@ div.m3.m3-switch
height: 30px height: 30px
& > input.m3 & > input.m3
cursor: pointer
appearance: none
opacity: 0 !important
margin: 0 margin: 0
width: 52px width: 52px
height: 32px height: 32px
cursor: pointer
appearance: none
position: absolute position: absolute
opacity: 0 !important
&:disabled &:disabled
cursor: not-allowed cursor: not-allowed
@ -93,8 +92,8 @@ div.m3.m3-switch
r: 14px r: 14px
&:not(:checked):disabled + svg > circle.m3.m3-switch-handler &:not(:checked):disabled + svg > circle.m3.m3-switch-handler
fill: var(--md-sys-color-on-surface)
fill-opacity: 38% fill-opacity: 38%
fill: var(--md-sys-color-on-surface)
&:hover:not(:disabled) &:hover:not(:disabled)
&:checked + svg &:checked + svg
@ -102,25 +101,25 @@ div.m3.m3-switch
fill: var(--md-sys-color-primary-container) fill: var(--md-sys-color-primary-container)
& > circle.m3.m3-switch-handler-state-layer & > circle.m3.m3-switch-handler-state-layer
fill: var(--md-sys-color-primary)
fill-opacity: 8% fill-opacity: 8%
fill: var(--md-sys-color-primary)
&:not(:checked) + svg &:not(:checked) + svg
& > circle.m3.m3-switch-handler & > circle.m3.m3-switch-handler
fill: var(--md-sys-color-on-surface-variant) fill: var(--md-sys-color-on-surface-variant)
& > circle.m3.m3-switch-handler-state-layer & > circle.m3.m3-switch-handler-state-layer
fill: var(--md-sys-color-on-surface)
fill-opacity: 8% fill-opacity: 8%
fill: var(--md-sys-color-on-surface)
&:active:not(:disabled) &:active:not(:disabled)
&:checked + svg > circle.m3.m3-switch-handler-state-layer &:checked + svg > circle.m3.m3-switch-handler-state-layer
fill: var(--md-sys-color-primary)
fill-opacity: 12% fill-opacity: 12%
fill: var(--md-sys-color-primary)
&:not(:checked) + svg > circle.m3.m3-switch-handler-state-layer &:not(:checked) + svg > circle.m3.m3-switch-handler-state-layer
fill: var(--md-sys-color-on-surface)
fill-opacity: 12% fill-opacity: 12%
fill: var(--md-sys-color-on-surface)
&:is(:checked, :checked:disabled) + svg > rect.m3.m3-switch-track &:is(:checked, :checked:disabled) + svg > rect.m3.m3-switch-track
rx: 16px rx: 16px
@ -137,8 +136,8 @@ div.m3.m3-switch
fill: var(--md-sys-color-surface-container-highest) fill: var(--md-sys-color-surface-container-highest)
&:checked + svg > rect.m3.m3-switch-track &:checked + svg > rect.m3.m3-switch-track
stroke: var(--md-sys-color-primary)
fill: var(--md-sys-color-primary) fill: var(--md-sys-color-primary)
stroke: var(--md-sys-color-primary)
&:disabled + svg &:disabled + svg
& > g > text.m3 & > g > text.m3
@ -154,5 +153,5 @@ div.m3.m3-switch
fill: color-mix(in srgb, var(--md-sys-color-on-surface) 38%, transparent) fill: color-mix(in srgb, var(--md-sys-color-on-surface) 38%, transparent)
& > rect.m3.m3-switch-track & > rect.m3.m3-switch-track
stroke: color-mix(in srgb, var(--md-sys-color-on-surface) 0%, transparent)
fill: color-mix(in srgb, var(--md-sys-color-on-surface) 12%, transparent) fill: color-mix(in srgb, var(--md-sys-color-on-surface) 12%, transparent)
stroke: color-mix(in srgb, var(--md-sys-color-on-surface) 0%, transparent)

View File

@ -1,15 +1,17 @@
@mixin m3-label-mixin @mixin m3-checkbox-container-mixin
gap: 16px
height: 40px
display: flex display: flex
aspect-ratio: 1
position: relative position: relative
align-items: center align-items: center
justify-content: center justify-content: center
aspect-ratio: 1
@mixin m3-state-layer-mixin @mixin m3-state-layer-mixin
position: absolute width: 40px
width: 2.5rem aspect-ratio: 1
aspect-ratio: inherit
border-radius: 50% border-radius: 50%
position: absolute
transition: background-color .2s cubic-bezier(0.2, 0, 0, 1) transition: background-color .2s cubic-bezier(0.2, 0, 0, 1)
@mixin m3-fab-default($b-radius, $width, $height : $width, $padding : 0) @mixin m3-fab-default($b-radius, $width, $height : $width, $padding : 0)