Compare commits

...

9 Commits

Author SHA1 Message Date
doryan04 74b97fa4a9 ADDED: Color variables for convenient codding styles 2024-02-26 23:17:05 +04:00
doryan04 33bd4f57a6 ADDED: slider label but it's not done 2024-02-25 19:52:36 +04:00
doryan04 1410861afb FIXED: Normalized colors in icon-buttons, typography color in night-mode 2024-02-25 00:37:57 +04:00
doryan04 91486200f7 ADDED: Mixins for icon buttons, but it's not completed feature
FIXED: Styles for segmented-button
2024-02-24 23:58:23 +04:00
doryan04 0219596ed1 ADDED: Now you can turn on or off Ripple effect on buttons (not for icon buttons, soon it's fixed), density for segmented-buttons, typography mixins, and etc.
CHANGED: For optimizing write styles added a few mixins
FIXED: Bug with width in segmented-buttons
2024-02-24 00:15:35 +04:00
doryan04 cd0e3e3f85 ADDED: Now you can turn on or off Ripple effect on buttons (not for icon buttons, soon it's fixed), density for segmented-buttons, typography mixins, and etc.
CHANGED: For optimizing write styles added a few mixins
FIXED: Bug with width in segmented-buttons
2024-02-23 23:55:21 +04:00
doryan 40a4d2277e FIXED: Segmented-buttons sizes fixed, typography is done 2024-02-22 12:22:32 +04:00
doryan04 b421ac7e4c TODO: fix segmented and default buttons styles for firefox 2024-02-21 23:21:52 +04:00
doryan04 cb04ae521a ADDED: Mozilla styles for slider
FIXED: Some typography issues and a ripple effect bug that appears in Firefox
And some changes, about which I forget
2024-02-19 23:43:39 +04:00
76 changed files with 1604 additions and 4348 deletions

View File

@ -1,6 +1,22 @@
<component name="InspectionProjectProfileManager"> <component name="InspectionProjectProfileManager">
<profile version="1.0"> <profile version="1.0">
<option name="myName" value="Project Default" /> <option name="myName" value="Project Default" />
<inspection_tool class="CssUnknownProperty" enabled="true" level="WARNING" enabled_by_default="true">
<option name="myCustomPropertiesEnabled" value="true" />
<option name="myIgnoreVendorSpecificProperties" value="false" />
<option name="myCustomPropertiesList">
<value>
<list size="6">
<item index="0" class="java.lang.String" itemvalue="cy" />
<item index="1" class="java.lang.String" itemvalue="cx" />
<item index="2" class="java.lang.String" itemvalue="r" />
<item index="3" class="java.lang.String" itemvalue="rx" />
<item index="4" class="java.lang.String" itemvalue="x" />
<item index="5" class="java.lang.String" itemvalue="y" />
</list>
</value>
</option>
</inspection_tool>
<inspection_tool class="ES6PreferShortImport" enabled="false" level="WARNING" enabled_by_default="false" /> <inspection_tool class="ES6PreferShortImport" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="Eslint" enabled="true" level="WARNING" enabled_by_default="true" /> <inspection_tool class="Eslint" enabled="true" level="WARNING" enabled_by_default="true" />
</profile> </profile>

View File

@ -1,142 +0,0 @@
import React from 'react';
import { Badge } from '../../src/primitive-components/badge/badge';
import { Divider } from '../../src/primitive-components/divider/divider';
export default function Badges() {
return (
<div
className={'m3 m3-wrapper'}
style={{
display: 'flex',
flexDirection: 'column',
alignItems: 'center',
justifyContent: 'center',
}}
>
<h1> Badges </h1>
<div>
<div
style={{
display: 'flex',
flexDirection: 'column',
gap: '0.5em',
justifyContent: 'center',
alignItems: 'center',
}}
>
<div
style={{
width: '24px',
aspectRatio: 1,
display: 'flex',
justifyContent: 'center',
alignItems: 'center',
}}
>
<Badge />
</div>
<Divider />
<div
style={{
width: '24px',
aspectRatio: 1,
display: 'flex',
justifyContent: 'center',
alignItems: 'center',
}}
>
<Badge disableValue />
</div>
<Divider />
<div
style={{
width: '24px',
aspectRatio: 1,
display: 'flex',
justifyContent: 'center',
alignItems: 'center',
}}
>
<Badge disableValue>3487</Badge>
</div>
<Divider />
<div
style={{
width: '24px',
aspectRatio: 1,
display: 'flex',
justifyContent: 'center',
alignItems: 'center',
}}
>
<Badge>5</Badge>
</div>
<Divider />
<div
style={{
width: '24px',
aspectRatio: 1,
display: 'flex',
justifyContent: 'center',
alignItems: 'center',
}}
>
<Badge>32</Badge>
</div>
<Divider />
<div
style={{
width: '24px',
aspectRatio: 1,
display: 'flex',
justifyContent: 'center',
alignItems: 'center',
}}
>
<Badge>322342</Badge>
</div>
</div>
</div>
{/*<Divider orientation={"vertical"} variant={"full-width"}/>*/}
{/*<div>*/}
{/* <div style={{*/}
{/* display: "flex",*/}
{/* flexDirection: "column",*/}
{/* gap: "0.5em",*/}
{/* justifyContent: "center",*/}
{/* alignItems: "center"*/}
{/* }}>*/}
{/* <div style={{*/}
{/* width: "24px",*/}
{/* aspectRatio: 1,*/}
{/* display: "flex",*/}
{/* justifyContent: "center",*/}
{/* alignItems: "center"*/}
{/* }}>*/}
{/* <Badge/>*/}
{/* </div>*/}
{/* <Divider variant={"inset"}/>*/}
{/* <div style={{*/}
{/* width: "24px",*/}
{/* aspectRatio: 1,*/}
{/* display: "flex",*/}
{/* justifyContent: "center",*/}
{/* alignItems: "center"*/}
{/* }}>*/}
{/* <Badge>5</Badge>*/}
{/* </div>*/}
{/* <Divider/>*/}
{/* <div style={{*/}
{/* width: "24px",*/}
{/* aspectRatio: 1,*/}
{/* display: "flex",*/}
{/* justifyContent: "center",*/}
{/* alignItems: "center"*/}
{/* }}>*/}
{/* <Badge>32</Badge>*/}
{/* </div>*/}
{/* </div>*/}
{/*</div>*/}
</div>
);
}

View File

@ -1,86 +0,0 @@
'use client';
import React, { useCallback, useState } from 'react';
import { Button } from '../../src/primitive-components/components';
export default function Buttons() {
const [state, setState] = useState(1);
const callback = useCallback(
() => setState(prevState => prevState + 1),
[state],
);
return (
<div
style={{
display: 'flex',
flexDirection: 'column',
alignItems: 'center',
justifyContent: 'center',
}}
>
<h1> Buttons </h1>
<div
style={{
display: 'flex',
flexDirection: 'row',
gap: '2em',
width: '100%',
height: '100%',
}}
>
<div>
<h2> Default buttons </h2>
<div
style={{
display: 'flex',
flexDirection: 'column',
width: '150px',
gap: '0.5em',
}}
>
<Button
centralRipple
onClick={callback}
variant={'filled'}
>
Label
</Button>
<Button variant={'outlined'}>Label</Button>
<Button variant={'tonal'}>Label</Button>
<Button variant={'elevated'}>Label</Button>
<Button variant={'text'}>Label</Button>
</div>
</div>
<div>
<h2> Buttons with icon </h2>
<div
style={{
display: 'flex',
flexDirection: 'column',
width: '150px',
gap: '0.5em',
}}
>
<Button icon={'add'} variant={'filled'}>
Label
</Button>
<Button icon={'add'} variant={'outlined'}>
Label
</Button>
<Button icon={'add'} variant={'tonal'}>
Label
</Button>
<Button icon={'add'} variant={'elevated'}>
Label
</Button>
<Button icon={'add'} variant={'text'}>
Label
</Button>
</div>
</div>
</div>
</div>
);
}

View File

@ -1,87 +0,0 @@
'use client';
import React from 'react';
import { Button, Checkbox } from '../../src/primitive-components/components';
export default function Checkboxes() {
return (
<div className={'m3 m3-wrapper'}>
<h1> Checkboxes </h1>
<div
style={{
display: 'flex',
flexDirection: 'row',
width: '100%',
gap: '5em',
justifyContent: 'center',
}}
>
<div
style={{
display: 'flex',
flexDirection: 'column',
gap: '2em',
}}
>
<div>
<h2> Default </h2>
<div style={{ display: 'flex', gap: '2em' }}>
<Checkbox centralRipple />
<Checkbox defaultChecked />
<Checkbox indeterminate={true} />
</div>
</div>
<div>
<h2> Disabled </h2>
<div style={{ display: 'flex', gap: '2em' }}>
<Checkbox disabled />
<Checkbox defaultChecked disabled />
</div>
</div>
</div>
<div>
<h2> Errored </h2>
<form
style={{
display: 'flex',
gap: '2em',
flexDirection: 'column',
}}
>
<div
style={{
display: 'flex',
gap: '2em',
flexDirection: 'row',
}}
>
<Checkbox required />
<Checkbox defaultChecked required />
<Checkbox indeterminate={true} required />
</div>
<div
style={{
display: 'flex',
gap: '2em',
flexDirection: 'row',
}}
>
<Checkbox className={'m3-error'} required />
<Checkbox
className={'m3-error'}
defaultChecked
required
/>
<Checkbox
className={'m3-error'}
indeterminate={true}
required
/>
</div>
<Button type={'submit'}>Send</Button>
</form>
</div>
</div>
</div>
);
}

View File

@ -1,221 +0,0 @@
import React from 'react';
import { FAB } from '../../src/primitive-components/components';
export default function Fabs() {
return (
<div className={'m3 m3-wrapper'}>
<div style={{ display: 'flex', flexDirection: 'row', gap: '2em' }}>
<div>
<h1> FABs with elevation</h1>
<div
style={{
display: 'flex',
flexDirection: 'column',
width: '100%',
gap: '2em',
}}
>
<div>
<h2> Small </h2>
<div style={{ display: 'flex', gap: '2em' }}>
<FAB
centralRipple
elevated
icon={'edit'}
size={'small'}
/>
<FAB
elevated
icon={'edit'}
size={'small'}
variant={'primary'}
/>
<FAB
elevated
icon={'edit'}
size={'small'}
variant={'secondary'}
/>
<FAB
elevated
icon={'edit'}
size={'small'}
variant={'tertiary'}
/>
</div>
</div>
<div>
<h2> Default </h2>
<div style={{ display: 'flex', gap: '2em' }}>
<FAB elevated icon={'edit'} />
<FAB
elevated
icon={'edit'}
variant={'primary'}
/>
<FAB
elevated
icon={'edit'}
variant={'secondary'}
/>
<FAB
elevated
icon={'edit'}
variant={'tertiary'}
/>
</div>
</div>
<div>
<h2> Large </h2>
<div style={{ display: 'flex', gap: '2em' }}>
<FAB elevated icon={'edit'} size={'large'} />
<FAB
elevated
icon={'edit'}
size={'large'}
variant={'primary'}
/>
<FAB
elevated
icon={'edit'}
size={'large'}
variant={'secondary'}
/>
<FAB
elevated
icon={'edit'}
size={'large'}
variant={'tertiary'}
/>
</div>
</div>
<div>
<h2> Extended </h2>
<div style={{ display: 'flex', gap: '2em' }}>
<FAB elevated icon={'edit'} size={'extended'}>
<span className={'label-large'}>Label</span>
</FAB>
<FAB
elevated
icon={'edit'}
size={'extended'}
variant={'primary'}
>
<span className={'label-large'}>Label</span>
</FAB>
<FAB
elevated
icon={'edit'}
size={'extended'}
variant={'secondary'}
>
<span className={'label-large'}>Label</span>
</FAB>
<FAB
elevated
icon={'edit'}
size={'extended'}
variant={'tertiary'}
>
<span className={'label-large'}>Label</span>
</FAB>
</div>
</div>
</div>
</div>
<div>
<h1> FABs without elevation</h1>
<div
style={{
display: 'flex',
flexDirection: 'column',
width: '100%',
gap: '2em',
}}
>
<div>
<h2> Small </h2>
<div style={{ display: 'flex', gap: '2em' }}>
<FAB icon={'edit'} size={'small'} />
<FAB
icon={'edit'}
size={'small'}
variant={'primary'}
/>
<FAB
icon={'edit'}
size={'small'}
variant={'secondary'}
/>
<FAB
icon={'edit'}
size={'small'}
variant={'tertiary'}
/>
</div>
</div>
<div>
<h2> Default </h2>
<div style={{ display: 'flex', gap: '2em' }}>
<FAB icon={'edit'} />
<FAB icon={'edit'} variant={'primary'} />
<FAB icon={'edit'} variant={'secondary'} />
<FAB icon={'edit'} variant={'tertiary'} />
</div>
</div>
<div>
<h2> Large </h2>
<div style={{ display: 'flex', gap: '2em' }}>
<FAB icon={'edit'} size={'large'} />
<FAB
icon={'edit'}
size={'large'}
variant={'primary'}
/>
<FAB
icon={'edit'}
size={'large'}
variant={'secondary'}
/>
<FAB
icon={'edit'}
size={'large'}
variant={'tertiary'}
/>
</div>
</div>
<div>
<h2> Extended </h2>
<div style={{ display: 'flex', gap: '2em' }}>
<FAB icon={'edit'} size={'extended'}>
<span className={'label-large'}>Label</span>
</FAB>
<FAB
icon={'edit'}
size={'extended'}
variant={'primary'}
>
<span className={'label-large'}>Label</span>
</FAB>
<FAB
icon={'edit'}
size={'extended'}
variant={'secondary'}
>
<span className={'label-large'}>Label</span>
</FAB>
<FAB
icon={'edit'}
size={'extended'}
variant={'tertiary'}
>
<span className={'label-large'}>Label</span>
</FAB>
</div>
</div>
</div>
</div>
</div>
</div>
);
}

View File

@ -1,197 +0,0 @@
'use client';
import React from 'react';
import { IconButton } from '../../src/primitive-components/components';
function IconButtons() {
return (
<div
style={{
display: 'flex',
flexDirection: 'column',
alignItems: 'center',
justifyContent: 'center',
}}
>
<h1> Icon buttons </h1>
<div style={{ display: 'flex', flexDirection: 'row', gap: '2em' }}>
<div>
<h2> Default buttons </h2>
<div
style={{
display: 'flex',
flexDirection: 'row',
gap: '0.5em',
}}
>
<IconButton centralRipple icon={'settings'} />
<IconButton icon={'settings'} variant={'filled'} />
<IconButton icon={'settings'} variant={'tonal'} />
<IconButton icon={'settings'} variant={'outlined'} />
</div>
<h2> Disabled default buttons </h2>
<div
style={{
display: 'flex',
flexDirection: 'row',
gap: '0.5em',
}}
>
<IconButton disabled icon={'settings'} />
<IconButton
disabled
icon={'settings'}
variant={'filled'}
/>
<IconButton
disabled
icon={'settings'}
variant={'tonal'}
/>
<IconButton
disabled
icon={'settings'}
variant={'outlined'}
/>
</div>
</div>
<div>
<h2> Toggle buttons </h2>
<div
style={{
display: 'flex',
flexDirection: 'row',
gap: '0.5em',
}}
>
<IconButton
icon={'settings'}
toggled={{
selected: 'settings',
unselected: 'settings',
}}
/>
<IconButton
icon={'settings'}
toggled={{
selected: 'settings',
unselected: 'settings',
}}
variant={'filled'}
/>
<IconButton
icon={'settings'}
toggled={{
selected: 'settings',
unselected: 'settings',
}}
variant={'tonal'}
/>
<IconButton
icon={'settings'}
toggled={{
selected: 'settings',
unselected: 'settings',
}}
variant={'outlined'}
/>
</div>
<h2> Disabled toggle buttons </h2>
<div
style={{
display: 'flex',
flexDirection: 'row',
gap: '0.5em',
}}
>
<IconButton
disabled
icon={'settings'}
toggled={{
selected: 'settings',
unselected: 'settings',
}}
/>
<IconButton
disabled
icon={'settings'}
toggled={{
selected: 'settings',
unselected: 'settings',
}}
variant={'filled'}
/>
<IconButton
disabled
icon={'settings'}
toggled={{
selected: 'settings',
unselected: 'settings',
}}
variant={'tonal'}
/>
<IconButton
disabled
icon={'settings'}
toggled={{
selected: 'settings',
unselected: 'settings',
}}
variant={'outlined'}
/>
</div>
<h2> Disabled selected toggle buttons </h2>
<div
style={{
display: 'flex',
flexDirection: 'row',
gap: '0.5em',
}}
>
<IconButton
disabled
icon={'settings'}
selected
toggled={{
selected: 'settings',
unselected: 'settings',
}}
/>
<IconButton
disabled
icon={'settings'}
selected
toggled={{
selected: 'settings',
unselected: 'settings',
}}
variant={'filled'}
/>
<IconButton
disabled
icon={'settings'}
selected
toggled={{
selected: 'settings',
unselected: 'settings',
}}
variant={'tonal'}
/>
<IconButton
disabled
icon={'settings'}
selected
toggled={{
selected: 'settings',
unselected: 'settings',
}}
variant={'outlined'}
/>
</div>
</div>
</div>
</div>
);
}
export default IconButtons;

View File

@ -1,34 +0,0 @@
import React from 'react';
import { Radio } from '../../src/primitive-components/components';
export default function Radios() {
return (
<div className={'m3 m3-wrapper'}>
<h1> Radio </h1>
<div
style={{
display: 'flex',
flexDirection: 'row',
width: '100%',
gap: '5em',
justifyContent: 'center',
}}
>
<div>
<h2> Default </h2>
<div style={{ display: 'flex', gap: '2em' }}>
<Radio centralRipple />
<Radio defaultChecked />
</div>
</div>
<div>
<h2> Disabled </h2>
<div style={{ display: 'flex', gap: '2em' }}>
<Radio disabled />
<Radio defaultChecked disabled />
</div>
</div>
</div>
</div>
);
}

View File

@ -1,100 +0,0 @@
'use client';
import React from 'react';
import { Switch } from '../../src/primitive-components/components';
export default function Switches() {
return (
<div
className={'m3 m3-wrapper'}
style={{ display: 'flex', flexDirection: 'column', gap: '1.5em' }}
>
<h1> Switches </h1>
<div style={{ display: 'flex', flexDirection: 'row', gap: '2em' }}>
<div style={{ display: 'flex', flexDirection: 'column' }}>
<h2 style={{ margin: 0 }}> Without icon </h2>
<div
style={{
display: 'flex',
flexDirection: 'row',
width: '100%',
gap: '2em',
}}
>
<div>
<h2> Default </h2>
<Switch />
<Switch defaultChecked />
</div>
<div>
<h2> Disabled </h2>
<Switch disabled />
<Switch defaultChecked disabled />
</div>
</div>
</div>
<div style={{ display: 'flex', flexDirection: 'column' }}>
<h2 style={{ margin: 0 }}> With icon (both)</h2>
<div
style={{
display: 'flex',
flexDirection: 'row',
width: '100%',
gap: '2em',
}}
>
<div>
<h2> Default </h2>
<Switch icon />
<Switch defaultChecked icon />
</div>
<div>
<h2> Disabled </h2>
<Switch disabled icon />
<Switch defaultChecked disabled icon />
</div>
</div>
</div>
<div style={{ display: 'flex', flexDirection: 'column' }}>
<h2 style={{ margin: 0 }}> With icon (selected)</h2>
<div
style={{
display: 'flex',
flexDirection: 'row',
width: '100%',
gap: '2em',
}}
>
<div>
<h2> Default </h2>
<Switch icon selected />
<Switch defaultChecked icon selected />
</div>
<div>
<h2> Disabled </h2>
<Switch disabled icon selected />
<Switch defaultChecked disabled icon selected />
</div>
</div>
</div>
<div style={{ display: 'flex', flexDirection: 'column' }}>
<h2 style={{ margin: 0 }}> With label</h2>
<div
style={{
display: 'flex',
flexDirection: 'row',
width: '100%',
gap: '2em',
}}
>
<div>
<h2> Default </h2>
<Switch icon labelPlacement={'left'} />
<Switch icon selected />
</div>
</div>
</div>
</div>
</div>
);
}

File diff suppressed because it is too large Load Diff

View File

@ -1,110 +1,32 @@
import React from 'react'; import React from 'react';
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 } from '../src/primitive-components/components';
import { CardBody } from '../src/primitive-components/card/card-body';
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';
import { CardHeader } from '../src/primitive-components/card/card-header';
import { Typography } from '../src/primitive-components/typography/typography';
import { CardActionArea } from '../src/primitive-components/card/card-action-area';
import { Slider } from '../src/primitive-components/input-components/slider/slider'; import { Slider } from '../src/primitive-components/input-components/slider/slider';
import { Button } from '../src/primitive-components/button-components/button/button';
import { SegmentButton } from '../src/primitive-components/button-components/segmented-buttons/segment-button';
import { SegmentedButtons } from '../src/primitive-components/button-components/segmented-buttons/segmented-buttons';
export default function Page() { export default function Page() {
return ( return (
<main> <main
<div style={{
display: 'flex',
maxHeight: '256px',
alignItems: 'center',
justifyContent: 'center',
}}
>
<Card
style={{ style={{
display: 'flex', display: 'flex',
flexDirection: 'column', maxWidth: '256px',
alignItems: 'center', minHeight: '256px',
gap: '8px', alignItems: 'flex-end',
padding: '8px', justifyContent: 'center',
}} }}
variant={'outlined'}
> >
<div <CardFooter>
style={{ display: 'flex', gap: '8px', maxWidth: '1024px' }} <Slider />
> </CardFooter>
<Card variant={'outlined'}> </Card>
<CardHeader>
<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>
<CardActionArea>
<CardMedia src={testImage1.src} type={'img'} />
<CardBody>
<Typography role={'body'} size={'large'}>
Lorem ipsum dolor sit amet, consecrate
adipiscing elit, sed do eiusmod tempor
incididunt ut labore et dolore magna aliqua.
Ut enim ad minim veniam, quis nostrud
exercitation ullamco laboris nisi ut aliquip
ex ea commodo consequat. Duis aute irure
dolor in reprehenderit in voluptate velit
esse cillum dolore eu fugiat nulla pariatur.
Excepteur sint occaecat cupidatat non
proident, sunt in culpa qui officia deserunt
mollit anim id est laborum.
</Typography>
</CardBody>
</CardActionArea>
<CardFooter>
<div className={'flex flex-row gap-3'}>
<Button icon={'add'}>Label 1</Button>
<Button icon={'add'} iconPlace={'right'}>
Label 2
</Button>
<SegmentedButtons toggled={true}>
<SegmentButton
fillIcon={1}
icon={'change_history'}
>
Label 1
</SegmentButton>
<SegmentButton
fillIcon={1}
icon={'change_history'}
iconPlace={'right'}
>
Label 2
</SegmentButton>
<SegmentButton disabled>
Label 3
</SegmentButton>
</SegmentedButtons>
<Checkbox />
<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>
</CardFooter>
</Card>
</div>
</div>
</main> </main>
); );
} }

Binary file not shown.

Before

Width:  |  Height:  |  Size: 132 KiB

View File

@ -7,11 +7,11 @@ import useRippleEffect from '../../ripple/hooks/useRippleEffect';
import React, { forwardRef, useId, useRef, useState } from 'react'; import React, { forwardRef, useId, useRef, useState } from 'react';
export const ButtonLayout = forwardRef<HTMLButtonElement, ButtonLayoutProps>( export const ButtonLayout = forwardRef<HTMLButtonElement, ButtonLayoutProps>(
({ centralRipple = false, ...props }, ref) => { ({ centralRipple = false, ripple = true, ...props }, ref) => {
const [isActive, setIsActive] = useState<boolean>(false), const [isActive, setIsActive] = useState<boolean>(false),
ripplesRef = useRef(null), ripplesRef = useRef(null),
buttonId = useId(), buttonId = useId(),
events = useRippleEffect(ripplesRef, setIsActive); events = useRippleEffect(ripplesRef, setIsActive, ripple);
const extraClassStyles = const extraClassStyles =
`m3${isActive ? ' is-active' : ''} ${props.className ?? ''}`.trimEnd(); `m3${isActive ? ' is-active' : ''} ${props.className ?? ''}`.trimEnd();
@ -26,11 +26,13 @@ export const ButtonLayout = forwardRef<HTMLButtonElement, ButtonLayoutProps>(
ref={ref} ref={ref}
> >
{props.children} {props.children}
<RippleEffect {ripple && (
callback={setIsActive} <RippleEffect
central={centralRipple} callback={setIsActive}
ref={ripplesRef} central={centralRipple}
/> ref={ripplesRef}
/>
)}
</button> </button>
); );
}, },

View File

@ -1,11 +1,11 @@
'use client'; 'use client';
import { forwardRef } from 'react'; import React, { forwardRef } from 'react';
import { ButtonProps } from './button.types'; 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 { IconWrapper } from '../../icon/icon-wrapper'; import { IconWrapper } from '../../icon/icon-wrapper';
import { Typography } from '../../typography/typography'; import { Typography } from '../../typography/typography';
import { ButtonLayout } from '../button-layout/button-layout';
/** /**
* Button component * Button component
@ -15,9 +15,10 @@ import { Typography } from '../../typography/typography';
export const Button = forwardRef<HTMLButtonElement, ButtonProps>( export const Button = forwardRef<HTMLButtonElement, ButtonProps>(
( (
{ {
icon = undefined, ripple = true,
className = '', className = '',
disabled = false, disabled = false,
icon = undefined,
variant = 'filled', variant = 'filled',
iconPlace = 'left', iconPlace = 'left',
centralRipple = false, centralRipple = false,
@ -28,9 +29,10 @@ export const Button = forwardRef<HTMLButtonElement, ButtonProps>(
<ButtonLayout <ButtonLayout
{...props} {...props}
centralRipple={centralRipple} centralRipple={centralRipple}
className={`${variant} ${className}`} className={`m3-common-button ${variant} ${className}`.trimEnd()}
disabled={disabled} disabled={disabled}
ref={ref} ref={ref}
ripple={ripple}
> >
<IconWrapper icon={icon} iconPlace={iconPlace}> <IconWrapper icon={icon} iconPlace={iconPlace}>
<Typography <Typography

View File

@ -5,8 +5,8 @@ export interface ButtonMainProps {
icon?: string; icon?: string;
children?: string; children?: string;
disabled?: boolean; disabled?: boolean;
variant?: 'filled' | 'outlined' | 'elevated' | 'tonal' | 'text';
iconPlace?: 'left' | 'right'; iconPlace?: 'left' | 'right';
variant?: 'filled' | 'outlined' | 'elevated' | 'tonal' | 'text';
} }
export type ButtonProps = RipplePropsForComponents<HTMLButtonElement> & export type ButtonProps = RipplePropsForComponents<HTMLButtonElement> &

View File

@ -3,7 +3,12 @@
import { Icon } from '../../components'; import { Icon } from '../../components';
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 { forwardRef, useImperativeHandle, useRef, useState } from 'react'; import React, {
forwardRef,
useImperativeHandle,
useRef,
useState,
} from 'react';
import { IconButtonProps, StateToggleIconType } from './icon-button.types'; import { IconButtonProps, StateToggleIconType } from './icon-button.types';
/** /**
@ -41,7 +46,7 @@ export const IconButton = forwardRef<HTMLButtonElement, IconButtonProps>(
const buttonRef = useRef<HTMLButtonElement>(null); const buttonRef = useRef<HTMLButtonElement>(null);
const callback = event => { const callback = (event: React.MouseEvent<HTMLButtonElement>) => {
if (toggled) { if (toggled) {
if (toggleIcon.state === 'selected') { if (toggleIcon.state === 'selected') {
toggle('', toggled.unselected ?? 'add_circle'); toggle('', toggled.unselected ?? 'add_circle');
@ -67,8 +72,9 @@ export const IconButton = forwardRef<HTMLButtonElement, IconButtonProps>(
> >
<Icon <Icon
fillIcon={toggleIcon.state === 'selected' ? 1 : 0} fillIcon={toggleIcon.state === 'selected' ? 1 : 0}
iconSize={28} iconSize={24}
svgSize={40} svgSize={40}
type={'rounded'}
> >
{toggled ? toggleIcon.icon : icon ? icon : undefined} {toggled ? toggleIcon.icon : icon ? icon : undefined}
</Icon> </Icon>

View File

@ -1,10 +1,18 @@
'use client'; 'use client';
import { string } from 'prop-types'; import { string } from 'prop-types';
import { Icon } from '../../components';
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 { 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';
/**
* Segment button
*/
export const SegmentButton = forwardRef< export const SegmentButton = forwardRef<
HTMLButtonElement, HTMLButtonElement,
ButtonLayoutProps & SegmentedButton ButtonLayoutProps & SegmentedButton
@ -20,7 +28,7 @@ export const SegmentButton = forwardRef<
children, children,
iconSize, iconSize,
opticalSize, opticalSize,
toggled = false, selectable = false,
iconPlace = 'left', iconPlace = 'left',
centralRipple = false, centralRipple = false,
...props ...props
@ -31,7 +39,21 @@ export const SegmentButton = forwardRef<
const classes = const classes =
`m3-button-segment${selectedState ? ' selected' : ''} ${props.className ?? ''}`.trimEnd(); `m3-button-segment${selectedState ? ' selected' : ''} ${props.className ?? ''}`.trimEnd();
const _icon = selectedState && icon; const ButtonLabel = (
<Typography className={'label-large'} role={'label'} size={'large'}>
{children}
</Typography>
);
const iconProps = {
grade: grade,
fillIcon: fillIcon,
iconSize: iconSize,
opticalSize: opticalSize,
svgSize: svgSize,
type: type,
weight: weight,
};
return ( return (
<ButtonLayout <ButtonLayout
@ -39,40 +61,30 @@ export const SegmentButton = forwardRef<
centralRipple={centralRipple} centralRipple={centralRipple}
className={classes} className={classes}
onClick={() => { onClick={() => {
if (toggled) { if (selectable) {
setSelectedState(state => !state); setSelectedState(state => !state);
} }
props.onClick?.apply(this, props.onClick.arguments); props.onClick?.apply(this, props.onClick.arguments);
}} }}
ref={ref} ref={ref}
> >
<IconWrapper <span className={'m3 m3-button-segment-content-layer'}>
fillIcon={fillIcon} <IconWrapper
grade={grade} {...iconProps}
icon={_icon} icon={icon}
iconPlace={iconPlace} iconPlace={iconPlace}
iconSize={iconSize}
opticalSize={opticalSize}
svgSize={svgSize}
type={type}
weight={weight}
>
<Typography
className={'label-large'}
role={'label'}
size={'large'}
> >
{children} {ButtonLabel}
</Typography> </IconWrapper>
</IconWrapper> </span>
<span className={'m3 m3-button-segment-state-layer'} /> <span className={'m3 m3-button-segment-frame-layer'}>
{icon && selectable && <Icon {...iconProps}>{icon}</Icon>}
{ButtonLabel}
</span>
</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

@ -7,26 +7,26 @@ import React, { cloneElement, forwardRef, ReactElement } from 'react';
export const SegmentedButtons = forwardRef< export const SegmentedButtons = forwardRef<
HTMLDivElement, HTMLDivElement,
SegmentedButtonsProps SegmentedButtonsProps
>(({ toggled = false, children, ...props }, ref) => { >(({ selectable = false, density = 0, children, ...props }, ref) => {
if (children.length <= 1) { if (children.length <= 1 && children.length > 5) {
throw 'You must build segmented button with 2 or more button'; throw 'You must build segmented button with 2 or more buttons, but no more 5';
} }
const extraClasses =
`m3 m3-segmented-buttons m3-density-${density} m3-button-segments-amount-${children.length} ${props.className ?? ''}`.trimEnd();
const SegmentedButtons: Array<ReactElement> = children.map( const SegmentedButtons: Array<ReactElement> = children.map(
(Button: ReactElement, index: number) => { (Button: ReactElement, index: number) => {
return cloneElement(<SegmentButton />, { return cloneElement(<SegmentButton />, {
...Button.props, ...Button.props,
toggled: Button.props.toggled ?? toggled, selectable: Button.props.selectable ?? selectable,
key: index, key: index,
}); });
}, },
); );
return ( return (
<div <div className={extraClasses} ref={ref}>
className={`m3 m3-segmented-buttons ${props.className ?? ''}`.trimEnd()}
ref={ref}
>
{SegmentedButtons} {SegmentedButtons}
</div> </div>
); );

View File

@ -3,12 +3,13 @@ import { IconWrapperProps } from '../../icon/icon.types';
export type SegmentedButton = IconWrapperProps & { export type SegmentedButton = IconWrapperProps & {
icon?: string; icon?: string;
toggled?: boolean; selectable?: boolean;
centralRipple?: boolean; centralRipple?: boolean;
}; };
export interface SegmentedButtons { export interface SegmentedButtons {
toggled?: boolean; selectable?: boolean;
density?: 0 | -1 | -2 | -3;
children?: ReactElement<HTMLButtonElement>[]; children?: ReactElement<HTMLButtonElement>[];
} }

View File

@ -1,16 +1,71 @@
'use client'; 'use client';
import { Typography } from '../../typography/typography';
import { InputLayout } from '../input-layout/input-layout'; import { InputLayout } from '../input-layout/input-layout';
import React, { forwardRef, InputHTMLAttributes, useId, useState } from 'react'; import React, {
ChangeEvent,
forwardRef,
HTMLProps,
InputHTMLAttributes,
useId,
useLayoutEffect,
useRef,
useState,
} from 'react';
interface SliderProps extends InputHTMLAttributes<HTMLInputElement> { interface SliderProps extends InputHTMLAttributes<HTMLInputElement> {
options?: number[]; options?: number[];
} }
function fractionCalc(current: number | string, max: number | string): number {
const _current = isNaN(parseInt(current as string))
? 50
: parseInt(current as string);
const _max = isNaN(parseInt(max as string)) ? 100 : parseInt(max as string);
return (_current / _max) * 100;
}
function gradientStyle(value: number): string {
return `linear-gradient( to right, var(--md-sys-color-primary) ${value}%, var(--md-sys-color-surface-container-highest) ${value}%)`;
}
function setWebkitProgressSlider(
element: SliderProps | HTMLProps<HTMLInputElement>,
isChrome: boolean,
) {
if (isChrome) {
const initialFraction = fractionCalc(
(element.value as string) ?? (element.defaultValue as string),
element.max as string,
);
if (element.style === undefined) {
element.style = {};
}
element.style.background = gradientStyle(initialFraction);
}
}
export const Slider = forwardRef<HTMLInputElement, SliderProps>( export const Slider = forwardRef<HTMLInputElement, SliderProps>(
({ options, ...props }, ref) => { ({ options, ...props }, ref) => {
const sliderId = useId(); const sliderId = useId();
const [progress, setProgress] = useState<number>(0); const isChrome = useRef<boolean>(
navigator.userAgent.indexOf('AppleWebKit') != -1,
);
const [value, setValue] = useState(props.defaultValue ?? 50);
const [mounted, setMounted] = useState<boolean>(false);
useLayoutEffect(() => {
setMounted(true);
}, []);
if (!mounted) {
return;
}
setWebkitProgressSlider(props, isChrome.current);
return ( return (
<div className={'m3 m3-slider-container'}> <div className={'m3 m3-slider-container'}>
@ -18,18 +73,15 @@ export const Slider = forwardRef<HTMLInputElement, SliderProps>(
{...props} {...props}
className={props.className} className={props.className}
list={sliderId} list={sliderId}
onChange={(event: React.ChangeEvent<HTMLInputElement>) => { onChange={(event: ChangeEvent<HTMLInputElement>) => {
setProgress( props.onChange?.apply(this, props?.onChange?.prototype);
(parseInt(event.target.value) / setValue(event.target.value);
parseInt(event.target.max)) * setWebkitProgressSlider(
100, event.target as unknown as HTMLProps<HTMLInputElement>,
isChrome.current,
); );
}} }}
ref={ref} 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'} type={'range'}
typeInput={'slider'} typeInput={'slider'}
/> />
@ -40,6 +92,11 @@ export const Slider = forwardRef<HTMLInputElement, SliderProps>(
))} ))}
</datalist> </datalist>
)} )}
<div className={'m3 m3-slider-label'}>
<Typography role={'label'} size={'small'}>
{value}
</Typography>
</div>
</div> </div>
); );
}, },

View File

@ -12,7 +12,7 @@ import { baseDOMRect, RippleContainer } from '../ripple.types';
import isEmpty, { rippleSizeCalculator } from '../utils/utils'; import isEmpty, { rippleSizeCalculator } from '../utils/utils';
import { InteractionEventsType } from './useRippleEffect'; import { InteractionEventsType } from './useRippleEffect';
const RIPPLE_LIFETIME: number = 550; const RIPPLE_LIFETIME: number = 55000;
const DEBOUNCE: number = 50; const DEBOUNCE: number = 50;
const UseRippleBuilder = ( const UseRippleBuilder = (

View File

@ -12,12 +12,12 @@ const Ripple = ({
rippleKey, rippleKey,
endLifetime, endLifetime,
}: RippleProps) => { }: RippleProps) => {
const [classes, setClasses] = useState<string>('m3 ripple visible'); const [classes, setClasses] = useState<string>('m3 m3-ripple visible');
const rippleDomainContext = useContext(rippleAreaContext); const rippleDomainContext = useContext(rippleAreaContext);
useLayoutEffect(() => { useLayoutEffect(() => {
if (endLifetime && !rippleDomainContext) { if (endLifetime && !rippleDomainContext) {
setClasses('m3 ripple'); setClasses('m3 m3-ripple');
setTimeout(() => endLifetime(rippleKey), lifetime); setTimeout(() => endLifetime(rippleKey), lifetime);
} }
}, [rippleDomainContext]); }, [rippleDomainContext]);

View File

@ -26,6 +26,7 @@ export interface RippleContainer {
} }
export interface RipplePropsForComponents<T> extends HTMLAttributes<T> { export interface RipplePropsForComponents<T> extends HTMLAttributes<T> {
ripple?: boolean;
centralRipple?: boolean; centralRipple?: boolean;
} }

View File

@ -1,25 +1,25 @@
svg.m3.m3-badge svg.m3.m3-badge
position: absolute position: absolute
background-color: var(--md-sys-color-error) background-color: $error
&.disable-value &.disable-value
padding: 0 padding: 0
height: 6px
width: 6px width: 6px
height: 6px
border-radius: 3px border-radius: 3px
& > text & > text
display: none display: none
& &
border-radius: 8px
height: 16px height: 16px
border-radius: 8px
& > text & > text
fill: var(--md-sys-color-on-error) @include center(flex)
font-size: var(--md-sys-typescale-label-small-font-size) @include m3-typography-mixin('label-small')
font-weight: var(--md-sys-typescale-label-small-font-weight)
line-height: var(--md-sys-typescale-label-small-line-height) fill: $on-error
text-anchor: middle
font-optical-sizing: none font-optical-sizing: none
alignment-baseline: central alignment-baseline: central
text-anchor: middle
display: flex
align-items: center
justify-content: center

View File

@ -70,13 +70,13 @@ button:not(.m3-fab, .m3-icon-button)::before {
position: absolute; position: absolute;
background: rgba(0, 0, 0, 0); background: rgba(0, 0, 0, 0);
} }
button:not(.m3-fab, .m3-icon-button).filled > .m3.m3-ripple-domain > .m3.ripple { button:not(.m3-fab, .m3-icon-button).filled > .m3.m3-ripple-domain > .m3.m3-ripple {
background: color-mix(in srgb, var(--md-sys-color-on-primary) 12%, transparent); background: color-mix(in srgb, var(--md-sys-color-on-primary) 12%, transparent);
} }
button:not(.m3-fab, .m3-icon-button):is(.outlined, .text, .elevated) > .m3.m3-ripple-domain > .m3.ripple { button:not(.m3-fab, .m3-icon-button):is(.outlined, .text, .elevated) > .m3.m3-ripple-domain > .m3.m3-ripple {
background: color-mix(in srgb, var(--md-sys-color-primary) 12%, transparent); background: color-mix(in srgb, var(--md-sys-color-primary) 12%, transparent);
} }
button:not(.m3-fab, .m3-icon-button).tonal > .m3.m3-ripple-domain > .m3.ripple { button:not(.m3-fab, .m3-icon-button).tonal > .m3.m3-ripple-domain > .m3.m3-ripple {
background: color-mix(in srgb, var(--md-sys-color-on-secondary-container) 12%, transparent); background: color-mix(in srgb, var(--md-sys-color-on-secondary-container) 12%, transparent);
} }
button:not(.m3-fab, .m3-icon-button):active:is(.filled, .tonal) { button:not(.m3-fab, .m3-icon-button):active:is(.filled, .tonal) {

View File

@ -1,85 +1,53 @@
input[type="button"].test-button button.m3.m3-common-button
color: white
&:not(:checked)
background-color: green
&:checked
background-color: blue
button:not(.m3-fab, .m3-icon-button)
width: min-content
height: min-content
max-height: 40px
box-sizing: border-box
white-space: nowrap
font-size: var(--md-sys-typescale-label-large-font-size)
font-weight: var(--md-sys-typescale-label-large-font-weight)
line-height: var(--md-sys-typescale-label-large-line-height)
font-family: var(--md-sys-typescale-label-large-font-family-name)
transition: background-color, box-shadow, .2s cubic-bezier(0.2, 0, 0, 1) !important
&.m3
gap: 8px
border: none
contain: content
text-align: center
padding: 10px 24px
align-items: center
flex-direction: row
display: inline-flex
border-radius: 100px
box-sizing: border-box
justify-content: center
&.filled &.filled
background-color: var(--md-sys-color-primary) background-color: $primary
&, & > svg.m3-svg-icon &, & > svg.m3-svg-icon
fill: var(--md-sys-color-on-primary) fill: $on-primary
color: var(--md-sys-color-on-primary) color: $on-primary
&.outlined &.outlined
color: $primary
outline-offset: -1px outline-offset: -1px
background-color: #00000000 background-color: transparent
color: var(--md-sys-color-primary) outline: 1px solid $outline !important
outline: 1px solid var(--md-sys-color-outline) !important
& > svg.m3-svg-icon & > svg.m3-svg-icon
fill: var(--md-sys-color-primary) fill: $primary
&.text &.text
background-color: #00000000 color: $primary
padding: 10px 12px !important background-color: transparent
color: var(--md-sys-color-primary)
& > svg.m3-svg-icon & > svg.m3-svg-icon
fill: var(--md-sys-color-primary) fill: $primary
&.elevated &.elevated
@include elevation-1(false) @include elevation-1(false)
color: var(--md-sys-color-primary)
background-color: var(--md-sys-color-surface-container-low) color: $primary
background-color: $surface-container-low
& > svg.m3-svg-icon & > svg.m3-svg-icon
fill: var(--md-sys-color-primary) fill: $primary
&.tonal &.tonal
color: var(--md-sys-color-on-secondary-container) color: $on-secondary-container
background-color: var(--md-sys-color-secondary-container) background-color: $secondary-container
& > svg.m3-svg-icon & > svg.m3-svg-icon
fill: var(--md-sys-color-on-secondary-container) fill: $on-secondary-container
&::before &.filled > span.m3.m3-ripple-domain > span.m3.m3-ripple
@include state-layer background: color-mix(in srgb, $on-primary 12%, transparent)
&.filled > .m3.m3-ripple-domain > .m3.ripple
background: color-mix(in srgb, var(--md-sys-color-on-primary) 12%, transparent)
&:is(.outlined, .text, .elevated) &:is(.outlined, .text, .elevated)
& > .m3.m3-ripple-domain > .m3.ripple & > span.m3.m3-ripple-domain > span.m3.m3-ripple
background: color-mix(in srgb, var(--md-sys-color-primary) 12%, transparent) background: color-mix(in srgb, $primary 12%, transparent)
&.tonal > .m3.m3-ripple-domain > .m3.ripple &.tonal > span.m3.m3-ripple-domain > span.m3.m3-ripple
background: color-mix(in srgb, var(--md-sys-color-on-secondary-container) 12%, transparent) background: color-mix(in srgb, $on-secondary-container 12%, transparent)
&:active &:active
&:is(.filled, .tonal) &:is(.filled, .tonal)
@ -88,21 +56,31 @@ button:not(.m3-fab, .m3-icon-button)
&.elevated &.elevated
@include elevation-1(true) @include elevation-1(true)
&.tonal::before &:not(&:has(span.m3.m3-ripple-domain))
background-color: color-mix(in srgb, var(--md-sys-color-on-secondary-container) 12%, transparent) &.outlined
border-color: $primary !important
&.filled
background-color: color-mix(in srgb, $on-primary 20%, $primary)
&:is(.outlined, .text, .elevated)
background-color: color-mix(in srgb, $primary 20%, transparent)
&.tonal
background-color: color-mix(in srgb, $on-secondary-container 20%, $secondary-container)
&:focus-visible &:focus-visible
&.outlined &.outlined
border-color: var(--md-sys-color-primary) !important border-color: $primary !important
&.filled::before &.filled
background-color: color-mix(in srgb, var(--md-sys-color-on-primary) 12%, transparent) background-color: color-mix(in srgb, $on-primary 12%, $primary)
&:is(.outlined, .text, .elevated)::before &:is(.outlined, .text, .elevated)
background-color: color-mix(in srgb, var(--md-sys-color-primary) 12%, transparent) background-color: color-mix(in srgb, $primary 12%, transparent)
&.tonal::before &.tonal
background-color: color-mix(in srgb, var(--md-sys-color-on-secondary-container) 12%, transparent) background-color: color-mix(in srgb, $on-secondary-container 12%, $secondary-container)
&:hover &:hover
&:is(.filled, .tonal) &:is(.filled, .tonal)
@ -111,26 +89,26 @@ button:not(.m3-fab, .m3-icon-button)
&.elevated &.elevated
@include elevation-2(false) @include elevation-2(false)
&.filled::before &.filled
background-color: color-mix(in srgb, var(--md-sys-color-on-primary) 8%, transparent) background-color: color-mix(in srgb, $on-primary 8%, $primary)
&:is(.outlined, .text, .elevated)::before &:is(.outlined, .text, .elevated)
background-color: color-mix(in srgb, var(--md-sys-color-primary) 8%, transparent) background-color: color-mix(in srgb, $primary 8%, transparent)
&.tonal::before &.tonal
background-color: color-mix(in srgb, var(--md-sys-color-on-secondary-container) 8%, transparent) background-color: color-mix(in srgb, $on-secondary-container 8%, $secondary-container)
&:disabled &:disabled
pointer-events: none pointer-events: none
&:is(.filled, .elevated, .tonal, .outlined, .text) &:is(.filled, .elevated, .tonal, .outlined, .text)
color: color-mix(in srgb, var(--md-sys-color-on-surface) 38%, transparent) color: color-mix(in srgb, $on-surface 38%, transparent)
&:is(.filled, .elevated, .tonal) &:is(.filled, .elevated, .tonal)
background: color-mix(in srgb, var(--md-sys-color-on-surface) 12%, transparent) background: color-mix(in srgb, $on-surface 12%, transparent)
&.elevated &.elevated
box-shadow: none box-shadow: none
&.outlined &.outlined
outline: 1px solid color-mix(in srgb, var(--md-sys-color-on-surface) 12%, transparent) !important outline: 1px solid color-mix(in srgb, $on-surface 12%, transparent) !important

View File

@ -1,34 +1,60 @@
@mixin m3-fab-default($b-radius, $width, $height : $width, $padding : 0)
width: $width
height: $height
padding: $padding
border-radius: $b-radius
@mixin m3-fab-colors-palette($bg-color, $color)
&:not(.without-elevation)
@include elevation-3(false)
color: $color
background-color: $bg-color
& > svg.m3-svg-icon
fill: $color
& > span.m3.m3-ripple-domain > span.m3.m3-ripple
background: color-mix(in srgb, $color 12%, transparent)
&:not(&:has(span.m3.m3-ripple-domain)):active
&::before
background: color-mix(in srgb, $color 20%, transparent)
button.m3.m3-fab button.m3.m3-fab
transition: background-color, box-shadow, .2s cubic-bezier(0.2, 0, 0, 1) !important transition: background-color, box-shadow, .2s cubic-bezier(0.2, 0, 0, 1) !important
& > span.m3-icon & > span.m3-icon
font-family: Material-Symbols-Outlined-Regular, sans-serif font-family: Material-Symbols-Rounded-Regular, sans-serif
&.m3 &.m3
contain: content
box-sizing: border-box
display: inline-flex
flex-direction: row
justify-content: center
align-items: center
text-align: center
border: none
gap: 12px gap: 12px
border: none
contain: content
text-align: center
align-items: center
flex-direction: row
display: inline-flex
box-sizing: border-box
justify-content: center
&::before &::before
@include state-layer @include m3-buttons-state-layer-mixin
content: ""
&.surface &.surface
@include m3-fab-colors-palette(--md-sys-color-surface-container-high, --md-sys-color-primary) @include m3-fab-colors-palette($surface-container-high, $primary)
&.primary &.primary
@include m3-fab-colors-palette(--md-sys-color-primary-container, --md-sys-color-on-primary-container) @include m3-fab-colors-palette($primary-container, $on-primary-container)
&.secondary &.secondary
@include m3-fab-colors-palette(--md-sys-color-secondary-container, --md-sys-color-on-secondary-container) @include m3-fab-colors-palette($secondary-container, $on-secondary-container)
&.tertiary &.tertiary
@include m3-fab-colors-palette(--md-sys-color-tertiary-container, --md-sys-color-on-tertiary-container) @include m3-fab-colors-palette($tertiary-container, $on-tertiary-container)
&.m3-small-fab &.m3-small-fab
@include m3-fab-default(12px, 40px, 40px, 11px) @include m3-fab-default(12px, 40px, 40px, 11px)
@ -53,27 +79,27 @@ button.m3.m3-fab
@include elevation-3(true) @include elevation-3(true)
&:hover &:hover
&.surface::before &.surface:before
background-color: color-mix(in srgb, var(--md-sys-color-primary) 8%, transparent) background-color: color-mix(in srgb, $primary 8%, transparent)
&.primary::before &.primary:before
background-color: color-mix(in srgb, var(--md-sys-color-on-primary-container) 8%, transparent) background-color: color-mix(in srgb, $on-primary-container 8%, transparent)
&.secondary::before &.secondary:before
background-color: color-mix(in srgb, var(--md-sys-color-on-secondary-container) 8%, transparent) background-color: color-mix(in srgb, $on-secondary-container 8%, transparent)
&.tertiary::before &.tertiary:before
background-color: color-mix(in srgb, var(--md-sys-color-on-tertiary-container) 8%, transparent) background-color: color-mix(in srgb, $on-tertiary-container 8%, transparent)
&:focus-visible &:focus-visible
&.surface::before &.surface:before
background-color: color-mix(in srgb, var(--md-sys-color-primary) 12%, transparent) background-color: color-mix(in srgb, $primary 12%, transparent)
&.primary::before &.primary:before
background-color: color-mix(in srgb, var(--md-sys-color-on-primary-container) 12%, transparent) background-color: color-mix(in srgb, $on-primary-container 12%, transparent)
&.secondary::before &.secondary:before
background-color: color-mix(in srgb, var(--md-sys-color-on-secondary-container) 12%, transparent) background-color: color-mix(in srgb, $on-secondary-container 12%, transparent)
&.tertiary::before &.tertiary:before
background-color: color-mix(in srgb, var(--md-sys-color-on-tertiary-container) 12%, transparent) background-color: color-mix(in srgb, $on-tertiary-container 12%, transparent)

View File

@ -79,25 +79,25 @@ button.m3.m3-icon-button.outlined.selected.toggled {
background-color: var(--md-sys-color-inverse-surface); background-color: var(--md-sys-color-inverse-surface);
fill: var(--md-sys-color-inverse-on-surface); fill: var(--md-sys-color-inverse-on-surface);
} }
button.m3.m3-icon-button.filled:not(:disabled) > .m3.m3-ripple-domain > .m3.ripple, button.m3.m3-icon-button.filled:not(:disabled).selected.toggled > .m3.m3-ripple-domain > .m3.ripple { button.m3.m3-icon-button.filled:not(:disabled) > .m3.m3-ripple-domain > .m3.m3-ripple, button.m3.m3-icon-button.filled:not(:disabled).selected.toggled > .m3.m3-ripple-domain > .m3.m3-ripple {
background-color: color-mix(in srgb, var(--md-sys-color-on-primary) 12%, transparent); background-color: color-mix(in srgb, var(--md-sys-color-on-primary) 12%, transparent);
} }
button.m3.m3-icon-button.filled:not(:disabled).toggled > .m3.m3-ripple-domain > .m3.ripple { button.m3.m3-icon-button.filled:not(:disabled).toggled > .m3.m3-ripple-domain > .m3.m3-ripple {
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);
} }
button.m3.m3-icon-button:is(.outlined, .default):not(:disabled) > .m3.m3-ripple-domain > .m3.ripple { button.m3.m3-icon-button:is(.outlined, .default):not(:disabled) > .m3.m3-ripple-domain > .m3.m3-ripple {
background-color: color-mix(in srgb, var(--md-sys-color-on-surface-variant) 12%, transparent); background-color: color-mix(in srgb, var(--md-sys-color-on-surface-variant) 12%, transparent);
} }
button.m3.m3-icon-button:is(.outlined, .default):not(:disabled):not(.outlined).toggled.selected > .m3.m3-ripple-domain > .m3.ripple { button.m3.m3-icon-button:is(.outlined, .default):not(:disabled):not(.outlined).toggled.selected > .m3.m3-ripple-domain > .m3.m3-ripple {
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);
} }
button.m3.m3-icon-button:is(.outlined, .default):not(:disabled):not(.default).toggled.selected > .m3.m3-ripple-domain > .m3.ripple { button.m3.m3-icon-button:is(.outlined, .default):not(:disabled):not(.default).toggled.selected > .m3.m3-ripple-domain > .m3.m3-ripple {
background-color: color-mix(in srgb, var(--md-sys-color-inverse-on-surface) 12%, transparent); background-color: color-mix(in srgb, var(--md-sys-color-inverse-on-surface) 12%, transparent);
} }
button.m3.m3-icon-button.tonal:not(:disabled) > .m3.m3-ripple-domain > .m3.ripple, button.m3.m3-icon-button.tonal:not(:disabled).selected.toggled > .m3.m3-ripple-domain > .m3.ripple { button.m3.m3-icon-button.tonal:not(:disabled) > .m3.m3-ripple-domain > .m3.m3-ripple, button.m3.m3-icon-button.tonal:not(:disabled).selected.toggled > .m3.m3-ripple-domain > .m3.m3-ripple {
background-color: color-mix(in srgb, var(--md-sys-color-on-secondary-container) 12%, transparent); background-color: color-mix(in srgb, var(--md-sys-color-on-secondary-container) 12%, transparent);
} }
button.m3.m3-icon-button.tonal:not(:disabled).toggled > .m3.m3-ripple-domain > .m3.ripple { button.m3.m3-icon-button.tonal:not(:disabled).toggled > .m3.m3-ripple-domain > .m3.m3-ripple {
background-color: color-mix(in srgb, var(--md-sys-color-on-surface-variant) 12%, transparent); background-color: color-mix(in srgb, var(--md-sys-color-on-surface-variant) 12%, transparent);
} }
button.m3.m3-icon-button:hover:not(:disabled):is(.default, .outlined)::before { button.m3.m3-icon-button:hover:not(:disabled):is(.default, .outlined)::before {

View File

@ -1,16 +1,57 @@
@mixin m3-icon-button-state-colors($opacity)
&:is(.default, .outlined)::before
background-color: color-mix(in srgb, $on-surface-variant $opacity, transparent)
&.outlined.selected.toggled::before
background-color: color-mix(in srgb, $inverse-on-surface $opacity, transparent)
&.filled::before,
&.filled.selected.toggled::before
background-color: color-mix(in srgb, $on-primary $opacity, transparent)
&.filled:not(.selected).toggled::before,
&.default.selected.toggled::before
background-color: color-mix(in srgb, $primary $opacity, transparent)
&.tonal::before,
&.tonal.selected.toggled::before
background-color: color-mix(in srgb, $on-secondary-container $opacity, transparent)
&.tonal.toggled::before
background-color: color-mix(in srgb, $on-surface-variant $opacity, transparent)
@mixin m3-icon-color-palette($border, $border-opacity, $fill, $fill-opacity, $background, $background-opacity)
@if $border != none
@if $border == transparent
border: 0 solid transparent
@else
border: 1px solid color-mix(in srgb, $border $border-opacity, transparent)
@if $fill != none
@if $fill == transparent
fill: $fill
@else
fill: color-mix(in srgb, $fill $fill-opacity, transparent)
@if $background != none
@if $background == transparent
background-color: $background
@else
background-color: color-mix(in srgb, $background $background-opacity, transparent)
button.m3.m3-icon-button button.m3.m3-icon-button
transition: background-color, box-shadow, .2s cubic-bezier(0.2, 0, 0, 1) !important @include center(inline-flex)
contain: content
border-radius: 50% padding: 0
position: relative
display: inline-flex
flex-direction: row
justify-content: center
align-items: center
width: 40px width: 40px
height: 40px height: 40px
border: none border: none
padding: 0 contain: content
border-radius: 50%
position: relative
flex-direction: row
transition: background-color, box-shadow, .2s cubic-bezier(0.2, 0, 0, 1) !important
&::before &::before
transition: background-color, box-shadow, .2s cubic-bezier(0.2, 0, 0, 1) !important transition: background-color, box-shadow, .2s cubic-bezier(0.2, 0, 0, 1) !important
@ -21,114 +62,80 @@ button.m3.m3-icon-button
& > span.m3-icon & > span.m3-icon
z-index: 25 z-index: 25
font-size: 2em font-size: 24px
font-variation-settings: 'FILL' 0, 'wght' 500, 'GRAD' 0, 'opsz' 48 font-variation-settings: 'FILL' 0, 'wght' 500, 'GRAD' 0, 'opsz' 48
&.default &.default
& &, &:not(.selected).toggled
fill: var(--md-sys-color-on-surface-variant) @include m3-icon-color-palette(none, none, $on-surface-variant, 100%, transparent, 0%)
background-color: #00000000
&:disabled, &.selected:disabled, &.selected.toggled:disabled
fill: color-mix(in srgb, var(--md-sys-color-on-surface-variant) 38%, transparent)
background-color: #00000000
&.selected.toggled &.selected.toggled
fill: var(--md-sys-color-primary) @include m3-icon-color-palette(none, none, $primary, 100%, transparent, 0%)
&:disabled,
&.selected:disabled,
&.selected.toggled:disabled
@include m3-icon-color-palette(none, none, $on-surface-variant, 38%, transparent, 0%)
&.filled &.filled
& &
fill: var(--md-sys-color-on-primary) @include m3-icon-color-palette(none, none, $on-primary, 100%, $primary, 100%)
background-color: var(--md-sys-color-primary)
&.toggled &:not(.selected).toggled
fill: var(--md-sys-color-primary) @include m3-icon-color-palette(none, none, $primary, 100%, $surface-container-highest, 100%)
background-color: var(--md-sys-color-surface-container-highest)
&.selected.toggled &.selected.toggled
fill: var(--md-sys-color-on-primary) @include m3-icon-color-palette(none, none, $on-primary, 100%, $primary, 100%)
background-color: var(--md-sys-color-primary)
&.tonal &.tonal
&.toggled &:not(.selected).toggled
fill: var(--md-sys-color-on-surface-variant) @include m3-icon-color-palette(none, none, $on-surface-variant, 100%, $surface-container-highest, 100%)
background-color: var(--md-sys-color-surface-container-highest)
&.selected.toggled, & &.selected.toggled, &
fill: var(--md-sys-color-on-secondary-container) @include m3-icon-color-palette(none, none, $on-secondary-container, 100%, $secondary-container, 100%)
background-color: var(--md-sys-color-secondary-container)
&:is(.tonal, .filled, .toggled.selected):disabled &:is(.tonal, .filled, .toggled.selected):disabled
fill: color-mix(in srgb, var(--md-sys-color-on-surface) 38%, transparent) @include m3-icon-color-palette(none, none, $on-surface, 38%, $on-surface, 12%)
background-color: color-mix(in srgb, var(--md-sys-color-on-surface) 12%, transparent)
&.outlined &.outlined
& &
border: 1px solid var(--md-sys-color-outline) @include m3-icon-color-palette($outline, 100%, $on-surface-variant, 100%, transparent, 0%)
fill: var(--md-sys-color-on-surface-variant)
background-color: #00000000
&:disabled
border: 1px solid color-mix(in srgb, var(--md-sys-color-outline) 12%, transparent)
fill: color-mix(in srgb, var(--md-sys-color-on-surface-variant) 38%, transparent)
background-color: #00000000
&.toggled.selected:disabled
border: 1px solid color-mix(in srgb, var(--md-sys-color-outline) 0%, transparent)
fill: color-mix(in srgb, var(--md-sys-color-on-surface) 38%, transparent)
background-color: color-mix(in srgb, var(--md-sys-color-on-surface) 12%, transparent)
&.selected.toggled &.selected.toggled
border: 1px solid #00000000 @include m3-icon-color-palette(transparent, 0%, $inverse-on-surface, 100%, $inverse-surface, 100%)
background-color: var(--md-sys-color-inverse-surface)
fill: var(--md-sys-color-inverse-on-surface) &:disabled
@include m3-icon-color-palette($outline, 12%, $on-surface-variant, 38%, transparent, 0%)
&.selected.toggled:disabled
@include m3-icon-color-palette(none, 0%, $on-surface, 38%, $on-surface, 12%)
&.filled:not(:disabled) &.filled:not(:disabled)
& > .m3.m3-ripple-domain > .m3.ripple, &.selected.toggled > .m3.m3-ripple-domain > .m3.ripple &:is(&.selected.toggled, &) > span.m3.m3-ripple-domain > span.m3.m3-ripple
background-color: color-mix(in srgb, var(--md-sys-color-on-primary) 12%, transparent) background-color: color-mix(in srgb, $on-primary 12%, transparent)
&.toggled > .m3.m3-ripple-domain > .m3.ripple
background-color: color-mix(in srgb, var(--md-sys-color-primary) 12%, transparent) &:is(&.toggled):not(&.toggled.selected) > span.m3.m3-ripple-domain > span.m3.m3-ripple
background-color: color-mix(in srgb, $primary 12%, transparent)
&:is(.outlined, .default):not(:disabled) &:is(.outlined, .default):not(:disabled)
& > .m3.m3-ripple-domain > .m3.ripple & > span.m3.m3-ripple-domain > span.m3.m3-ripple
background-color: color-mix(in srgb, var(--md-sys-color-on-surface-variant) 12%, transparent) background-color: color-mix(in srgb, $on-surface-variant 12%, transparent)
&:not(.outlined).toggled.selected> .m3.m3-ripple-domain > .m3.ripple &:not(.outlined).toggled.selected > span.m3.m3-ripple-domain > span.m3.m3-ripple
background-color: color-mix(in srgb, var(--md-sys-color-primary) 12%, transparent) background-color: color-mix(in srgb, $primary 12%, transparent)
&:not(.default).toggled.selected> .m3.m3-ripple-domain > .m3.ripple &:not(.default).toggled.selected > span.m3.m3-ripple-domain > span.m3.m3-ripple
background-color: color-mix(in srgb, var(--md-sys-color-inverse-on-surface) 12%, transparent) background-color: color-mix(in srgb, $inverse-on-surface 12%, transparent)
&.tonal:not(:disabled) &.tonal:not(:disabled)
& > .m3.m3-ripple-domain > .m3.ripple, &.selected.toggled > .m3.m3-ripple-domain > .m3.ripple &:is(&.selected.toggled, &) > span.m3.m3-ripple-domain > span.m3.m3-ripple
background-color: color-mix(in srgb, var(--md-sys-color-on-secondary-container) 12%, transparent) background-color: color-mix(in srgb, $on-secondary-container 12%, transparent)
&.toggled > .m3.m3-ripple-domain > .m3.ripple
background-color: color-mix(in srgb, var(--md-sys-color-on-surface-variant) 12%, transparent) &:is(&.toggled):not(&.toggled.selected) > span.m3.m3-ripple-domain > span.m3.m3-ripple
background-color: color-mix(in srgb, $on-surface-variant 12%, transparent)
&:hover:not(:disabled) &:hover:not(:disabled)
&:is(.default, .outlined)::before @include m3-icon-button-state-colors(8%)
background-color: color-mix(in srgb, var(--md-sys-color-on-surface-variant) 8%, transparent)
&.filled::before, &.filled.toggled.selected::before &:is(&:focus-visible:not(:disabled), &:active:not(:disabled, &:has(span.m3.m3-ripple-domain)))
background-color: color-mix(in srgb, var(--md-sys-color-on-primary) 8%, transparent) @include m3-icon-button-state-colors(12%)
&.filled.toggled::before
background-color: color-mix(in srgb, var(--md-sys-color-primary) 8%, transparent)
&.tonal::before, &.tonal.toggled.selected::before
background-color: color-mix(in srgb, var(--md-sys-color-on-secondary-container) 8%, transparent)
&.tonal.toggled::before
background-color: color-mix(in srgb, var(--md-sys-color-on-surface-variant) 8%, transparent)
&:focus-visible:not(:disabled)
&:is(.default, .outlined)::before
background-color: color-mix(in srgb, var(--md-sys-color-on-surface-variant) 12%, transparent)
&.filled::before, &.filled.toggled.selected::before
background-color: color-mix(in srgb, var(--md-sys-color-on-primary) 12%, transparent)
&.filled.toggled::before
background-color: color-mix(in srgb, var(--md-sys-color-primary) 12%, transparent)
&.tonal::before, &.tonal.toggled.selected::before
background-color: color-mix(in srgb, var(--md-sys-color-on-secondary-container) 12%, transparent)
&.tonal.toggled::before
background-color: color-mix(in srgb, var(--md-sys-color-on-surface-variant) 12%, transparent)

View File

@ -1,66 +1,100 @@
$densities: [0, -1, -2, -3]
@each $density in $densities
.m3.m3-density-#{$density}
$height: 40px + ($density * 4px)
& > button.m3.m3-button-segment
height: $height
&:first-child
border-radius: ($height / 2) 0 0 ($height / 2)
&:last-child
border-radius: 0 ($height / 2) ($height / 2) 0
padding: 10px + ($density * 2px) 12px
@mixin m3-segmented-button-content-color-mixin($color)
& > svg.m3.m3-svg-icon > text
fill: $color
& > label.m3.m3-typography
color: $color
div.m3.m3-segmented-buttons div.m3.m3-segmented-buttons
padding: 0 width: 100%
height: 40px padding: 4px 0
display: flex
flex-direction: row
border-radius: 20px border-radius: 20px
display: inline-flex
box-sizing: border-box box-sizing: border-box
border-collapse: collapse
& > button.m3.m3-button-segment & > button.m3.m3-button-segment
height: 40px width: 100%
display: flex min-width: 48px
min-width: 108px
border-radius: 0 border-radius: 0
width: max-content margin: 0 -0.5px
padding-inline: 10px display: inline-flex
margin: 0 -0.5px 0 -0.5px border: 1px solid $outline
background-color: transparent background-color: transparent
border: 1px solid var(--md-sys-color-outline)
&:first-child &::before
border-radius: 20px 0 0 20px @include m3-buttons-state-layer-mixin
&:last-child content: ""
border-radius: 0 20px 20px 0
& > span & > span.m3.m3-ripple-domain
color: var(--md-sys-color-on-surface) transition: .2s cubic-bezier(0.2, 0, 0, 1)
& > svg > text & > span.m3.m3-ripple
fill: var(--md-sys-color-on-surface) background-color: color-mix(in srgb, $on-secondary-container 12%, transparent)
& > span.m3:is(.m3-button-segment-frame-layer, .m3-button-segment-content-layer)
@include center(inline-flex)
gap: 8px
height: inherit
& > svg.m3.m3-svg-icon
height: inherit
& > span.m3.m3-button-segment-frame-layer
box-sizing: border-box
& > *
visibility: hidden
& > span.m3.m3-button-segment-content-layer
@include m3-segmented-button-content-color-mixin($on-surface)
position: absolute
& > svg.m3.m3-svg-icon
display: none
&.selected
background-color: $secondary-container
& > span.m3.m3-button-segment-content-layer
@include m3-segmented-button-content-color-mixin($on-secondary-container)
& > svg.m3.m3-svg-icon
display: initial
&:not(:disabled):hover
&::before
background-color: color-mix(in srgb, $on-secondary-container 8%, transparent)
&:is(&:not(&:has(span.m3.m3-ripple-domain)):active, &:focus-visible)
&::before
background-color: color-mix(in srgb, $on-secondary-container 12%, transparent)
&:disabled &:disabled
border: 1px solid color-mix(in srgb, var(--md-sys-color-outline) 12%, transparent) border: 1px solid color-mix(in srgb, $outline 12%, transparent)
& > * & > *
opacity: 38% opacity: 38%
&.selected
background-color: var(--md-sys-color-secondary-container)
& > span
color: var(--md-sys-color-on-secondary-container)
& > text
fill: var(--md-sys-color-on-secondary-container)
& > span.m3.m3-button-segment-state-layer
position: absolute
width: 100%
height: 100%
& > span.m3.m3-button-segment-state-layer, span.m3.m3-ripple-domain
transition: .2s cubic-bezier(0.2, 0, 0, 1)
&:hover
& > span.m3.m3-button-segment-state-layer
background-color: color-mix(in srgb, var(--md-sys-color-on-secondary-container) 8%, transparent)
&:is(&:active, &:focus-visible)
& > span.m3.m3-button-segment-state-layer
background-color: color-mix(in srgb, var(--md-sys-color-on-secondary-container) 12%, transparent)
&:active
& > span.m3.m3-ripple-domain > span.m3.ripple
background-color: color-mix(in srgb, var(--md-sys-color-on-secondary-container) 12%, transparent)

View File

@ -1,4 +1,5 @@
@import 'mixins/m3-mixins' @import 'mixins/m3-mixins'
@import './css/colors-variables'
$padding: 16px $padding: 16px
@ -10,25 +11,19 @@ $padding: 16px
div.m3.m3-card div.m3.m3-card
& > :is(div.m3-card-footer, header.m3-card-header, section.m3-card-body) > .m3-card-media:first-child, & > :is(div.m3-card-footer, header.m3-card-header, section.m3-card-body) > .m3-card-media:first-child,
& > .m3-card-media:first-child, & > .m3-card-action-area:first-child > .m3-card-action-area-content > .m3-card-media:first-child,
& > .m3-card-action-area:first-child > .m3-card-action-area-content > .m3-card-media:first-child & > .m3-card-media:first-child
padding: padding-calculating(false)
border-radius: 12px !important border-radius: 12px !important
padding: padding-calculating(false)
div.m3.m3-card > .m3-card-action-area:first-child > .m3-card-action-area-content > .m3-card-media:first-child
padding: padding-calculating(false)
border-radius: 12px !important
div.m3-card-footer, header.m3-card-header, section.m3-card-body, .m3-card-media.m3 div.m3-card-footer, header.m3-card-header, section.m3-card-body, .m3-card-media.m3
padding: padding-calculating(true)
display: block
box-sizing: border-box box-sizing: border-box
padding: padding-calculating(true)
.m3.m3-card-media .m3.m3-card-media
&.m3-rounded &.m3-rounded
border-radius: 12px + padding-calculating(true) border-radius: 12px + padding-calculating(true)
width: 100%
display: block display: block
contain: content contain: content
position: relative position: relative
@ -40,7 +35,7 @@ div.m3.m3-card-action-area
contain: content contain: content
position: relative position: relative
border-radius: inherit border-radius: inherit
transition: box-shadow .2s cubic-bezier(0.2, 0, 0, 1) transition: background-color, box-shadow, .2s cubic-bezier(0.2, 0, 0, 1)
& > div.m3.m3-card-action-area-content & > div.m3.m3-card-action-area-content
top: 0 top: 0
@ -52,15 +47,17 @@ div.m3.m3-card-action-area
width: 100% width: 100%
height: 100% height: 100%
position: absolute position: absolute
transition: background-color .2s cubic-bezier(0.2, 0, 0, 1)
& > .m3.m3-ripple-domain > .m3.m3-ripple
background-color: color-mix(in srgb, $on-surface 12%, transparent)
&:hover &:hover
& > span.m3.m3-card-state-layer & > span.m3.m3-card-state-layer
background-color: color-mix(in srgb, var(--md-sys-color-on-surface) 8%, transparent) background-color: color-mix(in srgb, $on-surface 8%, transparent)
&:is(&:focus, &:focus-visible, &:focus-within) &:is(&:focus, &:focus-visible, &:focus-within)
& > span.m3.m3-card-state-layer & > span.m3.m3-card-state-layer
background-color: color-mix(in srgb, var(--md-sys-color-on-surface) 12%, transparent) background-color: color-mix(in srgb, $on-surface 12%, transparent)
&:is(&:focus, &:focus-visible, &:focus-within, &:hover) &:is(&:focus, &:focus-visible, &:focus-within, &:hover)
&:is(.m3-card-outlined, .m3-card-filled) &:is(.m3-card-outlined, .m3-card-filled)
@ -78,7 +75,4 @@ div.m3.m3-card-action-area
&:not(&:has(span.m3.m3-ripple-domain)) &:not(&:has(span.m3.m3-ripple-domain))
& > span.m3.m3-card-state-layer & > span.m3.m3-card-state-layer
background-color: color-mix(in srgb, var(--md-sys-color-on-surface) 12%, transparent) background-color: color-mix(in srgb, $on-surface 12%, transparent)
& > span.m3.m3-ripple-domain > .m3.ripple
background-color: color-mix(in srgb, var(--md-sys-color-on-surface) 12%, transparent)

View File

@ -1,20 +1,22 @@
@import "mixins/m3-mixins" @import "mixins/m3-mixins"
@import './css/colors-variables'
div.m3.m3-container div.m3.m3-container
display: block display: block
border-radius: 12px
position: relative
contain: content contain: content
position: relative
border-radius: 12px
transition: box-shadow .2s cubic-bezier(0.2, 0, 0, 1) transition: box-shadow .2s cubic-bezier(0.2, 0, 0, 1)
&.m3-container-filled &.m3-container-filled
background-color: var(--md-sys-color-surface-container-highest) background-color: $surface-container-highest
&.m3-container-outlined &.m3-container-outlined
background-color: var(--md-sys-color-surface)
outline-offset: -1px outline-offset: -1px
outline: 1px solid var(--md-sys-color-outline-variant) background-color: $surface
outline: 1px solid $outline-variant
&.m3-container-elevated &.m3-container-elevated
@include elevation-1(false) @include elevation-1(false)
background-color: var(--md-sys-color-surface-container-low)
background-color: $surface-container-low

View File

@ -0,0 +1,3 @@
/*# sourceMappingURL=colors-variables.css.map */

View File

@ -0,0 +1 @@
{"version":3,"sourceRoot":"","sources":[],"names":[],"mappings":"","file":"colors-variables.css"}

View File

@ -0,0 +1,61 @@
$primary: var(--md-sys-color-primary)
$on-primary: var(--md-sys-color-on-primary)
$primary-container: var(--md-sys-color-primary-container)
$on-primary-container: var(--md-sys-color-on-primary-container)
$inverse-primary: var(--md-sys-color-inverse-primary)
$primary-fixed: var(--md-sys-color-primary-fixed)
$on-primary-fixed: var(--md-sys-color-on-primary-fixed)
$primary-fixed-dim: var(--md-sys-color-primary-fixed-dim)
$on-primary-fixed-variant: var(--md-sys-color-on-primary-fixed-variant)
$secondary: var(--md-sys-color-secondary)
$on-secondary: var(--md-sys-color-on-secondary)
$secondary-container: var(--md-sys-color-secondary-container)
$on-secondary-container: var(--md-sys-color-on-secondary-container)
$secondary-fixed: var(--md-sys-color-secondary-fixed)
$on-secondary-fixed: var(--md-sys-color-on-secondary-fixed)
$secondary-fixed-dim: var(--md-sys-color-secondary-fixed-dim)
$on-secondary-fixed-variant: var(--md-sys-color-on-secondary-fixed-variant)
$tertiary: var(--md-sys-color-tertiary)
$on-tertiary: var(--md-sys-color-on-tertiary)
$tertiary-container: var(--md-sys-color-tertiary-container)
$on-tertiary-container: var(--md-sys-color-on-tertiary-container)
$tertiary-fixed: var(--md-sys-color-tertiary-fixed)
$on-tertiary-fixed: var(--md-sys-color-on-tertiary-fixed)
$tertiary-fixed-dim: var(--md-sys-color-tertiary-fixed-dim)
$on-tertiary-fixed-variant: var(--md-sys-color-on-tertiary-fixed-variant)
$error: var(--md-sys-color-error)
$on-error: var(--md-sys-color-on-error)
$error-container: var(--md-sys-color-error-container)
$on-error-container: var(--md-sys-color-on-error-container)
$background: var(--md-sys-color-background)
$on-background: var(--md-sys-color-on-background)
$surface: var(--md-sys-color-surface)
$on-surface: var(--md-sys-color-on-surface)
$surface-variant: var(--md-sys-color-surface-variant)
$on-surface-variant: var(--md-sys-color-on-surface-variant)
$surface-dim: var(--md-sys-color-surface-dim)
$surface-bright: var(--md-sys-color-surface-bright)
$surface-container-lowest: var(--md-sys-color-surface-container-lowest)
$surface-container-low: var(--md-sys-color-surface-container-low)
$surface-container: var(--md-sys-color-surface-container)
$surface-container-high: var(--md-sys-color-surface-container-high)
$surface-container-highest: var(--md-sys-color-surface-container-highest)
$surface-tint: var(--md-sys-color-surface-tint)
$inverse-surface: var(--md-sys-color-inverse-surface)
$inverse-on-surface: var(--md-sys-color-inverse-on-surface)
$outline: var(--md-sys-color-outline)
$outline-variant: var(--md-sys-color-outline-variant)
$shadow: var(--md-sys-color-shadow)
$scrim: var(--md-sys-color-scrim)

View File

@ -1,6 +1,8 @@
@import './css/colors-variables'
hr.m3.m3-divider hr.m3.m3-divider
border: none border: none
outline: 0.5px solid var(--md-sys-color-outline-variant) outline: 0.5px solid $outline-variant
position: relative position: relative
margin: 0 margin: 0

View File

@ -1,56 +1,44 @@
@font-face { @font-face {
font-family: Material-Symbols-Rounded-Regular; font-family: Material-Symbols-Rounded-Regular;
src: url("./font/MaterialSymbolsRounded[FILL,GRAD,opsz,wght].ttf"); src: url("./font/MaterialSymbolsRounded[FILL,GRAD,opsz,wght].ttf");
src: url("./font/MaterialSymbolsRounded[FILL,GRAD,opsz,wght].woff2") src: url("./font/MaterialSymbolsRounded[FILL,GRAD,opsz,wght].woff2") format("woff2"); }
format("woff2");
}
@font-face { @font-face {
font-family: Material-Symbols-Outlined-Regular; font-family: Material-Symbols-Rounded-Regular;
src: url("./font/MaterialSymbolsOutlined[FILL,GRAD,opsz,wght].ttf"); src: url("./font/MaterialSymbolsOutlined[FILL,GRAD,opsz,wght].ttf");
src: url("./font/MaterialSymbolsOutlined[FILL,GRAD,opsz,wght].woff2") src: url("./font/MaterialSymbolsOutlined[FILL,GRAD,opsz,wght].woff2") format("woff2"); }
format("woff2");
}
@font-face { @font-face {
font-family: Material-Symbols-Sharp-Regular; font-family: Material-Symbols-Sharp-Regular;
src: url("./font/MaterialSymbolsSharp[FILL,GRAD,opsz,wght].ttf"); src: url("./font/MaterialSymbolsSharp[FILL,GRAD,opsz,wght].ttf");
src: url("./font/MaterialSymbolsSharp[FILL,GRAD,opsz,wght].woff2") src: url("./font/MaterialSymbolsSharp[FILL,GRAD,opsz,wght].woff2") format("woff2"); }
format("woff2");
}
@font-face { @font-face {
font-family: Roboto; font-family: Roboto, system-ui;
font-face-name: Thin; font-face-name: Thin;
font-weight: 100; font-weight: 100;
src: url("./font/Roboto-Thin.ttf"); src: url("./font/Roboto-Thin.ttf"); }
}
@font-face { @font-face {
font-family: Roboto; font-family: Roboto, system-ui;
font-face-name: Light; font-face-name: Light;
font-weight: 300; font-weight: 300;
src: url("./font/Roboto-Light.ttf"); src: url("./font/Roboto-Light.ttf"); }
}
@font-face { @font-face {
font-family: Roboto; font-family: Roboto, system-ui;
font-face-name: Regular; font-face-name: Regular;
font-weight: 400; font-weight: 400;
src: url("./font/Roboto-Regular.ttf"); src: url("./font/Roboto-Regular.ttf"); }
}
@font-face { @font-face {
font-family: Roboto; font-family: Roboto, system-ui;
font-face-name: Medium; font-face-name: Medium;
font-weight: 500; font-weight: 500;
src: url("./font/Roboto-Medium.ttf"); src: url("./font/Roboto-Medium.ttf"); }
}
@font-face { @font-face {
font-family: Roboto; font-family: Roboto, system-ui;
font-face-name: Bold; font-face-name: Bold;
font-weight: 700; font-weight: 700;
src: url("./font/Roboto-Bold.ttf"); src: url("./font/Roboto-Bold.ttf"); }
}
@font-face { @font-face {
font-family: Roboto; font-family: Roboto, system-ui;
font-face-name: Black; font-face-name: Black;
font-weight: 900; font-weight: 900;
src: url("./font/Roboto-Black.ttf"); src: url("./font/Roboto-Black.ttf"); }
}
/*# sourceMappingURL=fonts.css.map */ /*# sourceMappingURL=fonts.css.map */

View File

@ -1 +1,7 @@
{"version":3,"sourceRoot":"","sources":["fonts.sass"],"names":[],"mappings":"AAGI;EACI;EACA;EACA;;AAHJ;EACI;EACA;EACA;;AAHJ;EACI;EACA;EACA;;AAKJ;EACI;EACA;EACA;EACA;;AAJJ;EACI;EACA;EACA;EACA;;AAJJ;EACI;EACA;EACA;EACA;;AAJJ;EACI;EACA;EACA;EACA;;AAJJ;EACI;EACA;EACA;EACA;;AAJJ;EACI;EACA;EACA;EACA","file":"fonts.css"} {
"version": 3,
"mappings": ";EAIQ,WAAW,EAAE,gCAAwC;EACrD,GAAG,EAAE,6DAAqE;EAC1E,GAAG,EAAE,+EAAuF;;EAF5F,WAAW,EAAE,iCAAwC;EACrD,GAAG,EAAE,8DAAqE;EAC1E,GAAG,EAAE,gFAAuF;;EAF5F,WAAW,EAAE,8BAAwC;EACrD,GAAG,EAAE,2DAAqE;EAC1E,GAAG,EAAE,6EAAuF;;EAM5F,WAAW,EAAE,iBAAiB;EAC9B,cAAc,EAAE,IAAQ;EACxB,WAAW,EAAE,GAAU;EACvB,GAAG,EAAE,6BAAiC;;EAHtC,WAAW,EAAE,iBAAiB;EAC9B,cAAc,EAAE,KAAQ;EACxB,WAAW,EAAE,GAAU;EACvB,GAAG,EAAE,8BAAiC;;EAHtC,WAAW,EAAE,iBAAiB;EAC9B,cAAc,EAAE,OAAQ;EACxB,WAAW,EAAE,GAAU;EACvB,GAAG,EAAE,gCAAiC;;EAHtC,WAAW,EAAE,iBAAiB;EAC9B,cAAc,EAAE,MAAQ;EACxB,WAAW,EAAE,GAAU;EACvB,GAAG,EAAE,+BAAiC;;EAHtC,WAAW,EAAE,iBAAiB;EAC9B,cAAc,EAAE,IAAQ;EACxB,WAAW,EAAE,GAAU;EACvB,GAAG,EAAE,6BAAiC;;EAHtC,WAAW,EAAE,iBAAiB;EAC9B,cAAc,EAAE,KAAQ;EACxB,WAAW,EAAE,GAAU;EACvB,GAAG,EAAE,8BAAiC",
"sources": ["fonts.sass"],
"names": [],
"file": "fonts.css"
}

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

View File

@ -5,6 +5,7 @@
@import "ripple" @import "ripple"
@import "divider" @import "divider"
@import "container" @import "container"
@import "typography"
@import "mixins/m3-mixins" @import "mixins/m3-mixins"
@ -19,9 +20,9 @@
@import "input-styles/checkbox" @import "input-styles/checkbox"
@import "input-styles/text-field" @import "input-styles/text-field"
@import "./themes/tokens" @import "./themes/tokens.css"
@import "./themes/colors.module" @import "./themes/colors.module.css"
@import "./themes/typography.module" @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)
@ -36,3 +37,24 @@ html
background-color: var(--md-sys-color-surface) background-color: var(--md-sys-color-surface)
border-radius: 25px border-radius: 25px
button:not(.m3-fab, .m3-icon-button)
@include m3-typography-mixin('label-large')
max-height: 40px
width: min-content
white-space: nowrap
height: min-content
box-sizing: border-box
transition: background-color, box-shadow, .2s cubic-bezier(0.2, 0, 0, 1) !important
&.m3
@include center(inline-flex)
gap: 8px
border: none
contain: content
text-align: center
padding: 10px 24px
flex-direction: row
border-radius: 100px
box-sizing: border-box

View File

@ -1,69 +1,57 @@
svg.m3.m3-svg-icon > text { svg.m3.m3-svg-icon > text {
alignment-baseline: central;
text-anchor: middle; text-anchor: middle;
} dominant-baseline: middle;
alignment-baseline: middle; }
svg.m3.m3-svg-icon > text.m3-size-12px { svg.m3.m3-svg-icon > text.m3-size-12px {
width: 12px; width: 12px;
aspect-ratio: 1; aspect-ratio: 1;
line-height: 12px;
font-size: 12px; font-size: 12px;
} line-height: 12px; }
svg.m3.m3-svg-icon > text.m3-size-16px { svg.m3.m3-svg-icon > text.m3-size-16px {
width: 16px; width: 16px;
aspect-ratio: 1; aspect-ratio: 1;
line-height: 16px;
font-size: 16px; font-size: 16px;
} line-height: 16px; }
svg.m3.m3-svg-icon > text.m3-size-20px { svg.m3.m3-svg-icon > text.m3-size-20px {
width: 20px; width: 20px;
aspect-ratio: 1; aspect-ratio: 1;
line-height: 20px;
font-size: 20px; font-size: 20px;
} line-height: 20px; }
svg.m3.m3-svg-icon > text.m3-size-24px { svg.m3.m3-svg-icon > text.m3-size-24px {
width: 24px; width: 24px;
aspect-ratio: 1; aspect-ratio: 1;
line-height: 24px;
font-size: 24px; font-size: 24px;
} line-height: 24px; }
svg.m3.m3-svg-icon > text.m3-size-28px { svg.m3.m3-svg-icon > text.m3-size-28px {
width: 28px; width: 28px;
aspect-ratio: 1; aspect-ratio: 1;
line-height: 28px;
font-size: 28px; font-size: 28px;
} line-height: 28px; }
svg.m3.m3-svg-icon > text.m3-size-32px { svg.m3.m3-svg-icon > text.m3-size-32px {
width: 32px; width: 32px;
aspect-ratio: 1; aspect-ratio: 1;
line-height: 32px;
font-size: 32px; font-size: 32px;
} line-height: 32px; }
svg.m3.m3-svg-icon > text.m3-size-36px { svg.m3.m3-svg-icon > text.m3-size-36px {
width: 36px; width: 36px;
aspect-ratio: 1; aspect-ratio: 1;
line-height: 36px;
font-size: 36px; font-size: 36px;
} line-height: 36px; }
svg.m3.m3-svg-icon > text.m3-size-40px { svg.m3.m3-svg-icon > text.m3-size-40px {
width: 40px; width: 40px;
aspect-ratio: 1; aspect-ratio: 1;
line-height: 40px;
font-size: 40px; font-size: 40px;
} line-height: 40px; }
svg.m3.m3-svg-icon > text.m3-size-48px { svg.m3.m3-svg-icon > text.m3-size-48px {
width: 48px; width: 48px;
aspect-ratio: 1; aspect-ratio: 1;
line-height: 48px;
font-size: 48px; font-size: 48px;
} line-height: 48px; }
svg.m3.m3-svg-icon > text.m3-Outlined { svg.m3.m3-svg-icon > text.m3-Outlined {
font-family: Material-Symbols-Outlined-Regular; font-family: Material-Symbols-Rounded-Regular; }
}
svg.m3.m3-svg-icon > text.m3-Rounded { svg.m3.m3-svg-icon > text.m3-Rounded {
font-family: Material-Symbols-Rounded-Regular; font-family: Material-Symbols-Rounded-Regular; }
}
svg.m3.m3-svg-icon > text.m3-Sharp { svg.m3.m3-svg-icon > text.m3-Sharp {
font-family: Material-Symbols-Sharp-Regular; font-family: Material-Symbols-Sharp-Regular; }
}
/*# sourceMappingURL=icon.css.map */ /*# sourceMappingURL=icon.css.map */

View File

@ -1 +1,7 @@
{"version":3,"sourceRoot":"","sources":["icon.sass"],"names":[],"mappings":"AAII;EACI;EACA;;AAGA;EACI,OATA;EAUA;EACA,aAXA;EAYA,WAZA;;AAQJ;EACI,OATA;EAUA;EACA,aAXA;EAYA,WAZA;;AAQJ;EACI,OATA;EAUA;EACA,aAXA;EAYA,WAZA;;AAQJ;EACI,OATA;EAUA;EACA,aAXA;EAYA,WAZA;;AAQJ;EACI,OATA;EAUA;EACA,aAXA;EAYA,WAZA;;AAQJ;EACI,OATA;EAUA;EACA,aAXA;EAYA,WAZA;;AAQJ;EACI,OATA;EAUA;EACA,aAXA;EAYA,WAZA;;AAQJ;EACI,OATA;EAUA;EACA,aAXA;EAYA,WAZA;;AAQJ;EACI,OATA;EAUA;EACA,aAXA;EAYA,WAZA;;AAeJ;EACI;;AADJ;EACI;;AADJ;EACI","file":"icon.css"} {
"version": 3,
"mappings": "AAII,yBAAQ;EACJ,WAAW,EAAE,MAAM;EACnB,iBAAiB,EAAE,MAAM;EACzB,kBAAkB,EAAE,MAAM;AAG1B,sCAAyB;EACrB,KAAK,EAVZ,IAAI;EAWG,YAAY,EAAE,CAAC;EACf,SAAS,EAZhB,IAAI;EAaG,WAAW,EAblB,IAAI;AASD,sCAAyB;EACrB,KAAK,EAVN,IAAI;EAWH,YAAY,EAAE,CAAC;EACf,SAAS,EAZV,IAAI;EAaH,WAAW,EAbZ,IAAI;AASP,sCAAyB;EACrB,KAAK,EAVA,IAAI;EAWT,YAAY,EAAE,CAAC;EACf,SAAS,EAZJ,IAAI;EAaT,WAAW,EAbN,IAAI;AASb,sCAAyB;EACrB,KAAK,EAVM,IAAI;EAWf,YAAY,EAAE,CAAC;EACf,SAAS,EAZE,IAAI;EAaf,WAAW,EAbA,IAAI;AASnB,sCAAyB;EACrB,KAAK,EAVY,IAAI;EAWrB,YAAY,EAAE,CAAC;EACf,SAAS,EAZQ,IAAI;EAarB,WAAW,EAbM,IAAI;AASzB,sCAAyB;EACrB,KAAK,EAVkB,IAAI;EAW3B,YAAY,EAAE,CAAC;EACf,SAAS,EAZc,IAAI;EAa3B,WAAW,EAbY,IAAI;AAS/B,sCAAyB;EACrB,KAAK,EAVwB,IAAI;EAWjC,YAAY,EAAE,CAAC;EACf,SAAS,EAZoB,IAAI;EAajC,WAAW,EAbkB,IAAI;AASrC,sCAAyB;EACrB,KAAK,EAV8B,IAAI;EAWvC,YAAY,EAAE,CAAC;EACf,SAAS,EAZ0B,IAAI;EAavC,WAAW,EAbwB,IAAI;AAS3C,sCAAyB;EACrB,KAAK,EAVoC,IAAI;EAW7C,YAAY,EAAE,CAAC;EACf,SAAS,EAZgC,IAAI;EAa7C,WAAW,EAb8B,IAAI;AAgBjD,qCAAoB;EAChB,WAAW,EAAE,iCAAiC;AADlD,oCAAoB;EAChB,WAAW,EAAE,gCAAiC;AADlD,kCAAoB;EAChB,WAAW,EAAE,8BAAiC",
"sources": ["icon.sass"],
"names": [],
"file": "icon.css"
}

View File

@ -3,15 +3,16 @@ svg.m3.m3-svg-icon
$types: ["Outlined", "Rounded", "Sharp"] $types: ["Outlined", "Rounded", "Sharp"]
& > text & > text
alignment-baseline: central
text-anchor: middle text-anchor: middle
dominant-baseline: middle
alignment-baseline: middle
@each $size in $sizes @each $size in $sizes
& > text.m3-size-#{$size} & > text.m3-size-#{$size}
width: $size width: $size
aspect-ratio: 1 aspect-ratio: 1
line-height: $size
font-size: $size font-size: $size
line-height: $size
@each $type in $types @each $type in $types
& > text.m3-#{$type} & > text.m3-#{$type}

View File

@ -1,3 +1,5 @@
@import '../css/colors-variables'
div.m3.m3-checkbox-container div.m3.m3-checkbox-container
@include m3-checkbox-container-mixin @include m3-checkbox-container-mixin
@ -13,55 +15,53 @@ div.m3.m3-checkbox-container
position: absolute position: absolute
input[type="checkbox"].m3.m3-checkbox input[type="checkbox"].m3.m3-checkbox
@include center(flex)
z-index: 10 z-index: 10
display: flex
width: 1.125rem width: 1.125rem
height: 1.125rem height: 1.125rem
appearance: none appearance: none
position: absolute position: absolute
align-items: center
border-radius: .14rem border-radius: .14rem
box-sizing: content-box box-sizing: content-box
justify-content: center
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 position: absolute
color: var(--md-sys-color-on-surface-variant) color: $on-surface-variant
transition: color .2s cubic-bezier(0.2, 0, 0, 1) transition: color .2s cubic-bezier(0.2, 0, 0, 1)
&:is(:user-invalid:is(:checked, :indeterminate), .m3.m3-error:is(:checked, :indeterminate)) &:is(:user-invalid:is(:checked, :indeterminate), .m3.m3-error:is(:checked, :indeterminate))
& ~ span.m3-checkbox-state & ~ span.m3-checkbox-state
color: var(--md-sys-color-error) color: $error
background: var(--md-sys-color-on-error) background: $on-error
&:is(:user-invalid, .m3.m3-error):not(:checked) &:is(:user-invalid, .m3.m3-error):not(:checked)
& ~ span.m3-checkbox-state & ~ span.m3-checkbox-state
color: var(--md-sys-color-error) color: $error
&:is(:checked:is(:hover, &):not(.m3.m3-error, :disabled), :indeterminate:is(:hover, &):not(.m3.m3-error, :disabled)) &:is(:checked:is(:hover, &):not(.m3.m3-error, :disabled), :indeterminate:is(:hover, &):not(.m3.m3-error, :disabled))
& ~ span.m3-checkbox-state & ~ span.m3-checkbox-state
color: var(--md-sys-color-primary) color: $primary
background: var(--md-sys-color-on-primary) background: $on-primary
&:not(:checked, :indeterminate, :disabled, :user-invalid):hover ~ span.m3-checkbox-state &:not(:checked, :indeterminate, :disabled, :user-invalid):hover ~ span.m3-checkbox-state
color: var(--md-sys-color-on-surface) color: $on-surface
&:disabled ~ * &:disabled ~ *
&:is(:hover, &, :checked) &:is(:hover, &, :checked)
opacity: 38% opacity: 38%
& ~ span.m3-checkbox-state & ~ span.m3-checkbox-state
@include center(flex)
z-index: 10 z-index: 10
display: flex
font-size: 24px font-size: 24px
font-weight: 700 font-weight: 700
line-height: 24px line-height: 24px
align-items: center
pointer-events: none pointer-events: none
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
@ -78,30 +78,30 @@ input[type="checkbox"].m3.m3-checkbox
&:not(:disabled) &:not(:disabled)
&:is(:user-invalid:is(:hover, :indeterminate:hover), .m3.m3-error:hover) &:is(:user-invalid:is(:hover, :indeterminate:hover), .m3.m3-error:hover)
& ~ span.m3.m3-checkbox-state-layer & ~ span.m3.m3-checkbox-state-layer
background-color: color-mix(in srgb, var(--md-sys-color-error) 8%, transparent) background-color: color-mix(in srgb, $error 8%, transparent)
&: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, $error 12%, transparent)
& ~ span.m3-ripple-domain > .m3.ripple & ~ span.m3-ripple-domain > .m3.m3-ripple
background-color: color-mix(in srgb, var(--md-sys-color-error) 20%, transparent) background-color: color-mix(in srgb, $error 20%, transparent)
&:is(:checked:hover, :indeterminate:hover) ~ span.m3.m3-checkbox-state-layer &:is(:checked:hover, :indeterminate:hover) ~ span.m3.m3-checkbox-state-layer
background-color: color-mix(in srgb, var(--md-sys-color-primary) 8%, transparent) background-color: color-mix(in srgb, $primary 8%, transparent)
&: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, $primary 12%, transparent)
& ~ span.m3-ripple-domain > .m3.ripple & ~ span.m3-ripple-domain > .m3.m3-ripple
background-color: color-mix(in srgb, var(--md-sys-color-on-surface) 20%, transparent) background-color: color-mix(in srgb, $on-surface 20%, transparent)
&:hover &:hover
& ~ span.m3-checkbox-state-layer & ~ span.m3-checkbox-state-layer
background-color: color-mix(in srgb, var(--md-sys-color-on-surface) 8%, transparent) background-color: color-mix(in srgb, $on-surface 8%, transparent)
&: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, $on-surface 12%, transparent)
& ~ span.m3-ripple-domain > .m3.ripple & ~ span.m3-ripple-domain > .m3.m3-ripple
background-color: color-mix(in srgb, var(--md-sys-color-primary) 20%, transparent) background-color: color-mix(in srgb, $primary 20%, transparent)

