ESLINT is holy crap

This commit is contained in:
2024-02-01 01:58:19 +04:00
parent 7cdc259fb3
commit 26584d5482
151 changed files with 26811 additions and 47 deletions

View File

@@ -0,0 +1,37 @@
import { BadgeProps } from './badges.types';
import { bool, number, string } from 'prop-types';
import React, { forwardRef } from 'react';
const Badge = forwardRef<SVGSVGElement, BadgeProps>(function Badge(
{ disableValue = false, ...props },
ref,
) {
const digitLength = props.children
? 16 + (props.children.length - 1) * 6
: 6,
disableValueClassName =
disableValue || (!props.children ?? true) ? 'disable-value' : '';
return (
<svg
{...props}
className={`m3 m3-badge ${'' ?? props.className}${disableValueClassName}`.trimEnd()}
ref={ref}
width={`${digitLength}px`}
>
{props.children && (
<text x={'50%'} y={'50%'}>
{props.children}
</text>
)}
</svg>
);
});
Badge.propTypes = {
children: number,
className: string,
disableValue: bool,
};
export { Badge };

View File

@@ -0,0 +1,5 @@
import { PropsWithChildren } from 'react';
export interface BadgeProps extends PropsWithChildren<any> {
disableValue?: boolean;
}

View File

@@ -0,0 +1,48 @@
'use client';
import { RippleArea } from '../ripple/ripple-area';
import { IRippleProps } from '../ripple/ripple.types';
import useRippleEffect from '../ripple/hooks/useRippleEffect';
import React, {
forwardRef,
PropsWithChildren,
useId,
useRef,
useState,
} from 'react';
const ButtonLayout = forwardRef<
HTMLButtonElement,
PropsWithChildren<any> & IRippleProps
>(function ButtonBase({ centralRipple = false, ...props }, ref) {
const [isActive, setIsActive] = useState<boolean>(false),
ripplesRef = useRef(null),
buttonId = useId(),
events = useRippleEffect(ripplesRef, setIsActive);
const { variant, disabled, className } = props;
const classes = className
? `m3 ${className} ${variant}${isActive ? ' is-active' : ''}`
: `m3 ${variant}${isActive ? ' is-active' : ''}`;
return (
<button
{...props}
{...events}
className={classes}
disabled={disabled}
id={buttonId}
ref={ref}
>
{props.children}
<RippleArea
callback={setIsActive}
central={centralRipple}
ref={ripplesRef}
/>
</button>
);
});
export { ButtonLayout };

View File

@@ -0,0 +1,25 @@
import { PropsWithChildren } from 'react';
type ToggleButtonType = {
selected: string;
unselected: string;
};
export interface ButtonMainProps extends PropsWithChildren<any> {
disabled?: boolean;
variant?: 'filled' | 'outlined' | 'elevated' | 'tonal' | 'text';
}
export interface FABMainProps extends PropsWithChildren<any> {
icon: string;
disabled?: boolean;
size?: 'small' | 'default' | 'large' | 'extended';
variant?: 'surface' | 'primary' | 'secondary' | 'tertiary';
}
export interface IconButtonMainProps extends PropsWithChildren<any> {
icon: string;
toggled?: false | ToggleButtonType;
disabled?: boolean;
variant?: 'default' | 'filled' | 'tonal' | 'outlined';
}

View File

@@ -0,0 +1,33 @@
'use client';
import { forwardRef } from 'react';
import { Icon } from '../material-you-components';
import { IRippleProps } from '../ripple/ripple.types';
import { ButtonLayout } from '../button-layout/button-layout';
import { ButtonMainProps } from '../button-layout/button.types';
/**
* Button component
** description
*/
export const Button = forwardRef<
HTMLButtonElement,
ButtonMainProps & IRippleProps
>(
(
{ centralRipple = false, variant, disabled = false, icon, ...props },
ref,
) => (
<ButtonLayout
{...props}
centralRipple={centralRipple}
disabled={disabled}
ref={ref}
variant={variant ? variant : 'filled'}
>
{icon ? <Icon iconSize={20}>{icon}</Icon> : <></>}
<span className={'label-large'}>{props.children}</span>
</ButtonLayout>
),
);

View File

@@ -0,0 +1,38 @@
'use client';
import React, {
forwardRef,
useEffect,
useImperativeHandle,
useRef,
} from 'react';
import { CheckboxLayoutProps } from './checkbox-layout.types';
export const CheckBoxLayout = forwardRef(function CheckBoxBase(
{ indeterminate, typeInput, type, ...props }: CheckboxLayoutProps,
ref,
): JSX.Element {
const checkboxRef = useRef<any>(null);
useEffect(() => {
checkboxRef.current.indeterminate = indeterminate === true;
}, []);
useImperativeHandle(ref, () => checkboxRef.current);
const classesType = typeInput || type;
const classes =
props.className !== undefined
? `m3 m3-${type} ${props.className}`
: `m3 m3-${classesType}`;
return (
<input
ref={checkboxRef}
{...props}
className={classes.trimEnd()}
type={type}
/>
);
});

View File

@@ -0,0 +1,7 @@
import { PropsWithChildren } from 'react';
export interface CheckboxLayoutProps extends PropsWithChildren<any> {
indeterminate?: boolean;
typeInput?: string;
type?: string;
}

View File

@@ -0,0 +1,59 @@
'use client';
import { RippleArea } from '../ripple/ripple-area';
import { IRippleProps } from '../ripple/ripple.types';
import useRippleEffect from '../ripple/hooks/useRippleEffect';
import { CheckBoxLayout } from '../checkbox-layout/check-box-layout';
import {
forwardRef,
PropsWithChildren,
useEffect,
useImperativeHandle,
useRef,
useState,
} from 'react';
/**
* Checkbox component
** description
*/
export const Checkbox = forwardRef<
HTMLInputElement,
PropsWithChildren<any> & IRippleProps
>(({ centralRipple, ...props }, ref) => {
const [isActive, setIsActive] = useState<boolean>(false),
[checked, setChecked] = useState<boolean>(props.checked ?? false),
ripplesRef = useRef(null),
checkboxRef = useRef(null),
events = useRippleEffect(ripplesRef, setIsActive);
const classes =
`m3 m3-checkbox-label ${isActive === true ? 'visible' : ''}`.trimEnd();
const indeterminate = (props.indeterminate === true).toString();
useImperativeHandle(ref, () => checkboxRef.current);
useEffect(() => {
setChecked(!checked);
}, [checkboxRef.current?.checked]);
return (
<label {...events} className={classes}>
<CheckBoxLayout
{...props}
indeterminate={indeterminate}
ref={checkboxRef}
type={'checkbox'}
/>
<span className={'m3 m3-checkbox-state-layer'} />
<RippleArea
callback={setIsActive}
central={centralRipple}
className={'m3-checkbox-ripple-layer'}
ref={ripplesRef}
/>
{props.children}
</label>
);
});

View File

@@ -0,0 +1,18 @@
import React, { forwardRef, PropsWithChildren } from 'react';
interface DividerProps extends PropsWithChildren<any> {
orientation?: 'vertical' | 'horizontal';
variant?: 'full-width' | 'inset' | 'middle-inset';
}
const Divider = forwardRef<HTMLHRElement, DividerProps>(
({ orientation, variant, ...props }, ref) => (
<hr
{...props}
className={`m3 m3-divider ${orientation ?? 'horizontal'} ${variant ?? 'full-width'}`.trimEnd()}
ref={ref}
/>
),
);
export { Divider };

View File

@@ -0,0 +1,52 @@
'use client';
import { forwardRef } from 'react';
import { Icon } from '../material-you-components';
import { IRippleProps } from '../ripple/ripple.types';
import { FABMainProps } from '../button-layout/button.types';
import { ButtonLayout } from '../button-layout/button-layout';
/**
* FABs component
** description
*/
const sizes = {
small: 24,
default: 24,
large: 36,
extended: 24,
};
export const FAB = forwardRef<HTMLButtonElement, FABMainProps & IRippleProps>(
(
{
variant,
disabled,
icon,
centralRipple = false,
size = 'default',
elevated,
...props
},
ref,
) => (
<ButtonLayout
{...props}
centralRipple={centralRipple}
className={`m3-fab m3-${size}-fab ${!(elevated ?? false) && 'without-elevation'}`}
disabled={disabled}
ref={ref}
variant={variant ? variant : 'surface'}
>
<Icon iconSize={sizes[size]} svgSize={sizes[size]}>
{icon}
</Icon>
{size === 'extended' ? (
<span className={'label-large'}>{props.children}</span>
) : (
<></>
)}
</ButtonLayout>
),
);

View File

@@ -0,0 +1,86 @@
'use client';
import { Icon } from '../material-you-components';
import { toggleIconType } from './icon-button.types';
import { IRippleProps } from '../ripple/ripple.types';
import { ButtonLayout } from '../button-layout/button-layout';
import { IconButtonMainProps } from '../button-layout/button.types';
import {
forwardRef,
useCallback,
useImperativeHandle,
useRef,
useState,
} from 'react';
/**
* Icon button-layout component
** description
*/
export const IconButton = forwardRef<
HTMLButtonElement,
IconButtonMainProps & IRippleProps
>(
(
{
icon,
variant,
disabled,
selected = false,
toggled = false,
centralRipple,
...props
},
ref,
) => {
const [toggleIcon, setToggleIcon] = useState<toggleIconType>({
state: selected == true ? 'selected' : 'unselected',
icon: toggled ? toggled.unselected ?? 'add_circle' : 'add_circle',
});
const toggle = (classes: string, icon: string) => {
setToggleIcon(() => ({
state: classes,
icon: icon,
}));
};
const buttonRef = useRef<HTMLButtonElement>(null);
const callback = useCallback(() => {
if (toggled) {
if (toggleIcon.state === 'selected') {
toggle('', toggled.unselected ?? 'add_circle');
} else {
toggle('selected', toggled.selected ?? 'add_circle');
}
}
if (props.onClick) {
props.onClick();
}
}, [toggleIcon]);
useImperativeHandle(ref, () => buttonRef.current);
return (
<ButtonLayout
{...props}
centralRipple={centralRipple}
className={`m3-icon-button ${toggleIcon.state} ${toggled ? 'toggled' : ''}`.trimEnd()}
disabled={disabled}
onClick={callback}
ref={buttonRef}
variant={variant ? variant : 'default'}
>
<Icon
fill={toggleIcon.state === 'selected' ? 1 : 0}
iconSize={28}
svgSize={40}
>
{toggled ? toggleIcon.icon : icon ? icon : undefined}
</Icon>
</ButtonLayout>
);
},
);

View File

@@ -0,0 +1,4 @@
export type toggleIconType = {
state: string;
icon: string;
};

