@eccenca/gui-elements 23.2.0-rc.0 → 23.2.0-rc.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +28 -3
- package/dist/cjs/components/AutoSuggestion/AutoSuggestion.js +24 -20
- package/dist/cjs/components/AutoSuggestion/AutoSuggestion.js.map +1 -1
- package/dist/cjs/components/AutocompleteField/AutoCompleteField.js +59 -50
- package/dist/cjs/components/AutocompleteField/AutoCompleteField.js.map +1 -1
- package/dist/cjs/components/AutocompleteField/autoCompleteFieldUtils.js +3 -3
- package/dist/cjs/components/AutocompleteField/autoCompleteFieldUtils.js.map +1 -1
- package/dist/cjs/components/Breadcrumb/BreadcrumbItem.js +9 -6
- package/dist/cjs/components/Breadcrumb/BreadcrumbItem.js.map +1 -1
- package/dist/cjs/components/CodeAutocompleteField/CodeAutocompleteField.js +33 -0
- package/dist/cjs/components/CodeAutocompleteField/CodeAutocompleteField.js.map +1 -0
- package/dist/cjs/components/CodeAutocompleteField/index.js +14 -0
- package/dist/cjs/components/CodeAutocompleteField/index.js.map +1 -0
- package/dist/cjs/components/Depiction/Depiction.js +13 -13
- package/dist/cjs/components/Depiction/Depiction.js.map +1 -1
- package/dist/cjs/components/Icon/IconButton.js +9 -3
- package/dist/cjs/components/Icon/IconButton.js.map +1 -1
- package/dist/cjs/components/Icon/canonicalIconNames.js +2 -0
- package/dist/cjs/components/Icon/canonicalIconNames.js.map +1 -1
- package/dist/cjs/components/MultiSelect/MultiSelect.js +45 -17
- package/dist/cjs/components/MultiSelect/MultiSelect.js.map +1 -1
- package/dist/cjs/components/MultiSuggestField/MultiSuggestField.js +33 -0
- package/dist/cjs/components/MultiSuggestField/MultiSuggestField.js.map +1 -0
- package/dist/cjs/components/OverviewItem/OverviewItem.js +8 -10
- package/dist/cjs/components/OverviewItem/OverviewItem.js.map +1 -1
- package/dist/cjs/components/PropertyValuePair/PropertyName.js +4 -3
- package/dist/cjs/components/PropertyValuePair/PropertyName.js.map +1 -1
- package/dist/cjs/components/Select/Select.js +17 -3
- package/dist/cjs/components/Select/Select.js.map +1 -1
- package/dist/cjs/components/SuggestField/SuggestField.js +39 -0
- package/dist/cjs/components/SuggestField/SuggestField.js.map +1 -0
- package/dist/cjs/components/SuggestField/index.js +19 -0
- package/dist/cjs/components/SuggestField/index.js.map +1 -0
- package/dist/cjs/components/index.js +3 -0
- package/dist/cjs/components/index.js.map +1 -1
- package/dist/cjs/extensions/react-flow/nodes/NodeContent.js +54 -41
- package/dist/cjs/extensions/react-flow/nodes/NodeContent.js.map +1 -1
- package/dist/cjs/index.js +1 -0
- package/dist/cjs/index.js.map +1 -1
- package/dist/esm/components/AutoSuggestion/AutoSuggestion.js +23 -18
- package/dist/esm/components/AutoSuggestion/AutoSuggestion.js.map +1 -1
- package/dist/esm/components/AutocompleteField/AutoCompleteField.js +68 -59
- package/dist/esm/components/AutocompleteField/AutoCompleteField.js.map +1 -1
- package/dist/esm/components/AutocompleteField/autoCompleteFieldUtils.js +3 -3
- package/dist/esm/components/AutocompleteField/autoCompleteFieldUtils.js.map +1 -1
- package/dist/esm/components/Breadcrumb/BreadcrumbItem.js +9 -6
- package/dist/esm/components/Breadcrumb/BreadcrumbItem.js.map +1 -1
- package/dist/esm/components/CodeAutocompleteField/CodeAutocompleteField.js +37 -0
- package/dist/esm/components/CodeAutocompleteField/CodeAutocompleteField.js.map +1 -0
- package/dist/esm/components/CodeAutocompleteField/index.js +2 -0
- package/dist/esm/components/CodeAutocompleteField/index.js.map +1 -0
- package/dist/esm/components/Depiction/Depiction.js +12 -12
- package/dist/esm/components/Depiction/Depiction.js.map +1 -1
- package/dist/esm/components/Icon/IconButton.js +10 -4
- package/dist/esm/components/Icon/IconButton.js.map +1 -1
- package/dist/esm/components/Icon/canonicalIconNames.js +2 -0
- package/dist/esm/components/Icon/canonicalIconNames.js.map +1 -1
- package/dist/esm/components/MultiSelect/MultiSelect.js +52 -22
- package/dist/esm/components/MultiSelect/MultiSelect.js.map +1 -1
- package/dist/esm/components/MultiSuggestField/MultiSuggestField.js +37 -0
- package/dist/esm/components/MultiSuggestField/MultiSuggestField.js.map +1 -0
- package/dist/esm/components/OverviewItem/OverviewItem.js +8 -10
- package/dist/esm/components/OverviewItem/OverviewItem.js.map +1 -1
- package/dist/esm/components/PropertyValuePair/PropertyName.js +4 -3
- package/dist/esm/components/PropertyValuePair/PropertyName.js.map +1 -1
- package/dist/esm/components/Select/Select.js +18 -4
- package/dist/esm/components/Select/Select.js.map +1 -1
- package/dist/esm/components/SuggestField/SuggestField.js +43 -0
- package/dist/esm/components/SuggestField/SuggestField.js.map +1 -0
- package/dist/esm/components/SuggestField/index.js +6 -0
- package/dist/esm/components/SuggestField/index.js.map +1 -0
- package/dist/esm/components/index.js +3 -0
- package/dist/esm/components/index.js.map +1 -1
- package/dist/esm/extensions/react-flow/nodes/NodeContent.js +51 -39
- package/dist/esm/extensions/react-flow/nodes/NodeContent.js.map +1 -1
- package/dist/esm/index.js +2 -1
- package/dist/esm/index.js.map +1 -1
- package/dist/types/components/AutoSuggestion/AutoSuggestion.d.ts +35 -4
- package/dist/types/components/AutocompleteField/AutoCompleteField.d.ts +23 -6
- package/dist/types/components/AutocompleteField/autoCompleteFieldUtils.d.ts +3 -3
- package/dist/types/components/AutocompleteField/index.d.ts +1 -1
- package/dist/types/components/AutocompleteField/interfaces.d.ts +1 -1
- package/dist/types/components/CodeAutocompleteField/CodeAutocompleteField.d.ts +10 -0
- package/dist/types/components/CodeAutocompleteField/index.d.ts +1 -0
- package/dist/types/components/Icon/IconButton.d.ts +2 -2
- package/dist/types/components/Icon/canonicalIconNames.d.ts +1 -1
- package/dist/types/components/MultiSelect/MultiSelect.d.ts +20 -2
- package/dist/types/components/MultiSuggestField/MultiSuggestField.d.ts +10 -0
- package/dist/types/components/PropertyValuePair/PropertyName.d.ts +5 -1
- package/dist/types/components/Select/Select.d.ts +28 -9
- package/dist/types/components/SuggestField/SuggestField.d.ts +16 -0
- package/dist/types/components/SuggestField/index.d.ts +5 -0
- package/dist/types/components/index.d.ts +3 -0
- package/dist/types/extensions/react-flow/nodes/NodeContent.d.ts +7 -7
- package/dist/types/index.d.ts +2 -1
- package/package.json +1 -1
- package/src/components/AutoSuggestion/AutoSuggestion.stories.tsx +14 -0
- package/src/components/AutoSuggestion/AutoSuggestion.tsx +280 -221
- package/src/components/AutocompleteField/AutoCompleteField.stories.tsx +14 -0
- package/src/components/AutocompleteField/AutoCompleteField.tsx +157 -121
- package/src/components/AutocompleteField/autoCompleteFieldUtils.tsx +10 -16
- package/src/components/AutocompleteField/interfaces.ts +5 -6
- package/src/components/Breadcrumb/BreadcrumbItem.tsx +19 -18
- package/src/components/Breadcrumb/breadcrumb.scss +18 -16
- package/src/components/Breadcrumb/stories/BreadcrumbList.stories.tsx +18 -15
- package/src/components/CodeAutocompleteField/CodeAutocompleteField.stories.tsx +89 -0
- package/src/components/CodeAutocompleteField/CodeAutocompleteField.tsx +22 -0
- package/src/components/CodeAutocompleteField/index.ts +1 -0
- package/src/components/ContextOverlay/contextoverlay.scss +10 -2
- package/src/components/Depiction/Depiction.tsx +57 -55
- package/src/components/Icon/IconButton.tsx +25 -11
- package/src/components/Icon/canonicalIconNames.tsx +4 -0
- package/src/components/MultiSelect/MultiSelect.stories.tsx +9 -47
- package/src/components/MultiSelect/MultiSelect.tsx +110 -66
- package/src/components/MultiSuggestField/MultiSuggestField.stories.tsx +58 -0
- package/src/components/MultiSuggestField/MultiSuggestField.tsx +22 -0
- package/src/components/Notification/notification.scss +20 -17
- package/src/components/OverviewItem/OverviewItem.tsx +11 -20
- package/src/components/PropertyValuePair/PropertyName.tsx +17 -4
- package/src/components/PropertyValuePair/propertyvalue.scss +17 -1
- package/src/components/Select/Select.stories.tsx +49 -20
- package/src/components/Select/Select.tsx +93 -18
- package/src/components/Select/_select.scss +13 -1
- package/src/components/SuggestField/SuggestField.stories.tsx +99 -0
- package/src/components/SuggestField/SuggestField.tsx +28 -0
- package/src/components/SuggestField/index.ts +5 -0
- package/src/components/TagInput/taginput.scss +14 -0
- package/src/components/index.scss +1 -1
- package/src/components/index.ts +3 -0
- package/src/extensions/react-flow/nodes/NodeContent.tsx +105 -87
- package/src/index.ts +2 -5
- package/src/components/AutoSuggestion/stories/AutoSuggestion.stories.tsx +0 -83
- package/src/components/AutocompleteField/stories/AutoCompleteField.stories.tsx +0 -86
|
@@ -11,23 +11,23 @@
|
|
|
11
11
|
}
|
|
12
12
|
|
|
13
13
|
& > li::after {
|
|
14
|
-
background: none;
|
|
15
|
-
margin: 0;
|
|
16
|
-
height: auto;
|
|
17
|
-
width: auto;
|
|
18
14
|
display: inline-block;
|
|
19
|
-
|
|
20
|
-
|
|
15
|
+
flex-shrink: 0;
|
|
16
|
+
width: auto;
|
|
21
17
|
width: $eccgui-size-block-whitespace;
|
|
18
|
+
height: auto;
|
|
19
|
+
margin: 0;
|
|
22
20
|
text-align: center;
|
|
23
|
-
|
|
21
|
+
vertical-align: middle;
|
|
22
|
+
content: "/";
|
|
23
|
+
background: none;
|
|
24
24
|
}
|
|
25
25
|
|
|
26
26
|
.#{$ns}-breadcrumbs-collapsed {
|
|
27
27
|
padding: 0;
|
|
28
28
|
margin: 0;
|
|
29
29
|
|
|
30
|
-
|
|
30
|
+
&::before {
|
|
31
31
|
width: $eccgui-size-block-whitespace * 2;
|
|
32
32
|
height: $eccgui-size-block-whitespace;
|
|
33
33
|
background-image: url("~@carbon/icons/svg/32/overflow-menu--horizontal.svg");
|
|
@@ -49,30 +49,32 @@
|
|
|
49
49
|
}
|
|
50
50
|
|
|
51
51
|
.#{$eccgui}-breadcrumb__item > * {
|
|
52
|
-
|
|
52
|
+
display: inline;
|
|
53
53
|
overflow: hidden;
|
|
54
|
+
text-overflow: ellipsis;
|
|
54
55
|
vertical-align: middle;
|
|
55
|
-
display: inline;
|
|
56
56
|
}
|
|
57
57
|
}
|
|
58
58
|
|
|
59
59
|
.#{$eccgui}-breadcrumb__item {
|
|
60
|
-
|
|
60
|
+
display: inline-block;
|
|
61
61
|
overflow: hidden;
|
|
62
|
+
font-size: inherit;
|
|
62
63
|
text-overflow: ellipsis;
|
|
63
|
-
|
|
64
|
+
|
|
65
|
+
a {
|
|
66
|
+
@extend .#{$eccgui}-breadcrumb__item;
|
|
67
|
+
@extend .#{$ns}-breadcrumb;
|
|
68
|
+
}
|
|
64
69
|
}
|
|
65
70
|
|
|
66
71
|
a.#{$eccgui}-breadcrumb__item {
|
|
67
72
|
&:not(.#{$ns}-breadcrumb-current):not(.#{$ns}-disabled) {
|
|
68
73
|
text-decoration: underline;
|
|
74
|
+
|
|
69
75
|
&:hover,
|
|
70
76
|
&:focus {
|
|
71
77
|
text-decoration: none;
|
|
72
78
|
}
|
|
73
79
|
}
|
|
74
|
-
a {
|
|
75
|
-
@extend .#{$eccgui}-breadcrumb__item;
|
|
76
|
-
@extend .#{$ns}-breadcrumb;
|
|
77
|
-
}
|
|
78
80
|
}
|
|
@@ -1,27 +1,30 @@
|
|
|
1
1
|
import React from "react";
|
|
2
|
-
import {
|
|
3
|
-
|
|
2
|
+
import { Meta, StoryFn } from "@storybook/react";
|
|
3
|
+
|
|
4
|
+
import { BreadcrumbItem, BreadcrumbList } from "./../../../index";
|
|
4
5
|
|
|
5
6
|
export default {
|
|
6
7
|
title: "Components/Breadcrumbs/List",
|
|
7
8
|
component: BreadcrumbList,
|
|
8
9
|
subcomponents: { BreadcrumbItem },
|
|
9
|
-
argTypes: {
|
|
10
|
-
|
|
11
|
-
} as ComponentMeta<typeof BreadcrumbList>
|
|
10
|
+
argTypes: {},
|
|
11
|
+
} as Meta<typeof BreadcrumbList>;
|
|
12
12
|
|
|
13
|
-
const Template:
|
|
14
|
-
<BreadcrumbList {...args} />
|
|
15
|
-
);
|
|
13
|
+
const Template: StoryFn<typeof BreadcrumbList> = (args) => <BreadcrumbList {...args} />;
|
|
16
14
|
|
|
17
15
|
export const Default = Template.bind({});
|
|
18
16
|
Default.args = {
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
{text: "
|
|
22
|
-
{text:
|
|
23
|
-
{text: <
|
|
24
|
-
{
|
|
25
|
-
|
|
17
|
+
onItemClick: undefined,
|
|
18
|
+
items: [
|
|
19
|
+
{ text: "Non-click root page" },
|
|
20
|
+
{ text: "Main click category", onClick: () => alert("Breadcrumb click") },
|
|
21
|
+
{ text: <div>Sub category item</div>, href: "#" },
|
|
22
|
+
{
|
|
23
|
+
text: <span>Disabled breadcrumb with a very long title</span>,
|
|
24
|
+
disabled: true,
|
|
25
|
+
onClick: () => alert("Test click (should not be triggered)"),
|
|
26
|
+
},
|
|
27
|
+
{ text: <a href="#wrong">Wrongly placed link inside link</a> },
|
|
28
|
+
{ text: "Current breadcrumb item", current: true, href: "#" },
|
|
26
29
|
],
|
|
27
30
|
};
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
import { Meta, StoryFn } from "@storybook/react";
|
|
3
|
+
|
|
4
|
+
import { CodeAutocompleteField, CodeAutocompleteFieldProps } from "../../../index";
|
|
5
|
+
import { IPartialAutoCompleteResult } from "../AutoSuggestion/AutoSuggestion";
|
|
6
|
+
|
|
7
|
+
export default {
|
|
8
|
+
title: "Forms/CodeAutocompleteField",
|
|
9
|
+
component: CodeAutocompleteField,
|
|
10
|
+
argTypes: {},
|
|
11
|
+
} as Meta<typeof CodeAutocompleteField>;
|
|
12
|
+
|
|
13
|
+
const Template: StoryFn<typeof CodeAutocompleteField> = (args) => (
|
|
14
|
+
<CodeAutocompleteField {...args}></CodeAutocompleteField>
|
|
15
|
+
);
|
|
16
|
+
|
|
17
|
+
const resultList = ["find me", "item", "auto-completion result"];
|
|
18
|
+
|
|
19
|
+
const defaultProps: CodeAutocompleteFieldProps = {
|
|
20
|
+
initialValue: "",
|
|
21
|
+
fetchSuggestions(
|
|
22
|
+
inputString: string,
|
|
23
|
+
cursorPosition: number
|
|
24
|
+
): IPartialAutoCompleteResult | undefined | Promise<IPartialAutoCompleteResult | undefined> {
|
|
25
|
+
const stringBeforeCursor = inputString.substring(0, cursorPosition);
|
|
26
|
+
const lastSpaceIdx = stringBeforeCursor.lastIndexOf(" ");
|
|
27
|
+
const searchWordStart = lastSpaceIdx >= 0 ? lastSpaceIdx + 1 : 0;
|
|
28
|
+
const lastWordBeforeCursor = stringBeforeCursor
|
|
29
|
+
.substring(searchWordStart, stringBeforeCursor.length)
|
|
30
|
+
.toLowerCase()
|
|
31
|
+
.trim();
|
|
32
|
+
const replacements = resultList.filter((item) => item.toLowerCase().includes(lastWordBeforeCursor));
|
|
33
|
+
if (replacements.length) {
|
|
34
|
+
return {
|
|
35
|
+
cursorPosition: cursorPosition,
|
|
36
|
+
inputString: inputString,
|
|
37
|
+
replacementResults: [
|
|
38
|
+
{
|
|
39
|
+
extractedQuery: lastWordBeforeCursor,
|
|
40
|
+
replacementInterval: {
|
|
41
|
+
from: searchWordStart,
|
|
42
|
+
length: lastWordBeforeCursor.length,
|
|
43
|
+
},
|
|
44
|
+
replacements: replacements.map((v) => ({
|
|
45
|
+
label: `Label of '${v}'`,
|
|
46
|
+
description: `Description of '${v}'`,
|
|
47
|
+
value: v,
|
|
48
|
+
})),
|
|
49
|
+
},
|
|
50
|
+
],
|
|
51
|
+
};
|
|
52
|
+
}
|
|
53
|
+
},
|
|
54
|
+
placeholder:
|
|
55
|
+
"The word before the cursor will be auto-completed. At the beginning or after a space, all results are shown.",
|
|
56
|
+
onChange(): any {
|
|
57
|
+
// Do nothing
|
|
58
|
+
},
|
|
59
|
+
};
|
|
60
|
+
|
|
61
|
+
/** Offers basic auto-completion for the word right before the cursor. */
|
|
62
|
+
export const Default = Template.bind({});
|
|
63
|
+
|
|
64
|
+
Default.args = defaultProps;
|
|
65
|
+
|
|
66
|
+
/** Shows validation error if the input string contains the word 'not'. */
|
|
67
|
+
export const WithValidation = Template.bind({});
|
|
68
|
+
|
|
69
|
+
WithValidation.args = {
|
|
70
|
+
...defaultProps,
|
|
71
|
+
initialValue: "Contains not",
|
|
72
|
+
checkInput: (inputString) => {
|
|
73
|
+
const notIndex = inputString.indexOf("not");
|
|
74
|
+
if (notIndex >= 0) {
|
|
75
|
+
return {
|
|
76
|
+
valid: false,
|
|
77
|
+
parseError: {
|
|
78
|
+
message: "Strings containing the sub-string 'not' are NOT allowed.",
|
|
79
|
+
start: notIndex,
|
|
80
|
+
end: notIndex + 3,
|
|
81
|
+
},
|
|
82
|
+
};
|
|
83
|
+
} else {
|
|
84
|
+
return {
|
|
85
|
+
valid: true,
|
|
86
|
+
};
|
|
87
|
+
}
|
|
88
|
+
},
|
|
89
|
+
};
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
|
|
3
|
+
import { CLASSPREFIX as eccgui } from "../../configuration/constants";
|
|
4
|
+
import { AutoSuggestion, AutoSuggestionProps } from "../AutoSuggestion/AutoSuggestion";
|
|
5
|
+
|
|
6
|
+
export type CodeAutocompleteFieldProps = AutoSuggestionProps;
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* Input component that allows partial, fine-grained auto-completion, i.e. of sub-strings of the input string.
|
|
10
|
+
* This is comparable to a one line code editor.
|
|
11
|
+
*
|
|
12
|
+
* Example usage: input of a path string offering auto-completion for each single part of the path.
|
|
13
|
+
*/
|
|
14
|
+
export function CodeAutocompleteField({ className, ...otherProps }: CodeAutocompleteFieldProps) {
|
|
15
|
+
// Currently this works only as an alias element for `MultiSelect`.
|
|
16
|
+
return (
|
|
17
|
+
<AutoSuggestion
|
|
18
|
+
className={`${eccgui}-codeautocompletefield` + (className ? ` ${className}` : "")}
|
|
19
|
+
{...otherProps}
|
|
20
|
+
/>
|
|
21
|
+
);
|
|
22
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from "./CodeAutocompleteField";
|
|
@@ -5,13 +5,21 @@ $pt-dark-popover2-background-color: $dark-gray4 !default;
|
|
|
5
5
|
|
|
6
6
|
@import "~@blueprintjs/popover2/src/popover2";
|
|
7
7
|
|
|
8
|
-
.#{$ns}-
|
|
8
|
+
.#{$ns}-overlay-content,
|
|
9
|
+
.#{$ns}-popover2,
|
|
10
|
+
.#{$ns}-popover2-content,
|
|
11
|
+
.#{$ns}-popover2-target {
|
|
9
12
|
max-width: 100%;
|
|
10
13
|
}
|
|
11
14
|
|
|
15
|
+
.#{$ns}-popover2-content {
|
|
16
|
+
.#{$ns}-input-group {
|
|
17
|
+
display: block;
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
|
|
12
21
|
.#{$ns}-popover2-target {
|
|
13
22
|
cursor: pointer;
|
|
14
|
-
max-width: 100%;
|
|
15
23
|
}
|
|
16
24
|
|
|
17
25
|
.#{$ns}-submenu.#{$ns}-popover > .#{$ns}-popover-content {
|
|
@@ -1,18 +1,22 @@
|
|
|
1
|
-
import React, {useCallback, useEffect, useRef} from "react";
|
|
1
|
+
import React, { useCallback, useEffect, useRef } from "react";
|
|
2
|
+
import SVG from "react-inlinesvg";
|
|
2
3
|
import Color from "color";
|
|
3
|
-
|
|
4
|
+
|
|
5
|
+
import { CLASSPREFIX as eccgui } from "../../configuration/constants";
|
|
4
6
|
import { BadgeProps } from "../Badge/Badge";
|
|
5
7
|
import { IconProps } from "../Icon/Icon";
|
|
6
8
|
import { TestIconProps } from "../Icon/TestIcon";
|
|
7
9
|
import Tooltip, { TooltipProps } from "../Tooltip/Tooltip";
|
|
10
|
+
|
|
8
11
|
import decideContrastColorValue from "./../../common/utils/colorDecideContrastvalue";
|
|
9
|
-
import {CLASSPREFIX as eccgui} from "../../configuration/constants";
|
|
10
12
|
|
|
11
13
|
export interface DepictionProps extends React.HTMLAttributes<HTMLElement> {
|
|
12
14
|
/**
|
|
13
15
|
* Image that should be used as depiction.
|
|
14
16
|
*/
|
|
15
|
-
image: React.ReactElement<
|
|
17
|
+
image: React.ReactElement<
|
|
18
|
+
IconProps | TestIconProps | React.ImgHTMLAttributes<HTMLImageElement> | React.SVGProps<SVGSVGElement>
|
|
19
|
+
>;
|
|
16
20
|
/**
|
|
17
21
|
* In case you use an SVG encoded as a data URL in the `<img />` element, then it is transformed to a inline SVG inside the DOM tree.
|
|
18
22
|
* Should be work with Base64 and URL encoded data URIs.
|
|
@@ -67,7 +71,7 @@ export interface DepictionProps extends React.HTMLAttributes<HTMLElement> {
|
|
|
67
71
|
/**
|
|
68
72
|
* Attach a `<Badge />` element to the depiction.
|
|
69
73
|
*/
|
|
70
|
-
badge?: React.ReactElement<BadgeProps
|
|
74
|
+
badge?: React.ReactElement<BadgeProps>;
|
|
71
75
|
}
|
|
72
76
|
|
|
73
77
|
/**
|
|
@@ -77,11 +81,11 @@ export function Depiction({
|
|
|
77
81
|
className = "",
|
|
78
82
|
image,
|
|
79
83
|
forceInlineSvg = false,
|
|
80
|
-
size="medium",
|
|
81
|
-
resizing="cover",
|
|
82
|
-
ratio="source",
|
|
84
|
+
size = "medium",
|
|
85
|
+
resizing = "cover",
|
|
86
|
+
ratio = "source",
|
|
83
87
|
caption,
|
|
84
|
-
captionPosition="none",
|
|
88
|
+
captionPosition = "none",
|
|
85
89
|
backgroundColor,
|
|
86
90
|
border,
|
|
87
91
|
rounded,
|
|
@@ -92,37 +96,43 @@ export function Depiction({
|
|
|
92
96
|
}: DepictionProps) {
|
|
93
97
|
const containerRef = useRef<HTMLDivElement>(null);
|
|
94
98
|
|
|
95
|
-
let styleDepictionColors =
|
|
99
|
+
let styleDepictionColors = Object.create(null);
|
|
96
100
|
if (!!backgroundColor && backgroundColor !== "light" && backgroundColor !== "dark") {
|
|
97
101
|
try {
|
|
98
102
|
const color = Color(backgroundColor);
|
|
99
103
|
styleDepictionColors = {
|
|
100
104
|
[`--${eccgui}-depiction-background`]: color.rgb().toString(),
|
|
101
|
-
[`--${eccgui}-depiction-color`]: decideContrastColorValue({testColor: color})
|
|
102
|
-
}
|
|
103
|
-
} catch(ex) {
|
|
104
|
-
console.warn("Received invalid background color for depiction: " + backgroundColor)
|
|
105
|
+
[`--${eccgui}-depiction-color`]: decideContrastColorValue({ testColor: color }),
|
|
106
|
+
};
|
|
107
|
+
} catch (ex) {
|
|
108
|
+
console.warn("Received invalid background color for depiction: " + backgroundColor);
|
|
105
109
|
}
|
|
106
110
|
}
|
|
107
111
|
|
|
108
|
-
const updateSvgResizing = React.useCallback(
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
112
|
+
const updateSvgResizing = React.useCallback(
|
|
113
|
+
(el: SVGElement) => {
|
|
114
|
+
let preserveAspectRatio = "";
|
|
115
|
+
switch (resizing) {
|
|
116
|
+
case "cover":
|
|
117
|
+
preserveAspectRatio = "xMidYMid slice";
|
|
118
|
+
break;
|
|
119
|
+
case "stretch":
|
|
120
|
+
preserveAspectRatio = "none";
|
|
121
|
+
break;
|
|
122
|
+
}
|
|
123
|
+
el.setAttribute("preserveAspectRatio", preserveAspectRatio);
|
|
124
|
+
},
|
|
125
|
+
[resizing]
|
|
126
|
+
);
|
|
120
127
|
|
|
121
|
-
const inlineSvgCall = useCallback(
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
128
|
+
const inlineSvgCall = useCallback(
|
|
129
|
+
(svgElement: SVGElement) => {
|
|
130
|
+
if (svgElement) {
|
|
131
|
+
updateSvgResizing(svgElement);
|
|
132
|
+
}
|
|
133
|
+
},
|
|
134
|
+
[updateSvgResizing]
|
|
135
|
+
);
|
|
126
136
|
|
|
127
137
|
useEffect(() => {
|
|
128
138
|
// Resize element after every render
|
|
@@ -130,7 +140,7 @@ export function Depiction({
|
|
|
130
140
|
if (svgElement.length > 0) {
|
|
131
141
|
updateSvgResizing(svgElement[0]);
|
|
132
142
|
}
|
|
133
|
-
})
|
|
143
|
+
});
|
|
134
144
|
|
|
135
145
|
let depiction = image;
|
|
136
146
|
if (
|
|
@@ -141,13 +151,10 @@ export function Depiction({
|
|
|
141
151
|
image.props.src.startsWith("data:image/svg+xml")
|
|
142
152
|
) {
|
|
143
153
|
depiction = (
|
|
144
|
-
<SVG
|
|
145
|
-
src={image.props.src}
|
|
146
|
-
innerRef={inlineSvgCall}
|
|
147
|
-
>
|
|
154
|
+
<SVG src={image.props.src} innerRef={inlineSvgCall}>
|
|
148
155
|
{image}
|
|
149
156
|
</SVG>
|
|
150
|
-
)
|
|
157
|
+
);
|
|
151
158
|
}
|
|
152
159
|
|
|
153
160
|
const depictionContainer = (
|
|
@@ -158,11 +165,13 @@ export function Depiction({
|
|
|
158
165
|
` ${eccgui}-depiction__image--${size}` +
|
|
159
166
|
` ${eccgui}-depiction__image--${resizing}-sizing` +
|
|
160
167
|
` ${eccgui}-depiction__image--ratio-${ratio.replace(":", "to")}` +
|
|
161
|
-
(backgroundColor === "light" || backgroundColor === "dark"
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
(
|
|
165
|
-
(
|
|
168
|
+
(backgroundColor === "light" || backgroundColor === "dark"
|
|
169
|
+
? ` ${eccgui}-depiction__image--color-${backgroundColor}`
|
|
170
|
+
: "") +
|
|
171
|
+
(backgroundColor ? ` ${eccgui}-depiction__image--color-config` : "") +
|
|
172
|
+
(border ? ` ${eccgui}-depiction__image--hasborder` : "") +
|
|
173
|
+
(rounded ? ` ${eccgui}-depiction__image--roundedborder` : "") +
|
|
174
|
+
(padding && padding !== "none" ? ` ${eccgui}-depiction__image--padding-${padding}` : "")
|
|
166
175
|
}
|
|
167
176
|
style={styleDepictionColors as React.CSSProperties}
|
|
168
177
|
>
|
|
@@ -171,24 +180,17 @@ export function Depiction({
|
|
|
171
180
|
);
|
|
172
181
|
|
|
173
182
|
return (
|
|
174
|
-
<figure
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
{...otherFigureProps}
|
|
180
|
-
>
|
|
181
|
-
{ captionPosition === "tooltip" && !!caption ? (
|
|
182
|
-
<Tooltip content={caption} size="medium" {...tooltipProps}>{depictionContainer}</Tooltip>
|
|
183
|
+
<figure className={`${eccgui}-depiction` + (className ? ` ${className}` : "")} {...otherFigureProps}>
|
|
184
|
+
{captionPosition === "tooltip" && !!caption ? (
|
|
185
|
+
<Tooltip content={caption} size="medium" {...tooltipProps}>
|
|
186
|
+
{depictionContainer}
|
|
187
|
+
</Tooltip>
|
|
183
188
|
) : (
|
|
184
189
|
depictionContainer
|
|
185
190
|
)}
|
|
186
191
|
{!!caption && (
|
|
187
192
|
<figcaption
|
|
188
|
-
className={
|
|
189
|
-
`${eccgui}-depiction__caption` +
|
|
190
|
-
` ${eccgui}-depiction__caption--${captionPosition}`
|
|
191
|
-
}
|
|
193
|
+
className={`${eccgui}-depiction__caption` + ` ${eccgui}-depiction__caption--${captionPosition}`}
|
|
192
194
|
>
|
|
193
195
|
{caption}
|
|
194
196
|
</figcaption>
|
|
@@ -1,9 +1,11 @@
|
|
|
1
1
|
import React from "react";
|
|
2
|
-
|
|
3
|
-
import {CLASSPREFIX as eccgui} from "../../configuration/constants";
|
|
2
|
+
|
|
3
|
+
import { CLASSPREFIX as eccgui } from "../../configuration/constants";
|
|
4
|
+
import Button, { AnchorOrButtonProps, ButtonProps } from "../Button/Button";
|
|
5
|
+
|
|
6
|
+
import { ValidIconName } from "./canonicalIconNames";
|
|
4
7
|
import Icon from "./Icon";
|
|
5
8
|
import { TestIconProps } from "./TestIcon";
|
|
6
|
-
import {ValidIconName} from "./canonicalIconNames";
|
|
7
9
|
|
|
8
10
|
interface ExtendedButtonProps extends Omit<ButtonProps, "icon" | "rightIcon" | "text" | "minimal" | "tooltip"> {
|
|
9
11
|
/**
|
|
@@ -41,30 +43,42 @@ export const IconButton = ({
|
|
|
41
43
|
tooltipProps,
|
|
42
44
|
description,
|
|
43
45
|
tooltipAsTitle = false,
|
|
44
|
-
minimal=true,
|
|
46
|
+
minimal = true,
|
|
45
47
|
...restProps
|
|
46
48
|
}: IconButtonProps) => {
|
|
49
|
+
const defaultIconTooltipProps = {
|
|
50
|
+
hoverOpenDelay: 1000,
|
|
51
|
+
openOnTargetFocus: restProps.disabled || (restProps.tabIndex ?? "0") < 0 ? false : undefined,
|
|
52
|
+
};
|
|
47
53
|
const iconProps = {
|
|
48
54
|
small: restProps.small,
|
|
49
55
|
large: restProps.large,
|
|
50
56
|
tooltipText: tooltipAsTitle ? undefined : text,
|
|
51
|
-
tooltipProps:
|
|
57
|
+
tooltipProps: tooltipProps
|
|
58
|
+
? {
|
|
59
|
+
...defaultIconTooltipProps,
|
|
60
|
+
...tooltipProps,
|
|
61
|
+
}
|
|
62
|
+
: defaultIconTooltipProps,
|
|
52
63
|
description: description ? description : text,
|
|
53
64
|
};
|
|
54
65
|
|
|
55
66
|
return (
|
|
56
67
|
<Button
|
|
68
|
+
tabIndex={text && !tooltipAsTitle ? -1 : undefined}
|
|
57
69
|
title={tooltipAsTitle && text ? text : undefined}
|
|
58
70
|
{...restProps}
|
|
59
|
-
icon={
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
71
|
+
icon={
|
|
72
|
+
typeof name === "string" || Array.isArray(name) ? (
|
|
73
|
+
<Icon name={name} {...iconProps} />
|
|
74
|
+
) : (
|
|
75
|
+
React.cloneElement(name, iconProps)
|
|
76
|
+
)
|
|
77
|
+
}
|
|
64
78
|
className={`${eccgui}-button--icon ` + className}
|
|
65
79
|
minimal={minimal}
|
|
66
80
|
/>
|
|
67
81
|
);
|
|
68
|
-
}
|
|
82
|
+
};
|
|
69
83
|
|
|
70
84
|
export default IconButton;
|
|
@@ -103,6 +103,8 @@ export type ValidIconName =
|
|
|
103
103
|
| "operation-erase"
|
|
104
104
|
| "operation-filter"
|
|
105
105
|
| "operation-filteredit"
|
|
106
|
+
| "operation-filterremove"
|
|
107
|
+
| "operation-fix"
|
|
106
108
|
| "operation-link"
|
|
107
109
|
| "operation-logout"
|
|
108
110
|
| "operation-merge"
|
|
@@ -256,7 +258,9 @@ const canonicalIconNames: Record<ValidIconName, CarbonIconType> = {
|
|
|
256
258
|
"operation-comparison": icons.Compare,
|
|
257
259
|
"operation-erase": icons.Erase,
|
|
258
260
|
"operation-filteredit": icons.FilterEdit,
|
|
261
|
+
"operation-filterremove": icons.FilterRemove,
|
|
259
262
|
"operation-filter": icons.Filter,
|
|
263
|
+
"operation-fix": icons.Tools,
|
|
260
264
|
"operation-link": icons.Link,
|
|
261
265
|
"operation-logout": icons.Logout,
|
|
262
266
|
"operation-merge": icons.DirectionMerge,
|
|
@@ -1,52 +1,14 @@
|
|
|
1
|
-
import
|
|
2
|
-
|
|
3
|
-
import {
|
|
4
|
-
|
|
1
|
+
import { Meta } from "@storybook/react";
|
|
2
|
+
|
|
3
|
+
import { MultiSelect } from "./../../../index";
|
|
4
|
+
export { Default } from "../MultiSuggestField/MultiSuggestField.stories";
|
|
5
5
|
|
|
6
6
|
export default {
|
|
7
7
|
title: "Forms/MultiSelect",
|
|
8
|
-
component:
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
8
|
+
component: MultiSelect,
|
|
9
|
+
parameters: {
|
|
10
|
+
controls: {
|
|
11
|
+
exclude: /.*/g,
|
|
12
12
|
},
|
|
13
13
|
},
|
|
14
|
-
} as
|
|
15
|
-
|
|
16
|
-
const Template: ComponentStory<typeof MultiSelectExample> = (args) => <MultiSelectExample {...args} />;
|
|
17
|
-
|
|
18
|
-
export const Default = Template.bind({});
|
|
19
|
-
|
|
20
|
-
const testLabels = loremIpsum({
|
|
21
|
-
p: 1,
|
|
22
|
-
avgSentencesPerParagraph: 5,
|
|
23
|
-
avgWordsPerSentence: 1,
|
|
24
|
-
startWithLoremIpsum: false,
|
|
25
|
-
random: false
|
|
26
|
-
}).toString().split(".");
|
|
27
|
-
|
|
28
|
-
const items = new Array(5).fill(undefined).map((_, id) => {
|
|
29
|
-
const testLabel = testLabels[id];
|
|
30
|
-
return { testLabel, testId: `${testLabel}-id` };
|
|
31
|
-
});
|
|
32
|
-
|
|
33
|
-
Default.args = {
|
|
34
|
-
items,
|
|
35
|
-
canCreateNewItem: true,
|
|
36
|
-
prePopulateWithItems: false,
|
|
37
|
-
itemId: item => item.testId,
|
|
38
|
-
itemLabel: item => item.testLabel,
|
|
39
|
-
openOnKeyDown: true,
|
|
40
|
-
};
|
|
41
|
-
|
|
42
|
-
const TemplateWithOpenDropdown: ComponentStory<typeof MultiSelectExample> = (args) => <MultiSelectExample {...args} />;
|
|
43
|
-
|
|
44
|
-
export const openDropdownWhenFocused = TemplateWithOpenDropdown.bind({});
|
|
45
|
-
|
|
46
|
-
openDropdownWhenFocused.args = {
|
|
47
|
-
items,
|
|
48
|
-
canCreateNewItem: true,
|
|
49
|
-
prePopulateWithItems: false,
|
|
50
|
-
itemId: item => item.testId,
|
|
51
|
-
itemLabel: item => item.testLabel,
|
|
52
|
-
};
|
|
14
|
+
} as Meta<typeof MultiSelect>;
|