@eccenca/gui-elements 24.2.0-rc.1 → 24.2.0
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 +56 -0
- package/README.md +10 -7
- package/dist/cjs/cmem/markdown/Markdown.js +13 -11
- package/dist/cjs/cmem/markdown/Markdown.js.map +1 -1
- package/dist/cjs/cmem/markdown/highlightSearchWords.js +6 -1
- package/dist/cjs/cmem/markdown/highlightSearchWords.js.map +1 -1
- package/dist/cjs/common/Intent/index.js +4 -11
- package/dist/cjs/common/Intent/index.js.map +1 -1
- package/dist/cjs/components/AutoSuggestion/AutoSuggestion.js +35 -24
- package/dist/cjs/components/AutoSuggestion/AutoSuggestion.js.map +1 -1
- package/dist/cjs/components/Button/Button.js +2 -2
- package/dist/cjs/components/Button/Button.js.map +1 -1
- package/dist/cjs/components/ContextOverlay/ContextMenu.js +3 -2
- package/dist/cjs/components/ContextOverlay/ContextMenu.js.map +1 -1
- package/dist/cjs/components/ContextOverlay/ContextOverlay.js +46 -2
- package/dist/cjs/components/ContextOverlay/ContextOverlay.js.map +1 -1
- package/dist/cjs/components/Form/FieldItem.js +3 -2
- package/dist/cjs/components/Form/FieldItem.js.map +1 -1
- package/dist/cjs/components/Form/FieldSet.js +3 -2
- package/dist/cjs/components/Form/FieldSet.js.map +1 -1
- package/dist/cjs/components/Icon/canonicalIconNames.js +1 -0
- package/dist/cjs/components/Icon/canonicalIconNames.js.map +1 -1
- package/dist/cjs/components/MultiSelect/MultiSelect.js +18 -14
- package/dist/cjs/components/MultiSelect/MultiSelect.js.map +1 -1
- package/dist/cjs/components/Notification/Notification.js +7 -4
- package/dist/cjs/components/Notification/Notification.js.map +1 -1
- package/dist/cjs/components/OverviewItem/OverviewItemActions.js +9 -2
- package/dist/cjs/components/OverviewItem/OverviewItemActions.js.map +1 -1
- package/dist/cjs/components/Spinner/Spinner.js +7 -5
- package/dist/cjs/components/Spinner/Spinner.js.map +1 -1
- package/dist/cjs/components/Tooltip/Tooltip.js +75 -7
- package/dist/cjs/components/Tooltip/Tooltip.js.map +1 -1
- package/dist/esm/cmem/markdown/Markdown.js +13 -11
- package/dist/esm/cmem/markdown/Markdown.js.map +1 -1
- package/dist/esm/cmem/markdown/highlightSearchWords.js +6 -1
- package/dist/esm/cmem/markdown/highlightSearchWords.js.map +1 -1
- package/dist/esm/common/Intent/index.js +14 -10
- package/dist/esm/common/Intent/index.js.map +1 -1
- package/dist/esm/components/AutoSuggestion/AutoSuggestion.js +40 -31
- package/dist/esm/components/AutoSuggestion/AutoSuggestion.js.map +1 -1
- package/dist/esm/components/Button/Button.js +2 -2
- package/dist/esm/components/Button/Button.js.map +1 -1
- package/dist/esm/components/ContextOverlay/ContextMenu.js +3 -2
- package/dist/esm/components/ContextOverlay/ContextMenu.js.map +1 -1
- package/dist/esm/components/ContextOverlay/ContextOverlay.js +63 -3
- package/dist/esm/components/ContextOverlay/ContextOverlay.js.map +1 -1
- package/dist/esm/components/Form/FieldItem.js +3 -2
- package/dist/esm/components/Form/FieldItem.js.map +1 -1
- package/dist/esm/components/Form/FieldSet.js +3 -2
- package/dist/esm/components/Form/FieldSet.js.map +1 -1
- package/dist/esm/components/Icon/canonicalIconNames.js +1 -0
- package/dist/esm/components/Icon/canonicalIconNames.js.map +1 -1
- package/dist/esm/components/MultiSelect/MultiSelect.js +18 -14
- package/dist/esm/components/MultiSelect/MultiSelect.js.map +1 -1
- package/dist/esm/components/Notification/Notification.js +7 -4
- package/dist/esm/components/Notification/Notification.js.map +1 -1
- package/dist/esm/components/OverviewItem/OverviewItemActions.js +25 -2
- package/dist/esm/components/OverviewItem/OverviewItemActions.js.map +1 -1
- package/dist/esm/components/Spinner/Spinner.js +9 -5
- package/dist/esm/components/Spinner/Spinner.js.map +1 -1
- package/dist/esm/components/Tooltip/Tooltip.js +92 -8
- package/dist/esm/components/Tooltip/Tooltip.js.map +1 -1
- package/dist/types/cmem/markdown/Markdown.d.ts +8 -1
- package/dist/types/common/Intent/index.d.ts +10 -1
- package/dist/types/components/Button/Button.d.ts +5 -1
- package/dist/types/components/ContextOverlay/ContextMenu.d.ts +9 -2
- package/dist/types/components/ContextOverlay/ContextOverlay.d.ts +6 -1
- package/dist/types/components/Form/FieldItem.d.ts +10 -1
- package/dist/types/components/Form/FieldSet.d.ts +10 -1
- package/dist/types/components/Icon/canonicalIconNames.d.ts +1 -0
- package/dist/types/components/MultiSelect/MultiSelect.d.ts +12 -4
- package/dist/types/components/Notification/Notification.d.ts +10 -1
- package/dist/types/components/OverviewItem/OverviewItemActions.d.ts +13 -1
- package/dist/types/components/Spinner/Spinner.d.ts +8 -3
- package/dist/types/components/Table/TableContainer.d.ts +2 -2
- package/dist/types/components/Table/TableExpandRow.d.ts +1 -1
- package/dist/types/components/Table/index.d.ts +1 -0
- package/dist/types/components/Tooltip/Tooltip.d.ts +9 -1
- package/package.json +10 -7
- package/src/cmem/markdown/Markdown.tsx +25 -14
- package/src/cmem/markdown/highlightSearchWords.test.ts +8 -2
- package/src/cmem/markdown/highlightSearchWords.ts +6 -1
- package/src/common/Intent/index.ts +6 -6
- package/src/components/AutoSuggestion/AutoSuggestion.tsx +43 -33
- package/src/components/Button/Button.stories.tsx +10 -6
- package/src/components/Button/Button.tsx +7 -2
- package/src/components/ContextOverlay/ContextMenu.stories.tsx +1 -1
- package/src/components/ContextOverlay/ContextMenu.tsx +26 -13
- package/src/components/ContextOverlay/ContextOverlay.tsx +83 -5
- package/src/components/Form/FieldItem.tsx +14 -3
- package/src/components/Form/FieldSet.tsx +13 -2
- package/src/components/Form/Stories/FieldItem.stories.tsx +4 -0
- package/src/components/Form/Stories/FieldSet.stories.tsx +4 -0
- package/src/components/Icon/canonicalIconNames.tsx +1 -0
- package/src/components/MultiSelect/MultiSelect.tsx +27 -15
- package/src/components/MultiSuggestField/MultiSuggestField.stories.tsx +6 -0
- package/src/components/Notification/Notification.stories.tsx +4 -0
- package/src/components/Notification/Notification.tsx +17 -4
- package/src/components/OverviewItem/OverviewItemActions.tsx +24 -1
- package/src/components/OverviewItem/stories/OverviewItemList.stories.tsx +2 -7
- package/src/components/OverviewItem/stories/OverviewItemListPerformance.tsx +174 -0
- package/src/components/OverviewItem/stories/OverviewItemPerformance.stories.tsx +19 -0
- package/src/components/Spinner/Spinner.tsx +13 -5
- package/src/components/Spinner/Stories/spinner.stories.tsx +6 -1
- package/src/components/Table/TableContainer.tsx +2 -2
- package/src/components/Table/TableExpandRow.tsx +1 -1
- package/src/components/Table/index.tsx +1 -0
- package/src/components/Tooltip/Tooltip.stories.tsx +3 -2
- package/src/components/Tooltip/Tooltip.tsx +121 -10
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import React from "react";
|
|
2
|
+
import { IntentTypes } from "../../common/Intent";
|
|
2
3
|
export interface FieldSetProps extends Omit<React.FieldsetHTMLAttributes<HTMLFieldSetElement>, "title"> {
|
|
3
4
|
/**
|
|
4
5
|
* Displays the fieldset inside a box.
|
|
@@ -7,20 +8,28 @@ export interface FieldSetProps extends Omit<React.FieldsetHTMLAttributes<HTMLFie
|
|
|
7
8
|
boxed?: boolean;
|
|
8
9
|
/**
|
|
9
10
|
* The fieldsetsection is displayed with primary color scheme.
|
|
11
|
+
* @deprecated (v25) use `intent="primary"` instead.
|
|
10
12
|
*/
|
|
11
13
|
hasStatePrimary?: boolean;
|
|
12
14
|
/**
|
|
13
15
|
* The fieldset section is displayed with success (some type of green) color scheme.
|
|
16
|
+
* @deprecated (v25) use `intent="success"` instead.
|
|
14
17
|
*/
|
|
15
18
|
hasStateSuccess?: boolean;
|
|
16
19
|
/**
|
|
17
20
|
* The fieldset section is displayed with warning (some type of orange) color scheme.
|
|
21
|
+
* @deprecated (v25) use `intent="warning"` instead.
|
|
18
22
|
*/
|
|
19
23
|
hasStateWarning?: boolean;
|
|
20
24
|
/**
|
|
21
25
|
* The fieldsetsection is displayed with danger (some type of red) color scheme.
|
|
26
|
+
* @deprecated (v25) use `intent="danger"` instead.
|
|
22
27
|
*/
|
|
23
28
|
hasStateDanger?: boolean;
|
|
29
|
+
/**
|
|
30
|
+
* Intent state of the field item.
|
|
31
|
+
*/
|
|
32
|
+
intent?: IntentTypes;
|
|
24
33
|
/**
|
|
25
34
|
* Optional helper text. If given then it is displayed after the title.
|
|
26
35
|
*/
|
|
@@ -39,5 +48,5 @@ export interface FieldSetProps extends Omit<React.FieldsetHTMLAttributes<HTMLFie
|
|
|
39
48
|
/**
|
|
40
49
|
* Displays a group of input elements.
|
|
41
50
|
*/
|
|
42
|
-
export declare const FieldSet: ({ boxed, children, className, hasStatePrimary, hasStateSuccess, hasStateWarning, hasStateDanger, helperText, messageText, title, ...otherProps }: FieldSetProps) => React.JSX.Element;
|
|
51
|
+
export declare const FieldSet: ({ boxed, children, className, hasStatePrimary, hasStateSuccess, hasStateWarning, hasStateDanger, intent, helperText, messageText, title, ...otherProps }: FieldSetProps) => React.JSX.Element;
|
|
43
52
|
export default FieldSet;
|
|
@@ -120,6 +120,7 @@ declare const canonicalIcons: {
|
|
|
120
120
|
"operation-filteredit": icons.CarbonIconType;
|
|
121
121
|
"operation-filterremove": icons.CarbonIconType;
|
|
122
122
|
"operation-filter": icons.CarbonIconType;
|
|
123
|
+
"operation-focus": icons.CarbonIconType;
|
|
123
124
|
"operation-format-codeblock": icons.CarbonIconType;
|
|
124
125
|
"operation-format-text-code": icons.CarbonIconType;
|
|
125
126
|
"operation-format-text-bold": icons.CarbonIconType;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import React from "react";
|
|
2
|
-
import { HTMLInputProps as BlueprintHTMLInputProps } from "@blueprintjs/core";
|
|
2
|
+
import { HTMLInputProps as BlueprintHTMLInputProps, Intent as BlueprintIntent } from "@blueprintjs/core";
|
|
3
3
|
import { MultiSelect as BlueprintMultiSelect, MultiSelectProps as BlueprintMultiSelectProps } from "@blueprintjs/select";
|
|
4
4
|
import { TestableComponent } from "../interfaces";
|
|
5
5
|
import { ContextOverlayProps } from "./../../index";
|
|
@@ -64,20 +64,28 @@ interface MultiSelectCommonProps<T> extends TestableComponent, Pick<BlueprintMul
|
|
|
64
64
|
* Items that were newly created and not taken from the list will be post-fixed with this string.
|
|
65
65
|
*/
|
|
66
66
|
newItemPostfix?: string;
|
|
67
|
+
/**
|
|
68
|
+
* Intent state of the multi select.
|
|
69
|
+
*/
|
|
70
|
+
intent?: BlueprintIntent;
|
|
67
71
|
/**
|
|
68
72
|
* The input element is displayed with primary color scheme.
|
|
73
|
+
* @deprecated (v25) use `intent="primary"` instead.
|
|
69
74
|
*/
|
|
70
75
|
hasStatePrimary?: boolean;
|
|
71
76
|
/**
|
|
72
77
|
* The input element is displayed with success (some type of green) color scheme.
|
|
78
|
+
* @deprecated (v25) use `intent="success"` instead.
|
|
73
79
|
*/
|
|
74
80
|
hasStateSuccess?: boolean;
|
|
75
81
|
/**
|
|
76
|
-
* The input element is displayed with
|
|
82
|
+
* The input element is displayed with warning (some type of orange) color scheme.
|
|
83
|
+
* @deprecated (v25) use `intent="warning"` instead.
|
|
77
84
|
*/
|
|
78
85
|
hasStateWarning?: boolean;
|
|
79
86
|
/**
|
|
80
|
-
* The input element is displayed with
|
|
87
|
+
* The input element is displayed with danger (some type of red) color scheme.
|
|
88
|
+
* @deprecated (v25) use `intent="danger"` instead.
|
|
81
89
|
*/
|
|
82
90
|
hasStateDanger?: boolean;
|
|
83
91
|
/**
|
|
@@ -128,7 +136,7 @@ export type MultiSelectProps<T> = MultiSelectCommonProps<T> & ({
|
|
|
128
136
|
* This component will be re-implemented as `Select` like element allowing multiple selections (or a `Select` option).
|
|
129
137
|
* New name for this component is `MultiSuggestField`.
|
|
130
138
|
*/
|
|
131
|
-
declare function MultiSelect<T>({ items, selectedItems: externalSelectedItems, prePopulateWithItems, itemId, itemLabel, onSelection, contextOverlayProps, tagInputProps, inputProps, runOnQueryChange, fullWidth, noResultText, newItemCreationText, newItemPostfix, hasStatePrimary, hasStateDanger, hasStateSuccess, hasStateWarning, disabled, createNewItemFromQuery, requestDelay, clearQueryOnSelection, className, "data-test-id": dataTestId, "data-testid": dataTestid, wrapperProps, searchPredicate, limitHeightOpened, ...otherMultiSelectProps }: MultiSelectProps<T>): React.JSX.Element;
|
|
139
|
+
declare function MultiSelect<T>({ items, selectedItems: externalSelectedItems, prePopulateWithItems, itemId, itemLabel, onSelection, contextOverlayProps, tagInputProps, inputProps, runOnQueryChange, fullWidth, noResultText, newItemCreationText, newItemPostfix, hasStatePrimary, hasStateDanger, hasStateSuccess, hasStateWarning, disabled, createNewItemFromQuery, requestDelay, clearQueryOnSelection, className, "data-test-id": dataTestId, "data-testid": dataTestid, wrapperProps, searchPredicate, limitHeightOpened, intent, ...otherMultiSelectProps }: MultiSelectProps<T>): React.JSX.Element;
|
|
132
140
|
declare namespace MultiSelect {
|
|
133
141
|
var ofType: typeof BlueprintMultiSelect.ofType;
|
|
134
142
|
}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import React from "react";
|
|
2
2
|
import { ToastProps as BlueprintToastProps } from "@blueprintjs/core";
|
|
3
|
+
import { IntentTypes } from "../../common/Intent";
|
|
3
4
|
import { TestableComponent } from "../interfaces";
|
|
4
5
|
import { IconProps } from "./../Icon/Icon";
|
|
5
6
|
import { TestIconProps } from "./../Icon/TestIcon";
|
|
@@ -12,23 +13,31 @@ export interface NotificationProps extends TestableComponent, Omit<BlueprintToas
|
|
|
12
13
|
* Notification message that can be used as alternative to children elements.
|
|
13
14
|
*/
|
|
14
15
|
message?: JSX.Element | string;
|
|
16
|
+
/**
|
|
17
|
+
* Intent state of the notification.
|
|
18
|
+
*/
|
|
19
|
+
intent?: Extract<IntentTypes, "neutral" | "success" | "warning" | "danger" | "info">;
|
|
15
20
|
/**
|
|
16
21
|
* Notification has a neutral color scheme.
|
|
22
|
+
* @deprecated (v25) use `intent="neutral"` instead.
|
|
17
23
|
*/
|
|
18
24
|
neutral?: boolean;
|
|
19
25
|
/**
|
|
20
26
|
* Notification is a success info.
|
|
21
27
|
* This defines the colorization and the icon symbol.
|
|
28
|
+
* @deprecated (v25) use `intent="success"` instead.
|
|
22
29
|
*/
|
|
23
30
|
success?: boolean;
|
|
24
31
|
/**
|
|
25
32
|
* Notification is a warning alert.
|
|
26
33
|
* This defines the colorization and the icon symbol.
|
|
34
|
+
* @deprecated (v25) use `intent="warning"` instead.
|
|
27
35
|
*/
|
|
28
36
|
warning?: boolean;
|
|
29
37
|
/**
|
|
30
38
|
* Notification is a danger alert.
|
|
31
39
|
* This defines the colorization and the icon symbol.
|
|
40
|
+
* @deprecated (v25) use `intent="danger"` instead.
|
|
32
41
|
*/
|
|
33
42
|
danger?: boolean;
|
|
34
43
|
/**
|
|
@@ -52,5 +61,5 @@ export interface NotificationProps extends TestableComponent, Omit<BlueprintToas
|
|
|
52
61
|
* Displays a notification message, optionally combined with depiction and further action buttons.
|
|
53
62
|
* By default it uses colorization of an blueish info alert.
|
|
54
63
|
*/
|
|
55
|
-
export declare const Notification: ({ actions, children, className, message, success, warning, danger, neutral, flexWidth, icon, timeout, wrapperProps, "data-test-id": dataTestId, "data-testid": dataTestid, ...otherProps }: NotificationProps) => React.JSX.Element;
|
|
64
|
+
export declare const Notification: ({ actions, children, className, message, success, warning, danger, neutral, flexWidth, icon, timeout, wrapperProps, "data-test-id": dataTestId, "data-testid": dataTestid, intent, ...otherProps }: NotificationProps) => React.JSX.Element;
|
|
56
65
|
export default Notification;
|
|
@@ -4,10 +4,22 @@ export interface OverviewItemActionsProps extends React.HTMLAttributes<HTMLDivEl
|
|
|
4
4
|
* Display it only when the parent `OverviewItem` is hovered or focused.
|
|
5
5
|
*/
|
|
6
6
|
hiddenInteractions?: boolean;
|
|
7
|
+
/**
|
|
8
|
+
* Delay the rendering of the children by a time in milliseconds.
|
|
9
|
+
* Could be used to prevent browser freezes for the initial `OverviewItem` rendering.
|
|
10
|
+
* In general, it is better to fix the cause, i.e. action elements that are expensive to initialize/render should be
|
|
11
|
+
* optimized or replaced etc. This workaround only prevents the browser from getting blocked completely and does NOT
|
|
12
|
+
* solve the actual performance issue.
|
|
13
|
+
*/
|
|
14
|
+
delayDisplayChildren?: number;
|
|
15
|
+
/**
|
|
16
|
+
* Display element while the rendering of the actual children is delayed.
|
|
17
|
+
*/
|
|
18
|
+
delaySkeleton?: JSX.Element;
|
|
7
19
|
}
|
|
8
20
|
/**
|
|
9
21
|
* Contains an arbitrary number of elements for user-interactions.
|
|
10
22
|
* It does not make sense to include more than 1 or 2 of these elements within `OverviewItem`.
|
|
11
23
|
*/
|
|
12
|
-
export declare const OverviewItemActions: ({ children, className, hiddenInteractions, ...restProps }: OverviewItemActionsProps) => React.JSX.Element;
|
|
24
|
+
export declare const OverviewItemActions: ({ children, className, hiddenInteractions, delayDisplayChildren, delaySkeleton, ...restProps }: OverviewItemActionsProps) => React.JSX.Element;
|
|
13
25
|
export default OverviewItemActions;
|
|
@@ -3,13 +3,18 @@ import { OverlayProps as BlueprintOverlayProps, SpinnerProps as BlueprintSpinner
|
|
|
3
3
|
type SpinnerPosition = "local" | "inline" | "global";
|
|
4
4
|
type SpinnerSize = "tiny" | "small" | "medium" | "large" | "xlarge" | "inherit";
|
|
5
5
|
type SpinnerStroke = "thin" | "medium" | "bold";
|
|
6
|
-
type Intent = "inherit" | "primary" | "success" | "warning" | "danger";
|
|
6
|
+
type Intent = "inherit" | "primary" | "success" | "warning" | "danger" | "none";
|
|
7
7
|
/** A spinner that is either displayed globally or locally. */
|
|
8
|
-
export interface SpinnerProps extends Omit<BlueprintSpinnerProps, "size"> {
|
|
8
|
+
export interface SpinnerProps extends Omit<BlueprintSpinnerProps, "size" | "intent"> {
|
|
9
9
|
/**
|
|
10
10
|
* intent value or a valid css color definition
|
|
11
|
+
* @deprecated (v25) it will allow in the future only a color value string and that for other states the intent property needs to be used
|
|
11
12
|
*/
|
|
12
13
|
color?: Intent | string;
|
|
14
|
+
/**
|
|
15
|
+
* Intent state of the field item.
|
|
16
|
+
*/
|
|
17
|
+
intent?: Intent;
|
|
13
18
|
/**
|
|
14
19
|
* Additional CSS class names.
|
|
15
20
|
*/
|
|
@@ -53,5 +58,5 @@ export interface SpinnerProps extends Omit<BlueprintSpinnerProps, "size"> {
|
|
|
53
58
|
*/
|
|
54
59
|
description?: string;
|
|
55
60
|
}
|
|
56
|
-
export declare const Spinner: ({ className, color, position, size, stroke, showLocalBackdrop, delay, overlayProps, description, ...otherProps }: SpinnerProps) => React.JSX.Element | null;
|
|
61
|
+
export declare const Spinner: ({ className, color, intent, position, size, stroke, showLocalBackdrop, delay, overlayProps, description, ...otherProps }: SpinnerProps) => React.JSX.Element | null;
|
|
57
62
|
export default Spinner;
|
|
@@ -2,11 +2,11 @@ import React from "react";
|
|
|
2
2
|
import { DataTableHeader as CarbonDataTableHeader, DataTableProps as CarbonDataTableProps, DataTableRow as CarbonDataTableRow } from "@carbon/react";
|
|
3
3
|
import { TableContainerProps as CarbonTableContainerProps } from "@carbon/react/es/components/DataTable/TableContainer";
|
|
4
4
|
import { TableRowHeightSize } from "./Table";
|
|
5
|
-
interface TableDataContainerProps extends Omit<CarbonDataTableProps<Array<Omit<CarbonDataTableRow<Array<CarbonDataTableHeader>>, "cells">>, Array<CarbonDataTableHeader>>, "size" | "overflowMenuOnHover" | "stickyHeader" | "useStaticWidth">, React.TableHTMLAttributes<HTMLTableElement> {
|
|
5
|
+
export interface TableDataContainerProps extends Omit<CarbonDataTableProps<Array<Omit<CarbonDataTableRow<Array<CarbonDataTableHeader>>, "cells">>, Array<CarbonDataTableHeader>>, "size" | "overflowMenuOnHover" | "stickyHeader" | "useStaticWidth">, React.TableHTMLAttributes<HTMLTableElement> {
|
|
6
6
|
children(signature: any): JSX.Element;
|
|
7
7
|
size?: TableRowHeightSize;
|
|
8
8
|
}
|
|
9
|
-
interface TableSimpleContainerProps extends Omit<CarbonTableContainerProps, "description" | "stickyHeader" | "title" | "useStaticWidth">, React.HTMLAttributes<HTMLDivElement> {
|
|
9
|
+
export interface TableSimpleContainerProps extends Omit<CarbonTableContainerProps, "description" | "stickyHeader" | "title" | "useStaticWidth">, React.HTMLAttributes<HTMLDivElement> {
|
|
10
10
|
children?: JSX.Element;
|
|
11
11
|
}
|
|
12
12
|
export type TableContainerProps = TableDataContainerProps | TableSimpleContainerProps;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import React from "react";
|
|
2
2
|
import { TableExpandRow as CarbonTableExpandRow } from "@carbon/react";
|
|
3
3
|
type CarbonTableExpandRowProps = React.ComponentProps<typeof CarbonTableExpandRow>;
|
|
4
|
-
export interface TableExpandRowProps extends Omit<CarbonTableExpandRowProps, "ref" | "ariaLabel" | "expandIconDescription" | "aria-label">, React.HTMLAttributes<HTMLTableRowElement> {
|
|
4
|
+
export interface TableExpandRowProps extends Omit<CarbonTableExpandRowProps, "children" | "ref" | "ariaLabel" | "expandIconDescription" | "aria-label">, React.HTMLAttributes<HTMLTableRowElement> {
|
|
5
5
|
/**
|
|
6
6
|
* This text is displayed as tooltip for the button that toggles the expanded/collapsed state.
|
|
7
7
|
*/
|
|
@@ -5,3 +5,4 @@ export * from "./TableExpandRow";
|
|
|
5
5
|
export * from "./TableExpandHeader";
|
|
6
6
|
export * from "./TableCell";
|
|
7
7
|
export { TableHead, TableBody, TableExpandedRow, TableHeader } from "@carbon/react";
|
|
8
|
+
export type { TableHeadProps, TableBodyProps, TableExpandedRowProps, TableHeaderProps, DataTableRenderProps } from "@carbon/react";
|
|
@@ -25,6 +25,14 @@ export interface TooltipProps extends Omit<BlueprintTooltipProps, "position"> {
|
|
|
25
25
|
* Set properties for the Markdown parser
|
|
26
26
|
*/
|
|
27
27
|
markdownProps?: Omit<MarkdownProps, "children">;
|
|
28
|
+
/**
|
|
29
|
+
* Use the overlay target as placeholder before the real `<Tooltip /` is rendered on first hover or focus event.
|
|
30
|
+
* This can boost performance massive but it is currently experimental.
|
|
31
|
+
* Placeholders are never used when `disabled`, `defaultIsOpen` or `isOpen` is set to `true`, or if `renderTarget` is set.
|
|
32
|
+
* If the tooltip `content` is only a string then a placeholder is automatically used, too.
|
|
33
|
+
* You can prevent it in any case by setting it to `false`.
|
|
34
|
+
*/
|
|
35
|
+
usePlaceholder?: boolean;
|
|
28
36
|
}
|
|
29
|
-
export declare const Tooltip: ({ children, content, className, size, addIndicator, markdownEnabler, markdownProps, ...
|
|
37
|
+
export declare const Tooltip: ({ children, content, className, size, addIndicator, markdownEnabler, markdownProps, usePlaceholder, hoverOpenDelay, ...otherTooltipProps }: TooltipProps) => React.JSX.Element | null;
|
|
30
38
|
export default Tooltip;
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@eccenca/gui-elements",
|
|
3
3
|
"description": "GUI elements based on other libraries, usable in React application, written in Typescript.",
|
|
4
|
-
"version": "24.2.0
|
|
4
|
+
"version": "24.2.0",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"homepage": "https://github.com/eccenca/gui-elements",
|
|
7
7
|
"bugs": "https://github.com/eccenca/gui-elements/issues",
|
|
@@ -94,12 +94,14 @@
|
|
|
94
94
|
"react-flow-renderer": "9.7.4",
|
|
95
95
|
"react-flow-renderer-lts": "npm:react-flow-renderer@^10.3.17",
|
|
96
96
|
"react-inlinesvg": "^3.0.3",
|
|
97
|
-
"react-markdown": "^
|
|
97
|
+
"react-markdown": "^10.1.0",
|
|
98
|
+
"react-markdown-deprecated": "npm:react-markdown@^8.0.7",
|
|
98
99
|
"react-syntax-highlighter": "^15.6.1",
|
|
99
|
-
"rehype-
|
|
100
|
-
"
|
|
101
|
-
"remark-
|
|
102
|
-
"remark-
|
|
100
|
+
"rehype-external-links": "^3.0.0",
|
|
101
|
+
"rehype-raw": "^7.0.0",
|
|
102
|
+
"remark-definition-list": "^2.0.0",
|
|
103
|
+
"remark-gfm": "^4.0.1",
|
|
104
|
+
"remark-parse": "^11.0.0",
|
|
103
105
|
"reset-css": "^5.0.2",
|
|
104
106
|
"unified": "^11.0.5",
|
|
105
107
|
"wicg-inert": "^3.1.3",
|
|
@@ -176,7 +178,8 @@
|
|
|
176
178
|
},
|
|
177
179
|
"resolutions": {
|
|
178
180
|
"**/@types/react": "^17.0.85",
|
|
179
|
-
"node-sass-package-importer/**/postcss": "^8.4.49"
|
|
181
|
+
"node-sass-package-importer/**/postcss": "^8.4.49",
|
|
182
|
+
"hast-util-from-parse5": "8.0.0"
|
|
180
183
|
},
|
|
181
184
|
"husky": {
|
|
182
185
|
"hooks": {
|
|
@@ -1,15 +1,21 @@
|
|
|
1
1
|
import React from "react";
|
|
2
2
|
import ReactMarkdown from "react-markdown";
|
|
3
|
-
|
|
3
|
+
/**
|
|
4
|
+
* Recreate the old type to provide support until next major
|
|
5
|
+
*/
|
|
6
|
+
import { PluggableList as PluggableListDeprecated } from "react-markdown-deprecated/lib/react-markdown";
|
|
4
7
|
import { Prism as SyntaxHighlighter } from "react-syntax-highlighter";
|
|
5
8
|
// @ts-ignore: No declaration file for module (TODO: should be @ts-expect-error but GUI elements is used inside project with `noImplicitAny=false`)
|
|
6
9
|
import remarkTypograf from "@mavrin/remark-typograf";
|
|
10
|
+
import rehypeExternalLinks from "rehype-external-links";
|
|
7
11
|
import rehypeRaw from "rehype-raw";
|
|
8
12
|
import { remarkDefinitionList } from "remark-definition-list";
|
|
9
13
|
import remarkGfm from "remark-gfm";
|
|
14
|
+
import { PluggableList as PluggableListUnified } from "unified";
|
|
10
15
|
|
|
11
16
|
import { CLASSPREFIX as eccgui } from "../../configuration/constants";
|
|
12
17
|
import { HtmlContentBlock, HtmlContentBlockProps, TestableComponent } from "../../index";
|
|
18
|
+
type PluggableList = PluggableListUnified | PluggableListDeprecated;
|
|
13
19
|
|
|
14
20
|
export interface MarkdownProps extends TestableComponent {
|
|
15
21
|
children: string;
|
|
@@ -35,6 +41,7 @@ export interface MarkdownProps extends TestableComponent {
|
|
|
35
41
|
/**
|
|
36
42
|
* Additional reHype plugins to execute.
|
|
37
43
|
* @see https://github.com/remarkjs/react-markdown#architecture
|
|
44
|
+
* @deprecated (v25) this property won't support `PluggableList` from "react-markdown/lib/react-markdown" with the next major version, only the one from `unified` will be supported then.
|
|
38
45
|
*/
|
|
39
46
|
reHypePlugins?: PluggableList;
|
|
40
47
|
/**
|
|
@@ -54,9 +61,9 @@ const configDefault = {
|
|
|
54
61
|
@see https://github.com/remarkjs/react-markdown#api
|
|
55
62
|
*/
|
|
56
63
|
// @see https://github.com/remarkjs/remark/blob/main/doc/plugins.md#list-of-plugins
|
|
57
|
-
remarkPlugins: [remarkGfm, remarkTypograf, remarkDefinitionList] as
|
|
64
|
+
remarkPlugins: [remarkGfm, remarkTypograf, remarkDefinitionList] as PluggableListUnified,
|
|
58
65
|
// @see https://github.com/rehypejs/rehype/blob/main/doc/plugins.md#list-of-plugins
|
|
59
|
-
rehypePlugins: [] as
|
|
66
|
+
rehypePlugins: [] as PluggableListUnified,
|
|
60
67
|
allowedElements: [
|
|
61
68
|
// default markdown
|
|
62
69
|
"a",
|
|
@@ -110,6 +117,13 @@ export const Markdown = ({
|
|
|
110
117
|
htmlContentBlockProps,
|
|
111
118
|
...otherProps
|
|
112
119
|
}: MarkdownProps) => {
|
|
120
|
+
const configHtmlExternalLinks = {
|
|
121
|
+
rel: ["nofollow"],
|
|
122
|
+
target: linkTargetName,
|
|
123
|
+
};
|
|
124
|
+
|
|
125
|
+
configDefault.rehypePlugins = configDefault.rehypePlugins.concat([[rehypeExternalLinks, configHtmlExternalLinks]]);
|
|
126
|
+
|
|
113
127
|
const configHtml = allowHtml
|
|
114
128
|
? {
|
|
115
129
|
rehypePlugins: [...configDefault.rehypePlugins].concat([rehypeRaw]),
|
|
@@ -132,14 +146,10 @@ export const Markdown = ({
|
|
|
132
146
|
...configDefault,
|
|
133
147
|
...configHtml,
|
|
134
148
|
...configTextOnly,
|
|
135
|
-
linkTarget: linkTargetName
|
|
136
|
-
? (href: string, _children: any, _title: string) => {
|
|
137
|
-
const linkTarget = href.charAt(0) !== "#" ? linkTargetName : "";
|
|
138
|
-
return linkTarget as React.HTMLAttributeAnchorTarget;
|
|
139
|
-
}
|
|
140
|
-
: undefined,
|
|
141
149
|
components: {
|
|
150
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
142
151
|
code(props: any) {
|
|
152
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
143
153
|
const { children, className, node, inline, ...rest } = props;
|
|
144
154
|
const match = /language-(\w+)/.exec(className || "");
|
|
145
155
|
return match ? (
|
|
@@ -159,14 +169,15 @@ export const Markdown = ({
|
|
|
159
169
|
);
|
|
160
170
|
},
|
|
161
171
|
},
|
|
172
|
+
allowedElements,
|
|
162
173
|
};
|
|
163
|
-
|
|
164
|
-
reHypePlugins
|
|
165
|
-
|
|
166
|
-
|
|
174
|
+
|
|
175
|
+
if (reHypePlugins) {
|
|
176
|
+
reactMarkdownProperties.rehypePlugins = reactMarkdownProperties.rehypePlugins.concat(
|
|
177
|
+
reHypePlugins as PluggableListUnified
|
|
167
178
|
);
|
|
179
|
+
}
|
|
168
180
|
|
|
169
|
-
// @ts-ignore because against the lib spec it does not allow a function for linkTarget.
|
|
170
181
|
const markdownDisplay = <ReactMarkdown {...reactMarkdownProperties} />;
|
|
171
182
|
return inheritBlock && !(otherProps["data-test-id"] || htmlContentBlockProps) ? (
|
|
172
183
|
markdownDisplay
|
|
@@ -9,7 +9,12 @@ describe("Highlight search words reHype plugin", () => {
|
|
|
9
9
|
const highlightSearchWordsPlugin = markdownUtils.highlightSearchWordsPluginFactory(searchQuery);
|
|
10
10
|
const highlightSearchWordTransformer = highlightSearchWordsPlugin();
|
|
11
11
|
const textNode = (text: string): Text => ({ type: "text", value: text });
|
|
12
|
-
const markNode = (text: string): Element => ({
|
|
12
|
+
const markNode = (text: string): Element => ({
|
|
13
|
+
type: "element",
|
|
14
|
+
tagName: "mark",
|
|
15
|
+
properties: {},
|
|
16
|
+
children: [textNode(text)],
|
|
17
|
+
});
|
|
13
18
|
const result = highlightSearchWordTransformer(
|
|
14
19
|
{
|
|
15
20
|
type: "root",
|
|
@@ -17,12 +22,13 @@ describe("Highlight search words reHype plugin", () => {
|
|
|
17
22
|
{
|
|
18
23
|
type: "element",
|
|
19
24
|
tagName: "p",
|
|
25
|
+
properties: {},
|
|
20
26
|
children: [textNode("Text with abc query words xyz.")],
|
|
21
27
|
},
|
|
22
28
|
],
|
|
23
29
|
},
|
|
24
30
|
new VFile(),
|
|
25
|
-
|
|
31
|
+
|
|
26
32
|
() => {}
|
|
27
33
|
);
|
|
28
34
|
const rootChildren = (result as Root).children;
|
|
@@ -25,7 +25,12 @@ const highlightSearchWordsPluginFactory = (searchQuery: string | undefined) => {
|
|
|
25
25
|
let matchArray = multiWordRegex.exec(text);
|
|
26
26
|
while (matchArray !== null) {
|
|
27
27
|
result.push(createTextNode(text.slice(offset, matchArray.index)));
|
|
28
|
-
result.push({
|
|
28
|
+
result.push({
|
|
29
|
+
type: "element",
|
|
30
|
+
tagName: "mark",
|
|
31
|
+
properties: {},
|
|
32
|
+
children: [createTextNode(matchArray[0])],
|
|
33
|
+
});
|
|
29
34
|
offset = multiWordRegex.lastIndex;
|
|
30
35
|
matchArray = multiWordRegex.exec(text);
|
|
31
36
|
}
|
|
@@ -1,16 +1,16 @@
|
|
|
1
1
|
import { CLASSPREFIX as eccgui } from "../../configuration/constants";
|
|
2
|
+
import { Intent as BlueprintIntent } from "@blueprintjs/core";
|
|
2
3
|
|
|
3
|
-
export type
|
|
4
|
+
export type IntentBlueprint = BlueprintIntent;
|
|
5
|
+
export const DefinitionsBlueprint = BlueprintIntent;
|
|
6
|
+
|
|
7
|
+
export type IntentTypes = IntentBlueprint | "neutral" | "accent" | "info";
|
|
4
8
|
|
|
5
9
|
export const Definitions: { [key: string]: IntentTypes } = {
|
|
6
|
-
|
|
10
|
+
...DefinitionsBlueprint,
|
|
7
11
|
ACCENT: "accent",
|
|
8
12
|
NEUTRAL: "neutral",
|
|
9
|
-
NONE: "none",
|
|
10
|
-
SUCCESS: "success",
|
|
11
13
|
INFO: "info",
|
|
12
|
-
WARNING: "warning",
|
|
13
|
-
DANGER: "danger",
|
|
14
14
|
};
|
|
15
15
|
|
|
16
16
|
export const intentClassName = (intent: IntentTypes) => {
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
/* eslint-disable @typescript-eslint/no-explicit-any */
|
|
1
2
|
import React, { useEffect, useMemo, useState } from "react";
|
|
2
3
|
import { Classes as BlueprintClassNames } from "@blueprintjs/core";
|
|
3
4
|
import { EditorView, Rect } from "@codemirror/view";
|
|
@@ -207,7 +208,7 @@ const AutoSuggestion = ({
|
|
|
207
208
|
const suggestionRequestData = React.useRef<RequestMetaData>({ requestId: undefined });
|
|
208
209
|
const [pathValidationPending, setPathValidationPending] = React.useState(false);
|
|
209
210
|
const validationRequestData = React.useRef<RequestMetaData>({ requestId: undefined });
|
|
210
|
-
const
|
|
211
|
+
const errorMarkers = React.useRef<any[]>([])
|
|
211
212
|
const [validationResponse, setValidationResponse] = useState<CodeAutocompleteFieldValidationResult | undefined>(
|
|
212
213
|
undefined
|
|
213
214
|
);
|
|
@@ -219,8 +220,8 @@ const AutoSuggestion = ({
|
|
|
219
220
|
CodeAutocompleteFieldSuggestionWithReplacementInfo | undefined
|
|
220
221
|
>(undefined);
|
|
221
222
|
const [cm, setCM] = React.useState<EditorView>();
|
|
222
|
-
const currentCm = React.useRef<EditorView>()
|
|
223
|
-
currentCm.current = cm
|
|
223
|
+
const currentCm = React.useRef<EditorView>();
|
|
224
|
+
currentCm.current = cm;
|
|
224
225
|
const isFocused = React.useRef(false);
|
|
225
226
|
const autoSuggestionDivRef = React.useRef<HTMLDivElement>(null);
|
|
226
227
|
/** Mutable editor state, since this needs to be current in scope of the SingleLineEditorComponent. */
|
|
@@ -242,16 +243,16 @@ const AutoSuggestion = ({
|
|
|
242
243
|
changes: { from: 0, to: currentCm.current.state?.doc.length, insert: initialValue },
|
|
243
244
|
});
|
|
244
245
|
// Validate initial value change
|
|
245
|
-
checkValuePathValidity(initialValue)
|
|
246
|
+
checkValuePathValidity(initialValue);
|
|
246
247
|
}
|
|
247
248
|
}, [initialValue, reInitOnInitialValueChange]);
|
|
248
249
|
|
|
249
250
|
React.useEffect(() => {
|
|
250
|
-
if(currentCm.current) {
|
|
251
|
+
if (currentCm.current) {
|
|
251
252
|
// Validate initial value
|
|
252
|
-
checkValuePathValidity(initialValue)
|
|
253
|
+
checkValuePathValidity(initialValue);
|
|
253
254
|
}
|
|
254
|
-
}, [currentCm.current
|
|
255
|
+
}, [!!currentCm.current]);
|
|
255
256
|
|
|
256
257
|
const setCurrentIndex = (newIndex: number) => {
|
|
257
258
|
editorState.index = newIndex;
|
|
@@ -263,10 +264,9 @@ const AutoSuggestion = ({
|
|
|
263
264
|
editorState.cm = cm;
|
|
264
265
|
}, [cm, editorState]);
|
|
265
266
|
|
|
266
|
-
const dispatch =
|
|
267
|
-
(
|
|
268
|
-
|
|
269
|
-
) as EditorView["dispatch"];
|
|
267
|
+
const dispatch = (
|
|
268
|
+
typeof editorState?.cm?.dispatch === "function" ? editorState?.cm?.dispatch : () => {}
|
|
269
|
+
) as EditorView["dispatch"];
|
|
270
270
|
|
|
271
271
|
React.useEffect(() => {
|
|
272
272
|
editorState.dropdownShown = shouldShowDropdown;
|
|
@@ -288,8 +288,9 @@ const AutoSuggestion = ({
|
|
|
288
288
|
return () => removeMarkFromText({ view: cm, from, to });
|
|
289
289
|
}
|
|
290
290
|
} else {
|
|
291
|
-
|
|
292
|
-
|
|
291
|
+
if (cm) {
|
|
292
|
+
removeMarkFromText({ view: cm, from: 0, to: cm.state?.doc.length });
|
|
293
|
+
}
|
|
293
294
|
}
|
|
294
295
|
return;
|
|
295
296
|
}, [highlightedElement, selectedTextRanges, cm]);
|
|
@@ -298,32 +299,32 @@ const AutoSuggestion = ({
|
|
|
298
299
|
React.useEffect(() => {
|
|
299
300
|
const parseError = validationResponse?.parseError;
|
|
300
301
|
if (cm) {
|
|
302
|
+
const clearCurrentErrorMarker = () => {
|
|
303
|
+
if(errorMarkers.current.length) {
|
|
304
|
+
const [from, to] = errorMarkers.current;
|
|
305
|
+
removeMarkFromText({ view: cm, from, to })
|
|
306
|
+
errorMarkers.current = []
|
|
307
|
+
}
|
|
308
|
+
}
|
|
301
309
|
if (parseError) {
|
|
302
310
|
const { message, start, end } = parseError;
|
|
303
311
|
const { toOffset, fromOffset } = getOffsetRange(cm, start, end);
|
|
304
|
-
|
|
312
|
+
clearCurrentErrorMarker()
|
|
313
|
+
const {from, to} = markText({
|
|
305
314
|
view: cm,
|
|
306
315
|
from: fromOffset,
|
|
307
316
|
to: toOffset,
|
|
308
317
|
className: `${eccgui}-autosuggestion__text--highlighted-error`,
|
|
309
318
|
title: message,
|
|
310
319
|
});
|
|
311
|
-
|
|
312
|
-
setErrorMarkers((previousMarkers) => {
|
|
313
|
-
previousMarkers.forEach((m) => removeMarkFromText({ view: cm, from: m.from, to: m.to }));
|
|
314
|
-
return [from, to];
|
|
315
|
-
});
|
|
320
|
+
errorMarkers.current = [from, to]
|
|
316
321
|
} else {
|
|
317
|
-
|
|
318
|
-
setErrorMarkers((previous) => {
|
|
319
|
-
previous.forEach((m) => removeMarkFromText({ view: cm, from: m.from, to: m.to }));
|
|
320
|
-
return [];
|
|
321
|
-
});
|
|
322
|
+
clearCurrentErrorMarker()
|
|
322
323
|
}
|
|
323
324
|
}
|
|
324
325
|
|
|
325
326
|
const isValid = validationResponse?.valid === undefined || validationResponse.valid;
|
|
326
|
-
onInputChecked
|
|
327
|
+
onInputChecked?.(isValid);
|
|
327
328
|
}, [validationResponse?.valid, validationResponse?.parseError, cm, onInputChecked]);
|
|
328
329
|
|
|
329
330
|
/** generate suggestions and also populate the replacement indexes dict */
|
|
@@ -390,6 +391,7 @@ const AutoSuggestion = ({
|
|
|
390
391
|
try {
|
|
391
392
|
const result: CodeAutocompleteFieldValidationResult | undefined = await checkInput(inputString);
|
|
392
393
|
setValidationResponse(result);
|
|
394
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
393
395
|
} catch (e) {
|
|
394
396
|
setValidationResponse(undefined);
|
|
395
397
|
// TODO: Error handling
|
|
@@ -425,6 +427,7 @@ const AutoSuggestion = ({
|
|
|
425
427
|
setSuggestionResponse(result);
|
|
426
428
|
}
|
|
427
429
|
}
|
|
430
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
428
431
|
} catch (e) {
|
|
429
432
|
setSuggestionResponse(undefined);
|
|
430
433
|
// TODO: Error handling
|
|
@@ -445,12 +448,14 @@ const AutoSuggestion = ({
|
|
|
445
448
|
[asyncHandleEditorInputChange, autoCompletionRequestDelay]
|
|
446
449
|
);
|
|
447
450
|
|
|
448
|
-
const handleChange = (
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
451
|
+
const handleChange = React.useMemo( () => {
|
|
452
|
+
return (val: string) => {
|
|
453
|
+
value.current = val;
|
|
454
|
+
checkValuePathValidity.cancel();
|
|
455
|
+
checkValuePathValidity(value.current);
|
|
456
|
+
onChange(val);
|
|
457
|
+
}
|
|
458
|
+
}, [onChange, checkValuePathValidity]);
|
|
454
459
|
|
|
455
460
|
const handleCursorChange = (cursor: number, coords: Rect, scrollinfo: HTMLElement, view: EditorView) => {
|
|
456
461
|
//cursor here is offset from line 1, autosuggestion works with cursor per-line.
|
|
@@ -534,8 +539,13 @@ const AutoSuggestion = ({
|
|
|
534
539
|
};
|
|
535
540
|
|
|
536
541
|
const handleInputFocus = (focusState: boolean) => {
|
|
537
|
-
onFocusChange
|
|
538
|
-
|
|
542
|
+
onFocusChange?.(focusState);
|
|
543
|
+
if (focusState) {
|
|
544
|
+
setShouldShowDropdown(true);
|
|
545
|
+
} else {
|
|
546
|
+
closeDropDown();
|
|
547
|
+
}
|
|
548
|
+
|
|
539
549
|
if (!isFocused.current && focusState) {
|
|
540
550
|
// Just got focus
|
|
541
551
|
// Clear suggestions and repeat suggestion request, something else might have changed while this component was not focused
|