View File

@ -32,7 +32,7 @@ div.m3.m3-radio > input[type=radio].m3.m3-radio:not(:disabled):checked:hover + s
div.m3.m3-radio > input[type=radio].m3.m3-radio:not(:disabled):is(:checked:active, :indeterminate:active) + span.m3.m3-radio-state-layer { div.m3.m3-radio > input[type=radio].m3.m3-radio:not(:disabled):is(:checked:active, :indeterminate:active) + span.m3.m3-radio-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);
} }
div.m3.m3-radio > input[type=radio].m3.m3-radio:not(:disabled):is(:checked:active, :indeterminate:active) + span.m3.m3-radio-state-layer ~ span.m3-ripple-domain > .m3.ripple { div.m3.m3-radio > input[type=radio].m3.m3-radio:not(:disabled):is(:checked:active, :indeterminate:active) + span.m3.m3-radio-state-layer ~ span.m3-ripple-domain > .m3.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);
} }
div.m3.m3-radio > input[type=radio].m3.m3-radio:not(:disabled):hover + span.m3.m3-radio-state-layer { div.m3.m3-radio > input[type=radio].m3.m3-radio:not(:disabled):hover + span.m3.m3-radio-state-layer {
@ -41,7 +41,7 @@ div.m3.m3-radio > input[type=radio].m3.m3-radio:not(:disabled):hover + span.m3.m
div.m3.m3-radio > input[type=radio].m3.m3-radio:not(:disabled):active + span.m3.m3-radio-state-layer { div.m3.m3-radio > input[type=radio].m3.m3-radio:not(:disabled):active + span.m3.m3-radio-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);
} }
div.m3.m3-radio > input[type=radio].m3.m3-radio:not(:disabled):active + span.m3.m3-radio-state-layer ~ span.m3-ripple-domain > .m3.ripple { div.m3.m3-radio > input[type=radio].m3.m3-radio:not(:disabled):active + span.m3.m3-radio-state-layer ~ span.m3-ripple-domain > .m3.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);
} }
div.m3.m3-radio > input[type=radio].m3.m3-radio:disabled:is(:not(:checked), div.m3.m3-radio > input[type=radio].m3.m3-radio:disabled:checked) ~ svg > circle.m3-radio-outline { div.m3.m3-radio > input[type=radio].m3.m3-radio:disabled:is(:not(:checked), div.m3.m3-radio > input[type=radio].m3.m3-radio:disabled:checked) ~ svg > circle.m3-radio-outline {

View File

@ -1,9 +1,10 @@
@import '../css/colors-variables'
div.m3.m3-radio-container div.m3.m3-radio-container
@include center(inline-flex)
width: 20px width: 20px
height: 20px height: 20px
align-items: center
display: inline-flex
justify-content: center
& + label.m3.m3-radio-label & + label.m3.m3-radio-label
margin-inline: 3px margin-inline: 3px
@ -31,47 +32,49 @@ div.m3.m3-radio-container
&:not(:disabled) &:not(:disabled)
&:checked:hover + span.m3.m3-radio-state-layer &:checked:hover + span.m3.m3-radio-state-layer
background-color: color-mix(in srgb, var(--md-sys-color-primary) 8%, transparent) background-color: color-mix(in srgb, $primary 8%, transparent)
&:is(:checked:active, :indeterminate:active) + span.m3.m3-radio-state-layer &:is(:checked:active, :indeterminate:active) + span.m3.m3-radio-state-layer
background-color: color-mix(in srgb, var(--md-sys-color-primary) 12%, transparent) background-color: color-mix(in srgb, $primary 12%, transparent)
& ~ span.m3-ripple-domain > .m3.ripple
background-color: color-mix(in srgb, var(--md-sys-color-on-surface) 20%, transparent) & ~ span.m3-ripple-domain > .m3.m3-ripple
background-color: color-mix(in srgb, $on-surface 20%, transparent)
&:hover &:hover
& + span.m3.m3-radio-state-layer & + span.m3.m3-radio-state-layer
background-color: color-mix(in srgb, var(--md-sys-color-on-surface) 8%, transparent) background-color: color-mix(in srgb, $on-surface 8%, transparent)
&:active + span.m3.m3-radio-state-layer &:active + span.m3.m3-radio-state-layer
background-color: color-mix(in srgb, var(--md-sys-color-on-surface) 12%, transparent) background-color: color-mix(in srgb, $on-surface 12%, transparent)
& ~ span.m3-ripple-domain > .m3.ripple
background-color: color-mix(in srgb, var(--md-sys-color-primary) 20%, transparent) & ~ span.m3-ripple-domain > .m3.m3-ripple
background-color: color-mix(in srgb, $primary 20%, transparent)
&:disabled &:disabled
&:is(:not(:checked), &:checked) ~ svg &:is(:not(:checked), &:checked) ~ svg
& > circle.m3-radio-outline & > circle.m3-radio-outline
stroke-opacity: 38% stroke-opacity: 38%
stroke: var(--md-sys-color-on-surface) stroke: $on-surface
&:checked ~ svg > circle.m3-radio-state &:checked ~ svg > circle.m3-radio-state
fill-opacity: 38% fill-opacity: 38%
fill: var(--md-sys-color-on-surface) fill: $on-surface
&:not(:checked) ~ svg &:not(:checked) ~ svg
& > circle.m3-radio-outline & > circle.m3-radio-outline
stroke: var(--md-sys-color-on-surface-variant) stroke: $on-surface-variant
& > circle.m3-radio-state & > circle.m3-radio-state
fill: $primary
fill-opacity: 0 fill-opacity: 0
fill: var(--md-sys-color-primary)
&:checked ~ svg &:checked ~ svg
& > circle.m3-radio-outline & > circle.m3-radio-outline
stroke: var(--md-sys-color-primary) stroke: $primary
& > circle.m3-radio-state & > circle.m3-radio-state
fill: $primary
fill-opacity: 1 fill-opacity: 1
fill: var(--md-sys-color-primary)
svg svg
margin: 0 margin: 0
@ -89,7 +92,7 @@ div.m3.m3-radio-container
fill: black fill: black
fill-opacity: 0 fill-opacity: 0
stroke-width: 2px stroke-width: 2px
stroke: var(--md-sys-color-on-surface-variant) stroke: $on-surface-variant
&.m3-radio-state &.m3-radio-state
r: 5px r: 5px

View File

@ -1,3 +1,80 @@
/*
Error: Undefined mixin 'input-range-thumb-mixin'.
on line 35 of slider.sass, in `input-range-thumb-mixin'
from line 35 of slider.sass
30: overflow: hidden
31: border-radius: 2px
32: background-color: var(--md-sys-color-primary)
33:
34: &::-moz-range-thumb
35: @include input-range-thumb-mixin
36:
37: border: none
38:
39: &::-webkit-slider-container
40: appearance: none
/*# sourceMappingURL=slider.css.map */ Backtrace:
slider.sass:35:in `input-range-thumb-mixin'
slider.sass:35
/usr/lib/ruby/gems/3.0.0/gems/sass-3.7.4/lib/sass/tree/visitors/perform.rb:348:in `block in visit_mixin'
/usr/lib/ruby/gems/3.0.0/gems/sass-3.7.4/lib/sass/stack.rb:98:in `block in with_mixin'
/usr/lib/ruby/gems/3.0.0/gems/sass-3.7.4/lib/sass/stack.rb:135:in `with_frame'
/usr/lib/ruby/gems/3.0.0/gems/sass-3.7.4/lib/sass/stack.rb:98:in `with_mixin'
/usr/lib/ruby/gems/3.0.0/gems/sass-3.7.4/lib/sass/tree/visitors/perform.rb:346:in `visit_mixin'
/usr/lib/ruby/gems/3.0.0/gems/sass-3.7.4/lib/sass/tree/visitors/base.rb:36:in `visit'
/usr/lib/ruby/gems/3.0.0/gems/sass-3.7.4/lib/sass/tree/visitors/perform.rb:158:in `block in visit'
/usr/lib/ruby/gems/3.0.0/gems/sass-3.7.4/lib/sass/stack.rb:79:in `block in with_base'
/usr/lib/ruby/gems/3.0.0/gems/sass-3.7.4/lib/sass/stack.rb:135:in `with_frame'
/usr/lib/ruby/gems/3.0.0/gems/sass-3.7.4/lib/sass/stack.rb:79:in `with_base'
/usr/lib/ruby/gems/3.0.0/gems/sass-3.7.4/lib/sass/tree/visitors/perform.rb:158:in `visit'
/usr/lib/ruby/gems/3.0.0/gems/sass-3.7.4/lib/sass/tree/visitors/perform.rb:440:in `block (2 levels) in visit_rule'
/usr/lib/ruby/gems/3.0.0/gems/sass-3.7.4/lib/sass/tree/visitors/perform.rb:440:in `map'
/usr/lib/ruby/gems/3.0.0/gems/sass-3.7.4/lib/sass/tree/visitors/perform.rb:440:in `block in visit_rule'
/usr/lib/ruby/gems/3.0.0/gems/sass-3.7.4/lib/sass/tree/visitors/perform.rb:179:in `with_environment'
/usr/lib/ruby/gems/3.0.0/gems/sass-3.7.4/lib/sass/tree/visitors/perform.rb:438:in `visit_rule'
/usr/lib/ruby/gems/3.0.0/gems/sass-3.7.4/lib/sass/tree/visitors/base.rb:36:in `visit'
/usr/lib/ruby/gems/3.0.0/gems/sass-3.7.4/lib/sass/tree/visitors/perform.rb:158:in `block in visit'
/usr/lib/ruby/gems/3.0.0/gems/sass-3.7.4/lib/sass/stack.rb:79:in `block in with_base'
/usr/lib/ruby/gems/3.0.0/gems/sass-3.7.4/lib/sass/stack.rb:135:in `with_frame'
/usr/lib/ruby/gems/3.0.0/gems/sass-3.7.4/lib/sass/stack.rb:79:in `with_base'
/usr/lib/ruby/gems/3.0.0/gems/sass-3.7.4/lib/sass/tree/visitors/perform.rb:158:in `visit'
/usr/lib/ruby/gems/3.0.0/gems/sass-3.7.4/lib/sass/tree/visitors/perform.rb:440:in `block (2 levels) in visit_rule'
/usr/lib/ruby/gems/3.0.0/gems/sass-3.7.4/lib/sass/tree/visitors/perform.rb:440:in `map'
/usr/lib/ruby/gems/3.0.0/gems/sass-3.7.4/lib/sass/tree/visitors/perform.rb:440:in `block in visit_rule'
/usr/lib/ruby/gems/3.0.0/gems/sass-3.7.4/lib/sass/tree/visitors/perform.rb:179:in `with_environment'
/usr/lib/ruby/gems/3.0.0/gems/sass-3.7.4/lib/sass/tree/visitors/perform.rb:438:in `visit_rule'
/usr/lib/ruby/gems/3.0.0/gems/sass-3.7.4/lib/sass/tree/visitors/base.rb:36:in `visit'
/usr/lib/ruby/gems/3.0.0/gems/sass-3.7.4/lib/sass/tree/visitors/perform.rb:158:in `block in visit'
/usr/lib/ruby/gems/3.0.0/gems/sass-3.7.4/lib/sass/stack.rb:79:in `block in with_base'
/usr/lib/ruby/gems/3.0.0/gems/sass-3.7.4/lib/sass/stack.rb:135:in `with_frame'
/usr/lib/ruby/gems/3.0.0/gems/sass-3.7.4/lib/sass/stack.rb:79:in `with_base'
/usr/lib/ruby/gems/3.0.0/gems/sass-3.7.4/lib/sass/tree/visitors/perform.rb:158:in `visit'
/usr/lib/ruby/gems/3.0.0/gems/sass-3.7.4/lib/sass/tree/visitors/base.rb:52:in `block in visit_children'
/usr/lib/ruby/gems/3.0.0/gems/sass-3.7.4/lib/sass/tree/visitors/base.rb:52:in `map'
/usr/lib/ruby/gems/3.0.0/gems/sass-3.7.4/lib/sass/tree/visitors/base.rb:52:in `visit_children'
/usr/lib/ruby/gems/3.0.0/gems/sass-3.7.4/lib/sass/tree/visitors/perform.rb:167:in `block in visit_children'
/usr/lib/ruby/gems/3.0.0/gems/sass-3.7.4/lib/sass/tree/visitors/perform.rb:179:in `with_environment'
/usr/lib/ruby/gems/3.0.0/gems/sass-3.7.4/lib/sass/tree/visitors/perform.rb:166:in `visit_children'
/usr/lib/ruby/gems/3.0.0/gems/sass-3.7.4/lib/sass/tree/visitors/base.rb:36:in `block in visit'
/usr/lib/ruby/gems/3.0.0/gems/sass-3.7.4/lib/sass/tree/visitors/perform.rb:186:in `visit_root'
/usr/lib/ruby/gems/3.0.0/gems/sass-3.7.4/lib/sass/tree/visitors/base.rb:36:in `visit'
/usr/lib/ruby/gems/3.0.0/gems/sass-3.7.4/lib/sass/tree/visitors/perform.rb:157:in `visit'
/usr/lib/ruby/gems/3.0.0/gems/sass-3.7.4/lib/sass/tree/visitors/perform.rb:10:in `visit'
/usr/lib/ruby/gems/3.0.0/gems/sass-3.7.4/lib/sass/tree/root_node.rb:36:in `css_tree'
/usr/lib/ruby/gems/3.0.0/gems/sass-3.7.4/lib/sass/tree/root_node.rb:29:in `render_with_sourcemap'
/usr/lib/ruby/gems/3.0.0/gems/sass-3.7.4/lib/sass/engine.rb:389:in `_render_with_sourcemap'
/usr/lib/ruby/gems/3.0.0/gems/sass-3.7.4/lib/sass/engine.rb:307:in `render_with_sourcemap'
/usr/lib/ruby/gems/3.0.0/gems/sass-3.7.4/lib/sass/exec/sass_scss.rb:387:in `run'
/usr/lib/ruby/gems/3.0.0/gems/sass-3.7.4/lib/sass/exec/sass_scss.rb:63:in `process_result'
/usr/lib/ruby/gems/3.0.0/gems/sass-3.7.4/lib/sass/exec/base.rb:50:in `parse'
/usr/lib/ruby/gems/3.0.0/gems/sass-3.7.4/lib/sass/exec/base.rb:18:in `parse!'
/usr/lib/ruby/gems/3.0.0/gems/sass-3.7.4/bin/sass:13:in `<top (required)>'
/usr/bin/sass:23:in `load'
/usr/bin/sass:23:in `<main>'
*/
body:before {
white-space: pre;
font-family: monospace;
content: "Error: Undefined mixin 'input-range-thumb-mixin'.\A on line 35 of slider.sass, in `input-range-thumb-mixin'\A from line 35 of slider.sass\A \A 30: overflow: hidden\A 31: border-radius: 2px\A 32: background-color: var(--md-sys-color-primary)\A 33: \A 34: &::-moz-range-thumb\A 35: @include input-range-thumb-mixin\A 36: \A 37: border: none\A 38: \A 39: &::-webkit-slider-container\A 40: appearance: none"; }

View File

@ -1,47 +1,107 @@
@use 'sass:math'
@import '../css/colors-variables'
@mixin input-range-thumb-mixin
@include elevation-1(false)
&::after
content: '1'
&:hover
outline: 10px solid color-mix(in srgb, $primary 8%, transparent)
&:is(:active, :focus-visible)
outline: 10px solid color-mix(in srgb, $primary 12%, transparent)
width: 20px
height: 20px
appearance: none
border-radius: 50%
box-sizing: border-box
outline: 10px solid transparent
background: $primary
transition: .2s cubic-bezier(0.2, 0, 0, 1)
div.m3.m3-slider-container div.m3.m3-slider-container
height: 20px height: 20px
display: flex display: flex
position: relative
align-items: center align-items: center
& > input::-webkit-slider-thumb:hover + div.m3.m3-slider-label
opacity: 1
& > div.m3.m3-slider-label
@include center(inline-flex)
top: -10px
opacity: 0
width: 28px
position: absolute
pointer-events: none
height: 14px * math.sqrt(2) + 14px
&::before
top: 0
content: ""
width: 28px
rotate: 45deg
aspect-ratio: 1
position: absolute
border-radius: 14px 14px 0 14px
background-color: $primary
& > label.m3.m3-typography
display: inline
font-weight: 500
margin-top: -5px
position: absolute
font-size: 12px !important
color: $on-primary
& > datalist & > datalist
display: none display: none
input[type="range"].m3.m3-slider input[type="range"].m3.m3-slider
margin: 0 margin: 0
appearance: none appearance: none
border-radius: 2px border-radius: 2px
margin-inline: 8px background: $surface-container-highest
background: linear-gradient(to right, var(--md-sys-color-primary) 0%, var(--md-sys-color-surface-container-highest) 0%)
&:-moz-any(&)
height: 4px
&:-webkit-any(&)
background: linear-gradient(to right, $primary 0%, $surface-container-highest 0%)
&::-moz-range-track
height: 4px
overflow: hidden
border-radius: 2px
&::-moz-range-progress
height: 4px
overflow: hidden
border-radius: 2px
background-color: $primary
&::-moz-range-thumb
@include input-range-thumb-mixin
border: none
&::-webkit-slider-container &::-webkit-slider-container
height: 4px
appearance: none appearance: none
box-shadow: none box-shadow: none
border-radius: 2px border-radius: 2px
min-block-size: 4px min-block-size: 4px
height: 4px !important
&::-webkit-slider-runnable-track &::-webkit-slider-runnable-track
height: 4px height: 20px
&::-webkit-slider-thumb &::-webkit-slider-thumb
@include elevation-1(false) @include input-range-thumb-mixin
&:hover
outline: 10px solid color-mix(in srgb, var(--md-sys-color-primary) 8%, transparent)
&:is(:active, :focus-visible)
outline: 10px solid color-mix(in srgb, var(--md-sys-color-primary) 12%, transparent)
width: 20px
aspect-ratio: 1
appearance: none
border-radius: 50%
margin-top: -8px
box-sizing: border-box
outline: 10px solid transparent
background: var(--md-sys-color-primary)
transition: .2s cubic-bezier(0.2, 0, 0, 1)

View File

@ -1,225 +1,113 @@
div.m3.m3-switch { div.m3.m3-switch {
gap: 20px;
margin: 4px; margin: 4px;
box-sizing: content-box; 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 {
} width: 52px;
div.m3.m3-switch > svg { height: 32px;
overflow: visible; overflow: visible;
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); }
width: 52px; div.m3.m3-switch > svg > g {
height: 32px; transform: translate(11.5%, 81%);
} 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 > text {
transform: translate(11.5%, 81%); font-size: 20px;
transition: 0.2s cubic-bezier(0.175, 0.885, 0.32, 1.275); font-family: Material-Symbols-Outlined-Regular, serif; }
} 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 > g > text { cy: 50%;
font-family: Material-Symbols-Outlined-Regular; cx: 16px;
font-size: 20px; 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;
div.m3.m3-switch > svg > circle.m3.m3-switch-handler { fill-opacity: 0; }
transition: 0.2s cubic-bezier(0.175, 0.885, 0.32, 1.275); div.m3.m3-switch > svg > circle.m3.m3-switch-handler {
cy: 50%; r: 8px; }
cx: 16px; div.m3.m3-switch > svg > rect.m3.m3-switch-track {
} transition: fill 0.2s cubic-bezier(0.175, 0.885, 0.32, 1.275);
div.m3.m3-switch > svg > circle.m3.m3-switch-handler-state-layer { stroke-width: 2px;
r: 20px; border-radius: 16px;
fill-opacity: 0; rx: 15px;
} width: 50px;
div.m3.m3-switch > svg > circle.m3.m3-switch-handler { height: 30px; }
r: 8px; div.m3.m3-switch > input.m3 {
} margin: 0;
div.m3.m3-switch > svg > rect.m3.m3-switch-track { width: 52px;
transition: fill 0.2s cubic-bezier(0.175, 0.885, 0.32, 1.275); height: 32px;
stroke-width: 2px; cursor: pointer;
border-radius: 16px; appearance: none;
rx: 15px; position: absolute;
width: 50px; opacity: 0 !important; }
height: 30px; div.m3.m3-switch > input.m3:disabled {
} cursor: not-allowed; }
div.m3.m3-switch > input.m3 { div.m3.m3-switch > input.m3:not(:checked, :disabled) + svg > circle.m3.m3-switch-handler {
cursor: pointer; fill: var(--md-sys-color-outline); }
appearance: none; div.m3.m3-switch > input.m3:checked:not(:disabled) + svg > g {
opacity: 0 !important; transform: translate(50%, 81%); }
margin: 0; div.m3.m3-switch > input.m3:checked:not(:disabled) + svg > circle.m3.m3-switch-handler {
width: 52px; fill: var(--md-sys-color-on-primary); }
height: 32px; div.m3.m3-switch > input.m3:not(:disabled) + svg > g > text.m3.m3-icon-unchecked {
position: absolute; fill: var(--md-sys-color-on-primary); }
} div.m3.m3-switch > input.m3:not(:disabled) + svg > g > text.m3.m3-icon-checked {
div.m3.m3-switch > input.m3:disabled { fill: var(--md-sys-color-on-primary-container); }
cursor: not-allowed; div.m3.m3-switch > input.m3:checked:disabled + svg > circle.m3.m3-switch-handler {
} fill: var(--md-sys-color-surface); }
div.m3.m3-switch div.m3.m3-switch > input.m3:checked + svg > circle.m3.m3-switch-handler, div.m3.m3-switch > input.m3 + svg:has(text.m3.m3-icon-unchecked) > circle.m3.m3-switch-handler {
> input.m3:not(:checked, :disabled) r: 12px; }
+ svg div.m3.m3-switch > input.m3:checked + svg > g > text.m3.m3-icon-unchecked {
> circle.m3.m3-switch-handler { opacity: 0; }
fill: var(--md-sys-color-outline); div.m3.m3-switch > input.m3:checked + svg > circle.m3:is(.m3-switch-handler, .m3-switch-handler-state-layer) {
} cx: calc(100% - 16px); }
div.m3.m3-switch > input.m3:checked:not(:disabled) + svg > g { div.m3.m3-switch > input.m3:not(:checked) + svg > g > text.m3.m3-icon-checked {
transform: translate(50%, 81%); opacity: 0; }
} div.m3.m3-switch > input.m3:is(&:checked, &):not(:disabled):active + svg > circle.m3.m3-switch-handler {
div.m3.m3-switch r: 14px; }
> input.m3:checked:not(:disabled) div.m3.m3-switch > input.m3:not(:checked):disabled + svg > circle.m3.m3-switch-handler {
+ svg fill-opacity: 38%;
> circle.m3.m3-switch-handler { fill: var(--md-sys-color-on-surface); }
fill: var(--md-sys-color-on-primary); div.m3.m3-switch > input.m3:hover:not(:disabled):checked + svg > circle.m3.m3-switch-handler {
} fill: var(--md-sys-color-primary-container); }
div.m3.m3-switch div.m3.m3-switch > input.m3:hover:not(:disabled):checked + svg > circle.m3.m3-switch-handler-state-layer {
> input.m3:not(:disabled) fill-opacity: 8%;
+ svg fill: var(--md-sys-color-primary); }
> g div.m3.m3-switch > input.m3:hover:not(:disabled):not(:checked) + svg > circle.m3.m3-switch-handler {
> text.m3.m3-icon-unchecked { fill: var(--md-sys-color-on-surface-variant); }
fill: var(--md-sys-color-on-primary); div.m3.m3-switch > input.m3:hover:not(:disabled):not(:checked) + svg > circle.m3.m3-switch-handler-state-layer {
} fill-opacity: 8%;
div.m3.m3-switch fill: var(--md-sys-color-on-surface); }
> input.m3:not(:disabled) div.m3.m3-switch > input.m3:active:not(:disabled):checked + svg > circle.m3.m3-switch-handler-state-layer {
+ svg fill-opacity: 12%;
> g fill: var(--md-sys-color-primary); }
> text.m3.m3-icon-checked { 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-primary-container); fill-opacity: 12%;
} fill: var(--md-sys-color-on-surface); }
div.m3.m3-switch div.m3.m3-switch > input.m3:is(:checked, :checked:disabled) + svg > rect.m3.m3-switch-track {
> input.m3:checked:disabled rx: 16px;
+ svg width: 52px;
> circle.m3.m3-switch-handler { height: 32px;
fill: var(--md-sys-color-surface); stroke-width: 0; }
} div.m3.m3-switch > input.m3:is(&:not(:checked), &:not(:checked):disabled) + svg > rect.m3.m3-switch-track {
div.m3.m3-switch > input.m3:checked + svg > circle.m3.m3-switch-handler, x: 1px;
div.m3.m3-switch y: 1px; }
> input.m3 div.m3.m3-switch > input.m3:not(:checked) + svg > rect.m3.m3-switch-track {
+ svg:has(text.m3.m3-icon-unchecked) stroke: var(--md-sys-color-outline);
> circle.m3.m3-switch-handler { fill: var(--md-sys-color-surface-container-highest); }
r: 12px; div.m3.m3-switch > input.m3:checked + svg > rect.m3.m3-switch-track {
} fill: var(--md-sys-color-primary);
div.m3.m3-switch > input.m3:checked + svg > g > text.m3.m3-icon-unchecked { stroke: var(--md-sys-color-primary); }
opacity: 0; 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); }
div.m3.m3-switch div.m3.m3-switch > input.m3:disabled + svg > rect.m3.m3-switch-track {
> input.m3:checked stroke: color-mix(in srgb, var(--md-sys-color-on-surface) 12%, transparent);
+ svg fill: color-mix(in srgb, var(--md-sys-color-surface-variant) 12%, transparent); }
> circle.m3:is(.m3-switch-handler, .m3-switch-handler-state-layer) { div.m3.m3-switch > input.m3:checked:disabled + svg > g > text.m3 {
cx: calc(100% - 16px); transform: translateX(38.5%);
} fill: color-mix(in srgb, var(--md-sys-color-on-surface) 38%, transparent); }
div.m3.m3-switch div.m3.m3-switch > input.m3:checked:disabled + svg > rect.m3.m3-switch-track {
> input.m3:not(:checked) fill: color-mix(in srgb, var(--md-sys-color-on-surface) 12%, transparent);
+ svg stroke: color-mix(in srgb, var(--md-sys-color-on-surface) 0%, transparent); }
> g
> text.m3.m3-icon-checked {
opacity: 0;
}
div.m3.m3-switch
> input.m3:is(
div.m3.m3-switch > input.m3:checked,
div.m3.m3-switch > input.m3
):not(:disabled):active
+ svg
> circle.m3.m3-switch-handler {
r: 14px;
}
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%;
}
div.m3.m3-switch
> input.m3:hover:not(:disabled):checked
+ svg
> circle.m3.m3-switch-handler {
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 {
fill: var(--md-sys-color-primary);
fill-opacity: 8%;
}
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);
}
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%;
}
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%;
}
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%;
}
div.m3.m3-switch
> input.m3:is(:checked, :checked:disabled)
+ svg
> rect.m3.m3-switch-track {
rx: 16px;
width: 52px;
height: 32px;
stroke-width: 0;
}
div.m3.m3-switch
> input.m3:is(
div.m3.m3-switch > input.m3:not(:checked),
div.m3.m3-switch > input.m3:not(:checked):disabled
)
+ svg
> rect.m3.m3-switch-track {
x: 1px;
y: 1px;
}
div.m3.m3-switch > input.m3:not(:checked) + svg > rect.m3.m3-switch-track {
stroke: var(--md-sys-color-outline);
fill: var(--md-sys-color-surface-container-highest);
}
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);
}
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
);
}
div.m3.m3-switch > input.m3:disabled + svg > rect.m3.m3-switch-track {
stroke: color-mix(in srgb, var(--md-sys-color-on-surface) 12%, transparent);
fill: color-mix(
in srgb,
var(--md-sys-color-surface-variant) 12%,
transparent
);
}
div.m3.m3-switch > input.m3:checked:disabled + svg > g > text.m3 {
transform: translateX(38.5%);
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 {
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);
}
/*# sourceMappingURL=swtich.css.map */ /*# sourceMappingURL=swtich.css.map */

