Skip to content

Commit 116f047

Browse files
authored
Merge pull request #327 from AnnMarieW/chip
Add Chip and ChipGroup
2 parents e3e3d01 + 1a4f30c commit 116f047

File tree

8 files changed

+230
-24
lines changed

8 files changed

+230
-24
lines changed

.github/workflows/host-test.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,7 @@ jobs:
7777
env:
7878
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
7979
GITHUB_REPOSITORY: ${{ github.repository }}
80-
PR_NUMBER: ${{ github.event.inputs.pr_number }}
80+
PR_NUMBER: ${{ github.event.inputs.pr_number }}
8181
ARTIFACT_URL: ${{ env.artifact_url }}
8282
ARTIFACT_ID: ${{ env.artifact_id }}
8383
GITHUB_OWNER: snehilvj

CHANGELOG.md

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,13 @@
44

55
### Added
66

7-
- Added `autoplay` prop to the `Carousel` component #316 by @mmarfat
7+
8+
- Added `autoplay` prop to the `Carousel` component #316 by @mmarfat
9+
- Added the `ChipGroup` component and updated `Chip` to work with it. #327 by @AnnMarieW and @BSd3v
10+
Note: `Chip` was available before but not documented. If you used `Chip` in dmc>=0.14.0 to dmc<=0.14.5, you’ll now need to add `controlled=True` for it to work properly on its own.
811
- Added GitHub actions workflow for automated tests on PRs by @BSd3v
912

13+
1014
### Fixed
1115

1216
- Excluded the `loading_state` prop from being passed to the DOM. Added `data-dash-is-loading` attribute to

src/ts/components/core/chip/Chip.tsx

Lines changed: 36 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -38,33 +38,61 @@ interface Props
3838
disabled?: boolean;
3939
/** To be used with chip group */
4040
value?: string;
41+
/** Set to True when using as a single chip (not in a chip group). Default is False */
42+
controlled?: boolean;
4143
}
4244

43-
/** Chip */
45+
/**
46+
Chip for use with the ChipGroup.
47+
Must not set the `checked` prop because it conflicts with setting the value on the ChipGroup
48+
**/
4449
const Chip = (props: Props) => {
4550
const {
4651
children,
4752
setProps,
4853
persistence,
4954
persisted_props,
5055
persistence_type,
56+
checked,
57+
controlled,
58+
loading_state,
5159
...others
5260
} = props;
5361

5462
const onChange = (checked: boolean) => {
5563
setProps({ checked });
5664
};
57-
58-
return (
59-
<MantineChip onChange={onChange} {...others}>
60-
{children}
61-
</MantineChip>
62-
);
65+
if (controlled) {
66+
return (
67+
<MantineChip
68+
checked={checked}
69+
onChange={onChange}
70+
data-dash-is-loading={
71+
(loading_state && loading_state.is_loading) || undefined
72+
}
73+
{...others}
74+
>
75+
{children}
76+
</MantineChip>
77+
);
78+
} else {
79+
return (
80+
<MantineChip
81+
data-dash-is-loading={
82+
(loading_state && loading_state.is_loading) || undefined
83+
}
84+
{...others}
85+
>
86+
{children}
87+
</MantineChip>
88+
);
89+
}
6390
};
6491

6592
Chip.defaultProps = {
6693
persisted_props: ["checked"],
6794
persistence_type: "local",
95+
controlled: false,
6896
};
6997

70-
export default Chip;
98+
export default Chip;
Lines changed: 21 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,13 @@
11
import { Chip } from "@mantine/core";
2+
import { useDidUpdate } from "@mantine/hooks";
23
import { DashBaseProps, PersistenceProps } from "props/dash";
34
import React, { useState } from "react";
45