View File

@@ -0,0 +1,53 @@
import { IconProps } from './icon.types';
import { bool, number, string } from 'prop-types';
import React, { ForwardedRef, forwardRef } from 'react';
const Icon = forwardRef(function Icon(
{
grade = 0,
weight = 500,
svgSize = 20,
fill = false,
iconSize = 20,
opticalSize = 24,
type = 'outlined',
...props
}: IconProps,
ref: ForwardedRef<any>,
) {
const fontVariation = {
fontVariationSettings: `'FILL' ${fill ? 1 : 0}, 'wght' ${weight}, 'GRAD' ${grade}, 'optz' ${opticalSize}`,
};
return (
<svg
{...props}
className={`m3 m3-svg-icon ${props.className ?? ''}`.trim()}
height={svgSize}
ref={ref}
width={svgSize}
>
<text
className={`m3-${type[0].toUpperCase() + type.slice(1)} m3-size-${iconSize}px`}
style={fontVariation}
x={'50%'}
y={'50%'}
>
{props.children ?? 'add_circle'}
</text>
</svg>
);
});
Icon.propTypes = {
fill: bool,
type: string,
grade: number,
weight: number,
svgSize: number,
iconSize: number,
children: string,
opticalSize: number,
};
export { Icon };

View File

@@ -0,0 +1,11 @@
import { PropsWithChildren } from 'react';
export interface IconProps extends PropsWithChildren<any> {
fill?: boolean;
grade?: number;
svgSize?: number;
iconSize?: number;
opticalSize?: number;
type?: 'outlined' | 'rounded' | 'sharp';
weight?: 100 | 200 | 300 | 400 | 500 | 600 | 700;
}

View File

@@ -0,0 +1,13 @@
export { FAB } from './fab/fab';
export { Icon } from './icon/icon';
export { Radio } from './radio/radio';
export { Badge } from './badge/badge';
export { Switch } from './switch/switch';
export { Button } from './button/button';
export { Divider } from './divider/divider';
export { Checkbox } from './checkbox/checkbox';
export { RippleArea } from './ripple/ripple-area';
export { Ripples, Ripple } from './ripple/ripple';
export { TextField } from './text-field/text-field';
export { IconButton } from './icon-button/icon-button';
export { ButtonLayout } from './button-layout/button-layout';

View File

@@ -0,0 +1,38 @@
'use client';
import { RippleArea } from '../ripple/ripple-area';
import { IRippleProps } from '../ripple/ripple.types';
import useRippleEffect from '../ripple/hooks/useRippleEffect';
import { CheckBoxLayout } from '../checkbox-layout/check-box-layout';
import { forwardRef, PropsWithChildren, useRef, useState } from 'react';
/**
* Radio component
** description
*/
export const Radio = forwardRef<
HTMLInputElement,
PropsWithChildren<HTMLElement> & IRippleProps
>(({ centralRipple, ...props }, ref) => {
const [isActive, setIsActive] = useState<boolean>(false),
ripplesRef = useRef(null),
events = useRippleEffect(ripplesRef, setIsActive);
const classes =
`m3 m3-radio-label ${isActive === true ? 'visible' : ''}`.trimEnd();
return (
<label {...events} className={classes}>
<CheckBoxLayout {...props} ref={ref} type={'radio'} />
<span className={'m3 m3-radio-state-layer'} />
<RippleArea
callback={setIsActive}
central={centralRipple}
className={'m3-checkbox-ripple-layer'}
ref={ripplesRef}
/>
{props.children}
</label>
);
});

View File

@@ -0,0 +1,43 @@
import React, { useEffect, useState } from 'react';
interface RippleEventHandlers {
onBlur: React.FocusEventHandler;
onContextMenu: React.MouseEventHandler;
onDragLeave: React.DragEventHandler;
onMouseDown: React.MouseEventHandler;
onMouseLeave: React.MouseEventHandler;
onMouseUp: React.MouseEventHandler;
onTouchEnd: React.TouchEventHandler;
onTouchMove: React.TouchEventHandler;
onTouchStart: React.TouchEventHandler;
}
const UseRippleEffect = (ref, callback): undefined | RippleEventHandlers => {
const [mounted, setMounted] = useState<boolean>(false);
useEffect(() => {
if (!mounted) {
setMounted(true);
}
});
if (!mounted) {
return;
}
const { start, stop } = ref.current;
return {
onBlur: event => stop(event, callback),
onContextMenu: event => start(event, callback),
onDragLeave: event => stop(event, callback),
onMouseDown: event => start(event, callback),
onMouseLeave: event => stop(event, callback),
onMouseUp: event => stop(event, callback),
onTouchEnd: event => stop(event, callback),
onTouchMove: event => stop(event, callback),
onTouchStart: event => stop(event, callback),
};
};
export default UseRippleEffect;

View File

@@ -0,0 +1,130 @@
'use client';
import React, {
forwardRef,
useCallback,
useId,
useImperativeHandle,
useRef,
useState,
} from 'react';
import { Ripple } from './ripple';
import { Ripples } from './ripple';
import { RippleAreaProps } from './ripple.types';
const TIMEOUT: number = 550;
const rippleAreaContext = React.createContext(false);
const RippleArea = forwardRef(function RippleArea(
{ central = false, callback, ...props }: RippleAreaProps,
ref,
) {
const [ripples, setRipples] = useState<Array<JSX.Element>>([]),
rippleDomain = useRef<any>(null),
clicked = useRef<boolean>(false),
uniqueKey = useRef<number>(0),
uniqueId = useId();
const classes = props.className
? `m3 m3-ripple-domain ${props.className}`.trimEnd()
: 'm3 m3-ripple-domain';
const start = useCallback(
(event: any, cb: (state: boolean) => void): void => {
clicked.current = true;
cb(clicked.current);
const rippleDomainChar = rippleDomain.current
? rippleDomain.current.getBoundingClientRect()
: {
width: 0,
height: 0,
left: 0,
top: 0,
};
const rippleX: number = !central
? event.clientX - rippleDomainChar.left
: rippleDomainChar.width / 2,
rippleY: number = !central
? event.clientY - rippleDomainChar.top
: rippleDomainChar.height / 2,
rippleSizeX: number =
Math.max(
Math.abs(rippleDomainChar.width - rippleX),
rippleX,
) *
2 +
2,
rippleSizeY: number =
Math.max(
Math.abs(rippleDomainChar.height - rippleY),
rippleY,
) *
2 +
2,
rippleS: number = (rippleSizeX ** 2 + rippleSizeY ** 2) ** 0.5;
setRipples((prevRipples: Array<JSX.Element>) => {
if (prevRipples.length === 0) {
return [
<Ripple
key={uniqueKey.current}
lifetime={TIMEOUT}
rippleS={rippleS}
rippleX={rippleX}
rippleY={rippleY}
/>,
];
}
const old = [...prevRipples];
old.push(
<Ripple
key={uniqueKey.current}
lifetime={TIMEOUT}
rippleS={rippleS}
rippleX={rippleX}
rippleY={rippleY}
/>,
);
return old;
});
uniqueKey.current += 1;
},
[],
);
const stop = useCallback((_event: any, cb: (state: boolean) => void) => {
clicked.current = false;
cb(clicked.current);
setRipples((prevRipples: Array<JSX.Element>) => {
if (prevRipples.length > 0) {
const old = [...prevRipples];
old.shift();
return old;
}
return prevRipples;
});
}, []);
useImperativeHandle(
ref,
() => ({
start,
stop,
}),
[start, stop],
);
return (
<span className={classes} id={uniqueId} ref={rippleDomain}>
<rippleAreaContext.Provider value={clicked.current}>
<Ripples>{ripples}</Ripples>
</rippleAreaContext.Provider>
</span>
);
});
export { rippleAreaContext, RippleArea };

View File

@@ -0,0 +1,86 @@
'use client';
import isEmpty from './utils/utils';
import { rippleProps } from './ripple.types';
import { rippleAreaContext } from './ripple-area';
import RippleEffectBuild from './utils/ripple-effect-builder';
import React, {
ForwardedRef,
forwardRef,
JSX,
useCallback,
useContext,
useEffect,
useRef,
useState,
useTransition,
} from 'react';
const Ripples = forwardRef(function Ripples(
props: any,
ref: ForwardedRef<any>,
) {
const [ripples, setRipples] = useState({});
const firstRender = useRef<boolean>(true);
const [pending, startTransition] = useTransition();
const LifetimeEnd = useCallback((child: JSX.Element) => {
if (child.props.endLifetime) {
child.props.endLifetime();
}
setRipples(state => {
const children = { ...state };
delete children[child.key];
return children;
});
}, []);
useEffect(() => {
if (props.children.length > 0) {
startTransition(() => {
if (firstRender.current || isEmpty(ripples)) {
setRipples(RippleEffectBuild(props.children, LifetimeEnd));
firstRender.current = false;
} else {
setRipples(
RippleEffectBuild(props.children, LifetimeEnd, ripples),
);
}
});
}
}, [props.children]);
return <>{Object.values(ripples)}</>;
});
const Ripple = forwardRef(function Ripple(
props: rippleProps,
ref: ForwardedRef<any>,
) {
const { rippleX, rippleY, rippleS, endLifetime, lifetime } = props;
const clicked = useContext<boolean>(rippleAreaContext);
const [classes, setClasses] = useState<string>('m3 ripple visible');
useEffect(() => {
if (endLifetime !== null && !clicked) {
setClasses('m3 ripple');
setTimeout(endLifetime, lifetime);
}
}, [clicked, endLifetime]);
return (
<span
className={classes}
style={{
left: -(rippleS / 2) + rippleX,
top: -(rippleS / 2) + rippleY,
width: rippleS,
aspectRatio: 1,
}}
/>
);
});
export { Ripple, Ripples };

View File

@@ -0,0 +1,21 @@
import { Dispatch, SetStateAction } from 'react';
export interface IRippleProps extends PropsWithChildren<any> {
centralRipple?: boolean;
}
export interface RippleAreaProps extends PropsWithChildren<any> {
callback: Dispatch<SetStateAction<boolean>>;
central?: boolean;
}
export type rippleProps = {
rippleX: number;
rippleY: number;
rippleS: number;
endLifetime?: () => void;
lifetime: number;
key?: number;
};
import { PropsWithChildren } from 'react';

View File

@@ -0,0 +1,15 @@
import { cloneElement, ReactElement } from 'react';
export default function ArrayConvertToObj(
obj: Object,
nextChildren: ReactElement[],
callback: (child: any) => void,
): void {
Object.values(nextChildren).forEach(
(child: JSX.Element) =>
(obj[child.key] = cloneElement(child, {
...child.props,
endLifetime: callback.bind(null, child),
})),
);
}

