aboutsummaryrefslogtreecommitdiff
path: root/packages/anastasis-webui/src/components/picker/DurationPicker.tsx
diff options
context:
space:
mode:
Diffstat (limited to 'packages/anastasis-webui/src/components/picker/DurationPicker.tsx')
-rw-r--r--packages/anastasis-webui/src/components/picker/DurationPicker.tsx217
1 files changed, 137 insertions, 80 deletions
diff --git a/packages/anastasis-webui/src/components/picker/DurationPicker.tsx b/packages/anastasis-webui/src/components/picker/DurationPicker.tsx
index 235a63e2d..8a1faf4d0 100644
--- a/packages/anastasis-webui/src/components/picker/DurationPicker.tsx
+++ b/packages/anastasis-webui/src/components/picker/DurationPicker.tsx
@@ -15,9 +15,9 @@
*/
/**
-*
-* @author Sebastian Javier Marchano (sebasjm)
-*/
+ *
+ * @author Sebastian Javier Marchano (sebasjm)
+ */
import { h, VNode } from "preact";
import { useState } from "preact/hooks";
@@ -30,75 +30,123 @@ export interface Props {
seconds?: boolean;
days?: boolean;
onChange: (value: number) => void;
- value: number
+ value: number;
}
// inspiration taken from https://github.com/flurmbo/react-duration-picker
-export function DurationPicker({ days, hours, minutes, seconds, onChange, value }: Props): VNode {
- const ss = 1000
- const ms = ss * 60
- const hs = ms * 60
- const ds = hs * 24
- const i18n = useTranslator()
-
- return <div class="rdp-picker">
- {days && <DurationColumn unit={i18n`days`} max={99}
- value={Math.floor(value / ds)}
- onDecrease={value >= ds ? () => onChange(value - ds) : undefined}
- onIncrease={value < 99 * ds ? () => onChange(value + ds) : undefined}
- onChange={diff => onChange(value + diff * ds)}
- />}
- {hours && <DurationColumn unit={i18n`hours`} max={23} min={1}
- value={Math.floor(value / hs) % 24}
- onDecrease={value >= hs ? () => onChange(value - hs) : undefined}
- onIncrease={value < 99 * ds ? () => onChange(value + hs) : undefined}
- onChange={diff => onChange(value + diff * hs)}
- />}
- {minutes && <DurationColumn unit={i18n`minutes`} max={59} min={1}
- value={Math.floor(value / ms) % 60}
- onDecrease={value >= ms ? () => onChange(value - ms) : undefined}
- onIncrease={value < 99 * ds ? () => onChange(value + ms) : undefined}
- onChange={diff => onChange(value + diff * ms)}
- />}
- {seconds && <DurationColumn unit={i18n`seconds`} max={59}
- value={Math.floor(value / ss) % 60}
- onDecrease={value >= ss ? () => onChange(value - ss) : undefined}
- onIncrease={value < 99 * ds ? () => onChange(value + ss) : undefined}
- onChange={diff => onChange(value + diff * ss)}
- />}
- </div>
+export function DurationPicker({
+ days,
+ hours,
+ minutes,
+ seconds,
+ onChange,
+ value,
+}: Props): VNode {
+ const ss = 1000;
+ const ms = ss * 60;
+ const hs = ms * 60;
+ const ds = hs * 24;
+ const i18n = useTranslator();
+
+ return (
+ <div class="rdp-picker">
+ {days && (
+ <DurationColumn
+ unit={i18n`days`}
+ max={99}
+ value={Math.floor(value / ds)}
+ onDecrease={value >= ds ? () => onChange(value - ds) : undefined}
+ onIncrease={value < 99 * ds ? () => onChange(value + ds) : undefined}
+ onChange={(diff) => onChange(value + diff * ds)}
+ />
+ )}
+ {hours && (
+ <DurationColumn
+ unit={i18n`hours`}
+ max={23}
+ min={1}
+ value={Math.floor(value / hs) % 24}
+ onDecrease={value >= hs ? () => onChange(value - hs) : undefined}
+ onIncrease={value < 99 * ds ? () => onChange(value + hs) : undefined}
+ onChange={(diff) => onChange(value + diff * hs)}
+ />
+ )}
+ {minutes && (
+ <DurationColumn
+ unit={i18n`minutes`}
+ max={59}
+ min={1}
+ value={Math.floor(value / ms) % 60}
+ onDecrease={value >= ms ? () => onChange(value - ms) : undefined}
+ onIncrease={value < 99 * ds ? () => onChange(value + ms) : undefined}
+ onChange={(diff) => onChange(value + diff * ms)}
+ />
+ )}
+ {seconds && (
+ <DurationColumn
+ unit={i18n`seconds`}
+ max={59}
+ value={Math.floor(value / ss) % 60}
+ onDecrease={value >= ss ? () => onChange(value - ss) : undefined}
+ onIncrease={value < 99 * ds ? () => onChange(value + ss) : undefined}
+ onChange={(diff) => onChange(value + diff * ss)}
+ />
+ )}
+ </div>
+ );
}
interface ColProps {
- unit: string,
- min?: number,
- max: number,
- value: number,
+ unit: string;
+ min?: number;
+ max: number;
+ value: number;
onIncrease?: () => void;
onDecrease?: () => void;
onChange?: (diff: number) => void;
}
-function InputNumber({ initial, onChange }: { initial: number, onChange: (n: number) => void }) {
- const [value, handler] = useState<{v:string}>({
- v: toTwoDigitString(initial)
- })
-
- return <input
- value={value.v}
- onBlur={(e) => onChange(parseInt(value.v, 10))}
- onInput={(e) => {
- e.preventDefault()
- const n = Number.parseInt(e.currentTarget.value, 10);
- if (isNaN(n)) return handler({v:toTwoDigitString(initial)})
- return handler({v:toTwoDigitString(n)})
- }}
- style={{ width: 50, border: 'none', fontSize: 'inherit', background: 'inherit' }} />
-}
+function InputNumber({
+ initial,
+ onChange,
+}: {
+ initial: number;
+ onChange: (n: number) => void;
+}) {
+ const [value, handler] = useState<{ v: string }>({
+ v: toTwoDigitString(initial),
+ });
-function DurationColumn({ unit, min = 0, max, value, onIncrease, onDecrease, onChange }: ColProps): VNode {
+ return (
+ <input
+ value={value.v}
+ onBlur={(e) => onChange(parseInt(value.v, 10))}
+ onInput={(e) => {
+ e.preventDefault();
+ const n = Number.parseInt(e.currentTarget.value, 10);
+ if (isNaN(n)) return handler({ v: toTwoDigitString(initial) });
+ return handler({ v: toTwoDigitString(n) });
+ }}
+ style={{
+ width: 50,
+ border: "none",
+ fontSize: "inherit",
+ background: "inherit",
+ }}
+ />
+ );
+}
- const cellHeight = 35
+function DurationColumn({
+ unit,
+ min = 0,
+ max,
+ value,
+ onIncrease,
+ onDecrease,
+ onChange,
+}: ColProps): VNode {
+ const cellHeight = 35;
return (
<div class="rdp-column-container">
<div class="rdp-masked-div">
@@ -106,49 +154,58 @@ function DurationColumn({ unit, min = 0, max, value, onIncrease, onDecrease, onC
<hr class="rdp-reticule" style={{ top: cellHeight * 3 - 1 }} />
<div class="rdp-column" style={{ top: 0 }}>
-
<div class="rdp-cell" key={value - 2}>
- {onDecrease && <button style={{ width: '100%', textAlign: 'center', margin: 5 }}
- onClick={onDecrease}>
- <span class="icon">
- <i class="mdi mdi-chevron-up" />
- </span>
- </button>}
+ {onDecrease && (
+ <button
+ style={{ width: "100%", textAlign: "center", margin: 5 }}
+ onClick={onDecrease}
+ >
+ <span class="icon">
+ <i class="mdi mdi-chevron-up" />
+ </span>
+ </button>
+ )}
</div>
<div class="rdp-cell" key={value - 1}>
- {value > min ? toTwoDigitString(value - 1) : ''}
+ {value > min ? toTwoDigitString(value - 1) : ""}
</div>
<div class="rdp-cell rdp-center" key={value}>
- {onChange ?
- <InputNumber initial={value} onChange={(n) => onChange(n - value)} /> :
+ {onChange ? (
+ <InputNumber
+ initial={value}
+ onChange={(n) => onChange(n - value)}
+ />
+ ) : (
toTwoDigitString(value)
- }
+ )}
<div>{unit}</div>
</div>
<div class="rdp-cell" key={value + 1}>
- {value < max ? toTwoDigitString(value + 1) : ''}
+ {value < max ? toTwoDigitString(value + 1) : ""}
</div>
<div class="rdp-cell" key={value + 2}>
- {onIncrease && <button style={{ width: '100%', textAlign: 'center', margin: 5 }}
- onClick={onIncrease}>
- <span class="icon">
- <i class="mdi mdi-chevron-down" />
- </span>
- </button>}
+ {onIncrease && (
+ <button
+ style={{ width: "100%", textAlign: "center", margin: 5 }}
+ onClick={onIncrease}
+ >
+ <span class="icon">
+ <i class="mdi mdi-chevron-down" />
+ </span>
+ </button>
+ )}
</div>
-
</div>
</div>
</div>
);
}
-
function toTwoDigitString(n: number) {
if (n < 10) {
return `0${n}`;
}
return `${n}`;
-} \ No newline at end of file
+}