mirror of
https://codeberg.org/demostf/frontend.git
synced 2026-06-03 18:24:12 +02:00
edit wip
This commit is contained in:
parent
0ab24ead47
commit
189788a1b6
14 changed files with 599 additions and 6 deletions
30
script/components/Duration.tsx
Normal file
30
script/components/Duration.tsx
Normal file
|
|
@ -0,0 +1,30 @@
|
|||
export function formatDuration(input) {
|
||||
if (!input) {
|
||||
return '0:00';
|
||||
}
|
||||
const hours = Math.floor(input / 3600);
|
||||
const minutes = Math.floor((input - (hours * 3600)) / 60);
|
||||
const seconds = Math.floor(input - (hours * 3600) - (minutes * 60));
|
||||
|
||||
const hourString = (hours < 10) ? "0" + hours : "" + hours;
|
||||
const minuteString = (minutes < 10) ? "0" + minutes : "" + minutes;
|
||||
const secondString = (seconds < 10) ? "0" + seconds : "" + seconds;
|
||||
|
||||
if (hourString !== '00') {
|
||||
return hourString + ':' + minuteString + ':' + secondString;
|
||||
} else {
|
||||
return minuteString + ':' + secondString;
|
||||
}
|
||||
}
|
||||
|
||||
export interface DurationProps {
|
||||
duration: number;
|
||||
className?: string;
|
||||
}
|
||||
|
||||
export function Duration(props: DurationProps) {
|
||||
const duration = formatDuration(props.duration);
|
||||
return (
|
||||
<span className={props.className||''}>{duration}</span>
|
||||
);
|
||||
}
|
||||
110
script/components/MultiSlider.tsx
Normal file
110
script/components/MultiSlider.tsx
Normal file
|
|
@ -0,0 +1,110 @@
|
|||
import {createEffect, createSignal} from "solid-js";
|
||||
|
||||
export interface SliderProps {
|
||||
min: number,
|
||||
max: number,
|
||||
onChange: (min: number, max: number) => void,
|
||||
labelFn?: (value: number) => string,
|
||||
}
|
||||
|
||||
const MultiRangeSlider = (props: SliderProps) => {
|
||||
if (!props.labelFn) {
|
||||
props.labelFn = (_val) => '';
|
||||
}
|
||||
const [minVal, setMinVal] = createSignal<number>(props.min);
|
||||
const [maxVal, setMaxVal] = createSignal<number>(props.max);
|
||||
let range;
|
||||
|
||||
// Convert to percentage
|
||||
const getPercent = (value) => Math.round(((value - props.min) / (props.max - props.min)) * 100);
|
||||
|
||||
// Set width of the range to decrease from the left side
|
||||
createEffect(() => {
|
||||
const minPercent = getPercent(minVal());
|
||||
const maxPercent = getPercent(maxVal());
|
||||
|
||||
if (range) {
|
||||
range.style.left = `${minPercent}%`;
|
||||
range.style.width = `${maxPercent - minPercent}%`;
|
||||
}
|
||||
});
|
||||
|
||||
// Set width of the range to decrease from the right side
|
||||
createEffect(() => {
|
||||
const minPercent = getPercent(minVal());
|
||||
const maxPercent = getPercent(maxVal());
|
||||
|
||||
if (range) {
|
||||
range.style.width = `${maxPercent - minPercent}%`;
|
||||
}
|
||||
});
|
||||
|
||||
// Get min and max values when their state changes
|
||||
createEffect(() => {
|
||||
props.onChange(minVal(), maxVal());
|
||||
});
|
||||
|
||||
return (
|
||||
<span className="container">
|
||||
<input
|
||||
type="range"
|
||||
min={props.min}
|
||||
max={props.max}
|
||||
value={minVal()}
|
||||
onChange={(event) => {
|
||||
const value = Math.min(Number(event.target.value), maxVal() - 1);
|
||||
if (value != minVal()) {
|
||||
setMinVal(value);
|
||||
}
|
||||
}}
|
||||
className="thumb thumb--left"
|
||||
style={{ zIndex: (minVal() > props.max - 100) ? "5" : undefined }}
|
||||
/>
|
||||
<input
|
||||
type="range"
|
||||
min={props.min}
|
||||
max={props.max}
|
||||
value={maxVal()}
|
||||
onChange={(event) => {
|
||||
const value = Math.max(Number(event.target.value), minVal() + 1);
|
||||
if (value != maxVal()) {
|
||||
setMaxVal(value);
|
||||
}
|
||||
}}
|
||||
className="thumb thumb--right"
|
||||
/>
|
||||
|
||||
<span className="slider">
|
||||
<span className="slider__left-input">
|
||||
<input type="number" value={minVal()} onInput={(event) => {
|
||||
const value = Math.max(Math.min(Number(event.currentTarget.value), maxVal - 1), props.min);
|
||||
console.log(event.currentTarget.value, value);
|
||||
if (value != minVal()) {
|
||||
setMinVal(value);
|
||||
}
|
||||
}}/>
|
||||
</span>
|
||||
<span className="slider__right-input">
|
||||
<input type="number" value={maxVal()} onInput={(event) => {
|
||||
console.log(event);
|
||||
const value = Math.min(Math.max(Number(event.currentTarget.value), minVal + 1), props.max);
|
||||
console.log(event.currentTarget.value, value);
|
||||
if (value != maxVal()) {
|
||||
setMaxVal(value);
|
||||
}
|
||||
}}/>
|
||||
</span>
|
||||
<span className="slider__track" />
|
||||
<span ref={range} className="slider__range" />
|
||||
<span className="slider__left-value">
|
||||
{() => props.labelFn(minVal())}
|
||||
</span>
|
||||
<span className="slider__right-value">
|
||||
{() => props.labelFn(maxVal())}
|
||||
</span>
|
||||
</span>
|
||||
</span>
|
||||
);
|
||||
};
|
||||
|
||||
export default MultiRangeSlider;
|
||||
20
script/components/Section.tsx
Normal file
20
script/components/Section.tsx
Normal file
|
|
@ -0,0 +1,20 @@
|
|||
import * as React from 'react';
|
||||
|
||||
export interface SectionProps {
|
||||
title: string;
|
||||
children: any[] | any;
|
||||
className?: string;
|
||||
}
|
||||
|
||||
export function Section(props: SectionProps) {
|
||||
return (
|
||||
<section key={props.title} className={props.title + (props.className ? ' ' + props.className : '')}>
|
||||
<div className="title">
|
||||
<h3>
|
||||
{props.title}
|
||||
</h3>
|
||||
</div>
|
||||
{props.children}
|
||||
</section>
|
||||
);
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue