'init'
This commit is contained in:
14
app/components/SettingsInput/SettingsInput.module.css
Normal file
14
app/components/SettingsInput/SettingsInput.module.css
Normal file
@@ -0,0 +1,14 @@
|
||||
.input{
|
||||
cursor: pointer!important;
|
||||
@mixin light {
|
||||
color: var(--mantine-color-dark-3);
|
||||
text-align: right;
|
||||
}
|
||||
@mixin dark {
|
||||
color: #CCC;
|
||||
text-align: right;
|
||||
}
|
||||
&[data-disabled] {
|
||||
background-color: transparent!important;
|
||||
}
|
||||
}
|
||||
339
app/components/SettingsInput/SettingsInput.tsx
Normal file
339
app/components/SettingsInput/SettingsInput.tsx
Normal file
@@ -0,0 +1,339 @@
|
||||
import { Box, DefaultMantineColor, Flex, Input, MantineSpacing, Paper, Select, StyleProp, Switch, Text } from "@mantine/core"
|
||||
import classes from './SettingsInput.module.css'
|
||||
import { Children, cloneElement, HTMLInputTypeAttribute, isValidElement, MouseEvent, ReactNode, useEffect, useRef, useState } from "react";
|
||||
import { useRosettaColors } from "@/app/hooks/useRosettaColors";
|
||||
import { useClipboard } from "@mantine/hooks";
|
||||
import { IconChevronRight } from "@tabler/icons-react";
|
||||
|
||||
|
||||
export function SettingsInput() {}
|
||||
export interface SettingsInputCopy {
|
||||
hit: string;
|
||||
placeholder?: string;
|
||||
value?: string;
|
||||
style?: any;
|
||||
mt?: StyleProp<MantineSpacing>;
|
||||
}
|
||||
export interface SettingsInputDefaultProps {
|
||||
hit: string;
|
||||
placeholder?: string;
|
||||
value?: string;
|
||||
disabled?: boolean;
|
||||
onChange?: (event : any) => void;
|
||||
style?: any;
|
||||
mt?: StyleProp<MantineSpacing>;
|
||||
rightSection?: ReactNode;
|
||||
type?: HTMLInputTypeAttribute;
|
||||
}
|
||||
export interface SettingsInputGroupProps {
|
||||
mt?: StyleProp<MantineSpacing>;
|
||||
children: any;
|
||||
}
|
||||
export interface SettingsInputClickableProps {
|
||||
onClick: () => void;
|
||||
hit: string;
|
||||
placeholder?: string;
|
||||
style?: any;
|
||||
mt?: StyleProp<MantineSpacing>;
|
||||
value?: string;
|
||||
rightSection?: ReactNode;
|
||||
c?: StyleProp<DefaultMantineColor>;
|
||||
rightChevronHide?: boolean;
|
||||
settingsIcon?: React.ReactNode;
|
||||
}
|
||||
export interface SettingsInputSelectProps {
|
||||
hit: string;
|
||||
variants: string[];
|
||||
mt?: StyleProp<MantineSpacing>;
|
||||
style?: any;
|
||||
leftSection?: ReactNode;
|
||||
onChange?: (value: string|undefined) => void;
|
||||
width?: number;
|
||||
defaultValue?: string;
|
||||
}
|
||||
|
||||
export interface SettingsInputSwitch {
|
||||
hit: string;
|
||||
mt?: StyleProp<MantineSpacing>;
|
||||
style?: any;
|
||||
onChange?: (value: boolean) => void;
|
||||
defaultValue: boolean;
|
||||
}
|
||||
|
||||
SettingsInput.Copy = SettingsInputCopy;
|
||||
SettingsInput.Clickable = SettingsInputClickable;
|
||||
SettingsInput.Default = SettingsInputDefault;
|
||||
SettingsInput.Group = SettingsInputGroup;
|
||||
SettingsInput.Select = SettingsInputSelect;
|
||||
SettingsInput.Switch = SettingsInputSwitch;
|
||||
|
||||
function SettingsInputSwitch(props: SettingsInputSwitch) {
|
||||
const colors = useRosettaColors();
|
||||
const [checked, setChecked] = useState(props.defaultValue);
|
||||
|
||||
useEffect(() => {
|
||||
setChecked(props.defaultValue);
|
||||
}, [props.defaultValue]);
|
||||
|
||||
const onSwitch = (checked: boolean) => {
|
||||
if(props.onChange){
|
||||
props.onChange(checked);
|
||||
}
|
||||
setChecked(checked);
|
||||
}
|
||||
|
||||
return (
|
||||
<Paper mt={props.mt} style={props.style} withBorder styles={{
|
||||
root: {
|
||||
borderTop: '1px solid ' + colors.borderColor,
|
||||
borderBottom: '1px solid ' + colors.borderColor,
|
||||
borderLeft: '1px solid ' + colors.borderColor,
|
||||
borderRight: '1px solid ' + colors.borderColor,
|
||||
cursor: 'pointer'
|
||||
}
|
||||
}}
|
||||
>
|
||||
<Flex direction={'row'} pr={'sm'} pl={'sm'} align={'center'} justify={'space-between'}>
|
||||
<Text size={'sm'} fw={400}>{props.hit}</Text>
|
||||
<div style={{
|
||||
display: 'flex',
|
||||
alignItems: 'center',
|
||||
justifyContent: 'flex-end',
|
||||
height: 36,
|
||||
cursor: 'pointer'
|
||||
}}>
|
||||
<Switch
|
||||
checked={checked}
|
||||
onChange={(event) => onSwitch(event.currentTarget.checked)}
|
||||
size="sm"
|
||||
/>
|
||||
</div>
|
||||
</Flex>
|
||||
</Paper>
|
||||
);
|
||||
}
|
||||
|
||||
function SettingsInputSelect(props: SettingsInputSelectProps) {
|
||||
const colors = useRosettaColors();
|
||||
const [value, setValue] = useState(props.defaultValue);
|
||||
|
||||
const onChange = (selectValue : any) => {
|
||||
if(selectValue != value && selectValue != null){
|
||||
props.onChange!(selectValue);
|
||||
setValue(selectValue);
|
||||
}
|
||||
}
|
||||
|
||||
return (
|
||||
<Paper mt={props.mt} style={props.style} withBorder styles={{
|
||||
root: {
|
||||
borderTop: '1px solid ' + colors.borderColor,
|
||||
borderBottom: '1px solid ' + colors.borderColor,
|
||||
borderLeft: '1px solid ' + colors.borderColor,
|
||||
borderRight: '1px solid ' + colors.borderColor,
|
||||
cursor: 'pointer'
|
||||
}
|
||||
}}
|
||||
>
|
||||
<Flex direction={'row'} pr={'sm'} pl={'sm'} align={'center'} justify={'space-between'}>
|
||||
<Text size={'sm'} fw={400}>{props.hit}</Text>
|
||||
<div style={{
|
||||
display: 'flex',
|
||||
alignItems: 'center',
|
||||
justifyContent: 'flex-end',
|
||||
height: 36,
|
||||
cursor: 'pointer'
|
||||
}}>
|
||||
<Select allowDeselect={false} onChange={(v) => onChange(v)} style={{
|
||||
width: props.width
|
||||
}} leftSection={props.leftSection} color="gray" p={0} classNames={{
|
||||
input: classes.input
|
||||
}} variant={'unstyled'} comboboxProps={{
|
||||
middlewares: { flip: true, shift: true }, offset: 0, transitionProps: { transition: 'pop', duration: 50 } }} data={props.variants} value={props.defaultValue}>
|
||||
</Select>
|
||||
</div>
|
||||
</Flex>
|
||||
</Paper>
|
||||
);
|
||||
}
|
||||
|
||||
function SettingsInputCopy(props : SettingsInputCopy) {
|
||||
const colors = useRosettaColors();
|
||||
const {copied, copy} = useClipboard({
|
||||
timeout: 1500
|
||||
});
|
||||
const onClick = (e : MouseEvent) => {
|
||||
e.stopPropagation();
|
||||
copy(props.value);
|
||||
}
|
||||
return (
|
||||
<Paper mt={props.mt} style={props.style} withBorder styles={{
|
||||
root: {
|
||||
borderTop: '1px solid ' + colors.borderColor,
|
||||
borderBottom: '1px solid ' + colors.borderColor,
|
||||
borderLeft: '1px solid ' + colors.borderColor,
|
||||
borderRight: '1px solid ' + colors.borderColor,
|
||||
cursor: 'pointer'
|
||||
}
|
||||
}}
|
||||
|
||||
onClick={onClick}
|
||||
>
|
||||
<Flex direction={'row'} pr={'sm'} pl={'sm'} align={'center'} justify={'space-between'}>
|
||||
<Text size={'sm'} fw={400}>{props.hit}</Text>
|
||||
<div style={{
|
||||
display: 'flex',
|
||||
alignItems: 'center',
|
||||
justifyContent: 'flex-end',
|
||||
height: 36,
|
||||
cursor: 'pointer'
|
||||
}} onClick={onClick}>
|
||||
{!copied && (
|
||||
<Input defaultValue={ props.value } readOnly onClick={onClick} variant={'unstyled'} spellCheck={false} color="gray" classNames={{
|
||||
input: classes.input
|
||||
}} placeholder={props.placeholder}></Input>)}
|
||||
{copied && (
|
||||
<Input defaultValue={'copied'} readOnly spellCheck={false} styles={{
|
||||
input: {
|
||||
color: 'var(--mantine-color-green-6)',
|
||||
textAlign: 'right',
|
||||
cursor: 'pointer'
|
||||
}
|
||||
}} variant={'unstyled'}></Input>
|
||||
)}
|
||||
</div>
|
||||
</Flex>
|
||||
</Paper>
|
||||
);
|
||||
}
|
||||
|
||||
function SettingsInputClickable(
|
||||
props : SettingsInputClickableProps
|
||||
) {
|
||||
const colors = useRosettaColors();
|
||||
const onClick = (e : MouseEvent) => {
|
||||
e.stopPropagation();
|
||||
props.onClick();
|
||||
}
|
||||
return (
|
||||
<Paper mt={props.mt} style={props.style} withBorder styles={{
|
||||
root: {
|
||||
borderTop: '1px solid ' + colors.borderColor,
|
||||
borderBottom: '1px solid ' + colors.borderColor,
|
||||
borderLeft: '1px solid ' + colors.borderColor,
|
||||
borderRight: '1px solid ' + colors.borderColor,
|
||||
cursor: 'pointer'
|
||||
}
|
||||
}}
|
||||
|
||||
onClick={onClick}
|
||||
>
|
||||
<Flex direction={'row'} pr={'sm'} pl={'sm'} align={'center'} justify={'space-between'}>
|
||||
<Flex gap={'sm'} align={'center'}>
|
||||
{props.settingsIcon}
|
||||
<Text size={'sm'} c={props.c} fw={400}>{props.hit}</Text>
|
||||
</Flex>
|
||||
<div style={{
|
||||
display: 'flex',
|
||||
alignItems: 'center',
|
||||
justifyContent: 'flex-end',
|
||||
height: 36,
|
||||
cursor: 'pointer'
|
||||
}} onClick={onClick}>
|
||||
{props.rightSection && (
|
||||
<Input defaultValue={props.value} readOnly onClick={onClick} rightSection={props.rightSection} classNames={{
|
||||
input: classes.input
|
||||
}} spellCheck={false} variant={'unstyled'}></Input>
|
||||
)}
|
||||
{!props.rightSection && (
|
||||
<Input readOnly defaultValue={props.value} onClick={onClick} variant={'unstyled'} spellCheck={false} color="gray" classNames={{
|
||||
input: classes.input
|
||||
}} placeholder={props.placeholder}></Input>)
|
||||
}
|
||||
{!props.rightChevronHide && (<IconChevronRight size={20} onClick={onClick} color={colors.chevrons.active}></IconChevronRight>)}
|
||||
</div>
|
||||
</Flex>
|
||||
</Paper>
|
||||
);
|
||||
}
|
||||
|
||||
function SettingsInputDefault(props : SettingsInputDefaultProps) {
|
||||
const colors = useRosettaColors();
|
||||
const input = useRef<any>(undefined);
|
||||
|
||||
const onClick = (e : MouseEvent) => {
|
||||
e.stopPropagation();
|
||||
if(!props.disabled){
|
||||
input.current.focus();
|
||||
return;
|
||||
}
|
||||
}
|
||||
return (<>
|
||||
<Paper mt={props.mt} style={props.style} withBorder styles={{
|
||||
root: {
|
||||
borderTop: '1px solid ' + colors.borderColor,
|
||||
borderBottom: '1px solid ' + colors.borderColor,
|
||||
borderLeft: '1px solid ' + colors.borderColor,
|
||||
borderRight: '1px solid ' + colors.borderColor,
|
||||
cursor: 'pointer'
|
||||
}
|
||||
}}
|
||||
|
||||
onClick={onClick}
|
||||
>
|
||||
<Flex direction={'row'} pr={'sm'} pl={'sm'} align={'center'} justify={'space-between'}>
|
||||
<Text size={'sm'} fw={400}>{props.hit}</Text>
|
||||
<div style={{
|
||||
display: 'flex',
|
||||
alignItems: 'center',
|
||||
justifyContent: 'flex-end',
|
||||
height: 36,
|
||||
cursor: 'pointer'
|
||||
}} onClick={onClick}>
|
||||
{props.rightSection && (
|
||||
<Input type={props.type} defaultValue={props.value} readOnly onClick={onClick} rightSection={props.rightSection} classNames={{
|
||||
input: classes.input
|
||||
}} spellCheck={false} variant={'unstyled'}></Input>
|
||||
)}
|
||||
{!props.rightSection && (
|
||||
<Input type={props.type} defaultValue={!props.onChange ? props.value : undefined} value={!props.onChange ? undefined : props.value} ref={input} disabled={props.disabled} onClick={(e) => {
|
||||
onClick(e)
|
||||
}} onChange={props.onChange} variant={'unstyled'} spellCheck={false} color="gray" classNames={{
|
||||
input: classes.input
|
||||
}} placeholder={props.placeholder}></Input>)
|
||||
}
|
||||
</div>
|
||||
</Flex>
|
||||
</Paper>
|
||||
</>)
|
||||
}
|
||||
|
||||
|
||||
function SettingsInputGroup(props : SettingsInputGroupProps) {
|
||||
const colors = useRosettaColors();
|
||||
|
||||
const childrenArray = Children.toArray(props.children).filter(
|
||||
(child): child is React.ReactElement<{ style?: React.CSSProperties }> =>
|
||||
isValidElement(child)
|
||||
);
|
||||
return (
|
||||
<Box mt={props.mt}>
|
||||
{childrenArray.map((child, index) => {
|
||||
const isFirst = index === 0;
|
||||
const isLast = index === childrenArray.length - 1;
|
||||
return cloneElement(child, {
|
||||
style: {
|
||||
borderRadius: isFirst
|
||||
? "var(--mantine-radius-default) var(--mantine-radius-default) 0 0"
|
||||
: isLast
|
||||
? "0 0 var(--mantine-radius-default) var(--mantine-radius-default)"
|
||||
: "0",
|
||||
borderTop: isLast ? 'unset' : '1px solid ' + colors.borderColor,
|
||||
borderBottom: isFirst ? '1px solid ' + colors.borderColor : '1px solid ' + colors.borderColor,
|
||||
...(child.props.style || {}),
|
||||
},
|
||||
});
|
||||
})}
|
||||
</Box>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user