import { isArray, isBoolean, isNull, isNumber, isString } from "lodash";
import React, { FunctionComponent, useEffect } from "react";
import {
Button as BSButton,
ButtonProps as BSButtonProps,
Form,
} from "react-bootstrap";
import { useCollapse, useLatest } from ".";
import {
Chips as CChips,
ChipsProps as CChipsProps,
Selector as CSelector,
SelectorProps as CSelectorProps,
Slider as CSlider,
SliderProps as CSliderProps,
} from "../../components";
import { isReactText } from "../../utilites";
import { OverrideFuncType, useSingleUpdate } from "./hooks";
export const Message: FunctionComponent<{
type?: "warning" | "info";
}> = ({ type, children }) => {
const cls = ["pr-4"];
cls.push(type === "warning" ? "text-warning" : "text-muted");
return
{children};
};
export interface BaseInput {
disabled?: boolean;
settingKey: string;
override?: OverrideFuncType;
beforeStaged?: (v: T) => any;
}
export interface TextProps extends BaseInput {
placeholder?: React.ReactText;
password?: boolean;
controlled?: boolean;
}
export const Text: FunctionComponent = ({
placeholder,
disabled,
beforeStaged,
controlled,
override,
password,
settingKey,
}) => {
const value = useLatest(settingKey, isReactText, override);
const update = useSingleUpdate();
const collapse = useCollapse();
return (
{
const val = e.currentTarget.value;
collapse(val.toString());
const value = beforeStaged ? beforeStaged(val) : val;
update(value, settingKey);
}}
>
);
};
export interface CheckProps extends BaseInput {
label?: string;
inline?: boolean;
}
export const Check: FunctionComponent = ({
label,
inline,
override,
disabled,
settingKey,
}) => {
const update = useSingleUpdate();
const collapse = useCollapse();
const value = useLatest(settingKey, isBoolean, override);
useEffect(() => collapse(value ?? false), [collapse, value]);
return (
{
const { checked } = e.currentTarget;
update(checked, settingKey);
}}
disabled={disabled}
checked={value ?? undefined}
>
);
};
function selectorValidator(v: any): v is T {
return isString(v) || isNumber(v) || isArray(v);
}
type SelectorProps = BaseInput> &
CSelectorProps;
export function Selector<
T extends string | string[] | number | number[],
M extends boolean = false
>(props: SelectorProps) {
const update = useSingleUpdate();
const collapse = useCollapse();
const { settingKey, override, beforeStaged, ...selector } = props;
const value = useLatest>(
settingKey,
selectorValidator,
override
);
useEffect(() => {
if (isString(value) || isNull(value)) {
collapse(value ?? "");
}
});
return (
{
v = beforeStaged ? beforeStaged(v) : v;
update(v, settingKey);
}}
>
);
}
type SliderProps = {} & BaseInput &
Omit;
export const Slider: FunctionComponent = (props) => {
const { settingKey, override, ...slider } = props;
const update = useSingleUpdate();
const defaultValue = useLatest(settingKey, isNumber, override);
return (
{
update(v, settingKey);
}}
defaultValue={defaultValue ?? undefined}
{...slider}
>
);
};
type ChipsProp = {} & BaseInput &
Omit;
export const Chips: FunctionComponent = (props) => {
const { settingKey, override, ...chips } = props;
const update = useSingleUpdate();
const defaultValue = useLatest(settingKey, isArray, override);
return (
{
update(v, settingKey);
}}
{...chips}
>
);
};
type ButtonProps = {
onClick?: (
update: (v: any, key: string) => void,
key: string,
value?: string
) => void;
} & Omit, "override" | "beforeStaged">;
export const Button: FunctionComponent> = (
props
) => {
const { onClick, settingKey, ...button } = props;
const value = useLatest(settingKey, isString);
const update = useSingleUpdate();
return (
{
onClick && onClick(update, settingKey, value ?? undefined);
}}
{...button}
>
);
};