CHANGES: Added unoptimized progress bar inside <Slider> component
FIXED: Some styles
This commit is contained in:
parent
f736f73a1f
commit
ead00b5ae9
23
app/page.tsx
23
app/page.tsx
|
@ -61,7 +61,7 @@ export default function Page() {
|
|||
<Button icon={'add'} iconPlace={'right'}>
|
||||
Label 2
|
||||
</Button>
|
||||
<SegmentedButtons>
|
||||
<SegmentedButtons toggled={true}>
|
||||
<SegmentButton
|
||||
fillIcon={1}
|
||||
icon={'change_history'}
|
||||
|
@ -80,7 +80,26 @@ export default function Page() {
|
|||
</SegmentButton>
|
||||
</SegmentedButtons>
|
||||
<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>
|
||||
</CardFooter>
|
||||
</Card>
|
||||
|
|
|
@ -6,7 +6,3 @@ export interface InputLayoutProps
|
|||
typeInput?: string;
|
||||
type?: string;
|
||||
}
|
||||
|
||||
export interface LabelPlacement {
|
||||
labelPlacement?: 'left' | 'right';
|
||||
}
|
||||
|
|
|
@ -1,18 +1,46 @@
|
|||
import React, { forwardRef, HTMLAttributes } from 'react';
|
||||
import { InputLayout } from '../input-layout/input-layout';
|
||||
'use client';
|
||||
|
||||
export const Slider = forwardRef<
|
||||
HTMLInputElement,
|
||||
HTMLAttributes<HTMLInputElement>
|
||||
>((props, ref) => {
|
||||
return (
|
||||
<div className={'m3 m3-slider-container'}>
|
||||
<InputLayout
|
||||
className={props.className}
|
||||
ref={ref}
|
||||
type={'range'}
|
||||
typeInput={'slider'}
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
});
|
||||
import { InputLayout } from '../input-layout/input-layout';
|
||||
import React, { forwardRef, InputHTMLAttributes, useId, useState } from 'react';
|
||||
|
||||
interface SliderProps extends InputHTMLAttributes<HTMLInputElement> {
|
||||
options?: number[];
|
||||
}
|
||||
|
||||
export const Slider = forwardRef<HTMLInputElement, SliderProps>(
|
||||
({ options, ...props }, ref) => {
|
||||
const sliderId = useId();
|
||||
const [progress, setProgress] = useState<number>(0);
|
||||
|
||||
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>
|
||||
);
|
||||
},
|
||||
);
|
||||
|
|
|
@ -4,41 +4,41 @@ import { bool } from 'prop-types';
|
|||
import React, { forwardRef } from 'react';
|
||||
import { SwitchMainProps } from './switch.types';
|
||||
import { InputLayout } from '../input-layout/input-layout';
|
||||
import { LabelPlacement } from '../input-layout/input-layout.types';
|
||||
|
||||
/**
|
||||
* Switch component
|
||||
** description
|
||||
*/
|
||||
|
||||
export const Switch = forwardRef<
|
||||
HTMLInputElement,
|
||||
SwitchMainProps & LabelPlacement
|
||||
>(({ icon, selected = false, ...props }, ref) => (
|
||||
<>
|
||||
<div className={'m3 m3-switch'}>
|
||||
<InputLayout
|
||||
{...props}
|
||||
className={`m3 ${props.className ?? ''}`.trimEnd()}
|
||||
ref={ref}
|
||||
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>
|
||||
</>
|
||||
));
|
||||
export const Switch = forwardRef<HTMLInputElement, SwitchMainProps>(
|
||||
({ icon, selected = false, ...props }, ref) => (
|
||||
<>
|
||||
<div className={'m3 m3-switch'}>
|
||||
<InputLayout
|
||||
{...props}
|
||||
className={`m3 ${props.className ?? ''}`.trimEnd()}
|
||||
ref={ref}
|
||||
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>
|
||||
</>
|
||||
),
|
||||
);
|
||||
|
||||
Switch.propTypes = {
|
||||
icon: bool,
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
import { createElement, forwardRef } from 'react';
|
||||
import { getTypographyRole } from './get-typography-role';
|
||||
import { getTypographyRole } from './utils/get-typography-role';
|
||||
import {
|
||||
TypographyProps,
|
||||
Typography as TypographyTargetRef,
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import { TypographyRole, TypographySize } from './typography.types';
|
||||
import { TypographyRole, TypographySize } from '../typography.types';
|
||||
|
||||
export function getTypographyRole(role: TypographyRole, size: TypographySize) {
|
||||
switch (role) {
|
|
@ -881,36 +881,39 @@ div.m3.m3-slider-container {
|
|||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
div.m3.m3-slider-container > datalist {
|
||||
display: none;
|
||||
}
|
||||
|
||||
input[type=range].m3.m3-slider {
|
||||
margin: 0;
|
||||
height: 4px;
|
||||
appearance: none;
|
||||
overflow: visible;
|
||||
border-radius: 2px;
|
||||
margin-inline: 10px;
|
||||
background-color: var(--md-sys-color-surface-container-highest);
|
||||
margin-inline: 8px;
|
||||
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 {
|
||||
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 {
|
||||
box-shadow: 0 1px 3px 1px rgba(0, 0, 0, 0.15), 0 1px 2px 0 rgba(0, 0, 0, 0.3);
|
||||
width: 20px;
|
||||
aspect-ratio: 1;
|
||||
appearance: none;
|
||||
overflow: visible;
|
||||
border-radius: 50%;
|
||||
margin-top: -8px;
|
||||
box-sizing: border-box;
|
||||
outline: 10px solid transparent;
|
||||
background: var(--md-sys-color-primary);
|
||||
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 {
|
||||
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
|
@ -3,26 +3,30 @@ div.m3.m3-slider-container
|
|||
display: flex
|
||||
align-items: center
|
||||
|
||||
& > datalist
|
||||
display: none
|
||||
|
||||
|
||||
input[type="range"].m3.m3-slider
|
||||
margin: 0
|
||||
height: 4px
|
||||
appearance: none
|
||||
overflow: visible
|
||||
border-radius: 2px
|
||||
margin-inline: 10px
|
||||
background-color: var(--md-sys-color-surface-container-highest)
|
||||
margin-inline: 8px
|
||||
background: linear-gradient(to right, var(--md-sys-color-primary) 0%, var(--md-sys-color-surface-container-highest) 0%)
|
||||
|
||||
&::-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
|
||||
@include elevation-1(false)
|
||||
|
||||
&::after
|
||||
width: 40px
|
||||
aspect-ratio: 1
|
||||
background-color: transparent
|
||||
|
||||
&:hover
|
||||
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
|
||||
aspect-ratio: 1
|
||||
appearance: none
|
||||
overflow: visible
|
||||
border-radius: 50%
|
||||
margin-top: -8px
|
||||
box-sizing: border-box
|
||||
outline: 10px solid transparent
|
||||
background: var(--md-sys-color-primary)
|
||||
|
|
Loading…
Reference in New Issue