View File

@ -1 +1,7 @@
{"version":3,"sourceRoot":"","sources":["swtich.sass"],"names":[],"mappings":"AAAA;EACI;EACA;EACA;EACA;EACA;EACA;EACA;;AAEA;EACI;EACA;EACA;EACA;;AAEA;EACI;EACA;;AACA;EACI;EACA;;AAER;EACI;EACA;EACA;;AAEJ;EACI;EACA;;AAEJ;EACI;;AAEJ;EACI;EACA;EACA;EACA;EACA;EACA;;AAER;EACI;EACA;EACA;EACA;EACA;EACA;EACA;;AAEA;EACI;;AAGA;EACI;;AAGJ;EACI;;AAEJ;EACI;;AAGJ;EACI;;AAEJ;EACI;;AAER;EACI;;AAEJ;EAEI;;AAGA;EACI;;AAEJ;EACI;;AAGJ;EACI;;AAER;EACI;;AAEJ;EACI;EACA;;AAII;EACI;;AAEJ;EACI;EACA;;AAGJ;EACI;;AAEJ;EACI;EACA;;AAGR;EACI;EACA;;AAEJ;EACI;EACA;;AAER;EACI;EACA;EACA;EACA;;AAEJ;EACI;EACA;;AAEJ;EACI;EACA;;AAEJ;EACI;EACA;;AAGA;EACI;;AAEJ;EACI;EACA;;AAGJ;EACI;EACA;;AAEJ;EACI;EACA","file":"swtich.css"} {
"version": 3,
"mappings": "AAAA,gBAAgB;EACZ,GAAG,EAAE,IAAI;EACT,MAAM,EAAE,GAAG;EACX,MAAM,EAAE,IAAI;EACZ,OAAO,EAAE,IAAI;EACb,WAAW,EAAE,MAAM;EACnB,eAAe,EAAE,IAAI;EACrB,UAAU,EAAE,WAAW;EAEvB,sBAAO;IACH,KAAK,EAAE,IAAI;IACX,MAAM,EAAE,IAAI;IACZ,QAAQ,EAAE,OAAO;IACjB,UAAU,EAAE,4CAA2C;IAEvD,0BAAK;MACD,SAAS,EAAE,qBAAqB;MAChC,UAAU,EAAE,4CAA2C;MACvD,iCAAQ;QACJ,SAAS,EAAE,IAAI;QACf,WAAW,EAAE,wCAAuC;IAE5D,sHAA4E;MACxE,EAAE,EAAE,GAAG;MACP,EAAE,EAAE,IAAI;MACR,UAAU,EAAE,4CAA2C;IAE3D,gEAA2C;MACvC,CAAC,EAAE,IAAI;MACP,YAAY,EAAE,CAAC;IAEnB,oDAA+B;MAC3B,CAAC,EAAE,GAAG;IAEV,gDAA2B;MACvB,UAAU,EAAE,iDAAgD;MAC5D,YAAY,EAAE,GAAG;MACjB,aAAa,EAAE,IAAI;MACnB,EAAE,EAAE,IAAI;MACR,KAAK,EAAE,IAAI;MACX,MAAM,EAAE,IAAI;EAEpB,2BAAY;IACR,MAAM,EAAE,CAAC;IACT,KAAK,EAAE,IAAI;IACX,MAAM,EAAE,IAAI;IACZ,MAAM,EAAE,OAAO;IACf,UAAU,EAAE,IAAI;IAChB,QAAQ,EAAE,QAAQ;IAClB,OAAO,EAAE,YAAY;IAErB,oCAAU;MACN,MAAM,EAAE,WAAW;IAGnB,wFAA+B;MAC3B,IAAI,EAAE,2BAA2B;IAGrC,4DAAK;MACD,SAAS,EAAE,mBAAmB;IAElC,sFAA+B;MAC3B,IAAI,EAAE,8BAA8B;IAGxC,gFAAiC;MAC7B,IAAI,EAAE,8BAA8B;IAExC,8EAA+B;MAC3B,IAAI,EAAE,wCAAwC;IAEtD,gFAAsD;MAClD,IAAI,EAAE,2BAA2B;IAErC,uKAA8C;MAE1C,CAAC,EAAE,IAAI;IAGP,yEAAiC;MAC7B,OAAO,EAAE,CAAC;IAEd,4GAAoE;MAChE,EAAE,EAAE,iBAAiB;IAGzB,6EAA+B;MAC3B,OAAO,EAAE,CAAC;IAElB,sGAA4E;MACxE,CAAC,EAAE,IAAI;IAEX,sFAA4D;MACxD,YAAY,EAAE,GAAG;MACjB,IAAI,EAAE,8BAA8B;IAIhC,4FAA+B;MAC3B,IAAI,EAAE,qCAAqC;IAE/C,wGAA2C;MACvC,YAAY,EAAE,EAAE;MAChB,IAAI,EAAE,2BAA2B;IAGrC,kGAA+B;MAC3B,IAAI,EAAE,sCAAsC;IAEhD,8GAA2C;MACvC,YAAY,EAAE,EAAE;MAChB,IAAI,EAAE,8BAA8B;IAG5C,yGAAyD;MACrD,YAAY,EAAE,GAAG;MACjB,IAAI,EAAE,2BAA2B;IAErC,+GAA+D;MAC3D,YAAY,EAAE,GAAG;MACjB,IAAI,EAAE,8BAA8B;IAE5C,2FAAiE;MAC7D,EAAE,EAAE,IAAI;MACR,KAAK,EAAE,IAAI;MACX,MAAM,EAAE,IAAI;MACZ,YAAY,EAAE,CAAC;IAEnB,yGAA+E;MAC3E,CAAC,EAAE,GAAG;MACN,CAAC,EAAE,GAAG;IAEV,yEAA+C;MAC3C,MAAM,EAAE,2BAA2B;MACnC,IAAI,EAAE,6CAA6C;IAEvD,mEAAyC;MACrC,IAAI,EAAE,2BAA2B;MACjC,MAAM,EAAE,2BAA2B;IAGnC,wDAAe;MACX,IAAI,EAAE,kFAAkF;IAE5F,oEAA2B;MACvB,MAAM,EAAE,mEAAmE;MAC3E,IAAI,EAAE,wEAAwE;IAGlF,gEAAe;MACX,SAAS,EAAE,iBAAiB;MAC5B,IAAI,EAAE,mEAAmE;IAE7E,4EAA2B;MACvB,IAAI,EAAE,mEAAmE;MACzE,MAAM,EAAE,kEAAkE",
"sources": ["swtich.sass"],
"names": [],
"file": "swtich.css"
}

