experimental #3

Merged
doryan merged 2 commits from experimental into main 2024-02-18 21:55:51 +03: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)