@eccenca/gui-elements 24.2.0-rc.1 → 24.2.0-rc.2

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.
Files changed (109) hide show
  1. package/CHANGELOG.md +52 -0
  2. package/README.md +10 -7
  3. package/dist/cjs/cmem/markdown/Markdown.js +13 -11
  4. package/dist/cjs/cmem/markdown/Markdown.js.map +1 -1
  5. package/dist/cjs/cmem/markdown/highlightSearchWords.js +6 -1
  6. package/dist/cjs/cmem/markdown/highlightSearchWords.js.map +1 -1
  7. package/dist/cjs/common/Intent/index.js +4 -11
  8. package/dist/cjs/common/Intent/index.js.map +1 -1
  9. package/dist/cjs/components/AutoSuggestion/AutoSuggestion.js +27 -18
  10. package/dist/cjs/components/AutoSuggestion/AutoSuggestion.js.map +1 -1
  11. package/dist/cjs/components/Button/Button.js +2 -2
  12. package/dist/cjs/components/Button/Button.js.map +1 -1
  13. package/dist/cjs/components/ContextOverlay/ContextMenu.js +3 -2
  14. package/dist/cjs/components/ContextOverlay/ContextMenu.js.map +1 -1
  15. package/dist/cjs/components/ContextOverlay/ContextOverlay.js +46 -2
  16. package/dist/cjs/components/ContextOverlay/ContextOverlay.js.map +1 -1
  17. package/dist/cjs/components/Form/FieldItem.js +3 -2
  18. package/dist/cjs/components/Form/FieldItem.js.map +1 -1
  19. package/dist/cjs/components/Form/FieldSet.js +3 -2
  20. package/dist/cjs/components/Form/FieldSet.js.map +1 -1
  21. package/dist/cjs/components/Icon/canonicalIconNames.js +1 -0
  22. package/dist/cjs/components/Icon/canonicalIconNames.js.map +1 -1
  23. package/dist/cjs/components/MultiSelect/MultiSelect.js +18 -14
  24. package/dist/cjs/components/MultiSelect/MultiSelect.js.map +1 -1
  25. package/dist/cjs/components/Notification/Notification.js +7 -4
  26. package/dist/cjs/components/Notification/Notification.js.map +1 -1
  27. package/dist/cjs/components/OverviewItem/OverviewItemActions.js +9 -2
  28. package/dist/cjs/components/OverviewItem/OverviewItemActions.js.map +1 -1
  29. package/dist/cjs/components/Spinner/Spinner.js +7 -5
  30. package/dist/cjs/components/Spinner/Spinner.js.map +1 -1
  31. package/dist/cjs/components/Tooltip/Tooltip.js +75 -7
  32. package/dist/cjs/components/Tooltip/Tooltip.js.map +1 -1
  33. package/dist/esm/cmem/markdown/Markdown.js +13 -11
  34. package/dist/esm/cmem/markdown/Markdown.js.map +1 -1
  35. package/dist/esm/cmem/markdown/highlightSearchWords.js +6 -1
  36. package/dist/esm/cmem/markdown/highlightSearchWords.js.map +1 -1
  37. package/dist/esm/common/Intent/index.js +14 -10
  38. package/dist/esm/common/Intent/index.js.map +1 -1
  39. package/dist/esm/components/AutoSuggestion/AutoSuggestion.js +32 -25
  40. package/dist/esm/components/AutoSuggestion/AutoSuggestion.js.map +1 -1
  41. package/dist/esm/components/Button/Button.js +2 -2
  42. package/dist/esm/components/Button/Button.js.map +1 -1
  43. package/dist/esm/components/ContextOverlay/ContextMenu.js +3 -2
  44. package/dist/esm/components/ContextOverlay/ContextMenu.js.map +1 -1
  45. package/dist/esm/components/ContextOverlay/ContextOverlay.js +63 -3
  46. package/dist/esm/components/ContextOverlay/ContextOverlay.js.map +1 -1
  47. package/dist/esm/components/Form/FieldItem.js +3 -2
  48. package/dist/esm/components/Form/FieldItem.js.map +1 -1
  49. package/dist/esm/components/Form/FieldSet.js +3 -2
  50. package/dist/esm/components/Form/FieldSet.js.map +1 -1
  51. package/dist/esm/components/Icon/canonicalIconNames.js +1 -0
  52. package/dist/esm/components/Icon/canonicalIconNames.js.map +1 -1
  53. package/dist/esm/components/MultiSelect/MultiSelect.js +18 -14
  54. package/dist/esm/components/MultiSelect/MultiSelect.js.map +1 -1
  55. package/dist/esm/components/Notification/Notification.js +7 -4
  56. package/dist/esm/components/Notification/Notification.js.map +1 -1
  57. package/dist/esm/components/OverviewItem/OverviewItemActions.js +25 -2
  58. package/dist/esm/components/OverviewItem/OverviewItemActions.js.map +1 -1
  59. package/dist/esm/components/Spinner/Spinner.js +9 -5
  60. package/dist/esm/components/Spinner/Spinner.js.map +1 -1
  61. package/dist/esm/components/Tooltip/Tooltip.js +92 -8
  62. package/dist/esm/components/Tooltip/Tooltip.js.map +1 -1
  63. package/dist/types/cmem/markdown/Markdown.d.ts +8 -1
  64. package/dist/types/common/Intent/index.d.ts +10 -1
  65. package/dist/types/components/Button/Button.d.ts +5 -1
  66. package/dist/types/components/ContextOverlay/ContextMenu.d.ts +9 -2
  67. package/dist/types/components/ContextOverlay/ContextOverlay.d.ts +6 -1
  68. package/dist/types/components/Form/FieldItem.d.ts +10 -1
  69. package/dist/types/components/Form/FieldSet.d.ts +10 -1
  70. package/dist/types/components/Icon/canonicalIconNames.d.ts +1 -0
  71. package/dist/types/components/MultiSelect/MultiSelect.d.ts +12 -4
  72. package/dist/types/components/Notification/Notification.d.ts +10 -1
  73. package/dist/types/components/OverviewItem/OverviewItemActions.d.ts +13 -1
  74. package/dist/types/components/Spinner/Spinner.d.ts +8 -3
  75. package/dist/types/components/Table/TableContainer.d.ts +2 -2
  76. package/dist/types/components/Table/TableExpandRow.d.ts +1 -1
  77. package/dist/types/components/Table/index.d.ts +1 -0
  78. package/dist/types/components/Tooltip/Tooltip.d.ts +9 -1
  79. package/package.json +10 -7
  80. package/src/cmem/markdown/Markdown.tsx +25 -14
  81. package/src/cmem/markdown/highlightSearchWords.test.ts +8 -2
  82. package/src/cmem/markdown/highlightSearchWords.ts +6 -1
  83. package/src/common/Intent/index.ts +6 -6
  84. package/src/components/AutoSuggestion/AutoSuggestion.tsx +35 -27
  85. package/src/components/Button/Button.stories.tsx +10 -6
  86. package/src/components/Button/Button.tsx +7 -2
  87. package/src/components/ContextOverlay/ContextMenu.stories.tsx +1 -1
  88. package/src/components/ContextOverlay/ContextMenu.tsx +26 -13
  89. package/src/components/ContextOverlay/ContextOverlay.tsx +83 -5
  90. package/src/components/Form/FieldItem.tsx +14 -3
  91. package/src/components/Form/FieldSet.tsx +13 -2
  92. package/src/components/Form/Stories/FieldItem.stories.tsx +4 -0
  93. package/src/components/Form/Stories/FieldSet.stories.tsx +4 -0
  94. package/src/components/Icon/canonicalIconNames.tsx +1 -0
  95. package/src/components/MultiSelect/MultiSelect.tsx +27 -15
  96. package/src/components/MultiSuggestField/MultiSuggestField.stories.tsx +6 -0
  97. package/src/components/Notification/Notification.stories.tsx +4 -0
  98. package/src/components/Notification/Notification.tsx +17 -4
  99. package/src/components/OverviewItem/OverviewItemActions.tsx +24 -1
  100. package/src/components/OverviewItem/stories/OverviewItemList.stories.tsx +2 -7
  101. package/src/components/OverviewItem/stories/OverviewItemListPerformance.tsx +174 -0
  102. package/src/components/OverviewItem/stories/OverviewItemPerformance.stories.tsx +19 -0
  103. package/src/components/Spinner/Spinner.tsx +13 -5
  104. package/src/components/Spinner/Stories/spinner.stories.tsx +6 -1
  105. package/src/components/Table/TableContainer.tsx +2 -2
  106. package/src/components/Table/TableExpandRow.tsx +1 -1
  107. package/src/components/Table/index.tsx +1 -0
  108. package/src/components/Tooltip/Tooltip.stories.tsx +3 -2
  109. 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 success (some type of orange) color scheme.
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 success (some type of red) color scheme.
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, ...otherProps }: TooltipProps) => React.JSX.Element;
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-rc.1",
4
+ "version": "24.2.0-rc.2",
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": "^8.0.7",
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-raw": "^6.1.1",
100
- "remark-definition-list": "^1.2.0",
101
- "remark-gfm": "^3.0.1",
102
- "remark-parse": "^10.0.2",
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
- import { PluggableList } from "react-markdown/lib/react-markdown";
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 PluggableList,
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 PluggableList,
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
- allowedElements && (reactMarkdownProperties.allowedElements = allowedElements);
164
- reHypePlugins &&
165
- reHypePlugins.forEach(
166
- (plugin) => (reactMarkdownProperties.rehypePlugins = [...reactMarkdownProperties.rehypePlugins, plugin])
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 => ({ type: "element", tagName: "mark", children: [textNode(text)] });
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
- // eslint-disable-next-line @typescript-eslint/no-empty-function
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({ type: "element", tagName: "mark", children: [createTextNode(matchArray[0])] });
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 IntentTypes = "none" | "neutral" | "primary" | "accent" | "info" | "success" | "warning" | "danger";
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
- PRIMARY: "primary",
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 [, setErrorMarkers] = React.useState<any[]>([]);
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 = // eslint-disable-next-line @typescript-eslint/no-empty-function
267
- (
268
- typeof editorState?.cm?.dispatch === "function" ? editorState?.cm?.dispatch : () => {}
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
- //remove redundant markers
292
- cm && removeMarkFromText({ view: cm, from: 0, to: cm.state?.doc.length });
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
- const { from, to } = markText({
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
- // Valid, clear all error markers
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 && onInputChecked(isValid);
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
@@ -534,8 +537,13 @@ const AutoSuggestion = ({
534
537
  };
535
538
 
536
539
  const handleInputFocus = (focusState: boolean) => {
537
- onFocusChange && onFocusChange(focusState);
538
- focusState ? setShouldShowDropdown(true) : closeDropDown();
540
+ onFocusChange?.(focusState);
541
+ if (focusState) {
542
+ setShouldShowDropdown(true);
543
+ } else {
544
+ closeDropDown();
545
+ }
546
+
539
547
  if (!isFocused.current && focusState) {
540
548
  // Just got focus
541
549
  // Clear suggestions and repeat suggestion request, something else might have changed while this component was not focused
@@ -18,6 +18,10 @@ export default {
18
18
  onClick: {
19
19
  action: "clicked",
20
20
  },
21
+ intent: {
22
+ ...helpersArgTypes.exampleIntent,
23
+ options: ["UNDEFINED", "primary", "success", "warning", "danger"],
24
+ },
21
25
  },
22
26
  } as Meta<typeof Button>;
23
27
 
@@ -67,17 +71,17 @@ const TemplateSemantic: StoryFn<typeof Button> = (args) => (
67
71
  export const ButtonSemantics = TemplateSemantic.bind({});
68
72
  ButtonSemantics.args = FullExample.args;
69
73
 
70
- const TemplateState: StoryFn<typeof Button> = (args) => (
74
+ const TemplateIntent: StoryFn<typeof Button> = (args) => (
71
75
  <OverlaysProvider>
72
- <Button {...args} text="Success" hasStateSuccess />
76
+ <Button {...args} text="Success" intent="success" />
73
77
  <Spacing vertical />
74
- <Button {...args} text="Warning" hasStateWarning />
78
+ <Button {...args} text="Warning" intent="warning" />
75
79
  <Spacing vertical />
76
- <Button {...args} text="Danger" hasStateDanger />
80
+ <Button {...args} text="Danger" intent="danger" />
77
81
  </OverlaysProvider>
78
82
  );
79
- export const ButtonStates = TemplateState.bind({});
80
- ButtonStates.args = FullExample.args;
83
+ export const ButtonIntent = TemplateIntent.bind({});
84
+ ButtonIntent.args = FullExample.args;
81
85
 
82
86
  const TemplateContent: StoryFn<typeof Button> = (args) => (
83
87
  <OverlaysProvider>