View File

@ -1,3 +1,5 @@
@import '../css/colors-variables'
div.m3.m3-switch div.m3.m3-switch
gap: 20px gap: 20px
margin: 4px margin: 4px
@ -18,7 +20,7 @@ div.m3.m3-switch
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-size: 20px font-size: 20px
font-family: Material-Symbols-Outlined-Regular font-family: Material-Symbols-Outlined-Regular,serif
& > circle.m3.m3-switch-handler-state-layer, & > circle.m3.m3-switch-handler & > circle.m3.m3-switch-handler-state-layer, & > circle.m3.m3-switch-handler
cy: 50% cy: 50%
@ -54,24 +56,24 @@ div.m3.m3-switch
&:not(:checked, :disabled) + svg &:not(:checked, :disabled) + svg
& > circle.m3.m3-switch-handler & > circle.m3.m3-switch-handler
fill: var(--md-sys-color-outline) fill: $outline
&:checked:not(:disabled) + svg &:checked:not(:disabled) + svg
& > g & > g
transform: translate(50%, 81%) transform: translate(50%, 81%)
& > circle.m3.m3-switch-handler & > circle.m3.m3-switch-handler
fill: var(--md-sys-color-on-primary) fill: $on-primary
&:not(:disabled) + svg &:not(:disabled) + svg
& > g > text.m3.m3-icon-unchecked & > g > text.m3.m3-icon-unchecked
fill: var(--md-sys-color-on-primary) fill: $on-primary
& > g > text.m3.m3-icon-checked & > g > text.m3.m3-icon-checked
fill: var(--md-sys-color-on-primary-container) fill: $on-primary-container
&:checked:disabled + svg > circle.m3.m3-switch-handler &:checked:disabled + svg > circle.m3.m3-switch-handler
fill: var(--md-sys-color-surface) fill: $surface
&:checked + svg > circle.m3.m3-switch-handler, &:checked + svg > circle.m3.m3-switch-handler,
& + svg:has(text.m3.m3-icon-unchecked) > circle.m3.m3-switch-handler & + svg:has(text.m3.m3-icon-unchecked) > circle.m3.m3-switch-handler
@ -93,33 +95,33 @@ div.m3.m3-switch
&:not(:checked):disabled + svg > circle.m3.m3-switch-handler &:not(:checked):disabled + svg > circle.m3.m3-switch-handler
fill-opacity: 38% fill-opacity: 38%
fill: var(--md-sys-color-on-surface) fill: $on-surface
&:hover:not(:disabled) &:hover:not(:disabled)
&:checked + svg &:checked + svg
& > circle.m3.m3-switch-handler & > circle.m3.m3-switch-handler
fill: var(--md-sys-color-primary-container) fill: $primary-container
& > circle.m3.m3-switch-handler-state-layer & > circle.m3.m3-switch-handler-state-layer
fill: $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: $on-surface-variant
& > circle.m3.m3-switch-handler-state-layer & > circle.m3.m3-switch-handler-state-layer
fill-opacity: 8% fill-opacity: 8%
fill: var(--md-sys-color-on-surface) fill: $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: $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-opacity: 12% fill-opacity: 12%
fill: var(--md-sys-color-on-surface) fill: $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
@ -132,26 +134,26 @@ div.m3.m3-switch
y: 1px y: 1px
&:not(:checked) + svg > rect.m3.m3-switch-track &:not(:checked) + svg > rect.m3.m3-switch-track
stroke: var(--md-sys-color-outline) stroke: $outline
fill: var(--md-sys-color-surface-container-highest) fill: $surface-container-highest
&:checked + svg > rect.m3.m3-switch-track &:checked + svg > rect.m3.m3-switch-track
fill: var(--md-sys-color-primary) fill: $primary
stroke: var(--md-sys-color-primary) stroke: $primary
&:disabled + svg &:disabled + svg
& > g > text.m3 & > g > text.m3
fill: color-mix(in srgb, var(--md-sys-color-surface-container-highest) 38%, transparent) fill: color-mix(in srgb, $surface-container-highest 38%, transparent)
& > rect.m3.m3-switch-track & > rect.m3.m3-switch-track
stroke: color-mix(in srgb, var(--md-sys-color-on-surface) 12%, transparent) stroke: color-mix(in srgb, $on-surface 12%, transparent)
fill: color-mix(in srgb, var(--md-sys-color-surface-variant) 12%, transparent) fill: color-mix(in srgb, $surface-variant 12%, transparent)
&:checked:disabled + svg &:checked:disabled + svg
& > g > text.m3 & > g > text.m3
transform: translateX(38.5%) transform: translateX(38.5%)
fill: color-mix(in srgb, var(--md-sys-color-on-surface) 38%, transparent) fill: color-mix(in srgb, $on-surface 38%, transparent)
& > rect.m3.m3-switch-track & > rect.m3.m3-switch-track
fill: color-mix(in srgb, var(--md-sys-color-on-surface) 12%, transparent) fill: color-mix(in srgb, $on-surface 12%, transparent)
stroke: color-mix(in srgb, var(--md-sys-color-on-surface) 0%, transparent) stroke: color-mix(in srgb, $on-surface 0%, transparent)

