CHANGES: Added unoptimized progress bar inside <Slider> component

FIXED: Some styles
This commit is contained in:
doryan04 2024-02-18 22:39:34 +04:00
parent f736f73a1f
commit ead00b5ae9
9 changed files with 127 additions and 77 deletions

View File

@ -61,7 +61,7 @@ export default function Page() {
<Button icon={'add'} iconPlace={'right'}> <Button icon={'add'} iconPlace={'right'}>
Label 2 Label 2
</Button> </Button>
<SegmentedButtons> <SegmentedButtons toggled={true}>
<SegmentButton <SegmentButton
fillIcon={1} fillIcon={1}
icon={'change_history'} icon={'change_history'}
@ -80,7 +80,26 @@ export default function Page() {
</SegmentButton> </SegmentButton>
</SegmentedButtons> </SegmentedButtons>
<Checkbox /> <Checkbox />
<Slider /> <Slider
defaultValue={0}
max={100}
min={0}
options={[0, 10, 20, 100]}
/>
<Slider defaultValue={0} max={100} min={0} />
<div>
<input
list={'lol'}
max={100}
min={0}
type={'range'}
/>
<datalist id={'lol'}>
<option value={0} />
<option value={50} />
<option value={100} />
</datalist>
</div>
</div> </div>
</CardFooter> </CardFooter>
</Card> </Card>

View File

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

View File

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

View File

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

View File

@ -1,5 +1,5 @@
import { createElement, forwardRef } from 'react'; import { createElement, forwardRef } from 'react';
import { getTypographyRole } from './get-typography-role'; import { getTypographyRole } from './utils/get-typography-role';
import { import {
TypographyProps, TypographyProps,
Typography as TypographyTargetRef, Typography as TypographyTargetRef,

View File

@ -1,4 +1,4 @@
import { TypographyRole, TypographySize } from './typography.types'; import { TypographyRole, TypographySize } from '../typography.types';
export function getTypographyRole(role: TypographyRole, size: TypographySize) { export function getTypographyRole(role: TypographyRole, size: TypographySize) {
switch (role) { switch (role) {

View File

@ -881,36 +881,39 @@ div.m3.m3-slider-container {
display: flex; display: flex;
align-items: center; align-items: center;
} }
div.m3.m3-slider-container > datalist {
display: none;
}
input[type=range].m3.m3-slider { input[type=range].m3.m3-slider {
margin: 0; margin: 0;
height: 4px;
appearance: none; appearance: none;
overflow: visible;
border-radius: 2px; border-radius: 2px;
margin-inline: 10px; margin-inline: 8px;
background-color: var(--md-sys-color-surface-container-highest); background: linear-gradient(to right, var(--md-sys-color-primary) 0%, var(--md-sys-color-surface-container-highest) 0%);
} }
input[type=range].m3.m3-slider::-webkit-slider-container { input[type=range].m3.m3-slider::-webkit-slider-container {
margin-inline: -8px; appearance: none;
box-shadow: none;
border-radius: 2px;
min-block-size: 4px;
height: 4px !important;
}
input[type=range].m3.m3-slider::-webkit-slider-runnable-track {
height: 4px;
} }
input[type=range].m3.m3-slider::-webkit-slider-thumb { input[type=range].m3.m3-slider::-webkit-slider-thumb {
box-shadow: 0 1px 3px 1px rgba(0, 0, 0, 0.15), 0 1px 2px 0 rgba(0, 0, 0, 0.3); box-shadow: 0 1px 3px 1px rgba(0, 0, 0, 0.15), 0 1px 2px 0 rgba(0, 0, 0, 0.3);
width: 20px; width: 20px;
aspect-ratio: 1; aspect-ratio: 1;
appearance: none; appearance: none;
overflow: visible;
border-radius: 50%; border-radius: 50%;
margin-top: -8px;
box-sizing: border-box; box-sizing: border-box;
outline: 10px solid transparent; outline: 10px solid transparent;
background: var(--md-sys-color-primary); background: var(--md-sys-color-primary);
transition: 0.2s cubic-bezier(0.2, 0, 0, 1); transition: 0.2s cubic-bezier(0.2, 0, 0, 1);
} }
input[type=range].m3.m3-slider::-webkit-slider-thumb::after {
width: 40px;
aspect-ratio: 1;
background-color: transparent;
}
input[type=range].m3.m3-slider::-webkit-slider-thumb:hover { input[type=range].m3.m3-slider::-webkit-slider-thumb:hover {
outline: 10px solid color-mix(in srgb, var(--md-sys-color-primary) 8%, transparent); outline: 10px solid color-mix(in srgb, var(--md-sys-color-primary) 8%, transparent);
} }

File diff suppressed because one or more lines are too long

View File

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