Skip to content

Commit

Permalink
Sx prop on form control (#19)
Browse files Browse the repository at this point in the history
* Easy access to sx prop on FormControl

* Rush change
  • Loading branch information
ilbrando authored Jul 22, 2024
1 parent d087543 commit 6a463f6
Show file tree
Hide file tree
Showing 11 changed files with 92 additions and 18 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
{
"changes": [
{
"packageName": "@ilbrando/simple-form-joy",
"comment": "New sxFormControl prop to access sx prop on FormControl wrapper",
"type": "minor"
}
],
"packageName": "@ilbrando/simple-form-joy"
}
Original file line number Diff line number Diff line change
Expand Up @@ -13,14 +13,14 @@ export type FormControlWrapperProps = FormFieldBaseSharedProps & {
};

export const FormControlWrapper = (props: FormControlWrapperProps) => {
const { isRequired, isDisabled, size, label, errorMessage, reserveSpaceForValidationMessage, children } = props;
const { isRequired, isDisabled, size, label, errorMessage, reserveSpaceForValidationMessage, sxFormControl, children } = props;

const { effectiveReserveSpaceForValidationMessage } = useJoyFormUtils(reserveSpaceForValidationMessage);

const showErrorMessage = hasValue(errorMessage) || effectiveReserveSpaceForValidationMessage;

return (
<FormControl size={size} error={hasValue(errorMessage)} required={isRequired} disabled={isDisabled}>
<FormControl size={size} error={hasValue(errorMessage)} required={isRequired} disabled={isDisabled} sx={sxFormControl}>
{hasValue(label) && <FormLabel>{label}</FormLabel>}
{children}
{showErrorMessage && <FormHelperText>{errorMessage ?? (effectiveReserveSpaceForValidationMessage ? <>{"\u00A0"}</> : null)}</FormHelperText>}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,14 +20,22 @@ export type FormAutocompleteMultipleProps<TFields, TFormValue extends FormValue,
};

export const FormAutocompleteMultiple = function <TFields, TFormValue extends FormValue, TFieldName extends PropKeysOf<TFields, TFormValue[]>>(props: FormAutocompleteMultipleProps<TFields, TFormValue, TFieldName>) {
const { formManager, fieldName, disabled, options, label, size, reserveSpaceForValidationMessage, ...rest } = props;
const { formManager, fieldName, disabled, options, label, size, reserveSpaceForValidationMessage, sxFormControl, ...rest } = props;

const editor = getEditor<TFields, TFormValue[]>(formManager, fieldName, disabled);

const optionValues = useMemo(() => options.map(x => x.value), [options]);

return (
<FormControlWrapper label={label} size={size} errorMessage={editor.errorMessage} reserveSpaceForValidationMessage={reserveSpaceForValidationMessage} isRequired={editor.isRequired} isDisabled={editor.isDisabled}>
<FormControlWrapper
label={label}
size={size}
errorMessage={editor.errorMessage}
reserveSpaceForValidationMessage={reserveSpaceForValidationMessage}
isRequired={editor.isRequired}
isDisabled={editor.isDisabled}
sxFormControl={sxFormControl}
>
<Autocomplete
multiple={true}
value={editor.value ?? []}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,14 +20,22 @@ export type FormAutocompleteProps<TFields, TFormValue extends FormValue, TFieldN
};

export const FormAutocomplete = function <TFields, TFormValue extends FormValue, TFieldName extends PropKeysOf<TFields, TFormValue>>(props: FormAutocompleteProps<TFields, TFormValue, TFieldName>) {
const { formManager, fieldName, disabled, options, label, size, reserveSpaceForValidationMessage, ...rest } = props;
const { formManager, fieldName, disabled, options, label, size, reserveSpaceForValidationMessage, sxFormControl, ...rest } = props;

const editor = getEditor<TFields, TFormValue>(formManager, fieldName, disabled);

const optionValues = useMemo(() => options.map(x => x.value), [options]);

return (
<FormControlWrapper label={label} size={size} errorMessage={editor.errorMessage} reserveSpaceForValidationMessage={reserveSpaceForValidationMessage} isRequired={editor.isRequired} isDisabled={editor.isDisabled}>
<FormControlWrapper
label={label}
size={size}
errorMessage={editor.errorMessage}
reserveSpaceForValidationMessage={reserveSpaceForValidationMessage}
isRequired={editor.isRequired}
isDisabled={editor.isDisabled}
sxFormControl={sxFormControl}
>
<Autocomplete
value={editor.value}
options={optionValues}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,12 +11,19 @@ type FormValue = boolean;
export type FormCheckboxProps<TFields, TFieldName extends PropKeysOf<TFields, FormValue>> = OmitSafe<CheckboxProps, "checked" | "value" | "required" | "onChange"> & FormFieldBaseProps<TFields, FormValue, TFieldName>;

export const FormCheckbox = function <TFields, TFieldName extends PropKeysOf<TFields, FormValue>>(props: FormCheckboxProps<TFields, TFieldName>) {
const { formManager, fieldName, disabled, label, size, reserveSpaceForValidationMessage, ...rest } = props;
const { formManager, fieldName, disabled, label, size, reserveSpaceForValidationMessage, sxFormControl, ...rest } = props;

const editor = getEditor<TFields, FormValue>(formManager, fieldName, disabled);

return (
<FormControlWrapper size={size} errorMessage={editor.errorMessage} reserveSpaceForValidationMessage={reserveSpaceForValidationMessage} isRequired={editor.isRequired} isDisabled={editor.isDisabled}>
<FormControlWrapper
size={size}
errorMessage={editor.errorMessage}
reserveSpaceForValidationMessage={reserveSpaceForValidationMessage}
isRequired={editor.isRequired}
isDisabled={editor.isDisabled}
sxFormControl={sxFormControl}
>
<Checkbox checked={editor.value ?? false} onChange={e => editor.setFieldValue(e.target.checked)} label={label} {...rest} />
</FormControlWrapper>
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ type FormNumberProps<TFields, TFieldName extends PropKeysOf<TFields, FormValue>>
const isValidValue = (value: string) => /^[-]?(\d+)$/.test(value);

export const FormNumber = function <TFields, TFieldName extends PropKeysOf<TFields, FormValue>>(props: FormNumberProps<TFields, TFieldName>) {
const { formManager, fieldName, disabled, readOnly, label, size, reserveSpaceForValidationMessage, ...rest } = props;
const { formManager, fieldName, disabled, readOnly, label, size, reserveSpaceForValidationMessage, sxFormControl, ...rest } = props;

const { texts } = useLocalization();

Expand All @@ -29,7 +29,15 @@ export const FormNumber = function <TFields, TFieldName extends PropKeysOf<TFiel
}, [editor.value]);

return (
<FormControlWrapper label={label} size={size} errorMessage={editor.errorMessage} reserveSpaceForValidationMessage={reserveSpaceForValidationMessage} isRequired={editor.isRequired} isDisabled={isDisabled}>
<FormControlWrapper
label={label}
size={size}
errorMessage={editor.errorMessage}
reserveSpaceForValidationMessage={reserveSpaceForValidationMessage}
isRequired={editor.isRequired}
isDisabled={isDisabled}
sxFormControl={sxFormControl}
>
<Input
value={textBoxValue}
onChange={e => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,14 +20,22 @@ export type FormRadioGroupProps<TFields, TFormValue extends FormValue, TFieldNam
};

export const FormRadioGroup = function <TFields, TFormValue extends FormValue, TFieldName extends PropKeysOf<TFields, TFormValue>>(props: FormRadioGroupProps<TFields, TFormValue, TFieldName>) {
const { formManager, fieldName, disabled = false, label, size, options, reserveSpaceForValidationMessage, ...rest } = props;
const { formManager, fieldName, disabled = false, label, size, options, reserveSpaceForValidationMessage, sxFormControl, ...rest } = props;

const editor = getEditor<TFields, TFormValue>(formManager, fieldName, disabled);

const isValueString = options.length > 0 && typeof options[0].value === "string";

return (
<FormControlWrapper label={label} size={size} errorMessage={editor.errorMessage} reserveSpaceForValidationMessage={reserveSpaceForValidationMessage} isRequired={editor.isRequired} isDisabled={editor.isDisabled}>
<FormControlWrapper
label={label}
size={size}
errorMessage={editor.errorMessage}
reserveSpaceForValidationMessage={reserveSpaceForValidationMessage}
isRequired={editor.isRequired}
isDisabled={editor.isDisabled}
sxFormControl={sxFormControl}
>
<RadioGroup value={editor.value ?? ""} onChange={e => editor.setFieldValue((isValueString ? e.target.value : parseInt(e.target.value)) as TFormValue)} {...rest}>
{options.map(item => (
<Radio key={item.value} value={item.value} label={item.label} disabled={editor.isDisabled} />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ export type FormRangeSliderValue = {
type FormRangeSliderProps<TFields, TFieldName extends PropKeysOf<TFields, FormRangeSliderValue>> = OmitSafe<SliderProps, "value" | "onChange"> & FormFieldBaseProps<TFields, FormRangeSliderValue, TFieldName>;

export const FormRangeSlider = function <TFields, TFieldName extends PropKeysOf<TFields, FormRangeSliderValue>>(props: FormRangeSliderProps<TFields, TFieldName>) {
const { formManager, fieldName, label, size, disabled, reserveSpaceForValidationMessage, ...rest } = props;
const { formManager, fieldName, label, size, disabled, reserveSpaceForValidationMessage, sxFormControl, ...rest } = props;

const editor = getEditor<TFields, FormRangeSliderValue>(formManager, fieldName, disabled);

Expand All @@ -29,7 +29,15 @@ export const FormRangeSlider = function <TFields, TFieldName extends PropKeysOf<
};

return (
<FormControlWrapper label={label} size={size} errorMessage={editor.errorMessage} reserveSpaceForValidationMessage={reserveSpaceForValidationMessage} isRequired={editor.isRequired} isDisabled={editor.isDisabled}>
<FormControlWrapper
label={label}
size={size}
errorMessage={editor.errorMessage}
reserveSpaceForValidationMessage={reserveSpaceForValidationMessage}
isRequired={editor.isRequired}
isDisabled={editor.isDisabled}
sxFormControl={sxFormControl}
>
<Box px={1}>
<Slider value={hasValue(editor.value) ? [editor.value.from, editor.value.to] : [0, 0]} onChange={handleOnChange} disabled={editor.isDisabled} {...rest} />
</Box>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ export type FormSwitchProps<TFields, TFieldName extends PropKeysOf<TFields, Form
};

export const FormSwitch = function <TFields, TFieldName extends PropKeysOf<TFields, FormValue>>(props: FormSwitchProps<TFields, TFieldName>) {
const { formManager, fieldName, disabled, label, labelPlacement = "end", size, reserveSpaceForValidationMessage, sx, ...rest } = props;
const { formManager, fieldName, disabled, label, labelPlacement = "end", size, reserveSpaceForValidationMessage, sxFormControl, sx, ...rest } = props;

const editor = getEditor<TFields, FormValue>(formManager, fieldName, disabled);

Expand All @@ -24,7 +24,14 @@ export const FormSwitch = function <TFields, TFieldName extends PropKeysOf<TFiel
);

return (
<FormControlWrapper size={size} errorMessage={editor.errorMessage} reserveSpaceForValidationMessage={reserveSpaceForValidationMessage} isRequired={editor.isRequired} isDisabled={editor.isDisabled}>
<FormControlWrapper
size={size}
errorMessage={editor.errorMessage}
reserveSpaceForValidationMessage={reserveSpaceForValidationMessage}
isRequired={editor.isRequired}
isDisabled={editor.isDisabled}
sxFormControl={sxFormControl}
>
<Typography component="label" startDecorator={labelPlacement === "end" && Editor} endDecorator={labelPlacement === "start" && Editor}>
{label}
</Typography>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ export type FormTextProps<TFields, TFieldName extends PropKeysOf<TFields, FormVa
};

export const FormText = function <TFields, TFieldName extends PropKeysOf<TFields, FormValue>>(props: FormTextProps<TFields, TFieldName>) {
const { formManager, fieldName, textTransform, disabled, readOnly, label, size, reserveSpaceForValidationMessage, ...rest } = props;
const { formManager, fieldName, textTransform, disabled, readOnly, label, size, reserveSpaceForValidationMessage, sxFormControl, ...rest } = props;

const editor = getEditor<TFields, FormValue>(formManager, fieldName, disabled);

Expand All @@ -34,7 +34,15 @@ export const FormText = function <TFields, TFieldName extends PropKeysOf<TFields
};

return (
<FormControlWrapper label={label} size={size} errorMessage={editor.errorMessage} reserveSpaceForValidationMessage={reserveSpaceForValidationMessage} isRequired={editor.isRequired} isDisabled={isDisabled}>
<FormControlWrapper
label={label}
size={size}
errorMessage={editor.errorMessage}
reserveSpaceForValidationMessage={reserveSpaceForValidationMessage}
isRequired={editor.isRequired}
isDisabled={isDisabled}
sxFormControl={sxFormControl}
>
<Input value={editor.value ?? ""} onChange={e => editor.setFieldValue(parseValue(e.target.value))} readOnly={readOnly} {...rest} />
</FormControlWrapper>
);
Expand Down
2 changes: 2 additions & 0 deletions packages/simple-form-joy/src/form-components/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@ export type FormFieldBaseSharedProps = Pick<FormControlProps, "size"> & {
* prop if you want to override the value on each instance.
*/
reserveSpaceForValidationMessage?: boolean;
/** The sx prop for the wrapping `FormControl` */
sxFormControl?: FormControlProps["sx"];
};

export type FormFieldBaseProps<TFields, TFormValue, TFieldName extends PropKeysOf<TFields, TFormValue>> = FormFieldBaseSharedProps & {
Expand Down

0 comments on commit 6a463f6

Please sign in to comment.