View File

@ -1,66 +1,73 @@
@import '../css/colors-variables'
@mixin m3-text-field-fieldset-legend
border-top-width: 0
border-style: solid
border-bottom-width: 0
border-color: transparent
div.m3.m3-text-field div.m3.m3-text-field
position: relative margin: 0
display: flex display: flex
justify-content: center position: relative
flex-direction: column flex-direction: column
box-sizing: border-box box-sizing: border-box
margin: 0 justify-content: center
span.m3-icon.icon-before span.m3-icon.icon-before
align-self: start align-self: start
&:is(.filled, .outlined) > input::placeholder, & > input, & > label &:is(.filled, .outlined) > input::placeholder, & > input, & > label
line-height: var(--md-sys-typescale-body-large-line-height) @include m3-typography-mixin('body-large')
font-size: var(--md-sys-typescale-body-large-font-size)
& + span.m3-text-field-supporting-text & + span.m3-text-field-supporting-text
@include m3-typography-mixin('body-small')
display: flex display: flex
line-height: var(--md-sys-typescale-body-small-line-height)
font-size: var(--md-sys-typescale-body-small-font-size)
color: var(--md-sys-color-on-surface-variant)
margin: 4px 16px 2px 16px margin: 4px 16px 2px 16px
color: $on-surface-variant
& > label & > label
position: absolute
padding-inline: 4px padding-inline: 4px
pointer-events: none pointer-events: none
transform: translate(16px, 0) transform: translate(16px, 0)
transition: .2s cubic-bezier(0.2, 0, 0, 1) transition: .2s cubic-bezier(0.2, 0, 0, 1)
position: absolute
& > input & > input
transition: .2s cubic-bezier(0.2, 0, 0, 1)
background-color: transparent
border: none border: none
background-color: transparent
transition: .2s cubic-bezier(0.2, 0, 0, 1)
& > span.m3-icon & > span.m3-icon
position: absolute
align-self: end
margin: 12px
width: 24px width: 24px
line-height: 24px margin: 12px
font-size: 24px font-size: 24px
align-self: end
cursor: pointer
display: inherit display: inherit
line-height: 24px
position: absolute
align-items: center align-items: center
justify-content: inherit justify-content: inherit
cursor: pointer color: $on-surface-variant
color: var(--md-sys-color-on-surface-variant)
font-family: Material-Symbols-Outlined-Regular, serif font-family: Material-Symbols-Outlined-Regular, serif
& > span.m3-text-field-state-layer & > span.m3-text-field-state-layer
width: 100% width: 100%
height: 100% height: 100%
pointer-events: none
position: absolute position: absolute
pointer-events: none
& > input, & > label & > input, & > label
color: var(--md-sys-color-on-surface) color: $on-surface
&:is(.filled, .outlined) > input::placeholder &:is(.filled, .outlined) > input::placeholder
color: var(--md-sys-color-on-surface-variant) color: $on-surface-variant
&:is(.filled, .outlined) > input:focus-visible &:is(.filled, .outlined) > input:focus-visible
outline: none outline: none
caret-color: var(--md-sys-color-primary) caret-color: $primary
&:is(.filled, .outlined):has(input:disabled) &:is(.filled, .outlined):has(input:disabled)
& > *, & + span.m3-text-field-supporting-text & > *, & + span.m3-text-field-supporting-text
@ -86,41 +93,41 @@ div.m3.m3-text-field
&.with-after-icon.with-before-icon &.with-after-icon.with-before-icon
padding: 24px 48px 8px 48px padding: 24px 48px 8px 48px
display: inline-flex
align-items: center align-items: center
display: inline-flex
box-sizing: border-box box-sizing: border-box
border-radius: 4px 4px 0 0 border-radius: 4px 4px 0 0
background-color: var(--md-sys-color-surface-container-highest) background-color: $surface-container-highest
box-shadow: inset 0 -1px 0 var(--md-sys-color-on-surface-variant) box-shadow: inset 0 -1px 0 $on-surface-variant
& > label.raised & > label.raised
@include m3-typography-mixin('body-small')
transform: translate(12px, -12px) transform: translate(12px, -12px)
line-height: var(--md-sys-typescale-body-small-line-height)
font-size: var(--md-sys-typescale-body-small-font-size)
& > input:required:user-invalid & > input:required:user-invalid
caret-color: var(--md-sys-color-error) caret-color: $error
&:focus-visible &:focus-visible
box-shadow: inset 0 -3px 0 var(--md-sys-color-error) box-shadow: inset 0 -3px 0 $error
& &
box-shadow: inset 0 -1px 0 var(--md-sys-color-error) box-shadow: inset 0 -1px 0 $error
&:has(input:required:user-invalid) > *:not(input):nth-last-child(-n + 3), &:has(input:required:user-invalid) > *:not(input):nth-last-child(-n + 3),
&:has(input:required:user-invalid) + span.m3-text-field-supporting-text &:has(input:required:user-invalid) + span.m3-text-field-supporting-text
color: var(--md-sys-color-error) color: $error
& > input:focus-visible & > input:focus-visible
outline-offset: 3px outline-offset: 3px
box-shadow: inset 0 -3px 0 var(--md-sys-color-primary) box-shadow: inset 0 -3px 0 $primary
& > input:focus-visible + label & > input:focus-visible + label
color: var(--md-sys-color-primary) color: $primary
&:hover &:hover
& > input:not(:disabled) ~ span.m3-text-field-state-layer & > input:not(:disabled) ~ span.m3-text-field-state-layer
transition: .2s cubic-bezier(0.2, 0, 0, 1) transition: .2s cubic-bezier(0.2, 0, 0, 1)
background-color: color-mix(in srgb, var(--md-sys-color-on-surface) 8%, transparent) background-color: color-mix(in srgb, $on-surface 8%, transparent)
&.outlined &.outlined
& > fieldset & > fieldset
@ -129,27 +136,27 @@ div.m3.m3-text-field
border-radius: 4px border-radius: 4px
pointer-events: none pointer-events: none
padding-inline: 12px padding-inline: 12px
border: 1px solid var(--md-sys-color-outline)
inset: -7.5px 0px 0px 0px inset: -7.5px 0px 0px 0px
border: 1px solid $outline
transition: background-color .2s cubic-bezier(0.2, 0, 0, 1) transition: background-color .2s cubic-bezier(0.2, 0, 0, 1)
& > legend > span & > legend > span
width: 100% width: 100%
& > legend & > legend
opacity: 0
width: 0 width: 0
opacity: 0
padding: 0 padding: 0
pointer-events: none pointer-events: none
border: 0 solid transparent border: 0 solid transparent
transition: .05s cubic-bezier(0.2, 0, 0, 1) transition: .05s cubic-bezier(0.2, 0, 0, 1)
& > legend.raised & > legend.raised
border-inline-width: 6px
border-style: solid
border-color: transparent
width: auto width: auto
visibility: visible visibility: visible
border-style: solid
border-inline-width: 6px
border-color: transparent
& > input & > input
&.with-after-icon &.with-after-icon
@ -171,46 +178,41 @@ div.m3.m3-text-field
border-radius: 4px border-radius: 4px
&:has(input:focus-visible) > fieldset &:has(input:focus-visible) > fieldset
border: 3px solid var(--md-sys-color-primary) border: 3px solid $primary
&:not(&:has(label.raised)):has(input:focus-visible) > fieldset > legend &:not(&:has(label.raised)):has(input:focus-visible) > fieldset > legend
border-top-width: 0 @include m3-text-field-fieldset-legend
border-bottom-width: 0
border-inline-width: 5.5px border-inline-width: 5.5px
border-style: solid
border-color: transparent
&:not(&:has(input:focus-visible)):has(label.raised) > fieldset > legend &:not(&:has(input:focus-visible)):has(label.raised) > fieldset > legend
border-top-width: 0 @include m3-text-field-fieldset-legend
border-bottom-width: 0
border-inline-width: 7.5px border-inline-width: 7.5px
border-style: solid
border-color: transparent
& > input:focus-visible + label & > input:focus-visible + label
color: var(--md-sys-color-primary) color: $primary
& > label.raised, & > fieldset > * & > label.raised, & > fieldset > *
line-height: var(--md-sys-typescale-body-small-line-height) @include m3-typography-mixin('body-small')
font-size: var(--md-sys-typescale-body-small-font-size)
& > label.raised & > label.raised
transform: translate(16px, -27px) !important transform: translate(16px, -27px) !important
& > input:required:user-invalid & > input:required:user-invalid
caret-color: var(--md-sys-color-error) caret-color: $error
&:has(input:required:user-invalid) > *:not(input):nth-last-child(-n + 3), &:has(input:required:user-invalid) > *:not(input):nth-last-child(-n + 3),
&:has(input:required:user-invalid) + span.m3-text-field-supporting-text &:has(input:required:user-invalid) + span.m3-text-field-supporting-text
color: var(--md-sys-color-error) color: $error
&:has(input:required:user-invalid) > fieldset &:has(input:required:user-invalid) > fieldset
border: 3px solid var(--md-sys-color-error) border: 3px solid $error
&:has(input:required:user-invalid:not(:focus-visible)) > fieldset &:has(input:required:user-invalid:not(:focus-visible)) > fieldset
border: 1px solid var(--md-sys-color-error) border: 1px solid $error
&:hover &:hover
&:not(&:has(input:disabled, input:focus-visible, label.raised, input:required:user-invalid)) > fieldset &:not(&:has(input:disabled, input:focus-visible, label.raised, input:required:user-invalid)) > fieldset
transition: .2s cubic-bezier(0.2, 0, 0, 1) transition: .2s cubic-bezier(0.2, 0, 0, 1)
border-color: var(--md-sys-color-on-surface) border-color: $on-surface

