Skip to content
This repository has been archived by the owner on Mar 9, 2023. It is now read-only.

Commit

Permalink
Update SelectField to correctly work with number type (#117)
Browse files Browse the repository at this point in the history
  • Loading branch information
ljmotta authored Dec 27, 2022
1 parent 95f78e4 commit e342555
Show file tree
Hide file tree
Showing 3 changed files with 38 additions and 33 deletions.
2 changes: 1 addition & 1 deletion examples/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
"uniforms-bridge-json-schema": "3.5.1",
"uniforms-bridge-simple-schema": "3.5.1",
"uniforms-bridge-simple-schema-2": "3.5.1",
"uniforms-patternfly": "4.7.7"
"uniforms-patternfly": "4.7.8"
},
"devDependencies": {
"parcel-bundler": "^1.12.5",
Expand Down
5 changes: 3 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "uniforms-patternfly",
"version": "4.7.7",
"version": "4.7.8",
"description": "Patternfly forms for uniforms",
"repository": "[email protected]:aerogear/uniforms-patternfly.git",
"author": "Gianluca <[email protected]>",
Expand All @@ -27,7 +27,8 @@
"reset": "rimraf dist node_modules",
"release:validate": "./scripts/validateRelease.sh TAG=1.2.3",
"release:publish": "./scripts/publishRelease.sh",
"test": "jest --runInBand"
"test": "jest --runInBand",
"install:example": "rimraf ./examples/node_modules/uniforms-patternfly/dist && cp -a ./dist/ ./examples/node_modules/uniforms-patternfly/dist/"
},
"dependencies": {
"classnames": "^2.0.0",
Expand Down
64 changes: 34 additions & 30 deletions src/SelectField.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -48,25 +48,31 @@ type SelectInputProps = FieldProps<
required?: boolean;
id: string;
fieldType?: typeof Array | any;
onChange: (value?: string | string[]) => void;
onChange: (value?: string | string[] | number | number[]) => void;
placeholder: string;
allowedValues?: string[];
allowedValues?: (string | number)[];
disabled?: boolean;
error?: boolean;
transform?: (value?: string) => string;
transform?: (value?: string | number) => string | number;
direction: SelectDirection;
menuAppendTo: HTMLElement;
}
>;

function isSelectOptionObject(
toBeDetermined: string | SelectOptionObject
toBeDetermined: string | number | SelectOptionObject
): toBeDetermined is SelectOptionObject {
return typeof toBeDetermined === 'object' &&
!Array.isArray(toBeDetermined) &&
toBeDetermined !== null
}

function isSelectOptionString(
toBeDetermined: string[] | number[]
): toBeDetermined is string[] {
return (toBeDetermined.length > 0 && typeof toBeDetermined[0] === 'string') || toBeDetermined.length === 0;
}

export type SelectFieldProps = CheckboxesProps | SelectInputProps;

function SelectField(props: SelectFieldProps) {
Expand Down Expand Up @@ -112,26 +118,13 @@ function SelectField(props: SelectFieldProps) {
}

const [expanded, setExpanded] = useState<boolean>(false);
const [selected, setSelected] = useState<string | string[]>([]);

useEffect(() => {
if (!props.value) {
setSelected([]);
setExpanded(false);
} else if (Array.isArray(props.value)) {
setSelected([...props.value]);
setExpanded(false);
} else {
setSelected(props.value);
setExpanded(false);
}
}, [props.value]);
const [selected, setSelected] = useState<string | string[] | number | number[] | undefined>([]);

const parseInput = useCallback(
(
selection: string | SelectOptionObject,
selection: string | number | SelectOptionObject,
fieldType: typeof Array | any
): string | string[] => {
): string | string[] | number | number[] => {
const parsedSelection = isSelectOptionObject(selection)
? selection.toString()
: selection;
Expand All @@ -141,12 +134,19 @@ function SelectField(props: SelectFieldProps) {
}

if (Array.isArray(selected)) {
if (selected.includes(parsedSelection)) {
return selected.filter((s) => s !== parsedSelection);
if (isSelectOptionString(selected) && typeof parsedSelection === "string") {
if (selected.includes(parsedSelection)) {
return selected.filter((s) => s !== parsedSelection);
}
return [parsedSelection, ...selected];
} else if (!isSelectOptionString(selected) && typeof parsedSelection === "number") {
if (selected.includes(parsedSelection)) {
return selected.filter((s) => s !== parsedSelection);
}
return [parsedSelection, ...selected];
}
return [parsedSelection, ...selected];
}
return [parsedSelection, selected];
return [];
},
[selected]
);
Expand All @@ -158,17 +158,21 @@ function SelectField(props: SelectFieldProps) {
) => {
if (selection === props.placeholder) {
props.onChange(undefined);
setSelected(undefined);
} else {
const items = parseInput(selection, props.fieldType);
props.onChange(items);
setSelected(items);
}
setExpanded(false);

},
[parseInput, props]
);

const selectedOptions = useMemo(
const selectOptions = useMemo(
() =>
props.allowedValues!.map((value) => (
props.allowedValues?.map((value) => (
<SelectOption key={value} value={value}>
{props.transform ? props.transform(value) : value}
</SelectOption>
Expand All @@ -178,14 +182,14 @@ function SelectField(props: SelectFieldProps) {

useEffect(() => {
if (props.placeholder)
selectedOptions.unshift(
selectOptions?.unshift(
<SelectOption
key={props.allowedValues!.length}
isPlaceholder
value={props.placeholder}
/>
);
}, [props.placeholder, selectedOptions])
}, [props.placeholder, selectOptions])

return wrapField(
props,
Expand All @@ -201,13 +205,13 @@ function SelectField(props: SelectFieldProps) {
placeholderText={props.placeholder}
isOpen={expanded}
selections={selected}
onToggle={() => setExpanded(!expanded)}
onToggle={(isExpanded) => setExpanded(isExpanded)}
onSelect={handleSelect}
value={props.value || (props.fieldType === Array ? [] : undefined)}
menuAppendTo={props.menuAppendTo}
direction={props.direction}
>
{selectedOptions}
{selectOptions}
</Select>
);
}
Expand Down

0 comments on commit e342555

Please sign in to comment.