Skip to content

Commit a99cf66

Browse files
authored
Merge pull request #263 from eccenca/feature/align-intent-property-CMEM-6544
Add intent property to components that still use similar other ones to do the same (CMEM-6544)
2 parents 3f96e3a + 3af080f commit a99cf66

File tree

13 files changed

+129
-38
lines changed

13 files changed

+129
-38
lines changed

CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,10 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/) and this p
66

77
## [Unreleased]
88

9+
### Added
10+
11+
- `intent` property to `Button`, `FieldItem`, `FieldSet`, `Notification`, and `Spinner`
12+
913
## [24.1.0] - 2025-04-16
1014

1115
### Added

src/components/Button/Button.stories.tsx

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,10 @@ export default {
1818
onClick: {
1919
action: "clicked",
2020
},
21+
intent: {
22+
...helpersArgTypes.exampleIntent,
23+
options: ["UNDEFINED", "primary", "success", "warning", "danger"],
24+
},
2125
},
2226
} as Meta<typeof Button>;
2327

@@ -67,17 +71,17 @@ const TemplateSemantic: StoryFn<typeof Button> = (args) => (
6771
export const ButtonSemantics = TemplateSemantic.bind({});
6872
ButtonSemantics.args = FullExample.args;
6973

70-
const TemplateState: StoryFn<typeof Button> = (args) => (
74+
const TemplateIntent: StoryFn<typeof Button> = (args) => (
7175
<OverlaysProvider>
72-
<Button {...args} text="Success" hasStateSuccess />
76+
<Button {...args} text="Success" intent="success" />
7377
<Spacing vertical />
74-
<Button {...args} text="Warning" hasStateWarning />
78+
<Button {...args} text="Warning" intent="warning" />
7579
<Spacing vertical />
76-
<Button {...args} text="Danger" hasStateDanger />
80+
<Button {...args} text="Danger" intent="danger" />
7781
</OverlaysProvider>
7882
);
79-
export const ButtonStates = TemplateState.bind({});
80-
ButtonStates.args = FullExample.args;
83+
export const ButtonIntent = TemplateIntent.bind({});
84+
ButtonIntent.args = FullExample.args;
8185

8286
const TemplateContent: StoryFn<typeof Button> = (args) => (
8387
<OverlaysProvider>

src/components/Button/Button.tsx

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -32,18 +32,22 @@ interface AdditionalButtonProps {
3232
elevated?: boolean;
3333
/**
3434
* The button is displayed with primary color scheme.
35+
* @deprecated (v25) use `intent="primary"` instead.
3536
*/
3637
hasStatePrimary?: boolean;
3738
/**
3839
* The button is displayed with success (some type of green) color scheme.
40+
* @deprecated (v25) use `intent="success"` instead.
3941
*/
4042
hasStateSuccess?: boolean;
4143
/**
4244
* The button is displayed with warning (some type of orange) color scheme.
45+
* @deprecated (v25) use `intent="warning"` instead.
4346
*/
4447
hasStateWarning?: boolean;
4548
/**
4649
* The button is displayed with danger (some type of red) color scheme.
50+
* @deprecated (v25) use `intent="danger"` instead.
4751
*/
4852
hasStateDanger?: boolean;
4953
/**
@@ -100,6 +104,7 @@ export const Button = ({
100104
tooltipProps,
101105
badge,
102106
badgeProps = { size: "small", position: "top-right", maxLength: 2 },
107+
intent,
103108
...restProps
104109
}: ButtonProps) => {
105110
let intention;
@@ -120,13 +125,13 @@ export const Button = ({
120125
break;
121126
}
122127

123-
const ButtonType: any = restProps.href ? BlueprintAnchorButton : BlueprintButton;
128+
const ButtonType = restProps.href ? BlueprintAnchorButton : BlueprintButton;
124129

125130
const button = (
126131
<ButtonType
127132
{...restProps}
128133
className={`${eccgui}-button ` + className}
129-
intent={intention}
134+
intent={(intent || intention) as BlueprintIntent}
130135
icon={typeof icon === "string" ? <Icon name={icon} /> : icon}
131136
rightIcon={typeof rightIcon === "string" ? <Icon name={rightIcon} /> : rightIcon}
132137
>

src/components/Form/FieldItem.tsx

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import React from "react";
22

3-
import { ClassNames as IntentClassNames } from "../../common/Intent";
3+
import { ClassNames as IntentClassNames, IntentTypes } from "../../common/Intent";
44
import { CLASSPREFIX as eccgui } from "../../configuration/constants";
55
import { TestableComponent } from "../interfaces";
66
import Label, { LabelProps } from "../Label/Label";
@@ -18,23 +18,31 @@ export interface FieldItemProps extends React.HTMLAttributes<HTMLDivElement>, Te
1818
/**
1919
* Set primary state.
2020
* This is not routed through automatically.
21+
* @deprecated (v25) use `intent="primary"` instead.
2122
*/
2223
hasStatePrimary?: boolean;
2324
/**
2425
* Set success state.
2526
* This is not routed through automatically.
27+
* @deprecated (v25) use `intent="success"` instead.
2628
*/
2729
hasStateSuccess?: boolean;
2830
/**
2931
* Set warning state.
3032
* This is not routed through automatically.
33+
* @deprecated (v25) use `intent="warning"` instead.
3134
*/
3235
hasStateWarning?: boolean;
3336
/**
3437
* Set danger state.
3538
* This is not routed through automatically.
39+
* @deprecated (v25) use `intent="danger"` instead.
3640
*/
3741
hasStateDanger?: boolean;
42+
/**
43+
* Intent state of the field item.
44+
*/
45+
intent?: IntentTypes;
3846
/**
3947
* Is disabled.
4048
* The included inout element nedd to set disabled directly itself.
@@ -71,6 +79,7 @@ export const FieldItem = ({
7179
labelProps,
7280
helperText,
7381
messageText,
82+
intent,
7483
...otherProps
7584
}: FieldItemProps) => {
7685
let classIntent = "";
@@ -91,6 +100,8 @@ export const FieldItem = ({
91100
break;
92101
}
93102

103+
const intentClass = intent ? " " + IntentClassNames[intent.toUpperCase()] : "";
104+
94105
const label = <Label {...labelProps} disabled={disabled} />;
95106

96107
const userhelp =
@@ -106,9 +117,9 @@ export const FieldItem = ({
106117
const notification =
107118
messageText &&
108119
(typeof messageText === "string" ? (
109-
<p className={`${eccgui}-fielditem__message` + classIntent}>{messageText}</p>
120+
<p className={`${eccgui}-fielditem__message` + (intentClass || classIntent)}>{messageText}</p>
110121
) : (
111-
<div className={`${eccgui}-fielditem__message` + classIntent}>{messageText}</div>
122+
<div className={`${eccgui}-fielditem__message` + (intentClass || classIntent)}>{messageText}</div>
112123
));
113124

114125
return (

src/components/Form/FieldSet.tsx

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import React from "react";
22

3-
import { ClassNames as IntentClassNames } from "../../common/Intent";
3+
import { ClassNames as IntentClassNames, IntentTypes } from "../../common/Intent";
44
import { CLASSPREFIX as eccgui } from "../../configuration/constants";
55

66
export interface FieldSetProps extends Omit<React.FieldsetHTMLAttributes<HTMLFieldSetElement>, "title"> {
@@ -11,20 +11,28 @@ export interface FieldSetProps extends Omit<React.FieldsetHTMLAttributes<HTMLFie
1111
boxed?: boolean;
1212
/**
1313
* The fieldsetsection is displayed with primary color scheme.
14+
* @deprecated (v25) use `intent="primary"` instead.
1415
*/
1516
hasStatePrimary?: boolean;
1617
/**
1718
* The fieldset section is displayed with success (some type of green) color scheme.
19+
* @deprecated (v25) use `intent="success"` instead.
1820
*/
1921
hasStateSuccess?: boolean;
2022
/**
2123
* The fieldset section is displayed with warning (some type of orange) color scheme.
24+
* @deprecated (v25) use `intent="warning"` instead.
2225
*/
2326
hasStateWarning?: boolean;
2427
/**
2528
* The fieldsetsection is displayed with danger (some type of red) color scheme.
29+
* @deprecated (v25) use `intent="danger"` instead.
2630
*/
2731
hasStateDanger?: boolean;
32+
/**
33+
* Intent state of the field item.
34+
*/
35+
intent?: IntentTypes;
2836
/**
2937
* Optional helper text. If given then it is displayed after the title.
3038
*/
@@ -52,6 +60,7 @@ export const FieldSet = ({
5260
hasStateSuccess = false,
5361
hasStateWarning = false,
5462
hasStateDanger = false,
63+
intent,
5564
helperText,
5665
messageText,
5766
title,
@@ -75,6 +84,8 @@ export const FieldSet = ({
7584
break;
7685
}
7786

87+
const intentClass = intent ? " " + IntentClassNames[intent.toUpperCase()] : "";
88+
7889
const userhelp =
7990
helperText &&
8091
(typeof helperText === "string" ? (
@@ -98,7 +109,7 @@ export const FieldSet = ({
98109
className={
99110
`${eccgui}-fieldset` +
100111
(className ? " " + className : "") +
101-
classIntent +
112+
(intentClass || classIntent) +
102113
(boxed ? ` ${eccgui}-fieldset--boxed` : "")
103114
}
104115
{...otherProps}

src/components/Form/Stories/FieldItem.stories.tsx

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import React from "react";
22
import { LoremIpsum } from "react-lorem-ipsum";
33
import { Meta, StoryFn } from "@storybook/react";
44

5+
import { helpersArgTypes } from "../../../../.storybook/helpers";
56
import { FieldItem, TextField } from "../../../../index";
67

78
export default {
@@ -11,6 +12,9 @@ export default {
1112
children: {
1213
control: "none",
1314
},
15+
intent: {
16+
...helpersArgTypes.exampleIntent,
17+
},
1418
},
1519
} as Meta<typeof FieldItem>;
1620

src/components/Form/Stories/FieldSet.stories.tsx

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import React from "react";
22
import { LoremIpsum } from "react-lorem-ipsum";
33
import { Meta, StoryFn } from "@storybook/react";
44

5+
import { helpersArgTypes } from "../../../../.storybook/helpers";
56
import { FieldItem, FieldItemRow, FieldSet, TitleSubsection } from "../../../../index";
67

78
import { Default as SimpleFieldItemExample } from "./FieldItem.stories";
@@ -14,6 +15,9 @@ export default {
1415
children: {
1516
control: "none",
1617
},
18+
intent: {
19+
...helpersArgTypes.exampleIntent,
20+
},
1721
},
1822
} as Meta<typeof FieldSet>;
1923

src/components/MultiSelect/MultiSelect.tsx

Lines changed: 27 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -78,20 +78,28 @@ interface MultiSelectCommonProps<T>
7878
* Items that were newly created and not taken from the list will be post-fixed with this string.
7979
*/
8080
newItemPostfix?: string;
81+
/**
82+
* Intent state of the multi select.
83+
*/
84+
intent?: BlueprintIntent;
8185
/**
8286
* The input element is displayed with primary color scheme.
87+
* @deprecated (v25) use `intent="primary"` instead.
8388
*/
8489
hasStatePrimary?: boolean;
8590
/**
8691
* The input element is displayed with success (some type of green) color scheme.
92+
* @deprecated (v25) use `intent="success"` instead.
8793
*/
8894
hasStateSuccess?: boolean;
8995
/**
90-
* The input element is displayed with success (some type of orange) color scheme.
96+
* The input element is displayed with warning (some type of orange) color scheme.
97+
* @deprecated (v25) use `intent="warning"` instead.
9198
*/
9299
hasStateWarning?: boolean;
93100
/**
94-
* The input element is displayed with success (some type of red) color scheme.
101+
* The input element is displayed with danger (some type of red) color scheme.
102+
* @deprecated (v25) use `intent="danger"` instead.
95103
*/
96104
hasStateDanger?: boolean;
97105
/**
@@ -179,6 +187,7 @@ function MultiSelect<T>({
179187
wrapperProps,
180188
searchPredicate,
181189
limitHeightOpened,
190+
intent,
182191
...otherMultiSelectProps
183192
}: MultiSelectProps<T>) {
184193
// Options created by a user
@@ -203,19 +212,19 @@ function MultiSelect<T>({
203212
timeoutId?: number;
204213
}>({});
205214

206-
let intent;
215+
let stateIntent;
207216
switch (true) {
208217
case hasStatePrimary:
209-
intent = BlueprintIntent.PRIMARY;
218+
stateIntent = BlueprintIntent.PRIMARY;
210219
break;
211220
case hasStateSuccess:
212-
intent = BlueprintIntent.SUCCESS;
221+
stateIntent = BlueprintIntent.SUCCESS;
213222
break;
214223
case hasStateWarning:
215-
intent = BlueprintIntent.WARNING;
224+
stateIntent = BlueprintIntent.WARNING;
216225
break;
217226
case hasStateDanger:
218-
intent = BlueprintIntent.DANGER;
227+
stateIntent = BlueprintIntent.DANGER;
219228
break;
220229
default:
221230
break;
@@ -230,12 +239,11 @@ function MultiSelect<T>({
230239
}, [items.map((item) => itemId(item)).join("|")]);
231240

232241
React.useEffect(() => {
233-
onSelection &&
234-
onSelection({
235-
newlySelected: selectedItems.slice(-1)[0],
236-
createdItems: createdItems.current,
237-
selectedItems,
238-
});
242+
onSelection?.({
243+
newlySelected: selectedItems.slice(-1)[0],
244+
createdItems: createdItems.current,
245+
selectedItems,
246+
});
239247
}, [
240248
onSelection,
241249
selectedItems.map((item) => itemId(item)).join("|"),
@@ -430,7 +438,11 @@ function MultiSelect<T>({
430438
const handleOnKeyDown = (event: React.KeyboardEvent<HTMLElement>) => {
431439
if (event.key === "Tab" && !!requestState.current.query) {
432440
event.preventDefault();
433-
focusedItem ? onItemSelect(focusedItem) : onItemSelect(createNewItem(requestState.current.query));
441+
if (focusedItem) {
442+
onItemSelect(focusedItem);
443+
} else {
444+
onItemSelect(createNewItem(requestState.current.query));
445+
}
434446
requestState.current.query = "";
435447
setTimeout(() => inputRef.current?.focus());
436448
}
@@ -511,7 +523,7 @@ function MultiSelect<T>({
511523
className: `${eccgui}-multiselect` + (className ? ` ${className}` : ""),
512524
fill: fullWidth,
513525
inputRef: inputRef,
514-
intent,
526+
intent: intent || stateIntent,
515527
addOnBlur: true,
516528
onKeyDown: handleOnKeyDown,
517529
onKeyUp: handleOnKeyUp,

src/components/MultiSuggestField/MultiSuggestField.stories.tsx

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@ import { OverlaysProvider } from "@blueprintjs/core";
44
import { Meta, StoryFn } from "@storybook/react";
55
import { fn } from "@storybook/test";
66

7+
import { helpersArgTypes } from "../../../.storybook/helpers";
8+
79
import { MultiSuggestField, MultiSuggestFieldSelectionProps, SimpleDialog } from "./../../../index";
810

911
const testLabels = loremIpsum({
@@ -29,6 +31,10 @@ export default {
2931
items: {
3032
control: "none",
3133
},
34+
intent: {
35+
...helpersArgTypes.exampleIntent,
36+
options: ["UNDEFINED", "primary", "success", "warning", "danger"],
37+
},
3238
},
3339
args: {
3440
onSelection: fn(),

src/components/Notification/Notification.stories.tsx

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,10 @@ export default {
1515
icon: {
1616
...helpersArgTypes.exampleIcon,
1717
},
18+
intent: {
19+
...helpersArgTypes.exampleIntent,
20+
options: ["UNDEFINED", "success", "warning", "danger", "neutral", "info"],
21+
},
1822
},
1923
} as Meta<typeof Notification>;
2024

0 commit comments

Comments
 (0)