View File

@ -1 +1,3 @@
/*# sourceMappingURL=m3-mixins.css.map */ /*# sourceMappingURL=m3-mixins.css.map */

View File

@ -1 +1,7 @@
{"version":3,"sourceRoot":"","sources":[],"names":[],"mappings":"","file":"m3-mixins.css"} {
"version": 3,
"mappings": "",
"sources": [],
"names": [],
"file": "m3-mixins.css"
}

View File

@ -1,3 +1,8 @@
@mixin center($display)
display: $display
align-items: center
justify-content: center
@mixin m3-checkbox-container-mixin @mixin m3-checkbox-container-mixin
gap: 16px gap: 16px
height: 40px height: 40px
@ -7,6 +12,13 @@
align-items: center align-items: center
justify-content: center justify-content: center
@mixin m3-typography-mixin($type)
font-size: var(--md-sys-typescale-#{$type}-font-size)
font-weight: var(--md-sys-typescale-#{$type}-font-weight)
line-height: var(--md-sys-typescale-#{$type}-line-height)
font-family: var(--md-sys-typescale-#{$type}-font-family-name)
letter-spacing: var(--md-sys-typescale-#{$type}-letter-spacing)
@mixin m3-state-layer-mixin @mixin m3-state-layer-mixin
width: 40px width: 40px
aspect-ratio: 1 aspect-ratio: 1
@ -14,22 +26,6 @@
position: absolute 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)
width: $width
height: $height
border-radius: $b-radius
padding: $padding
@mixin m3-fab-colors-palette($bg-color, $color)
&:not(.without-elevation)
@include elevation-3(false)
background-color: var($bg-color)
color: var($color)
& > svg.m3-svg-icon
fill: var($color)
& > .m3.m3-ripple-domain > .m3.ripple
background: color-mix(in srgb, var($color) 12%, transparent)
@mixin elevation-0($important) @mixin elevation-0($important)
@if $important == true @if $important == true
box-shadow: none !important box-shadow: none !important
@ -66,12 +62,8 @@
@else @else
box-shadow: 0 4px 4px 0 rgba(0, 0, 0, 0.30), 0 8px 12px 6px rgba(0, 0, 0, 0.15) box-shadow: 0 4px 4px 0 rgba(0, 0, 0, 0.30), 0 8px 12px 6px rgba(0, 0, 0, 0.15)
@mixin state-layer @mixin m3-buttons-state-layer-mixin
transition: background-color, box-shadow, .2s cubic-bezier(0.2, 0, 0, 1) !important width: 100%
content: "" height: 100%
top: 0
bottom: 0
left: 0
right: 0
position: absolute position: absolute
background: #00000000 transition: background-color, box-shadow, .2s cubic-bezier(0.2, 0, 0, 1) !important

View File

@ -3,10 +3,9 @@
width: 100%; width: 100%;
height: 100%; height: 100%;
z-index: 20; z-index: 20;
pointer-events: none; pointer-events: none; }
}
.m3.ripple { .m3.m3-ripple {
position: absolute; position: absolute;
overflow: hidden; overflow: hidden;
pointer-events: none; pointer-events: none;
@ -15,26 +14,20 @@
z-index: 20; z-index: 20;
aspect-ratio: 1; aspect-ratio: 1;
border-radius: 50%; border-radius: 50%;
animation-duration: 0.55s;
animation-iteration-count: 1;
animation-name: rippleAppearanceAnimation; animation-name: rippleAppearanceAnimation;
animation-timing-function: cubic-bezier(0.4, 0, 0.2, 1); animation-timing-function: cubic-bezier(0.4, 0, 0.2, 1);
animation-duration: 0.55s; transition-duration: 0.55s;
transition: transition-property: opacity, background-color;
opacity, transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1); }
background, .m3.m3-ripple.visible {
background-color, opacity: 1 !important; }
0.55s cubic-bezier(0.4, 0, 0.2, 1);
}
.m3.ripple.visible {
opacity: 1 !important;
}
@keyframes rippleAppearanceAnimation { @keyframes rippleAppearanceAnimation {
0% { 0% {
transform: scale3d(0, 0, 0); transform: scale3d(0, 0, 0); }
}
100% { 100% {
transform: scale3d(1, 1, 1); transform: scale3d(1, 1, 1); } }
}
}
/*# sourceMappingURL=ripple.css.map */ /*# sourceMappingURL=ripple.css.map */

View File

@ -1 +1,7 @@
{"version":3,"sourceRoot":"","sources":["ripple.sass"],"names":[],"mappings":"AAAA;EACE;EACA;EACA;EACA;EACA;;;AAEF;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAEA;EACE;;;AAEJ;EACE;IACE;;EACF;IACE","file":"ripple.css"} {
"version": 3,
"mappings": "AAAA,oBAAoB;EAClB,QAAQ,EAAE,QAAQ;EAClB,KAAK,EAAE,IAAI;EACX,MAAM,EAAE,IAAI;EACZ,OAAO,EAAE,EAAE;EACX,cAAc,EAAE,IAAI;;AAEtB,UAAU;EACR,QAAQ,EAAE,QAAQ;EAClB,QAAQ,EAAE,MAAM;EAChB,cAAc,EAAE,IAAI;EACpB,gBAAgB,EAAE,MAAM;EACxB,OAAO,EAAE,CAAC;EACV,OAAO,EAAE,EAAE;EACX,YAAY,EAAE,CAAC;EACf,aAAa,EAAE,GAAG;EAElB,kBAAkB,EAAE,KAAI;EACxB,yBAAyB,EAAE,CAAC;EAC5B,cAAc,EAAE,yBAAyB;EACzC,yBAAyB,EAAE,4BAA4B;EAEvD,mBAAmB,EAAE,KAAI;EACzB,mBAAmB,EAAE,yBAAyB;EAC9C,0BAA0B,EAAE,4BAA4B;EAExD,kBAAS;IACP,OAAO,EAAE,YAAY;;;;IAIrB,SAAS,EAAE,gBAAgB;;IAE3B,SAAS,EAAE,gBAAgB",
"sources": ["ripple.sass"],
"names": [],
"file": "ripple.css"
}

View File

@ -1,23 +1,28 @@
.m3.m3-ripple-domain .m3.m3-ripple-domain
position: absolute
width: 100% width: 100%
height: 100%
z-index: 20 z-index: 20
height: 100%
position: absolute
pointer-events: none pointer-events: none
.m3.ripple .m3.m3-ripple
position: absolute
overflow: hidden
pointer-events: none
transform-origin: center
opacity: 0 opacity: 0
z-index: 20 z-index: 20
aspect-ratio: 1 aspect-ratio: 1
overflow: hidden
position: absolute
border-radius: 50% border-radius: 50%
pointer-events: none
transform-origin: center
animation-duration: .55s
animation-iteration-count: 1
animation-name: rippleAppearanceAnimation animation-name: rippleAppearanceAnimation
animation-timing-function: cubic-bezier(0.4, 0, 0.2, 1) animation-timing-function: cubic-bezier(0.4, 0, 0.2, 1)
animation-duration: .55s
transition: opacity, background, background-color, .55s cubic-bezier(0.4, 0, 0.2, 1) transition-duration: .55s
transition-property: opacity, background-color
transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1)
&.visible &.visible
opacity: 1 !important opacity: 1 !important
@ -25,5 +30,6 @@
@keyframes rippleAppearanceAnimation @keyframes rippleAppearanceAnimation
0% 0%
transform: scale3d(0, 0, 0) transform: scale3d(0, 0, 0)
100% 100%
transform: scale3d(1, 1, 1) transform: scale3d(1, 1, 1)

View File

@ -0,0 +1,3 @@
/*# sourceMappingURL=typography.css.map */

View File

@ -0,0 +1,7 @@
{
"version": 3,
"mappings": "",
"sources": [],
"names": [],
"file": "typography.css"
}

View File

@ -0,0 +1,2 @@
.m3.m3-typography
position: relative