View File

@@ -0,0 +1,34 @@
import ArrayConvertToObj from './array-convert-to-obj';
import { cloneElement, ReactElement } from 'react';
import isEmpty from './utils';
export default function RippleEffectBuild(
nextRipples: ReactElement[],
callback: (child: any) => void,
prevRipples?: any | null,
) {
const empty: boolean = isEmpty(prevRipples);
const preparedRipples: object = empty ? {} : prevRipples;
switch (empty) {
case true:
ArrayConvertToObj(preparedRipples, nextRipples, callback);
break;
case false:
// eslint-disable-next-line no-case-declarations
const next: object = {};
ArrayConvertToObj(next, nextRipples, callback);
for (const rippleKey of Object.keys(next)) {
if (preparedRipples[rippleKey] == undefined) {
preparedRipples[rippleKey] = cloneElement(next[rippleKey], {
...next[rippleKey].props,
endLifetime: callback.bind(null, next[rippleKey]),
});
}
}
break;
}
return preparedRipples;
}

View File

@@ -0,0 +1,6 @@
export default function isEmpty(obj: Object): boolean {
for (const _i in obj) {
return false;
}
return true;
}

View File

@@ -0,0 +1,36 @@
'use client';
import React, { forwardRef } from 'react';
import { SwitchMainProps } from './switch.types';
import { CheckBoxLayout } from '../checkbox-layout/check-box-layout';
/**
* Switch component
** description
*/
export const Switch = forwardRef<HTMLInputElement, SwitchMainProps>(
({ icon, disabled, selected = false, ...props }, ref) => (
<div className={'m3 m3-switch-exp'} ref={ref}>
<CheckBoxLayout
{...props}
className={`m3 ${props.className ?? ''}`.trimEnd()}
disabled={disabled}
type={'checkbox'}
/>
<svg>
<rect className={'m3 m3-switch-track'} />
<circle className={'m3 m3-switch-handler'} />
<circle className={'m3 m3-switch-handler-state-layer'} />
<g>
{icon && !selected && (
<text className={'m3 m3-icon-unchecked'}>close</text>
)}
{icon && (
<text className={'m3 m3-icon-checked'}>check</text>
)}
</g>
</svg>
</div>
),
);

View File

@@ -0,0 +1,7 @@
import { PropsWithChildren } from 'react';
export interface SwitchMainProps extends PropsWithChildren<any> {
disabled?: boolean;
icon?: boolean;
selected?: boolean;
}

View File

@@ -0,0 +1,103 @@
'use client';
import React, { forwardRef, useState } from 'react';
import { bool, string } from 'prop-types';
import { type TextFieldInterface } from './text-field.types';
export const TextField = forwardRef<HTMLInputElement, TextFieldInterface>(
(
{
variant = 'filled',
withAfterIcon,
withBeforeIcon,
supportingText,
...props
},
ref,
) => {
const [raised, setRaised] = useState<boolean>(
props.placeholder ?? false,
);
const callback = (e: any): void => {
if (
e.type === 'blur' &&
e.target.value.length === 0 &&
!props.placeholder
) {
setRaised(false);
} else if (e.type === 'focus') {
setRaised(true);
}
};
const iconStyles =
withBeforeIcon && withAfterIcon
? 'with-before-icon with-after-icon'
: withBeforeIcon
? 'with-before-icon'
: withAfterIcon
? 'with-after-icon'
: '';
return (
<span>
<div className={`m3 m3-text-field ${variant}`.trimEnd()}>
{variant === 'outlined' && (
<fieldset>
<legend className={raised && 'raised'}>
<span>Label</span>
</legend>
</fieldset>
)}
{withBeforeIcon && (
<span className={'m3-icon icon-before'}>
{withBeforeIcon && 'search'}
</span>
)}
<input
ref={ref}
{...props}
className={`${props.className ?? ''} ${iconStyles}`.trim()}
onBlur={event => {
callback(event);
if (props.onBlur) {
props.onBlur(event);
}
}}
onFocus={event => {
callback(event);
if (props.onFocus) {
props.onFocus(event);
}
}}
/>
<label className={raised ? 'raised' : ''}>
{props.children ?? 'Label'}
</label>
<span className={'m3-text-field-state-layer'} />
{withAfterIcon && (
<span className={'m3-icon'}>
{withAfterIcon && 'cancel'}
</span>
)}
</div>
{supportingText !== '' && (
<span className={'m3-text-field-supporting-text'}>
{supportingText}
</span>
)}
</span>
);
},
);
TextField.propTypes = {
children: string,
withBeforeIcon: bool,
withAfterIcon: bool,
className: string,
variant: string,
placeholder: string,
supportingText: string,
};

View File

@@ -0,0 +1,8 @@
import { PropsWithChildren } from 'react';
export interface TextFieldInterface extends PropsWithChildren<any> {
variant: 'filled' | 'outlined';
withAfterIcon?: boolean;
withBeforeIcon?: boolean;
supportingText?: string;
}

31
src/styles/badge.css Normal file
View File

@@ -0,0 +1,31 @@
svg.m3.m3-badge {
position: absolute;
background-color: var(--md-sys-color-error);
}
svg.m3.m3-badge.disable-value {
padding: 0;
height: 6px;
width: 6px;
border-radius: 3px;
}
svg.m3.m3-badge.disable-value > text {
display: none;
}
svg.m3.m3-badge {
border-radius: 8px;
height: 16px;
}
svg.m3.m3-badge > text {
fill: var(--md-sys-color-on-error);
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;
align-items: center;
justify-content: center;
}
/*# sourceMappingURL=badge.css.map */

1
src/styles/badge.css.map Normal file
View File

@@ -0,0 +1 @@
{"version":3,"sourceRoot":"","sources":["badge.sass"],"names":[],"mappings":"AAAA;EACI;EACA;;AACA;EACI;EACA;EACA;EACA;;AACA;EACI;;AACR;EACI;EACA;;AAEJ;EACI;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA","file":"badge.css"}

25
src/styles/badge.sass Normal file
View File

@@ -0,0 +1,25 @@
svg.m3.m3-badge
position: absolute
background-color: var(--md-sys-color-error)
&.disable-value
padding: 0
height: 6px
width: 6px
border-radius: 3px
& > text
display: none
&
border-radius: 8px
height: 16px
& > text
fill: var(--md-sys-color-on-error)
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
align-items: center
justify-content: center

206
src/styles/button.css Normal file
View File

