mirror of
https://github.com/luxfi/explore.git
synced 2026-09-24 00:28:18 +00:00
168 lines
4.2 KiB
TypeScript
168 lines
4.2 KiB
TypeScript
import { formAnatomy as parts } from '@chakra-ui/anatomy';
|
|
import { createMultiStyleConfigHelpers } from '@chakra-ui/styled-system';
|
|
import type { StyleFunctionProps } from '@chakra-ui/theme-tools';
|
|
|
|
import getFormStyles from '../utils/getFormStyles';
|
|
import FancySelect from './FancySelect';
|
|
import FormLabel from './FormLabel';
|
|
import Input from './Input';
|
|
import Textarea from './Textarea';
|
|
|
|
const { definePartsStyle, defineMultiStyleConfig } =
|
|
createMultiStyleConfigHelpers(parts.keys);
|
|
|
|
function getFloatingVariantStylesForSize(size: 'md' | 'lg', props: StyleFunctionProps) {
|
|
const formStyles = getFormStyles(props);
|
|
|
|
const activeLabelStyles = {
|
|
...FormLabel.variants?.floating?.(props)._focusWithin,
|
|
...FormLabel.sizes?.[size](props)._focusWithin,
|
|
};
|
|
|
|
const activeInputStyles = (() => {
|
|
switch (size) {
|
|
case 'md': {
|
|
return {
|
|
paddingTop: '26px',
|
|
paddingBottom: '10px',
|
|
};
|
|
}
|
|
|
|
case 'lg': {
|
|
return {
|
|
paddingTop: '38px',
|
|
paddingBottom: '18px',
|
|
};
|
|
}
|
|
}
|
|
})();
|
|
|
|
const inputPx = (() => {
|
|
switch (size) {
|
|
case 'md': {
|
|
return '16px';
|
|
}
|
|
|
|
case 'lg': {
|
|
return '24px';
|
|
}
|
|
}
|
|
})();
|
|
|
|
return {
|
|
container: {
|
|
// active styles
|
|
_focusWithin: {
|
|
label: activeLabelStyles,
|
|
'input, textarea': activeInputStyles,
|
|
},
|
|
'&[data-active=true] label': activeLabelStyles,
|
|
|
|
// label styles
|
|
label: FormLabel.sizes?.[size](props) || {},
|
|
'input:not(:placeholder-shown) + label, textarea:not(:placeholder-shown) + label': activeLabelStyles,
|
|
'textarea:not(:placeholder-shown) + label': {
|
|
bgColor: formStyles.input.filled.bgColor,
|
|
},
|
|
[`
|
|
input[readonly] + label,
|
|
textarea[readonly] + label,
|
|
&[aria-readonly=true] label
|
|
`]: {
|
|
bgColor: formStyles.input.readOnly.bgColor,
|
|
},
|
|
[`
|
|
input[aria-invalid=true] + label,
|
|
textarea[aria-invalid=true] + label,
|
|
&[aria-invalid=true] label
|
|
`]: {
|
|
color: formStyles.placeholder.error.color,
|
|
},
|
|
[`
|
|
input[disabled] + label,
|
|
textarea[disabled] + label,
|
|
&[aria-disabled=true] label
|
|
`]: {
|
|
color: formStyles.placeholder.disabled.color,
|
|
},
|
|
|
|
// input styles
|
|
input: Input.sizes?.[size].field,
|
|
'input[aria-autocomplete=list]': FancySelect.sizes[size].field,
|
|
textarea: Textarea.sizes?.[size],
|
|
'input, textarea': {
|
|
padding: inputPx,
|
|
},
|
|
'input:not(:placeholder-shown), textarea:not(:placeholder-shown)': activeInputStyles,
|
|
|
|
// indicator styles
|
|
'input:not(:placeholder-shown) + label .chakra-form__required-indicator, textarea:not(:placeholder-shown) + label .chakra-form__required-indicator': {
|
|
color: formStyles.placeholder.default.color,
|
|
},
|
|
[`
|
|
input[aria-invalid=true] + label .chakra-form__required-indicator,
|
|
textarea[aria-invalid=true] + label .chakra-form__required-indicator,
|
|
&[aria-invalid=true] .chakra-form__required-indicator
|
|
`]: {
|
|
color: formStyles.placeholder.error.color,
|
|
},
|
|
[`
|
|
input[disabled] + label .chakra-form__required-indicator,
|
|
textarea[disabled] + label .chakra-form__required-indicator,
|
|
&[aria-disabled=true] .chakra-form__required-indicator
|
|
`]: {
|
|
color: formStyles.placeholder.disabled.color,
|
|
},
|
|
},
|
|
};
|
|
}
|
|
|
|
const baseStyle = definePartsStyle(() => {
|
|
return {
|
|
requiredIndicator: {
|
|
marginStart: 0,
|
|
color: 'gray.500',
|
|
},
|
|
};
|
|
});
|
|
|
|
const variantFloating = definePartsStyle((props) => {
|
|
return {
|
|
container: {
|
|
label: FormLabel.variants?.floating(props) || {},
|
|
},
|
|
};
|
|
});
|
|
|
|
const sizes = {
|
|
lg: definePartsStyle((props) => {
|
|
if (props.variant === 'floating') {
|
|
return getFloatingVariantStylesForSize('lg', props);
|
|
}
|
|
|
|
return {};
|
|
}),
|
|
md: definePartsStyle((props) => {
|
|
if (props.variant === 'floating') {
|
|
return getFloatingVariantStylesForSize('md', props);
|
|
}
|
|
|
|
return {};
|
|
}),
|
|
};
|
|
|
|
const variants = {
|
|
floating: variantFloating,
|
|
};
|
|
|
|
const Form = defineMultiStyleConfig({
|
|
baseStyle,
|
|
variants,
|
|
sizes,
|
|
defaultProps: {
|
|
size: 'md',
|
|
},
|
|
});
|
|
|
|
export default Form;
|