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
This commit is contained in:
doryan04 2024-02-23 23:55:21 +04:00
parent 40a4d2277e
commit cd0e3e3f85
28 changed files with 1627 additions and 3528 deletions

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,18 +1,11 @@
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 { import {
Button, Button,
Checkbox, FAB,
IconButton, IconButton,
} from '../src/primitive-components/components'; } 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 { SegmentButton } from '../src/primitive-components/button-components/segmented-buttons/segment-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'; import { SegmentedButtons } from '../src/primitive-components/button-components/segmented-buttons/segmented-buttons';
@ -33,22 +26,51 @@ export default function Page() {
> >
<Card variant={'outlined'}> <Card variant={'outlined'}>
<CardFooter> <CardFooter>
<SegmentedButtons toggled={true}> <SegmentedButtons selectable={true}>
<SegmentButton <SegmentButton
fillIcon={1} fillIcon={1}
icon={'change_history'} icon={'change_history'}
> >
fin ita la comedia Label 1
</SegmentButton> </SegmentButton>
<SegmentButton <SegmentButton
fillIcon={1} fillIcon={1}
icon={'change_history'} icon={'change_history'}
iconPlace={'right'} iconPlace={'right'}
selectable={false}
> >
Label 2 Not selectable
</SegmentButton> </SegmentButton>
<SegmentButton disabled>Label 3</SegmentButton> <SegmentButton
fillIcon={1}
icon={'change_history'}
iconPlace={'right'}
iconSize={48}
svgSize={48}
>
Label 3
</SegmentButton>
<SegmentButton disabled>Label 4</SegmentButton>
</SegmentedButtons> </SegmentedButtons>
<Button ripple={false}>Filled button</Button>
<Button ripple={false} variant={'outlined'}>
Outlined button
</Button>
<Button ripple={false} variant={'elevated'}>
Elevated button
</Button>
<Button ripple={false} variant={'text'}>
Text button
</Button>
<Button ripple={false} variant={'tonal'}>
Tonal button
</Button>
<FAB icon={'edit'} ripple={false}></FAB>
<FAB icon={'edit'}></FAB>
<IconButton
icon={'settings'}
variant={'filled'}
></IconButton>
</CardFooter> </CardFooter>
</Card> </Card>
</div> </div>

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,6 +1,6 @@
'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 { ButtonLayout } from '../button-layout/button-layout';
@ -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,
@ -31,6 +32,7 @@ export const Button = forwardRef<HTMLButtonElement, ButtonProps>(
className={`${variant} ${className}`} className={`${variant} ${className}`}
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

@ -44,6 +44,7 @@ export const FAB = forwardRef<HTMLButtonElement, FABProps>(
<Icon iconSize={sizes[size]} svgSize={sizes[size]}> <Icon iconSize={sizes[size]} svgSize={sizes[size]}>
{icon} {icon}
</Icon> </Icon>
<span className={'m3 m3-fab-state-layer'}></span>
{size === 'extended' ? ( {size === 'extended' ? (
<Typography <Typography
className={'label-large'} className={'label-large'}

View File

@ -5,6 +5,14 @@ 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';
import { Icon } from '../../components';
/**
* 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,46 +39,56 @@ 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 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
{...props} {...props}
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-state-layer'}>
{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,7 +7,7 @@ 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) {
throw 'You must build segmented button with 2 or more button'; throw 'You must build segmented button with 2 or more button';
} }
@ -16,7 +16,7 @@ export const SegmentedButtons = forwardRef<
(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,
}); });
}, },
@ -24,7 +24,7 @@ export const SegmentedButtons = forwardRef<
return ( return (
<div <div
className={`m3 m3-segmented-buttons ${props.className ?? ''}`.trimEnd()} className={`m3 m3-segmented-buttons m3-density-${density} ${props.className ?? ''}`.trimEnd()}
ref={ref} ref={ref}
> >
{SegmentedButtons} {SegmentedButtons}

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

@ -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

@ -3,23 +3,22 @@ svg.m3.m3-badge
background-color: var(--md-sys-color-error) background-color: var(--md-sys-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 m3-typography-mixin('label-small')
font-size: var(--md-sys-typescale-label-small-font-size)
font-weight: var(--md-sys-typescale-label-small-font-weight)
line-height: var(--md-sys-typescale-label-small-line-height)
font-optical-sizing: none
alignment-baseline: central
text-anchor: middle
display: flex display: flex
align-items: center align-items: center
text-anchor: middle
justify-content: center justify-content: center
font-optical-sizing: none
alignment-baseline: central
fill: var(--md-sys-color-on-error)

View File

@ -1,20 +1,11 @@
input[type="button"].test-button
color: white
&:not(:checked)
background-color: green
&:checked
background-color: blue
button:not(.m3-fab, .m3-icon-button) button:not(.m3-fab, .m3-icon-button)
width: min-content @include m3-typography-mixin('label-large')
height: min-content
max-height: 40px max-height: 40px
box-sizing: border-box width: min-content
white-space: nowrap white-space: nowrap
font-size: var(--md-sys-typescale-label-large-font-size) height: min-content
font-weight: var(--md-sys-typescale-label-large-font-weight) box-sizing: border-box
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 transition: background-color, box-shadow, .2s cubic-bezier(0.2, 0, 0, 1) !important
&.m3 &.m3
@ -32,13 +23,14 @@ button:not(.m3-fab, .m3-icon-button)
&.filled &.filled
background-color: var(--md-sys-color-primary) background-color: var(--md-sys-color-primary)
&, & > svg.m3-svg-icon &, & > svg.m3-svg-icon
fill: var(--md-sys-color-on-primary) fill: var(--md-sys-color-on-primary)
color: var(--md-sys-color-on-primary) color: var(--md-sys-color-on-primary)
&.outlined &.outlined
outline-offset: -1px outline-offset: -1px
background-color: #00000000 background-color: transparent
color: var(--md-sys-color-primary) color: var(--md-sys-color-primary)
outline: 1px solid var(--md-sys-color-outline) !important outline: 1px solid var(--md-sys-color-outline) !important
@ -46,8 +38,7 @@ button:not(.m3-fab, .m3-icon-button)
fill: var(--md-sys-color-primary) fill: var(--md-sys-color-primary)
&.text &.text
background-color: #00000000 background-color: transparent
padding: 10px 12px !important
color: var(--md-sys-color-primary) color: var(--md-sys-color-primary)
& > svg.m3-svg-icon & > svg.m3-svg-icon
@ -55,6 +46,7 @@ button:not(.m3-fab, .m3-icon-button)
&.elevated &.elevated
@include elevation-1(false) @include elevation-1(false)
color: var(--md-sys-color-primary) color: var(--md-sys-color-primary)
background-color: var(--md-sys-color-surface-container-low) background-color: var(--md-sys-color-surface-container-low)
@ -68,17 +60,14 @@ button:not(.m3-fab, .m3-icon-button)
& > svg.m3-svg-icon & > svg.m3-svg-icon
fill: var(--md-sys-color-on-secondary-container) fill: var(--md-sys-color-on-secondary-container)
&::before &.filled > span.m3.m3-ripple-domain > span.m3.ripple
@include state-layer
&.filled > .m3.m3-ripple-domain > .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)
&:is(.outlined, .text, .elevated) &:is(.outlined, .text, .elevated)
& > .m3.m3-ripple-domain > .m3.ripple & > span.m3.m3-ripple-domain > span.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)
&.tonal > .m3.m3-ripple-domain > .m3.ripple &.tonal > span.m3.m3-ripple-domain > span.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)
&:active &:active
@ -88,21 +77,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: var(--md-sys-color-primary) !important
&.filled
background-color: color-mix(in srgb, var(--md-sys-color-on-primary) 20%, var(--md-sys-color-primary))
&:is(.outlined, .text, .elevated)
background-color: color-mix(in srgb, var(--md-sys-color-primary) 20%, transparent)
&.tonal
background-color: color-mix(in srgb, var(--md-sys-color-on-secondary-container) 20%, var(--md-sys-color-secondary-container))
&:focus-visible &:focus-visible
&.outlined &.outlined
border-color: var(--md-sys-color-primary) !important border-color: var(--md-sys-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, var(--md-sys-color-on-primary) 12%, var(--md-sys-color-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, var(--md-sys-color-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, var(--md-sys-color-on-secondary-container) 12%, var(--md-sys-color-secondary-container))
&:hover &:hover
&:is(.filled, .tonal) &:is(.filled, .tonal)
@ -111,14 +110,14 @@ 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, var(--md-sys-color-on-primary) 8%, var(--md-sys-color-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, var(--md-sys-color-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, var(--md-sys-color-on-secondary-container) 8%, var(--md-sys-color-secondary-container))
&:disabled &:disabled
pointer-events: none pointer-events: none

View File

@ -1,3 +1,27 @@
@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: var($color)
background-color: var($bg-color)
& > svg.m3-svg-icon
fill: var($color)
& > span.m3.m3-ripple-domain > span.m3.ripple
background: color-mix(in srgb, var($color) 12%, transparent)
&:not(&:has(span.m3.m3-ripple-domain)):active
& > span.m3.m3-fab-state-layer
background: color-mix(in srgb, var($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
@ -15,8 +39,8 @@ button.m3.m3-fab
border: none border: none
gap: 12px gap: 12px
&::before & > span.m3.m3-fab-state-layer
@include state-layer @include m3-buttons-state-layer-mixin
&.surface &.surface
@include m3-fab-colors-palette(--md-sys-color-surface-container-high, --md-sys-color-primary) @include m3-fab-colors-palette(--md-sys-color-surface-container-high, --md-sys-color-primary)
@ -53,27 +77,27 @@ button.m3.m3-fab
@include elevation-3(true) @include elevation-3(true)
&:hover &:hover
&.surface::before &.surface > span.m3.m3-fab-state-layer
background-color: color-mix(in srgb, var(--md-sys-color-primary) 8%, transparent) background-color: color-mix(in srgb, var(--md-sys-color-primary) 8%, transparent)
&.primary::before &.primary > span.m3.m3-fab-state-layer
background-color: color-mix(in srgb, var(--md-sys-color-on-primary-container) 8%, transparent) background-color: color-mix(in srgb, var(--md-sys-color-on-primary-container) 8%, transparent)
&.secondary::before &.secondary > span.m3.m3-fab-state-layer
background-color: color-mix(in srgb, var(--md-sys-color-on-secondary-container) 8%, transparent) background-color: color-mix(in srgb, var(--md-sys-color-on-secondary-container) 8%, transparent)
&.tertiary::before &.tertiary > span.m3.m3-fab-state-layer
background-color: color-mix(in srgb, var(--md-sys-color-on-tertiary-container) 8%, transparent) background-color: color-mix(in srgb, var(--md-sys-color-on-tertiary-container) 8%, transparent)
&:focus-visible &:focus-visible
&.surface::before &.surface > span.m3.m3-fab-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)
&.primary::before &.primary > span.m3.m3-fab-state-layer
background-color: color-mix(in srgb, var(--md-sys-color-on-primary-container) 12%, transparent) background-color: color-mix(in srgb, var(--md-sys-color-on-primary-container) 12%, transparent)
&.secondary::before &.secondary > span.m3.m3-fab-state-layer
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)
&.tertiary::before &.tertiary > span.m3.m3-fab-state-layer
background-color: color-mix(in srgb, var(--md-sys-color-on-tertiary-container) 12%, transparent) background-color: color-mix(in srgb, var(--md-sys-color-on-tertiary-container) 12%, transparent)

View File

@ -1,47 +1,88 @@
$densities: [0, -1, -2, -3]
@each $density in $densities
.m3.m3-density-#{$density}
$height: 40px + ($density * 2px)
& > 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
& > span.m3.m3-button-segment-state-layer
padding-top: 10px + ($density * 1px)
padding-bottom: 10px + ($density * 1px)
@mixin m3-segmented-button-content-color-mixin($color)
& > svg.m3.m3-svg-icon > text
fill: var($color)
& > label.m3.m3-typography
color: var($color)
div.m3.m3-segmented-buttons div.m3.m3-segmented-buttons
padding: 0
height: 40px
display: flex display: flex
padding: 4px 0
border-radius: 20px border-radius: 20px
box-sizing: border-box box-sizing: border-box
& > button.m3.m3-button-segment & > button.m3.m3-button-segment
width: auto flex: 1 1
height: 40px padding: 0
padding: 10px width: 100%
min-width: 108px min-width: 48px
border-radius: 0 border-radius: 0
margin: 0 -0.5px margin: 0 -0.5px
display: inline-flex display: inline-flex
background-color: transparent background-color: transparent
border: 1px solid var(--md-sys-color-outline) border: 1px solid var(--md-sys-color-outline)
&:first-child & > span.m3.m3-ripple-domain
border-radius: 20px 0 0 20px transition: .2s cubic-bezier(0.2, 0, 0, 1)
&:last-child & > span.m3.ripple
border-radius: 0 20px 20px 0 background-color: color-mix(in srgb, var(--md-sys-color-on-secondary-container) 12%, transparent)
& > span & > span.m3.m3-button-segment-state-layer
color: var(--md-sys-color-on-surface) @include m3-buttons-state-layer-mixin
& > svg box-sizing: border-box
opacity: 0
& > text & > *
fill: var(--md-sys-color-on-surface) visibility: hidden
&:not(.selected) & > span.m3.m3-button-segment-content-layer
& > svg @include center(inline-flex)
@include m3-segmented-button-content-color-mixin(--md-sys-color-on-surface)
gap: 8px
position: absolute
max-height: inherit
& > svg.m3.m3-svg-icon
display: none display: none
&::after, &::before &.selected
content: ''
width: 6px
position: relative
& > span.m3.m3-ripple-domain > span.m3.ripple background-color: var(--md-sys-color-secondary-container)
background-color: color-mix(in srgb, var(--md-sys-color-on-secondary-container) 12%, transparent)
& > span.m3.m3-button-segment-content-layer
@include m3-segmented-button-content-color-mixin(--md-sys-color-on-secondary-container)
& > svg.m3.m3-svg-icon
display: initial
&:hover
& > span.m3.m3-button-segment-state-layer
background-color: color-mix(in srgb, var(--md-sys-color-on-secondary-container) 8%, transparent)
&:is(&:not(&:has(span.m3.m3-ripple-domain)):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)
&:disabled &:disabled
border: 1px solid color-mix(in srgb, var(--md-sys-color-outline) 12%, transparent) border: 1px solid color-mix(in srgb, var(--md-sys-color-outline) 12%, transparent)
@ -49,31 +90,4 @@ div.m3.m3-segmented-buttons
& > * & > *
opacity: 38% opacity: 38%
&.selected
background-color: var(--md-sys-color-secondary-container)
& > svg
opacity: 1
& > 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
width: 100%
height: 100%
position: absolute
& > 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)

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

View File

@ -1,3 +1,26 @@
@mixin input-range-thumb-mixin
@include elevation-1(false)
&:hover
&::after
content: '1'
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
height: 20px
appearance: none
border-radius: 50%
box-sizing: border-box
outline: 10px solid transparent
background: var(--md-sys-color-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
@ -6,7 +29,6 @@ div.m3.m3-slider-container
& > 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

View File

@ -1,56 +1,55 @@
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: var(--md-sys-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: var(--md-sys-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: var(--md-sys-color-on-surface)
@ -86,17 +85,17 @@ 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: var(--md-sys-color-surface-container-highest)
box-shadow: inset 0 -1px 0 var(--md-sys-color-on-surface-variant) box-shadow: inset 0 -1px 0 var(--md-sys-color-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: var(--md-sys-color-error)
@ -129,27 +128,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 var(--md-sys-color-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
@ -175,24 +174,23 @@ div.m3.m3-text-field
&:not(&:has(label.raised)):has(input:focus-visible) > fieldset > legend &:not(&:has(label.raised)):has(input:focus-visible) > fieldset > legend
border-top-width: 0 border-top-width: 0
border-bottom-width: 0
border-inline-width: 5.5px
border-style: solid border-style: solid
border-bottom-width: 0
border-color: transparent border-color: transparent
border-inline-width: 5.5px
&:not(&:has(input:focus-visible)):has(label.raised) > fieldset > legend &:not(&:has(input:focus-visible)):has(label.raised) > fieldset > legend
border-top-width: 0 border-top-width: 0
border-bottom-width: 0
border-inline-width: 7.5px
border-style: solid border-style: solid
border-bottom-width: 0
border-color: transparent border-color: transparent
border-inline-width: 7.5px
& > input:focus-visible + label & > input:focus-visible + label
color: var(--md-sys-color-primary) color: var(--md-sys-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

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,34 +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
@mixin input-range-thumb-mixin
@include elevation-1(false)
&:hover
&:after
content: '1'
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
height: 20px
appearance: none
border-radius: 50%
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

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