@@ -0,0 +1,206 @@
button:not(.m3-fab, .m3-icon-button) {
transition:
background-color,
box-shadow,
0.2s cubic-bezier(0.2, 0, 0, 1) !important;
font-family: var(--md-sys-typescale-label-large-font-family-name);
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);
box-sizing: border-box;
}
button:not(.m3-fab, .m3-icon-button).m3 {
contain: content;
box-sizing: border-box;
border-radius: 100px;
display: inline-flex;
flex-direction: row;
justify-content: center;
align-items: center;
text-align: center;
padding: 10px 24px;
border: none;
gap: 8px;
}
button:not(.m3-fab, .m3-icon-button).filled {
background-color: var(--md-sys-color-primary);
}
button:not(.m3-fab, .m3-icon-button).filled,
button:not(.m3-fab, .m3-icon-button).filled > svg.m3-svg-icon {
color: var(--md-sys-color-on-primary);
fill: var(--md-sys-color-on-primary);
}
button:not(.m3-fab, .m3-icon-button).outlined {
outline-offset: -1px;
outline: 1px solid var(--md-sys-color-outline) !important;
background-color: rgba(0, 0, 0, 0);
color: var(--md-sys-color-primary);
}
button:not(.m3-fab, .m3-icon-button).outlined > svg.m3-svg-icon {
fill: var(--md-sys-color-primary);
}
button:not(.m3-fab, .m3-icon-button).text {
padding: 10px 12px !important;
background-color: rgba(0, 0, 0, 0);
color: var(--md-sys-color-primary);
}
button:not(.m3-fab, .m3-icon-button).text > svg.m3-svg-icon {
fill: var(--md-sys-color-primary);
}
button:not(.m3-fab, .m3-icon-button).elevated {
box-shadow:
0 1px 3px 1px rgba(0, 0, 0, 0.15),
0 1px 2px 0 rgba(0, 0, 0, 0.3);
background-color: var(--md-sys-color-surface-container-low);
color: var(--md-sys-color-primary);
}
button:not(.m3-fab, .m3-icon-button).elevated > svg.m3-svg-icon {
fill: var(--md-sys-color-primary);
}
button:not(.m3-fab, .m3-icon-button).tonal {
background-color: var(--md-sys-color-secondary-container);
color: var(--md-sys-color-on-secondary-container);
}
button:not(.m3-fab, .m3-icon-button).tonal > svg.m3-svg-icon {
fill: var(--md-sys-color-on-secondary-container);
}
button:not(.m3-fab, .m3-icon-button)::before {
transition:
background-color,
box-shadow,
0.2s cubic-bezier(0.2, 0, 0, 1) !important;
content: "";
top: 0;
bottom: 0;
left: 0;
right: 0;
position: absolute;
background: rgba(0, 0, 0, 0);
}
button:not(.m3-fab, .m3-icon-button).filled
> .m3.m3-ripple-domain
> .m3.ripple {
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 {
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 {
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) {
box-shadow: none !important;
}
button:not(.m3-fab, .m3-icon-button):active.elevated {
box-shadow:
0 1px 3px 1px rgba(0, 0, 0, 0.15),
0 1px 2px 0 rgba(0, 0, 0, 0.3) !important;
}
button:not(.m3-fab, .m3-icon-button):active.tonal::before {
background-color: color-mix(
in srgb,
var(--md-sys-color-on-secondary-container) 12%,
transparent
);
}
button:not(.m3-fab, .m3-icon-button):focus-visible.outlined {
border-color: var(--md-sys-color-primary) !important;
}
button:not(.m3-fab, .m3-icon-button):focus-visible.filled::before {
background-color: color-mix(
in srgb,
var(--md-sys-color-on-primary) 12%,
transparent
);
}
button:not(.m3-fab, .m3-icon-button):focus-visible:is(
.outlined,
.text,
.elevated
)::before {
background-color: color-mix(
in srgb,
var(--md-sys-color-primary) 12%,
transparent
);
}
button:not(.m3-fab, .m3-icon-button):focus-visible.tonal::before {
background-color: color-mix(
in srgb,
var(--md-sys-color-on-secondary-container) 12%,
transparent
);
}
button:not(.m3-fab, .m3-icon-button):hover:is(.filled, .tonal) {
box-shadow:
0 1px 3px 1px rgba(0, 0, 0, 0.15),
0 1px 2px 0 rgba(0, 0, 0, 0.3);
}
button:not(.m3-fab, .m3-icon-button):hover.elevated {
box-shadow:
0 2px 6px 2px rgba(0, 0, 0, 0.15),
0 1px 2px 0 rgba(0, 0, 0, 0.3);
}
button:not(.m3-fab, .m3-icon-button):hover.filled::before {
background-color: color-mix(
in srgb,
var(--md-sys-color-on-primary) 8%,
transparent
);
}
button:not(.m3-fab, .m3-icon-button):hover:is(
.outlined,
.text,
.elevated
)::before {
background-color: color-mix(
in srgb,
var(--md-sys-color-primary) 8%,
transparent
);
}
button:not(.m3-fab, .m3-icon-button):hover.tonal::before {
background-color: color-mix(
in srgb,
var(--md-sys-color-on-secondary-container) 8%,
transparent
);
}
button:not(.m3-fab, .m3-icon-button):disabled {
pointer-events: none;
}
button:not(.m3-fab, .m3-icon-button):disabled:is(
.filled,
.elevated,
.tonal,
.outlined,
.text
) {
color: color-mix(in srgb, var(--md-sys-color-on-surface) 38%, transparent);
}
button:not(.m3-fab, .m3-icon-button):disabled:is(.filled, .elevated, .tonal) {
background: color-mix(
in srgb,
var(--md-sys-color-on-surface) 12%,
transparent
);
}
button:not(.m3-fab, .m3-icon-button):disabled.elevated {
box-shadow: none;
}
button:not(.m3-fab, .m3-icon-button):disabled.outlined {
outline: 1px solid
color-mix(in srgb, var(--md-sys-color-on-surface) 12%, transparent) !important;
}
/*# sourceMappingURL=button.css.map */

View File

@@ -0,0 +1 @@
{"version":3,"sourceRoot":"","sources":["button.sass","mixins/m3-mixins.sass"],"names":[],"mappings":"AAEA;EACI;EACA;EACA;EACA;EACA;EACA;;AAEA;EACI;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAEJ;EACI;;AACA;EACI;EACA;;AAER;EACI;EACA;EACA;EACA;;AAEA;EACI;;AAER;EACI;EACA;EACA;;AAEA;EACI;;AAER;ECNI;EDQA;EACA;;AAEA;EACI;;AAER;EACI;EACA;;AAEA;EACI;;AAER;ECMA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;ADVA;EACI;;AAGA;EACI;;AAER;EACI;;AAGA;EC3CA;;AD8CA;ECxCA;;AD2CA;EACI;;AAGJ;EACI;;AAEJ;EACI;;AAEJ;EACI;;AAEJ;EACI;;AAGJ;EC1DA;;AD6DA;ECvDA;;AD0DA;EACI;;AAEJ;EACI;;AAEJ;EACI;;AAER;EACI;;AAEA;EACI;;AAEJ;EACI;;AAEJ;EACI;;AAEJ;EACI","file":"button.css"}

127
src/styles/button.sass Normal file
View File

@@ -0,0 +1,127 @@
@import "mixins/m3-mixins"
button:not(.m3-fab, .m3-icon-button)
transition: background-color, box-shadow, .2s cubic-bezier(0.2, 0, 0, 1) !important
font-family: var(--md-sys-typescale-label-large-font-family-name)
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)
box-sizing: border-box
&.m3
contain: content
box-sizing: border-box
border-radius: 100px
display: inline-flex
flex-direction: row
justify-content: center
align-items: center
text-align: center
padding: 10px 24px
border: none
gap: 8px
&.filled
background-color: var(--md-sys-color-primary)
&, & > svg.m3-svg-icon
color: var(--md-sys-color-on-primary)
fill: var(--md-sys-color-on-primary)
&.outlined
outline-offset: -1px
outline: 1px solid var(--md-sys-color-outline) !important
background-color: #00000000
color: var(--md-sys-color-primary)
& > svg.m3-svg-icon
fill: var(--md-sys-color-primary)
&.text
padding: 10px 12px !important
background-color: #00000000
color: var(--md-sys-color-primary)
& > svg.m3-svg-icon
fill: var(--md-sys-color-primary)
&.elevated
@include elevation-1(false)
background-color: var(--md-sys-color-surface-container-low)
color: var(--md-sys-color-primary)
& > svg.m3-svg-icon
fill: var(--md-sys-color-primary)
&.tonal
background-color: var(--md-sys-color-secondary-container)
color: var(--md-sys-color-on-secondary-container)
& > svg.m3-svg-icon
fill: var(--md-sys-color-on-secondary-container)
&::before
@include state-layer
&.filled > .m3.m3-ripple-domain > .m3.ripple
background: color-mix(in srgb, var(--md-sys-color-on-primary) 12%, transparent)
&:is(.outlined, .text, .elevated)
& > .m3.m3-ripple-domain > .m3.ripple
background: color-mix(in srgb, var(--md-sys-color-primary) 12%, transparent)
&.tonal > .m3.m3-ripple-domain > .m3.ripple
background: color-mix(in srgb, var(--md-sys-color-on-secondary-container) 12%, transparent)
&:active
&:is(.filled, .tonal)
@include elevation-0(true)
&.elevated
@include elevation-1(true)
&.tonal::before
background-color: color-mix(in srgb, var(--md-sys-color-on-secondary-container) 12%, transparent)
&:focus-visible
&.outlined
border-color: var(--md-sys-color-primary) !important
&.filled::before
background-color: color-mix(in srgb, var(--md-sys-color-on-primary) 12%, transparent)
&:is(.outlined, .text, .elevated)::before
background-color: color-mix(in srgb, var(--md-sys-color-primary) 12%, transparent)
&.tonal::before
background-color: color-mix(in srgb, var(--md-sys-color-on-secondary-container) 12%, transparent)
&:hover
&:is(.filled, .tonal)
@include elevation-1(false)
&.elevated
@include elevation-2(false)
&.filled::before
background-color: color-mix(in srgb, var(--md-sys-color-on-primary) 8%, transparent)
&:is(.outlined, .text, .elevated)::before
background-color: color-mix(in srgb, var(--md-sys-color-primary) 8%, transparent)
&.tonal::before
background-color: color-mix(in srgb, var(--md-sys-color-on-secondary-container) 8%, transparent)
&:disabled
pointer-events: none
&:is(.filled, .elevated, .tonal, .outlined, .text)
color: color-mix(in srgb, var(--md-sys-color-on-surface) 38%, transparent)
&:is(.filled, .elevated, .tonal)
background: color-mix(in srgb, var(--md-sys-color-on-surface) 12%, transparent)
&.elevated
box-shadow: none
&.outlined
outline: 1px solid color-mix(in srgb, var(--md-sys-color-on-surface) 12%, transparent) !important

190
src/styles/checkbox.css Normal file
View File

@@ -0,0 +1,190 @@
label.m3.m3-checkbox-label {
display: flex;
position: relative;
align-items: center;
justify-content: center;
aspect-ratio: 1;
}
label.m3.m3-checkbox-label > span.m3.m3-checkbox-state-layer {
position: absolute;
width: 2.5rem;
aspect-ratio: inherit;
border-radius: 50%;
transition: background-color 0.2s cubic-bezier(0.2, 0, 0, 1);
}
span.m3.m3-checkbox-ripple-layer {
z-index: 20;
contain: content;
border-radius: 50%;
position: absolute;
width: 2.5rem;
height: 2.5rem;
}
input[type="checkbox"].m3.m3-checkbox {
appearance: none;
display: flex;
align-items: center;
justify-content: center;
box-sizing: content-box;
z-index: 10;
width: 1.125rem;
height: 1.125rem;
margin: 0;
outline-offset: -0.14rem;
border-radius: 0.14rem;
outline: 0.14rem solid var(--md-sys-color-on-surface-variant);
transition: background-color 0.2s cubic-bezier(0.2, 0, 0, 1);
}
input[type="checkbox"].m3.m3-checkbox:is(
:user-invalid:is(:checked, :indeterminate),
.m3.m3-error:is(:checked, :indeterminate)
) {
outline-color: var(--md-sys-color-error);
background-color: var(--md-sys-color-error);
}
input[type="checkbox"].m3.m3-checkbox:is(.m3.m3-error, :user-invalid) {
outline-color: var(--md-sys-color-error);
}
input[type="checkbox"].m3.m3-checkbox:is(
:checked:is(:hover, input[type="checkbox"].m3.m3-checkbox):not(
.m3.m3-error,
:disabled
),
:indeterminate:is(:hover, input[type="checkbox"].m3.m3-checkbox):not(
.m3.m3-error,
:disabled
)
) {
outline-color: var(--md-sys-color-primary);
background-color: var(--md-sys-color-primary);
}
input[type="checkbox"].m3.m3-checkbox:disabled:is(
:hover,
input[type="checkbox"].m3.m3-checkbox:disabled
) {
opacity: 38%;
border: 2px solid var(--md-sys-color-on-surface);
}
input[type="checkbox"].m3.m3-checkbox:disabled:checked:is(
:hover,
input[type="checkbox"].m3.m3-checkbox:disabled
) {
opacity: 38%;
background-color: var(--md-sys-color-on-surface);
}
input[type="checkbox"].m3.m3-checkbox::after {
line-height: 1.125rem;
font-family: Material-Symbols-Outlined-Regular, sans-serif;
font-weight: 700;
font-size: 1.125rem;
color: var(--md-sys-color-on-primary);
}
input[type="checkbox"].m3.m3-checkbox:checked::after {
content: "done";
}
input[type="checkbox"].m3.m3-checkbox:indeterminate::after {
content: "check_indeterminate_small";
}
input[type="checkbox"].m3.m3-checkbox:hover {
outline-color: var(--md-sys-color-on-surface);
}
input[type="checkbox"].m3.m3-checkbox:not(:disabled):is(
:user-invalid:is(:hover, :indeterminate:hover),
.m3.m3-error:hover
)
+ span.m3.m3-checkbox-state-layer {
background-color: color-mix(
in srgb,
var(--md-sys-color-error) 8%,
transparent
);
}
input[type="checkbox"].m3.m3-checkbox:not(:disabled):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
);
}
input[type="checkbox"].m3.m3-checkbox:not(:disabled):is(
:user-invalid:is(:active, :indeterminate:active),
.m3.m3-error:active
)
+ span.m3.m3-checkbox-state-layer
+ span.m3-ripple-domain
> .m3.ripple {
background-color: color-mix(
in srgb,
var(--md-sys-color-error) 20%,
transparent
);
}
input[type="checkbox"].m3.m3-checkbox:not(:disabled):is(
:checked:hover,
:indeterminate:hover
)
+ span.m3.m3-checkbox-state-layer {
background-color: color-mix(
in srgb,
var(--md-sys-color-primary) 8%,
transparent
);
}
input[type="checkbox"].m3.m3-checkbox:not(:disabled):is(
:checked:active,
:indeterminate:active
)
+ span.m3.m3-checkbox-state-layer {
background-color: color-mix(
in srgb,
var(--md-sys-color-primary) 12%,
transparent
);
}
input[type="checkbox"].m3.m3-checkbox:not(:disabled):is(
:checked:active,
:indeterminate:active
)
+ span.m3.m3-checkbox-state-layer
+ span.m3-ripple-domain
> .m3.ripple {
background-color: color-mix(
in srgb,
var(--md-sys-color-on-surface) 20%,
transparent
);
}
input[type="checkbox"].m3.m3-checkbox:not(:disabled):hover
+ span.m3-checkbox-state-layer {
background-color: color-mix(
in srgb,
var(--md-sys-color-on-surface) 8%,
transparent
);
}
input[type="checkbox"].m3.m3-checkbox:not(:disabled):active
+ span.m3.m3-checkbox-state-layer {
background-color: color-mix(
in srgb,
var(--md-sys-color-on-surface) 12%,
transparent
);
}
input[type="checkbox"].m3.m3-checkbox:not(:disabled):active
+ span.m3.m3-checkbox-state-layer
+ span.m3-ripple-domain
> .m3.ripple {
background-color: color-mix(
in srgb,
var(--md-sys-color-primary) 20%,
transparent
);
}
/*# sourceMappingURL=checkbox.css.map */

