Skip to content

Commit 0f3730a

Browse files
committed
Allow item select to be nullable
1 parent f176d94 commit 0f3730a

File tree

4 files changed

+53
-10
lines changed

4 files changed

+53
-10
lines changed

packages/form-components/src/item-select/examples.ts

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -38,16 +38,16 @@ export const exampleMapLayers: MapLayer[] = [
3838
{ id: 5, name: "Layer 5" },
3939
];
4040

41-
export function BaseDataTypeSelect({ state, setState }) {
41+
export function BaseDataTypeSelect({ state, setState, ...rest }) {
4242
return h(ItemSelect<DataType>, {
43+
...rest,
4344
items: exampleDataTypes,
4445
selectedItem: state,
4546
onSelectItem: setState,
4647
label: "data type",
4748
icon: "tag",
4849
itemComponent: ({ item, ...rest }) => {
4950
return h(MenuItem, {
50-
...rest,
5151
icon: h(Box, {
5252
is: "span",
5353
width: "1em",
@@ -56,13 +56,15 @@ export function BaseDataTypeSelect({ state, setState }) {
5656
borderRadius: "3px",
5757
}),
5858
text: item.name,
59+
...rest,
5960
});
6061
},
6162
});
6263
}
6364

64-
export function BaseMapLayerSelect({ state, setState }) {
65+
export function BaseMapLayerSelect({ state, setState, ...rest }) {
6566
return h(ItemSelect<MapLayer>, {
67+
...rest,
6668
items: exampleMapLayers,
6769
selectedItem: state,
6870
onSelectItem: (layer) => {
Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,12 @@
1-
.placeholder
1+
.placeholder:global(.bp5-menu-item)
22
color: var(--secondary-color)
3+
4+
.target-container
5+
display: flex
6+
flex-direction: row
7+
8+
.target-select
9+
list-style: none
10+
padding: 0
11+
margin: 0
12+
flex-grow: 1

packages/form-components/src/item-select/index.ts

Lines changed: 26 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import hyper from "@macrostrat/hyper";
2-
import { IconName, Menu, MenuItem, Spinner } from "@blueprintjs/core";
2+
import { IconName, MenuItem, Spinner, Button } from "@blueprintjs/core";
33
import { ComponentType, MouseEventHandler, ReactNode } from "react";
44
import { Select } from "@blueprintjs/select";
55
import styles from "./index.module.sass";
@@ -15,14 +15,22 @@ export function ItemSelect<T extends Nameable>({
1515
icon = null,
1616
itemComponent = DefaultItemComponent,
1717
className,
18+
filterable = false,
19+
minimal = true,
20+
usePortal = true,
21+
nullable = false,
1822
}: {
1923
items: T[] | null;
2024
selectedItem: T | null;
21-
onSelectItem(item: T): void;
25+
onSelectItem(item: T | null): void;
2226
label: string;
2327
icon: IconName | ReactNode | null;
2428
itemComponent?: ComponentType<ItemComponentProps<T>>;
2529
className?: string;
30+
filterable?: boolean;
31+
minimal?: boolean;
32+
usePortal?: boolean;
33+
nullable?: boolean;
2634
}) {
2735
let placeholder = `Select ${singularReferent(label)}`;
2836
let _icon: IconName | ReactNode = icon;
@@ -54,14 +62,26 @@ export function ItemSelect<T extends Nameable>({
5462
},
5563
onItemSelect: onSelectItem,
5664
popoverProps: {
57-
minimal: true,
58-
usePortal: false,
65+
minimal,
66+
usePortal,
5967
matchTargetWidth: true,
6068
},
61-
filterable: false,
69+
filterable,
6270
fill: true,
6371
},
64-
h(Menu, content)
72+
h("div.target-container", [
73+
h("ul.target-select", content),
74+
h.if(nullable)(Button, {
75+
minimal: true,
76+
icon: "cross",
77+
intent: "danger",
78+
onClick(evt) {
79+
onSelectItem(null);
80+
evt.stopPropagation();
81+
},
82+
disabled: selectedItem == null,
83+
}),
84+
])
6585
)
6686
);
6787
}

packages/form-components/src/item-select/item-select.stories.ts

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,3 +32,14 @@ export function DataTypeSelect() {
3232
const [state, setState] = useState<DataType | null>(null);
3333
return h(BaseDataTypeSelect, { state, setState });
3434
}
35+
36+
export function Nullable() {
37+
const [state, setState] = useState<DataType | null>(null);
38+
return h(BaseDataTypeSelect, {
39+
state,
40+
setState(dt) {
41+
console.log(dt), setState(dt);
42+
},
43+
nullable: true,
44+
});
45+
}

0 commit comments

Comments
 (0)