Skip to content

Commit

Permalink
Pass all props to custom elements
Browse files Browse the repository at this point in the history
- Fixed an issue where loading state was not shown in placeholders (fix prioritization)
- Passed all form props to custom elements with overrides
  • Loading branch information
kirankunigiri committed Dec 1, 2024
1 parent 2ee0aab commit 146e054
Show file tree
Hide file tree
Showing 3 changed files with 29 additions and 12 deletions.
4 changes: 2 additions & 2 deletions example-client/src/form/lib/searchable-select.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ interface SearchableSelectProps {
onBlur?: () => void
onFocus?: () => void
defaultValue?: BaseValue | null
inputPlaceholder?: string
placeholder?: string
searchPlaceholder?: string
label?: string
description?: string
Expand Down Expand Up @@ -94,7 +94,7 @@ export function SearchableSelect(props: SearchableSelectProps) {
<SearchableSelectOption key={item.value} item={item} selectedValue={value} combobox={combobox} index={index} />
));

const inputPlaceholder = props.inputPlaceholder || 'Select...';
const inputPlaceholder = props.placeholder || 'Select...';

return (
<Combobox
Expand Down
2 changes: 1 addition & 1 deletion package/package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "zenstack-ui",
"description": "Customizable react components for zenstack (forms/lists/etc.)",
"version": "0.0.9",
"version": "0.0.10",
"repository": {
"type": "git",
"url": "https://github.com/kirankunigiri/zenstack-ui",
Expand Down
35 changes: 26 additions & 9 deletions package/src/form/form.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@ import { Field, FieldType, Metadata, UseFindUniqueHook, UseMutationHook, UseQuer
import { useZenstackUIProvider } from '../utils/provider';
import { getIdField, getModelFields } from '../utils/utils';

const LOADING_PLACEHOLDER = 'Loading...';

// Form ref type
export interface ZenstackFormRef {
form: ReturnType<typeof useForm>
Expand Down Expand Up @@ -548,7 +550,7 @@ const ZenstackFormInputInternal = (props: ZenstackFormInputProps) => {
};
});
} else {
labelData = [{ label: 'Loading...', value: 'Loading...' }];
labelData = [{ label: LOADING_PLACEHOLDER, value: LOADING_PLACEHOLDER }];
}
}

Expand All @@ -572,7 +574,7 @@ const ZenstackFormInputInternal = (props: ZenstackFormInputProps) => {
}

let placeholder = field.placeholder;
if (props.isLoadingInitialData) placeholder = 'Loading...';
if (props.isLoadingInitialData) placeholder = LOADING_PLACEHOLDER;

// Create wrapped onChange handler
// This handler is used to reset dependent fields when the main field changes (using dependsOn from metadata)
Expand Down Expand Up @@ -601,15 +603,30 @@ const ZenstackFormInputInternal = (props: ZenstackFormInputProps) => {
const dirtyClassName = isDirty ? 'dirty' : '';
const combinedClassName = `${originalClassName} ${dirtyClassName}`.trim();

return React.cloneElement(props.customElement, {
// Create base props that we want to pass
const baseProps = {
...props.form.getInputProps(fieldName),
onChange: handleChange,
'onChange': handleChange,
required,
key: props.form.key(fieldName),
className: combinedClassName,
disabled: isDisabled,
placeholder: placeholder,
});
'key': props.form.key(fieldName),
'className': combinedClassName,
'disabled': isDisabled,
'placeholder': placeholder,
label,
'data': labelData,
'data-autofocus': props.index === 0,
};

// Filter out props that are already defined in customElement
const finalProps = Object.fromEntries(
Object.entries(baseProps).filter(([key]) =>
props.customElement!.props[key] === undefined,
),
);
// For custom elements, we need to prioritize the loading placeholder
if (props.isLoadingInitialData) finalProps.placeholder = LOADING_PLACEHOLDER;

return React.cloneElement(props.customElement, finalProps);
}

return (
Expand Down

0 comments on commit 146e054

Please sign in to comment.