View File

@@ -0,0 +1 @@
{"version":3,"sourceRoot":"","sources":["checkbox.sass","mixins/m3-mixins.sass"],"names":[],"mappings":"AAEA;ECDI;EACA;EACA;EACA;EACA;;ADDA;ECIA;EACA;EACA;EACA;EACA;;;ADLJ;EACI;EACA;EACA;EACA;EACA;EACA;;;AAEJ;EACI;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAEA;EACI;EACA;;AAEJ;EACI;;AAEJ;EACI;EACA;;AAGA;EACI;EACA;;AAEJ;EACI;EACA;;AAER;EACI;EACA;EACA;EACA;EACA;;AAEJ;EACI;;AAEJ;EACI;;AAEJ;EACI;;AAII;EACI;;AAER;EACI;;AACA;EACI;;AAER;EACI;;AAEJ;EACI;;AACA;EACI;;AAGJ;EACI;;AAER;EACI;;AACA;EACI","file":"checkbox.css"}

93
src/styles/checkbox.sass Normal file
View File

@@ -0,0 +1,93 @@
@import "mixins/m3-mixins"
label.m3.m3-checkbox-label
@include m3-label-mixin
& > span.m3.m3-checkbox-state-layer
@include m3-state-layer-mixin
span.m3.m3-checkbox-ripple-layer
z-index: 20
contain: content
border-radius: 50%
position: absolute
width: 2.5rem
height: 2.5rem
input[type="checkbox"].m3.m3-checkbox
appearance: none
display: flex
align-items: center
justify-content: center
box-sizing: content-box
z-index: 10
width: 1.125rem
height: 1.125rem
margin: 0
outline-offset: -.14rem
border-radius: .14rem
outline: .14rem solid var(--md-sys-color-on-surface-variant)
transition: background-color .2s cubic-bezier(0.2, 0, 0, 1)
&:is(:user-invalid:is(:checked, :indeterminate), .m3.m3-error:is(:checked, :indeterminate))
outline-color: var(--md-sys-color-error)
background-color: var(--md-sys-color-error)
&:is(.m3.m3-error, :user-invalid)
outline-color: var(--md-sys-color-error)
&:is(:checked:is(:hover, &):not(.m3.m3-error, :disabled), :indeterminate:is(:hover, &):not(.m3.m3-error, :disabled))
outline-color: var(--md-sys-color-primary)
background-color: var(--md-sys-color-primary)
&:disabled
&:is(:hover, &)
opacity: 38%
border: 2px solid var(--md-sys-color-on-surface)
&:checked:is(:hover, &)
opacity: 38%
background-color: var(--md-sys-color-on-surface)
&::after
line-height: 1.125rem
font-family: Material-Symbols-Outlined-Regular, sans-serif
font-weight: 700
font-size: 1.125rem
color: var(--md-sys-color-on-primary)
&:checked::after
content: "done"
&:indeterminate::after
content: "check_indeterminate_small"
&:hover
outline-color: var(--md-sys-color-on-surface)
&:not(:disabled)
&:is(:user-invalid:is(:hover, :indeterminate:hover), .m3.m3-error:hover)
& + span.m3.m3-checkbox-state-layer
background-color: color-mix(in srgb, var(--md-sys-color-error) 8%, transparent)
&: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)
& + span.m3-ripple-domain > .m3.ripple
background-color: color-mix(in srgb, var(--md-sys-color-error) 20%, transparent)
&:is(:checked:hover, :indeterminate:hover) + span.m3.m3-checkbox-state-layer
background-color: color-mix(in srgb, var(--md-sys-color-primary) 8%, transparent)
&:is(:checked:active, :indeterminate:active) + span.m3.m3-checkbox-state-layer
background-color: color-mix(in srgb, var(--md-sys-color-primary) 12%, transparent)
& + span.m3-ripple-domain > .m3.ripple
background-color: color-mix(in srgb, var(--md-sys-color-on-surface) 20%, transparent)
&:hover
& + span.m3-checkbox-state-layer
background-color: color-mix(in srgb, var(--md-sys-color-on-surface) 8%, transparent)
&:active + span.m3.m3-checkbox-state-layer
background-color: color-mix(in srgb, var(--md-sys-color-on-surface) 12%, transparent)
& + span.m3-ripple-domain > .m3.ripple
background-color: color-mix(in srgb, var(--md-sys-color-primary) 20%, transparent)

View File

@@ -0,0 +1,51 @@
.dark-high-contrast {
--md-sys-color-primary: rgb(255 249 251);
--md-sys-color-surface-tint: rgb(227 183 244);
--md-sys-color-on-primary: rgb(0 0 0);
--md-sys-color-primary-container: rgb(231 187 248);
--md-sys-color-on-primary-container: rgb(0 0 0);
--md-sys-color-secondary: rgb(255 249 251);
--md-sys-color-on-secondary: rgb(0 0 0);
--md-sys-color-secondary-container: rgb(216 196 220);
--md-sys-color-on-secondary-container: rgb(0 0 0);
--md-sys-color-tertiary: rgb(255 249 249);
--md-sys-color-on-tertiary: rgb(0 0 0);
--md-sys-color-tertiary-container: rgb(249 187 186);
--md-sys-color-on-tertiary-container: rgb(0 0 0);
--md-sys-color-error: rgb(255 249 249);
--md-sys-color-on-error: rgb(0 0 0);
--md-sys-color-error-container: rgb(255 186 177);
--md-sys-color-on-error-container: rgb(0 0 0);
--md-sys-color-background: rgb(22 18 23);
--md-sys-color-on-background: rgb(233 224 231);
--md-sys-color-surface: rgb(22 18 23);
--md-sys-color-on-surface: rgb(255 255 255);
--md-sys-color-surface-variant: rgb(76 68 77);
--md-sys-color-on-surface-variant: rgb(255 249 251);
--md-sys-color-outline: rgb(210 199 210);
--md-sys-color-outline-variant: rgb(210 199 210);
--md-sys-color-shadow: rgb(0 0 0);
--md-sys-color-scrim: rgb(0 0 0);
--md-sys-color-inverse-surface: rgb(233 224 231);
--md-sys-color-inverse-on-surface: rgb(0 0 0);
--md-sys-color-inverse-primary: rgb(60 27 77);
--md-sys-color-primary-fixed: rgb(248 222 255);
--md-sys-color-on-primary-fixed: rgb(0 0 0);
--md-sys-color-primary-fixed-dim: rgb(231 187 248);
--md-sys-color-on-primary-fixed-variant: rgb(39 5 56);
--md-sys-color-secondary-fixed: rgb(245 224 248);
--md-sys-color-on-secondary-fixed: rgb(0 0 0);
--md-sys-color-secondary-fixed-dim: rgb(216 196 220);
--md-sys-color-on-secondary-fixed-variant: rgb(29 18 34);
--md-sys-color-tertiary-fixed: rgb(255 224 222);
--md-sys-color-on-tertiary-fixed: rgb(0 0 0);
--md-sys-color-tertiary-fixed-dim: rgb(249 187 186);
--md-sys-color-on-tertiary-fixed-variant: rgb(44 11 13);
--md-sys-color-surface-dim: rgb(22 18 23);
--md-sys-color-surface-bright: rgb(61 55 61);
--md-sys-color-surface-container-lowest: rgb(17 13 18);
--md-sys-color-surface-container-low: rgb(30 26 31);
--md-sys-color-surface-container: rgb(35 30 35);
--md-sys-color-surface-container-high: rgb(45 40 46);
--md-sys-color-surface-container-highest: rgb(56 51 57);
}

View File

@@ -0,0 +1,51 @@
.dark-medium-contrast {
--md-sys-color-primary: rgb(231 187 248);
--md-sys-color-surface-tint: rgb(227 183 244);
--md-sys-color-on-primary: rgb(39 5 56);
--md-sys-color-primary-container: rgb(170 130 187);
--md-sys-color-on-primary-container: rgb(0 0 0);
--md-sys-color-secondary: rgb(216 196 220);
--md-sys-color-on-secondary: rgb(29 18 34);
--md-sys-color-secondary-container: rgb(156 139 161);
--md-sys-color-on-secondary-container: rgb(0 0 0);
--md-sys-color-tertiary: rgb(249 187 186);
--md-sys-color-on-tertiary: rgb(44 11 13);
--md-sys-color-tertiary-container: rgb(186 131 130);
--md-sys-color-on-tertiary-container: rgb(0 0 0);
--md-sys-color-error: rgb(255 186 177);
--md-sys-color-on-error: rgb(55 0 1);
--md-sys-color-error-container: rgb(255 84 73);
--md-sys-color-on-error-container: rgb(0 0 0);
--md-sys-color-background: rgb(22 18 23);
--md-sys-color-on-background: rgb(233 224 231);
--md-sys-color-surface: rgb(22 18 23);
--md-sys-color-on-surface: rgb(255 249 251);
--md-sys-color-surface-variant: rgb(76 68 77);
--md-sys-color-on-surface-variant: rgb(210 199 210);
--md-sys-color-outline: rgb(170 160 170);
--md-sys-color-outline-variant: rgb(137 128 138);
--md-sys-color-shadow: rgb(0 0 0);
--md-sys-color-scrim: rgb(0 0 0);
--md-sys-color-inverse-surface: rgb(233 224 231);
--md-sys-color-inverse-on-surface: rgb(45 40 46);
--md-sys-color-inverse-primary: rgb(93 58 109);
--md-sys-color-primary-fixed: rgb(246 217 255);
--md-sys-color-on-primary-fixed: rgb(33 0 50);
--md-sys-color-primary-fixed-dim: rgb(227 183 244);
--md-sys-color-on-primary-fixed-variant: rgb(74 40 90);
--md-sys-color-secondary-fixed: rgb(240 220 244);
--md-sys-color-on-secondary-fixed: rgb(24 13 29);
--md-sys-color-secondary-fixed-dim: rgb(212 192 216);
--md-sys-color-on-secondary-fixed-variant: rgb(63 49 68);
--md-sys-color-tertiary-fixed: rgb(255 218 217);
--md-sys-color-on-tertiary-fixed: rgb(37 7 8);
--md-sys-color-tertiary-fixed-dim: rgb(245 183 182);
--md-sys-color-on-tertiary-fixed-variant: rgb(83 43 43);
--md-sys-color-surface-dim: rgb(22 18 23);
--md-sys-color-surface-bright: rgb(61 55 61);
--md-sys-color-surface-container-lowest: rgb(17 13 18);
--md-sys-color-surface-container-low: rgb(30 26 31);
--md-sys-color-surface-container: rgb(35 30 35);
--md-sys-color-surface-container-high: rgb(45 40 46);
--md-sys-color-surface-container-highest: rgb(56 51 57);
}