56
interface Props extends DashBaseProps, PersistenceProps {
6-
/** Controlled component value */
7-
value?: string[];
7+
/** Determines whether it is allowed to select multiple values, `false` by default */
8+
multiple?: boolean;
9+
/** When using multiple=true, value must be a list */
10+
value?: string[] | string | null;
811
/** `Chip` components and any other elements */
912
children?: React.ReactNode;
1013
}
@@ -18,22 +21,28 @@ const ChipGroup = (props: Props) => {
1821
persistence,
1922
persisted_props,
2023
persistence_type,
24+
loading_state,
2125
...others
2226
} = props;
23-
2427
const [val, setVal] = useState(value);
2528

26-
// const onChange = (value: string[]) => {
27-
// setVal(value);
28-
// setProps({ value });
29-
// };
29+
useDidUpdate(() => {
30+
setVal(value);
31+
}, [value]);
3032

31-
// useEffect(() => {
32-
// setVal(value);
33-
// }, [value]);
33+
useDidUpdate(() => {
34+
setProps({ value: val });
35+
}, [val]);
3436

3537
return (
36-
<Chip.Group multiple value={val} onChange={setVal} {...others}>
38+
<Chip.Group
39+
value={val}
40+
onChange={setVal}
41+
data-dash-is-loading={
42+
(loading_state && loading_state.is_loading) || undefined
43+
}
44+
{...others}
45+
>
3746
{children}
3847
</Chip.Group>
3948
);
@@ -42,7 +51,6 @@ const ChipGroup = (props: Props) => {
4251
ChipGroup.defaultProps = {
4352
persisted_props: ["value"],
4453
persistence_type: "local",
45-
value: [],
4654
};
4755

48-
export default ChipGroup;
56+
export default ChipGroup;

src/ts/index.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -146,7 +146,7 @@ import NotificationProvider from "./components/extensions/notifications/Notifica
146146
import NavigationProgress from "./components/extensions/nprogress/NavigationProgress";
147147
import NavigationProgressProvider from "./components/extensions/nprogress/NavigationProgressProvider";
148148
import MantineProvider from "./components/styles/MantineProvider";
149-
// import ChipGroup from "./components/core/chip/ChipGroup";
149+
import ChipGroup from "./components/core/chip/ChipGroup";
150150

151151
export {
152152
Accordion,
@@ -187,6 +187,7 @@ export {
187187
Checkbox,
188188
CheckboxGroup,
189189
Chip,
190+
ChipGroup,
190191
Code,
191192
CodeHighlight,
192193
CodeHighlightTabs,

usage-chip.py

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
2+
import dash_mantine_components as dmc
3+
from dash import Dash, _dash_renderer, Input, Output
4+
from dash_iconify import DashIconify
5+
_dash_renderer._set_react_version("18.2.0")
6+
7+
8+
app = Dash(external_stylesheets=dmc.styles.ALL)
9+
10+
with_callback = dmc.Box([
11+
dmc.Text("Set chip with toggle button or clicking on chip", m="sm"),
12+
dmc.Button("toggle", id="btn-chip", n_clicks=0, mb="sm"),
13+
dmc.Chip("awesome chip", checked=True, id="chip", controlled=True),
14+
dmc.Text(id="chip-container"),
15+
], p=20)
16+
17+
icon = dmc.Chip("Forbidden", icon=DashIconify(icon="bi-x-circle"), color="red", checked=True, m="sm", controlled=True)
18+
19+
20+
tooltip = dmc.Tooltip(
21+
label="chip tooltip",
22+
# refProp="rootRef", Need to update Tootlip to add this prop but still works ok
23+
children=dmc.Chip("chip with tooltip", controlled=True)
24+
)
25+
26+
add_props_to_root = dmc.Chip(
27+
"Chip with props added to root" ,
28+
wrapperProps={'data-testid': 'wrapper'},
29+
checked=True,
30+
controlled=True
31+
)
32+
33+
34+
35+
app.layout = dmc.MantineProvider([
36+
with_callback,
37+
dmc.Divider(my="lg"),
38+
icon,
39+
dmc.Divider(my="lg"),
40+
tooltip,
41+
dmc.Divider(my="lg"),
42+
add_props_to_root
43+
])
44+
45+
46+
@app.callback(
47+
Output("chip", "checked"),
48+
Input("btn-chip", "n_clicks")
49+
)
50+
def update(n):
51+
if n %2 == 0:
52+
return True
53+
return False
54+
55+
56+
@app.callback(
57+
Output("chip-container", "children"),
58+
Input("chip", "checked")
59+
)
60+
def update(checked):
61+
return f"You selected: {checked}"
62+
63+
if __name__ == "__main__":
64+
app.run(debug=True)

usage-chipgroup-multiple.py

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
2+
import dash_mantine_components as dmc
3+
from dash import Dash, _dash_renderer, Input, Output
4+
_dash_renderer._set_react_version("18.2.0")
5+
6+
7+
app = Dash(external_stylesheets=dmc.styles.ALL)
8+
9+
chip_group = dmc.ChipGroup(
10+
children=dmc.Group([
11+
dmc.Chip("Chip a", value="a"),
12+
dmc.Chip("Chip b", value="b")
13+
]),
14+
#value=["a", "b"],
15+
id ="chip-group",
16+
multiple=True
17+
)
18+
19+
with_callback = dmc.Box([
20+
dmc.Text("Multiple chips can be set at one time"),
21+
dmc.Text("Set chip with toggle button or clicking on chip"),
22+
dmc.Button("toggle group", id="btn-chip-group", n_clicks=0 ,m="sm"),
23+
chip_group,
24+
dmc.Text(id="chip-group-container"),
25+
], p=20)
26+
27+
app.layout = dmc.MantineProvider(
28+
with_callback
29+
)
30+
31+
@app.callback(
32+
Output("chip-group", "value"),
33+
Input("btn-chip-group", "n_clicks")
34+
)
35+
def update(n):
36+
if n % 2 == 0:
37+
return ["a", "b"]
38+
return []
39+
40+
41+
@app.callback(
42+
Output("chip-group-container", "children"),
43+
Input("chip-group", "value")
44+
)
45+
def update(checked):
46+
return f"You selected: {checked}"
47+
48+
49+
if __name__ == "__main__":
50+
app.run(debug=True)

usage-chipgroup.py

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
2+
import dash_mantine_components as dmc
3+
from dash import Dash, _dash_renderer, Input, Output
4+
_dash_renderer._set_react_version("18.2.0")
5+
6+
7+
app = Dash(external_stylesheets=dmc.styles.ALL)
8+
9+
chip_group = dmc.ChipGroup(
10+
children=dmc.Group([
11+
dmc.Chip("Chip a", value="a"),
12+
dmc.Chip("Chip b", value="b")
13+
]),
14+
value="a",
15+
id ="chip-group",
16+
multiple=True
17+
)
18+
19+
20+
with_callback = dmc.Box([
21+
dmc.Text("Single Chip can be set at a time"),
22+
dmc.Text("Set chip with toggle button or clicking on chip"),
23+
dmc.Button("toggle", id="btn-chip-group", n_clicks=0 , m="sm"),
24+
chip_group,
25+
dmc.Text(id="chip-group-container"),
26+
], p=20)
27+
28+
app.layout = dmc.MantineProvider([
29+
with_callback,
30+
])
31+
32+
@app.callback(
33+
Output("chip-group", "value"),
34+
Input("btn-chip-group", "n_clicks")
35+
)
36+
def update(n):
37+
if n % 2 == 0:
38+
return "a"
39+
return "b"
40+
41+
42+
@app.callback(
43+
Output("chip-group-container", "children"),
44+
Input("chip-group", "value")
45+
)
46+
def update(checked):
47+
return f"You selected: {checked}"
48+
49+
50+
if __name__ == "__main__":
51+
app.run(debug=True)

0 commit comments

Comments
 (0)