Skip to content

Commit

Permalink
Added deselectable prop for radio-type components
Browse files Browse the repository at this point in the history
  • Loading branch information
RenaudLN committed Oct 11, 2024
1 parent 76789a5 commit f383959
Show file tree
Hide file tree
Showing 6 changed files with 54 additions and 2 deletions.
6 changes: 6 additions & 0 deletions src/ts/components/core/chip/Chip.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import { BoxProps } from "props/box";
import { DashBaseProps, PersistenceProps } from "props/dash";
import { StylesApiProps } from "props/styles";
import React from "react";
import ChipGroupContext from "./ChipGroupContext"

interface Props
extends BoxProps,
Expand Down Expand Up @@ -59,11 +60,15 @@ const Chip = (props: Props) => {
const onChange = (checked: boolean) => {
setProps({ checked });
};

const { chipOnClick } = React.useContext(ChipGroupContext);

if (controlled) {
return (
<MantineChip
checked={checked}
onChange={onChange}
onClick={chipOnClick}
data-dash-is-loading={
(loading_state && loading_state.is_loading) || undefined
}
Expand All @@ -78,6 +83,7 @@ const Chip = (props: Props) => {
data-dash-is-loading={
(loading_state && loading_state.is_loading) || undefined
}
onClick={chipOnClick}
{...others}
>
{children}
Expand Down
14 changes: 13 additions & 1 deletion src/ts/components/core/chip/ChipGroup.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { Chip } from "@mantine/core";
import { useDidUpdate } from "@mantine/hooks";
import { DashBaseProps, PersistenceProps } from "props/dash";
import React, { useState } from "react";
import ChipGroupContext from "./ChipGroupContext";

interface Props extends DashBaseProps, PersistenceProps {
/** Determines whether it is allowed to select multiple values, `false` by default */
Expand All @@ -10,6 +11,8 @@ interface Props extends DashBaseProps, PersistenceProps {
value?: string[] | string | null;
/** `Chip` components and any other elements */
children?: React.ReactNode;
/** Allow to deselect Chip in Radio mode */
deselectable?: boolean;
}

/** ChipGroup */
Expand All @@ -22,6 +25,7 @@ const ChipGroup = (props: Props) => {
persisted_props,
persistence_type,
loading_state,
deselectable,
...others
} = props;
const [val, setVal] = useState(value);
Expand All @@ -34,6 +38,12 @@ const ChipGroup = (props: Props) => {
setProps({ value: val });
}, [val]);

const handleChipClick = (event: React.MouseEvent<HTMLInputElement>) => {
if (event.currentTarget.value === value) {
setVal(null);
}
};

return (
<Chip.Group
value={val}
Expand All @@ -43,7 +53,9 @@ const ChipGroup = (props: Props) => {
}
{...others}
>
{children}
<ChipGroupContext.Provider value={{ chipOnClick: deselectable ? handleChipClick : null }}>
{children}
</ChipGroupContext.Provider>
</Chip.Group>
);
};
Expand Down
9 changes: 9 additions & 0 deletions src/ts/components/core/chip/ChipGroupContext.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import React, { createContext } from "react";

interface ChipGroupContextProps {
chipOnClick?: (e: React.MouseEvent<HTMLInputElement>) => void;
}

const ChipGroupContext = createContext<ChipGroupContextProps | null>(null);

export default ChipGroupContext;
4 changes: 4 additions & 0 deletions src/ts/components/core/radio/Radio.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import { BoxProps } from "props/box";
import { DashBaseProps, PersistenceProps } from "props/dash";
import { StylesApiProps } from "props/styles";
import React from "react";
import RadioGroupContext from "./RadioGroupContext";

interface Props
extends BoxProps,
Expand Down Expand Up @@ -49,12 +50,15 @@ const Radio = (props: Props) => {
...others
} = props;

const { radioOnClick } = React.useContext(RadioGroupContext);

return (
<MantineRadio
data-dash-is-loading={
(loading_state && loading_state.is_loading) || undefined
}
onChange={(ev) => setProps({ checked: ev.currentTarget.checked })}
onClick={radioOnClick}
{...others}
/>
);
Expand Down
14 changes: 13 additions & 1 deletion src/ts/components/core/radio/RadioGroup.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { MantineSize, Radio } from "@mantine/core";
import { DashBaseProps, PersistenceProps } from "props/dash";
import { InputWrapperProps } from "props/input";
import React from "react";
import RadioGroupContext from "./RadioGroupContext";

interface Props extends InputWrapperProps, DashBaseProps, PersistenceProps {
/** `Radio` components and any other elements */
Expand All @@ -16,6 +17,8 @@ interface Props extends InputWrapperProps, DashBaseProps, PersistenceProps {
name?: string;
/** If set, value cannot be changed */
readOnly?: boolean;
/** Allow to deselect Chip in Radio mode */
deselectable?: boolean;
}

/** RadioGroup */
Expand All @@ -28,13 +31,20 @@ const RadioGroup = (props: Props) => {
persistence,
persisted_props,
persistence_type,
deselectable,
...others
} = props;

const onChange = (value: string) => {
setProps({ value });
};

const handleRadioClick = (event: React.MouseEvent<HTMLInputElement>) => {
if (event.currentTarget.value === value) {
setProps({ value: null });
}
};

return (
<Radio.Group
data-dash-is-loading={
Expand All @@ -44,7 +54,9 @@ const RadioGroup = (props: Props) => {
value={value}
{...others}
>
{children}
<RadioGroupContext.Provider value={{radioOnClick: deselectable ? handleRadioClick : null}}>
{children}
</RadioGroupContext.Provider>
</Radio.Group>
);
};
Expand Down
9 changes: 9 additions & 0 deletions src/ts/components/core/radio/RadioGroupContext.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import React, { createContext } from "react";

interface RadioGroupContextProps {
radioOnClick?: (e: React.MouseEvent<HTMLInputElement>) => void;
}

const RadioGroupContext = createContext<RadioGroupContextProps | null>(null);

export default RadioGroupContext;

0 comments on commit f383959

Please sign in to comment.