51
src/styles/css/dark.css Normal file
View File

@@ -0,0 +1,51 @@
.dark {
--md-sys-color-primary: rgb(227 183 244);
--md-sys-color-surface-tint: rgb(227 183 244);
--md-sys-color-on-primary: rgb(67 34 84);
--md-sys-color-primary-container: rgb(92 57 108);
--md-sys-color-on-primary-container: rgb(246 217 255);
--md-sys-color-secondary: rgb(212 192 216);
--md-sys-color-on-secondary: rgb(57 44 62);
--md-sys-color-secondary-container: rgb(80 66 85);
--md-sys-color-on-secondary-container: rgb(240 220 244);
--md-sys-color-tertiary: rgb(245 183 182);
--md-sys-color-on-tertiary: rgb(76 37 37);
--md-sys-color-tertiary-container: rgb(102 59 59);
--md-sys-color-on-tertiary-container: rgb(255 218 217);
--md-sys-color-error: rgb(255 180 171);
--md-sys-color-on-error: rgb(105 0 5);
--md-sys-color-error-container: rgb(147 0 10);
--md-sys-color-on-error-container: rgb(255 218 214);
--md-sys-color-background: rgb(22 18 23);
--md-sys-color-on-background: rgb(233 224 231);
--md-sys-color-surface: rgb(22 18 23);
--md-sys-color-on-surface: rgb(233 224 231);
--md-sys-color-surface-variant: rgb(76 68 77);
--md-sys-color-on-surface-variant: rgb(206 195 206);
--md-sys-color-outline: rgb(151 142 151);
--md-sys-color-outline-variant: rgb(76 68 77);
--md-sys-color-shadow: rgb(0 0 0);
--md-sys-color-scrim: rgb(0 0 0);
--md-sys-color-inverse-surface: rgb(233 224 231);
--md-sys-color-inverse-on-surface: rgb(52 47 52);
--md-sys-color-inverse-primary: rgb(117 80 134);
--md-sys-color-primary-fixed: rgb(246 217 255);
--md-sys-color-on-primary-fixed: rgb(45 11 62);
--md-sys-color-primary-fixed-dim: rgb(227 183 244);
--md-sys-color-on-primary-fixed-variant: rgb(92 57 108);
--md-sys-color-secondary-fixed: rgb(240 220 244);
--md-sys-color-on-secondary-fixed: rgb(35 23 40);
--md-sys-color-secondary-fixed-dim: rgb(212 192 216);
--md-sys-color-on-secondary-fixed-variant: rgb(80 66 85);
--md-sys-color-tertiary-fixed: rgb(255 218 217);
--md-sys-color-on-tertiary-fixed: rgb(51 17 18);
--md-sys-color-tertiary-fixed-dim: rgb(245 183 182);
--md-sys-color-on-tertiary-fixed-variant: rgb(102 59 59);
--md-sys-color-surface-dim: rgb(22 18 23);
--md-sys-color-surface-bright: rgb(61 55 61);
--md-sys-color-surface-container-lowest: rgb(17 13 18);
--md-sys-color-surface-container-low: rgb(30 26 31);
--md-sys-color-surface-container: rgb(35 30 35);
--md-sys-color-surface-container-high: rgb(45 40 46);
--md-sys-color-surface-container-highest: rgb(56 51 57);
}

View File

@@ -0,0 +1,51 @@
.light-high-contrast {
--md-sys-color-primary: rgb(52 19 69);
--md-sys-color-surface-tint: rgb(117 80 134);
--md-sys-color-on-primary: rgb(255 255 255);
--md-sys-color-primary-container: rgb(87 53 104);
--md-sys-color-on-primary-container: rgb(255 255 255);
--md-sys-color-secondary: rgb(42 30 47);
--md-sys-color-on-secondary: rgb(255 255 255);
--md-sys-color-secondary-container: rgb(76 62 81);
--md-sys-color-on-secondary-container: rgb(255 255 255);
--md-sys-color-tertiary: rgb(59 23 24);
--md-sys-color-on-tertiary: rgb(255 255 255);
--md-sys-color-tertiary-container: rgb(98 55 55);
--md-sys-color-on-tertiary-container: rgb(255 255 255);
--md-sys-color-error: rgb(78 0 2);
--md-sys-color-on-error: rgb(255 255 255);
--md-sys-color-error-container: rgb(140 0 9);
--md-sys-color-on-error-container: rgb(255 255 255);
--md-sys-color-background: rgb(255 247 252);
--md-sys-color-on-background: rgb(30 26 31);
--md-sys-color-surface: rgb(255 247 252);
--md-sys-color-on-surface: rgb(0 0 0);
--md-sys-color-surface-variant: rgb(235 223 234);
--md-sys-color-on-surface-variant: rgb(40 34 42);
--md-sys-color-outline: rgb(72 65 73);
--md-sys-color-outline-variant: rgb(72 65 73);
--md-sys-color-shadow: rgb(0 0 0);
--md-sys-color-scrim: rgb(0 0 0);
--md-sys-color-inverse-surface: rgb(52 47 52);
--md-sys-color-inverse-on-surface: rgb(255 255 255);
--md-sys-color-inverse-primary: rgb(251 229 255);
--md-sys-color-primary-fixed: rgb(87 53 104);
--md-sys-color-on-primary-fixed: rgb(255 255 255);
--md-sys-color-primary-fixed-dim: rgb(63 30 80);
--md-sys-color-on-primary-fixed-variant: rgb(255 255 255);
--md-sys-color-secondary-fixed: rgb(76 62 81);
--md-sys-color-on-secondary-fixed: rgb(255 255 255);
--md-sys-color-secondary-fixed-dim: rgb(53 40 58);
--md-sys-color-on-secondary-fixed-variant: rgb(255 255 255);
--md-sys-color-tertiary-fixed: rgb(98 55 55);
--md-sys-color-on-tertiary-fixed: rgb(255 255 255);
--md-sys-color-tertiary-fixed-dim: rgb(72 33 34);
--md-sys-color-on-tertiary-fixed-variant: rgb(255 255 255);
--md-sys-color-surface-dim: rgb(225 215 223);
--md-sys-color-surface-bright: rgb(255 247 252);
--md-sys-color-surface-container-lowest: rgb(255 255 255);
--md-sys-color-surface-container-low: rgb(251 241 248);
--md-sys-color-surface-container: rgb(245 235 243);
--md-sys-color-surface-container-high: rgb(239 229 237);
--md-sys-color-surface-container-highest: rgb(233 224 231);
}

View File

@@ -0,0 +1,51 @@
.light-medium-contrast {
--md-sys-color-primary: rgb(87 53 104);
--md-sys-color-surface-tint: rgb(117 80 134);
--md-sys-color-on-primary: rgb(255 255 255);
--md-sys-color-primary-container: rgb(140 102 157);
--md-sys-color-on-primary-container: rgb(255 255 255);
--md-sys-color-secondary: rgb(76 62 81);
--md-sys-color-on-secondary: rgb(255 255 255);
--md-sys-color-secondary-container: rgb(127 111 132);
--md-sys-color-on-secondary-container: rgb(255 255 255);
--md-sys-color-tertiary: rgb(98 55 55);
--md-sys-color-on-tertiary: rgb(255 255 255);
--md-sys-color-tertiary-container: rgb(154 103 103);
--md-sys-color-on-tertiary-container: rgb(255 255 255);
--md-sys-color-error: rgb(140 0 9);
--md-sys-color-on-error: rgb(255 255 255);
--md-sys-color-error-container: rgb(218 52 46);
--md-sys-color-on-error-container: rgb(255 255 255);
--md-sys-color-background: rgb(255 247 252);
--md-sys-color-on-background: rgb(30 26 31);
--md-sys-color-surface: rgb(255 247 252);
--md-sys-color-on-surface: rgb(30 26 31);
--md-sys-color-surface-variant: rgb(235 223 234);
--md-sys-color-on-surface-variant: rgb(72 65 73);
--md-sys-color-outline: rgb(100 93 101);
--md-sys-color-outline-variant: rgb(129 120 129);
--md-sys-color-shadow: rgb(0 0 0);
--md-sys-color-scrim: rgb(0 0 0);
--md-sys-color-inverse-surface: rgb(52 47 52);
--md-sys-color-inverse-on-surface: rgb(248 238 246);
--md-sys-color-inverse-primary: rgb(227 183 244);
--md-sys-color-primary-fixed: rgb(140 102 157);
--md-sys-color-on-primary-fixed: rgb(255 255 255);
--md-sys-color-primary-fixed-dim: rgb(114 78 131);
--md-sys-color-on-primary-fixed-variant: rgb(255 255 255);
--md-sys-color-secondary-fixed: rgb(127 111 132);
--md-sys-color-on-secondary-fixed: rgb(255 255 255);
--md-sys-color-secondary-fixed-dim: rgb(102 87 107);
--md-sys-color-on-secondary-fixed-variant: rgb(255 255 255);
--md-sys-color-tertiary-fixed: rgb(154 103 103);
--md-sys-color-on-tertiary-fixed: rgb(255 255 255);
--md-sys-color-tertiary-fixed-dim: rgb(127 79 79);
--md-sys-color-on-tertiary-fixed-variant: rgb(255 255 255);
--md-sys-color-surface-dim: rgb(225 215 223);
--md-sys-color-surface-bright: rgb(255 247 252);
--md-sys-color-surface-container-lowest: rgb(255 255 255);
--md-sys-color-surface-container-low: rgb(251 241 248);
--md-sys-color-surface-container: rgb(245 235 243);
--md-sys-color-surface-container-high: rgb(239 229 237);
--md-sys-color-surface-container-highest: rgb(233 224 231);
}

