Skip to content

Commit ffd849b

Browse files
committed
Some updates to item-select component
1 parent a097a2e commit ffd849b

File tree

6 files changed

+66
-27
lines changed

6 files changed

+66
-27
lines changed

packages/form-components/CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,9 @@
11
# Changelog
22

3+
## [0.2.1] - 2025-02-22
4+
5+
- `ItemSelect` component: add option to not fill width, and add active highlight
6+
37
## [0.2.0] - 2025-02-20
48

59
- Add `ItemSelect` component for general selections (items must have a `name`

packages/form-components/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@macrostrat/form-components",
3-
"version": "0.2.0",
3+
"version": "0.2.1",
44
"description": "Form components for user input into Macrostrat apps",
55
"type": "module",
66
"source": "src/index.ts",

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

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ export function BaseDataTypeSelect({ state, setState, ...rest }) {
4646
onSelectItem: setState,
4747
label: "data type",
4848
icon: "tag",
49-
itemComponent: ({ item, ...rest }) => {
49+
itemComponent: ({ item, selected, icon, ...rest }) => {
5050
return h(MenuItem, {
5151
icon: h(Box, {
5252
is: "span",
@@ -56,6 +56,7 @@ export function BaseDataTypeSelect({ state, setState, ...rest }) {
5656
borderRadius: "3px",
5757
}),
5858
text: item.name,
59+
active: selected,
5960
...rest,
6061
});
6162
},

packages/form-components/src/item-select/index.module.sass

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,13 @@
55
display: flex
66
flex-direction: row
77

8+
&.fill-width .target-select
9+
flex-grow: 1
10+
811
.target-select
912
list-style: none
1013
padding: 0
1114
margin: 0
12-
flex-grow: 1
15+
16+
.selected
17+
font-weight: 600

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

Lines changed: 41 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,9 @@
11
import hyper from "@macrostrat/hyper";
2-
import { IconName, MenuItem, Spinner, Button } from "@blueprintjs/core";
2+
import { IconName, MenuItem, Spinner, Button, Intent } from "@blueprintjs/core";
33
import { ComponentType, MouseEventHandler, ReactNode } from "react";
44
import { Select } from "@blueprintjs/select";
55
import styles from "./index.module.sass";
6+
import classNames from "classnames";
67

78
const h = hyper.styled(styles);
89

@@ -19,6 +20,7 @@ export function ItemSelect<T extends Nameable>({
1920
minimal = true,
2021
usePortal = true,
2122
nullable = false,
23+
fill = true,
2224
}: {
2325
items: T[] | null;
2426
selectedItem: T | null;
@@ -31,6 +33,7 @@ export function ItemSelect<T extends Nameable>({
3133
minimal?: boolean;
3234
usePortal?: boolean;
3335
nullable?: boolean;
36+
fill?: boolean;
3437
}) {
3538
let placeholder = `Select ${singularReferent(label)}`;
3639
let _icon: IconName | ReactNode = icon;
@@ -58,61 +61,75 @@ export function ItemSelect<T extends Nameable>({
5861
{
5962
items: items ?? [],
6063
itemRenderer: (item, { handleClick }) => {
61-
return h(itemComponent, { item, onClick: handleClick, icon });
64+
return h(itemComponent, {
65+
key: item.name,
66+
item,
67+
onClick: handleClick,
68+
icon,
69+
selected: selectedItem == item,
70+
});
6271
},
6372
onItemSelect: onSelectItem,
6473
popoverProps: {
6574
minimal,
6675
usePortal,
67-
matchTargetWidth: true,
76+
matchTargetWidth: fill,
6877
},
6978
filterable,
70-
fill: true,
79+
fill,
7180
},
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-
])
81+
h(
82+
"div.target-container",
83+
{
84+
className: classNames({ "fill-width": fill }),
85+
},
86+
[
87+
h("ul.target-select", content),
88+
h.if(nullable)(Button, {
89+
minimal: true,
90+
icon: "cross",
91+
intent: "danger",
92+
onClick(evt) {
93+
onSelectItem(null);
94+
evt.stopPropagation();
95+
},
96+
disabled: selectedItem == null,
97+
}),
98+
]
99+
)
85100
)
86101
);
87102
}
88103

89104
interface Nameable {
90105
name: string;
91106
icon?: IconName | ReactNode;
107+
intent?: Intent;
92108
}
93109

94110
interface ItemComponentProps<T> {
95111
item: T;
96112
className?: string;
97113
onClick?: MouseEventHandler<HTMLElement>;
98114
icon?: IconName | ReactNode;
115+
selected?: boolean;
116+
intent?: Intent;
99117
}
100118

101119
function DefaultItemComponent<T extends Nameable>({
102120
item,
103121
className,
104122
onClick,
105123
icon,
106-
}: {
107-
item: T;
108-
className?: string;
109-
onClick?: MouseEventHandler<HTMLElement>;
110-
icon?: IconName | ReactNode;
111-
}) {
124+
selected,
125+
intent,
126+
}: ItemComponentProps<T>) {
112127
return h(MenuItem, {
113128
icon: item.icon ?? icon,
114129
text: item.name,
115-
className,
130+
intent: item.intent ?? intent,
131+
className: classNames({ selected }),
132+
active: selected,
116133
onClick,
117134
});
118135
}

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

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,3 +43,15 @@ export function Nullable() {
4343
nullable: true,
4444
});
4545
}
46+
47+
export function NotFillArea() {
48+
const [state, setState] = useState<DataType | null>(null);
49+
return h(BaseDataTypeSelect, {
50+
state,
51+
setState(dt) {
52+
console.log(dt), setState(dt);
53+
},
54+
nullable: true,
55+
fill: false,
56+
});
57+
}

0 commit comments

Comments
 (0)