init
This commit is contained in:
89
src/components/sheet/slide-panel/slide-panel-field.tsx
Normal file
89
src/components/sheet/slide-panel/slide-panel-field.tsx
Normal file
@@ -0,0 +1,89 @@
|
||||
import { Box, Text, UnstyledButton, Flex, Stack } from "@mantine/core";
|
||||
import { CaretRightIcon } from "@phosphor-icons/react";
|
||||
import { ComponentType, useContext } from "react";
|
||||
import { SlidePanelContext } from "./slide-panel-context";
|
||||
|
||||
interface SlidePanelFieldProps {
|
||||
key: string;
|
||||
value?: any;
|
||||
onChange?: (value: any) => void;
|
||||
Component: ComponentType<any>;
|
||||
title: string;
|
||||
label?: string;
|
||||
placeholder?: string;
|
||||
formatValue?: (value: any) => string;
|
||||
componentProps?: Record<string, any>;
|
||||
withAsterisk?: boolean;
|
||||
error?: string;
|
||||
}
|
||||
|
||||
const SlidePanelField = ({
|
||||
value,
|
||||
onChange,
|
||||
Component,
|
||||
title,
|
||||
label,
|
||||
placeholder = "Select value",
|
||||
withAsterisk = false,
|
||||
formatValue,
|
||||
componentProps,
|
||||
error,
|
||||
}: SlidePanelFieldProps) => {
|
||||
const context = useContext(SlidePanelContext);
|
||||
|
||||
if (!context) {
|
||||
throw new Error('SlidePanelField must be used within a SlidePanel');
|
||||
}
|
||||
|
||||
const handleClick = () => {
|
||||
if (!onChange) return;
|
||||
|
||||
context.openPanel({
|
||||
title,
|
||||
Component,
|
||||
value,
|
||||
onChange,
|
||||
componentProps,
|
||||
});
|
||||
};
|
||||
|
||||
const displayValue = () => {
|
||||
if (formatValue && value != null) {
|
||||
return formatValue(value);
|
||||
}
|
||||
if (value != null) {
|
||||
if (value instanceof Date) {
|
||||
return value.toLocaleDateString();
|
||||
}
|
||||
return String(value);
|
||||
}
|
||||
return placeholder;
|
||||
};
|
||||
|
||||
return (
|
||||
<Box>
|
||||
<UnstyledButton
|
||||
onClick={handleClick}
|
||||
p='sm'
|
||||
style={{
|
||||
width: '100%',
|
||||
border: error ? '1px solid var(--mantine-color-error)' : '1px solid var(--mantine-color-dimmed)',
|
||||
borderRadius: 'var(--mantine-radius-lg)',
|
||||
backgroundColor: 'var(--mantine-color-body)',
|
||||
textAlign: 'left',
|
||||
}}
|
||||
>
|
||||
<Flex justify="space-between" align="center">
|
||||
<Stack>
|
||||
<Text size="sm" fw={500}>{label}{withAsterisk && <Text span size="sm" c='var(--mantine-color-error)' fw={500} ml={4}>*</Text>}</Text>
|
||||
<Text size="sm" c='dimmed'>{displayValue()}</Text>
|
||||
</Stack>
|
||||
<CaretRightIcon size={24} weight='thin' style={{ marginRight: '12px' }} />
|
||||
</Flex>
|
||||
</UnstyledButton>
|
||||
{error && <Text size="xs" c='var(--mantine-color-error)' fw={500} ml={4} mt={4}>{error}</Text>}
|
||||
</Box>
|
||||
);
|
||||
};
|
||||
|
||||
export { SlidePanelField };
|
||||
Reference in New Issue
Block a user