51
src/styles/css/light.css Normal file
View File

@@ -0,0 +1,51 @@
.light {
--md-sys-color-primary: rgb(117 80 134);
--md-sys-color-surface-tint: rgb(117 80 134);
--md-sys-color-on-primary: rgb(255 255 255);
--md-sys-color-primary-container: rgb(246 217 255);
--md-sys-color-on-primary-container: rgb(45 11 62);
--md-sys-color-secondary: rgb(104 89 109);
--md-sys-color-on-secondary: rgb(255 255 255);
--md-sys-color-secondary-container: rgb(240 220 244);
--md-sys-color-on-secondary-container: rgb(35 23 40);
--md-sys-color-tertiary: rgb(129 82 81);
--md-sys-color-on-tertiary: rgb(255 255 255);
--md-sys-color-tertiary-container: rgb(255 218 217);
--md-sys-color-on-tertiary-container: rgb(51 17 18);
--md-sys-color-error: rgb(186 26 26);
--md-sys-color-on-error: rgb(255 255 255);
--md-sys-color-error-container: rgb(255 218 214);
--md-sys-color-on-error-container: rgb(65 0 2);
--md-sys-color-background: rgb(255 247 252);
--md-sys-color-on-background: rgb(30 26 31);
--md-sys-color-surface: rgb(255 247 252);
--md-sys-color-on-surface: rgb(30 26 31);
--md-sys-color-surface-variant: rgb(235 223 234);
--md-sys-color-on-surface-variant: rgb(76 68 77);
--md-sys-color-outline: rgb(125 116 126);
--md-sys-color-outline-variant: rgb(206 195 206);
--md-sys-color-shadow: rgb(0 0 0);
--md-sys-color-scrim: rgb(0 0 0);
--md-sys-color-inverse-surface: rgb(52 47 52);
--md-sys-color-inverse-on-surface: rgb(248 238 246);
--md-sys-color-inverse-primary: rgb(227 183 244);
--md-sys-color-primary-fixed: rgb(246 217 255);
--md-sys-color-on-primary-fixed: rgb(45 11 62);
--md-sys-color-primary-fixed-dim: rgb(227 183 244);
--md-sys-color-on-primary-fixed-variant: rgb(92 57 108);
--md-sys-color-secondary-fixed: rgb(240 220 244);
--md-sys-color-on-secondary-fixed: rgb(35 23 40);
--md-sys-color-secondary-fixed-dim: rgb(212 192 216);
--md-sys-color-on-secondary-fixed-variant: rgb(80 66 85);
--md-sys-color-tertiary-fixed: rgb(255 218 217);
--md-sys-color-on-tertiary-fixed: rgb(51 17 18);
--md-sys-color-tertiary-fixed-dim: rgb(245 183 182);
--md-sys-color-on-tertiary-fixed-variant: rgb(102 59 59);
--md-sys-color-surface-dim: rgb(225 215 223);
--md-sys-color-surface-bright: rgb(255 247 252);
--md-sys-color-surface-container-lowest: rgb(255 255 255);
--md-sys-color-surface-container-low: rgb(251 241 248);
--md-sys-color-surface-container: rgb(245 235 243);
--md-sys-color-surface-container-high: rgb(239 229 237);
--md-sys-color-surface-container-highest: rgb(233 224 231);
}

35
src/styles/divider.css Normal file
View File

@@ -0,0 +1,35 @@
hr.m3.m3-divider {
display: flex;
align-items: end;
box-sizing: border-box;
border: none;
outline: 0.5px solid var(--md-sys-color-outline-variant);
margin: 4px;
}
hr.m3.m3-divider.vertical {
writing-mode: tb-rl;
}
hr.m3.m3-divider.vertical,
hr.m3.m3-divider.vertical.full-width {
height: 100%;
}
hr.m3.m3-divider.vertical.inset {
align-self: end;
height: calc(100% - 16px);
}
hr.m3.m3-divider.vertical.middle-inset {
height: calc(100% - 32px);
}
hr.m3.m3-divider.horizontal,
hr.m3.m3-divider.horizontal.full-width {
width: 100%;
}
hr.m3.m3-divider.horizontal.inset {
align-self: end;
width: calc(100% - 16px);
}
hr.m3.m3-divider.horizontal.middle-inset {
width: calc(100% - 32px);
}
/*# sourceMappingURL=divider.css.map */

View File

@@ -0,0 +1 @@
{"version":3,"sourceRoot":"","sources":["divider.sass"],"names":[],"mappings":"AAAA;EACI;EACA;EACA;EACA;EACA;EACA;;AAEA;EACI;;AACA;EACI;;AACJ;EACI;EACA;;AACJ;EACI;;AAGJ;EACI;;AACJ;EACI;EACA;;AACJ;EACI","file":"divider.css"}

26
src/styles/divider.sass Normal file
View File

@@ -0,0 +1,26 @@
hr.m3.m3-divider
display: flex
align-items: end
box-sizing: border-box
border: none
outline: 0.5px solid var(--md-sys-color-outline-variant)
margin: 4px
&.vertical
writing-mode: tb-rl
&, &.full-width
height: 100%
&.inset
align-self: end
height: calc(100% - 16px)
&.middle-inset
height: calc(100% - (2 * 16px))
&.horizontal
&, &.full-width
width: 100%
&.inset
align-self: end
width: calc(100% - 16px)
&.middle-inset
width: calc(100% - (2 * 16px))

31
src/styles/elevation.css Normal file
View File

@@ -0,0 +1,31 @@
.elevation-1 {
box-shadow:
0 1px 3px 1px rgba(0, 0, 0, 0.15),
0 1px 2px 0 rgba(0, 0, 0, 0.3);
}
.elevation-2 {
box-shadow:
0 2px 6px 2px rgba(0, 0, 0, 0.15),
0 1px 2px 0 rgba(0, 0, 0, 0.3);
}
.elevation-3 {
box-shadow:
0 1px 3px 0 rgba(0, 0, 0, 0.3),
0 4px 8px 3px rgba(0, 0, 0, 0.15);
}
.elevation-4 {
box-shadow:
0 2px 3px 0 rgba(0, 0, 0, 0.3),
0 6px 10px 4px rgba(0, 0, 0, 0.15);
}
.elevation-5 {
box-shadow:
0 4px 4px 0 rgba(0, 0, 0, 0.3),
0 8px 12px 6px rgba(0, 0, 0, 0.15);
}
/*# sourceMappingURL=elevation.css.map */

View File

@@ -0,0 +1 @@
{"version":3,"sourceRoot":"","sources":["elevation.sass"],"names":[],"mappings":"AAAA;EACE;;;AAEF;EACE;;;AAEF;EACE;;;AAEF;EACE;;;AAEF;EACE","file":"elevation.css"}

14
src/styles/elevation.sass Normal file
View File

@@ -0,0 +1,14 @@
.elevation-1
box-shadow: 0 1px 3px 1px rgba(0, 0, 0, 0.15), 0 1px 2px 0 rgba(0, 0, 0, 0.30)
.elevation-2
box-shadow: 0 2px 6px 2px rgba(0, 0, 0, 0.15), 0 1px 2px 0 rgba(0, 0, 0, 0.30)
.elevation-3
box-shadow: 0 1px 3px 0 rgba(0, 0, 0, 0.30), 0 4px 8px 3px rgba(0, 0, 0, 0.15)
.elevation-4
box-shadow: 0 2px 3px 0 rgba(0, 0, 0, 0.30), 0 6px 10px 4px rgba(0, 0, 0, 0.15)
.elevation-5
box-shadow: 0 4px 4px 0 rgba(0, 0, 0, 0.30), 0 8px 12px 6px rgba(0, 0, 0, 0.15)

211
src/styles/fabs.css Normal file
View File

@@ -0,0 +1,211 @@
button.m3.m3-fab {
transition:
background-color,
box-shadow,
0.2s cubic-bezier(0.2, 0, 0, 1) !important;
}
button.m3.m3-fab > span.m3-icon {
font-family: Material-Symbols-Outlined-Regular, sans-serif;
}
button.m3.m3-fab.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;
}
button.m3.m3-fab::before {
transition:
background-color,
box-shadow,
0.2s cubic-bezier(0.2, 0, 0, 1) !important;
content: "";
top: 0;
bottom: 0;
left: 0;
right: 0;
position: absolute;
background: rgba(0, 0, 0, 0);
}
button.m3.m3-fab.surface {
background-color: var(--md-sys-color-surface-container-high);
color: var(--md-sys-color-primary);
}
button.m3.m3-fab.surface:not(.without-elevation) {
box-shadow:
0 1px 3px 0 rgba(0, 0, 0, 0.3),
0 4px 8px 3px rgba(0, 0, 0, 0.15);
}
button.m3.m3-fab.surface > svg.m3-svg-icon {
fill: var(--md-sys-color-primary);
}
button.m3.m3-fab.surface > .m3.m3-ripple-domain > .m3.ripple {
background: color-mix(in srgb, var(--md-sys-color-primary) 12%, transparent);
}
button.m3.m3-fab.primary {
background-color: var(--md-sys-color-primary-container);
color: var(--md-sys-color-on-primary-container);
}
button.m3.m3-fab.primary:not(.without-elevation) {
box-shadow:
0 1px 3px 0 rgba(0, 0, 0, 0.3),
0 4px 8px 3px rgba(0, 0, 0, 0.15);
}
button.m3.m3-fab.primary > svg.m3-svg-icon {
fill: var(--md-sys-color-on-primary-container);
}
button.m3.m3-fab.primary > .m3.m3-ripple-domain > .m3.ripple {
background: color-mix(
in srgb,
var(--md-sys-color-on-primary-container) 12%,
transparent
);
}
button.m3.m3-fab.secondary {
background-color: var(--md-sys-color-secondary-container);
color: var(--md-sys-color-on-secondary-container);
}
button.m3.m3-fab.secondary:not(.without-elevation) {
box-shadow:
0 1px 3px 0 rgba(0, 0, 0, 0.3),
0 4px 8px 3px rgba(0, 0, 0, 0.15);
}
button.m3.m3-fab.secondary > svg.m3-svg-icon {
fill: var(--md-sys-color-on-secondary-container);
}
button.m3.m3-fab.secondary > .m3.m3-ripple-domain > .m3.ripple {
background: color-mix(
in srgb,
var(--md-sys-color-on-secondary-container) 12%,
transparent
);
}
button.m3.m3-fab.tertiary {
background-color: var(--md-sys-color-tertiary-container);
color: var(--md-sys-color-on-tertiary-container);
}
button.m3.m3-fab.tertiary:not(.without-elevation) {
box-shadow:
0 1px 3px 0 rgba(0, 0, 0, 0.3),
0 4px 8px 3px rgba(0, 0, 0, 0.15);
}
button.m3.m3-fab.tertiary > svg.m3-svg-icon {
fill: var(--md-sys-color-on-tertiary-container);
}
button.m3.m3-fab.tertiary > .m3.m3-ripple-domain > .m3.ripple {
background: color-mix(
in srgb,
var(--md-sys-color-on-tertiary-container) 12%,
transparent
);
}
button.m3.m3-fab.m3-small-fab {
width: 40px;
height: 40px;
border-radius: 12px;
padding: 11px;
font-size: 24px;
}
button.m3.m3-fab.m3-default-fab {
width: 56px;
height: 56px;
border-radius: 16px;
padding: 19px;
font-size: 24px;
}
button.m3.m3-fab.m3-large-fab {
width: 96px;
height: 96px;
border-radius: 28px;
padding: 34.5px;
font-size: 36px;
}
button.m3.m3-fab.m3-extended-fab {
width: auto;
height: 56px;
border-radius: 16px;
padding: 19px;
font-size: 24px;
}
button.m3.m3-fab:not(.without-elevation):is(
.surface,
.primary,
.secondary,
.tertiary
):hover {
box-shadow:
0 2px 3px 0 rgba(0, 0, 0, 0.3),
0 6px 10px 4px rgba(0, 0, 0, 0.15);
}
button.m3.m3-fab:not(.without-elevation):is(
.surface,
.primary,
.secondary,
.tertiary
):active {
box-shadow:
0 1px 3px 0 rgba(0, 0, 0, 0.3),
0 4px 8px 3px rgba(0, 0, 0, 0.15) !important;
}
button.m3.m3-fab:hover.surface::before {
background-color: color-mix(
in srgb,
var(--md-sys-color-primary) 8%,
transparent
);
}
button.m3.m3-fab:hover.primary::before {
background-color: color-mix(
in srgb,
var(--md-sys-color-on-primary-container) 8%,
transparent
);
}
button.m3.m3-fab:hover.secondary::before {
background-color: color-mix(
in srgb,
var(--md-sys-color-on-secondary-container) 8%,
transparent
);
}
button.m3.m3-fab:hover.tertiary::before {
background-color: color-mix(
in srgb,
var(--md-sys-color-on-tertiary-container) 8%,
transparent
);
}
button.m3.m3-fab:focus-visible.surface::before {
background-color: color-mix(
in srgb,
var(--md-sys-color-primary) 12%,
transparent
);
}
button.m3.m3-fab:focus-visible.primary::before {
background-color: color-mix(
in srgb,
var(--md-sys-color-on-primary-container) 12%,
transparent
);
}
button.m3.m3-fab:focus-visible.secondary::before {
background-color: color-mix(
in srgb,
var(--md-sys-color-on-secondary-container) 12%,
transparent
);
}
button.m3.m3-fab:focus-visible.tertiary::before {
background-color: color-mix(
in srgb,
var(--md-sys-color-on-tertiary-container) 12%,
transparent
);
}
/*# sourceMappingURL=fabs.css.map */

1
src/styles/fabs.css.map Normal file
View File

@@ -0,0 +1 @@
{"version":3,"sourceRoot":"","sources":["fabs.sass","mixins/m3-mixins.sass"],"names":[],"mappings":"AAEA;EACI;;AAEA;EACI;;AAEJ;EACI;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAEJ;ECgDA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;ADpDA;ECCA;EACA;;AAHA;EA+BI;;AA3BJ;EACI;;AACJ;EACI;;ADHJ;ECFA;EACA;;AAHA;EA+BI;;AA3BJ;EACI;;AACJ;EACI;;ADAJ;ECLA;EACA;;AAHA;EA+BI;;AA3BJ;EACI;;AACJ;EACI;;ADGJ;ECRA;EACA;;AAHA;EA+BI;;AA3BJ;EACI;;AACJ;EACI;;ADMJ;ECnBA,ODoBkC;ECnBlC,QDmBwC;EClBxC,eDkB4B;ECjB5B,SDiB8C;EAC1C;;AAEJ;ECvBA,ODwBkC;ECvBlC,QDuBwC;ECtBxC,eDsB4B;ECrB5B,SDqB8C;EAC1C;;AAEJ;EC3BA,OD4BkC;EC3BlC,QD2BwC;EC1BxC,eD0B4B;ECzB5B,SDyB8C;EAC1C;;AAEJ;EC/BA,ODgCkC;EC/BlC,QD+BwC;EC9BxC,eD8B4B;EC7B5B,SD6B8C;EAC1C;;AAEJ;ECQI;;ADLJ;ECHI;;ADOA;EACI;;AAEJ;EACI;;AAEJ;EACI;;AAEJ;EACI;;AAGJ;EACI;;AAEJ;EACI;;AAEJ;EACI;;AAEJ;EACI","file":"fabs.css"}

81
src/styles/fabs.sass Normal file
View File

@@ -0,0 +1,81 @@
@import "mixins/m3-mixins"
button.m3.m3-fab
transition: background-color, box-shadow, .2s cubic-bezier(0.2, 0, 0, 1) !important
& > span.m3-icon
font-family: Material-Symbols-Outlined-Regular, sans-serif
&.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
&::before
@include state-layer
&.surface
@include m3-fab-colors-palette(--md-sys-color-surface-container-high, --md-sys-color-primary)
&.primary
@include m3-fab-colors-palette(--md-sys-color-primary-container, --md-sys-color-on-primary-container)
&.secondary
@include m3-fab-colors-palette(--md-sys-color-secondary-container, --md-sys-color-on-secondary-container)
&.tertiary
@include m3-fab-colors-palette(--md-sys-color-tertiary-container, --md-sys-color-on-tertiary-container)
&.m3-small-fab
@include m3-fab-default(12px, 40px, 40px, 11px)
font-size: 24px
&.m3-default-fab
@include m3-fab-default(16px, 56px, 56px, 19px)
font-size: 24px
&.m3-large-fab
@include m3-fab-default(28px, 96px, 96px, 34.5px)
font-size: 36px
&.m3-extended-fab
@include m3-fab-default(16px, auto, 56px, 19px)
font-size: 24px
&:not(.without-elevation):is(.surface, .primary, .secondary, .tertiary):hover
@include elevation-4(false)
&:not(.without-elevation):is(.surface, .primary, .secondary, .tertiary):active
@include elevation-3(true)
&:hover
&.surface::before
background-color: color-mix(in srgb, var(--md-sys-color-primary) 8%, transparent)
&.primary::before
background-color: color-mix(in srgb, var(--md-sys-color-on-primary-container) 8%, transparent)
&.secondary::before
background-color: color-mix(in srgb, var(--md-sys-color-on-secondary-container) 8%, transparent)
&.tertiary::before
background-color: color-mix(in srgb, var(--md-sys-color-on-tertiary-container) 8%, transparent)
&:focus-visible
&.surface::before
background-color: color-mix(in srgb, var(--md-sys-color-primary) 12%, transparent)
&.primary::before
background-color: color-mix(in srgb, var(--md-sys-color-on-primary-container) 12%, transparent)
&.secondary::before
background-color: color-mix(in srgb, var(--md-sys-color-on-secondary-container) 12%, transparent)
&.tertiary::before
background-color: color-mix(in srgb, var(--md-sys-color-on-tertiary-container) 12%, transparent)

File diff suppressed because it is too large Load Diff

Binary file not shown.

File diff suppressed because it is too large Load Diff

Binary file not shown.

File diff suppressed because it is too large Load Diff

Binary file not shown.

File diff suppressed because it is too large Load Diff

Binary file not shown.

File diff suppressed because it is too large Load Diff

Binary file not shown.

37
src/styles/font/README.md Normal file
View File

@@ -0,0 +1,37 @@
This is the directory for Material Icons fonts—note that the font versions of these icons have not been updated since early 2022; the newer Material Symbols fonts are more current, and can be found at [../variablefont](https://github.com/google/material-design-icons/tree/master/variablefont).
Material Icons are the non-variable classic icon fonts, while the Material Symbols variable fonts offer weight, optical size, grade and fill variations (with grade and Fill being intended also for animated effects).
The recommended way to use the Material Icons font is by linking to the web font hosted on Google Fonts:
```html
<!-- https://material.io/resources/icons/?style=baseline -->
<link
href="https://fonts.googleapis.com/css2?family=Material+Icons"
rel="stylesheet"
/>
<!-- https://material.io/resources/icons/?style=outline -->
<link
href="https://fonts.googleapis.com/css2?family=Material+Icons+Outlined"
rel="stylesheet"
/>
<!-- https://material.io/resources/icons/?style=round -->
<link
href="https://fonts.googleapis.com/css2?family=Material+Icons+Round"
rel="stylesheet"
/>
<!-- https://material.io/resources/icons/?style=sharp -->
<link
href="https://fonts.googleapis.com/css2?family=Material+Icons+Sharp"
rel="stylesheet"
/>
<!-- https://material.io/resources/icons/?style=twotone -->
<link
href="https://fonts.googleapis.com/css2?family=Material+Icons+Two+Tone"
rel="stylesheet"
/>
```

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

56
src/styles/fonts.css Normal file
View File

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

1
src/styles/fonts.css.map Normal file
View File

@@ -0,0 +1 @@
{"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"}

16
src/styles/fonts.sass Normal file
View File

@@ -0,0 +1,16 @@
$fonts-family: ["Rounded", "Outlined", "Sharp"]
@each $font-family in $fonts-family
@font-face
font-family: Material-Symbols-#{$font-family}-Regular
src: url("./font/MaterialSymbols#{$font-family}[FILL,GRAD,opsz,wght].ttf")
src: url("./font/MaterialSymbols#{$font-family}[FILL,GRAD,opsz,wght].woff2") format("woff2")
$weights: ("Thin": 100, "Light": 300, "Regular": 400, "Medium": 500, "Bold": 700, "Black": 900)
@each $name, $weight in $weights
@font-face
font-family: Roboto
font-face-name: #{$name}
font-weight: #{$weight}
src: url("./font/Roboto-#{$name}.ttf")

1710
src/styles/generics.css Normal file

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

Some files were not shown because too many files have changed in this diff Show More