@eccenca/gui-elements 23.0.0-rc.7 → 23.1.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.
Files changed (248) hide show
  1. package/CHANGELOG.md +58 -20
  2. package/README.md +7 -0
  3. package/dist/cjs/cmem/ActivityControl/ActivityControlWidget.js.map +1 -1
  4. package/dist/cjs/cmem/react-flow/ReactFlow/ReactFlow.js +7 -2
  5. package/dist/cjs/cmem/react-flow/ReactFlow/ReactFlow.js.map +1 -1
  6. package/dist/cjs/cmem/react-flow/StickyNoteModal/StickyNoteModal.js +3 -7
  7. package/dist/cjs/cmem/react-flow/StickyNoteModal/StickyNoteModal.js.map +1 -1
  8. package/dist/cjs/cmem/react-flow/extensions/scrollOnDragHook.js +200 -0
  9. package/dist/cjs/cmem/react-flow/extensions/scrollOnDragHook.js.map +1 -0
  10. package/dist/cjs/common/Intent/index.js +7 -3
  11. package/dist/cjs/common/Intent/index.js.map +1 -1
  12. package/dist/cjs/common/utils/characters.js +82 -0
  13. package/dist/cjs/common/utils/characters.js.map +1 -0
  14. package/dist/cjs/components/Application/ApplicationTitle.js +2 -2
  15. package/dist/cjs/components/Application/ApplicationTitle.js.map +1 -1
  16. package/dist/cjs/components/Badge/Badge.js +44 -0
  17. package/dist/cjs/components/Badge/Badge.js.map +1 -0
  18. package/dist/cjs/components/Depiction/Depiction.js +111 -0
  19. package/dist/cjs/components/Depiction/Depiction.js.map +1 -0
  20. package/dist/cjs/components/Grid/Grid.js +7 -2
  21. package/dist/cjs/components/Grid/Grid.js.map +1 -1
  22. package/dist/cjs/components/Grid/GridColumn.js +6 -2
  23. package/dist/cjs/components/Grid/GridColumn.js.map +1 -1
  24. package/dist/cjs/components/Grid/GridRow.js +3 -0
  25. package/dist/cjs/components/Grid/GridRow.js.map +1 -1
  26. package/dist/cjs/components/Icon/BaseIcon.js +38 -0
  27. package/dist/cjs/components/Icon/BaseIcon.js.map +1 -0
  28. package/dist/cjs/components/Icon/Icon.js +9 -24
  29. package/dist/cjs/components/Icon/Icon.js.map +1 -1
  30. package/dist/cjs/components/Icon/IconButton.js +8 -1
  31. package/dist/cjs/components/Icon/IconButton.js.map +1 -1
  32. package/dist/cjs/components/Icon/TestIcon.js +35 -0
  33. package/dist/cjs/components/Icon/TestIcon.js.map +1 -0
  34. package/dist/cjs/components/Icon/canonicalIconNames.js +123 -621
  35. package/dist/cjs/components/Icon/canonicalIconNames.js.map +1 -1
  36. package/dist/cjs/components/Icon/index.js +11 -0
  37. package/dist/cjs/components/Icon/index.js.map +1 -0
  38. package/dist/cjs/components/Menu/MenuItem.js +1 -1
  39. package/dist/cjs/components/Menu/MenuItem.js.map +1 -1
  40. package/dist/cjs/components/MultiSelect/MultiSelect.js +56 -23
  41. package/dist/cjs/components/MultiSelect/MultiSelect.js.map +1 -1
  42. package/dist/cjs/components/Notification/Notification.js +10 -2
  43. package/dist/cjs/components/Notification/Notification.js.map +1 -1
  44. package/dist/cjs/components/OverviewItem/OverviewItemDepiction.js +24 -0
  45. package/dist/cjs/components/OverviewItem/OverviewItemDepiction.js.map +1 -1
  46. package/dist/cjs/components/Tag/Tag.js +6 -2
  47. package/dist/cjs/components/Tag/Tag.js.map +1 -1
  48. package/dist/cjs/components/TextField/TextArea.js +4 -2
  49. package/dist/cjs/components/TextField/TextArea.js.map +1 -1
  50. package/dist/cjs/components/TextField/TextField.js +4 -2
  51. package/dist/cjs/components/TextField/TextField.js.map +1 -1
  52. package/dist/cjs/components/TextField/useTextValidation.js +84 -0
  53. package/dist/cjs/components/TextField/useTextValidation.js.map +1 -0
  54. package/dist/cjs/components/Tree/Tree.js.map +1 -1
  55. package/dist/cjs/components/Typography/Highlighter.js.map +1 -1
  56. package/dist/cjs/components/Typography/OverflowText.js.map +1 -1
  57. package/dist/cjs/components/Typography/WhiteSpaceContainer.js +35 -12
  58. package/dist/cjs/components/Typography/WhiteSpaceContainer.js.map +1 -1
  59. package/dist/cjs/components/Typography/index.js +21 -0
  60. package/dist/cjs/components/Typography/index.js.map +1 -0
  61. package/dist/cjs/components/Workspace/WorkspaceContent.js +1 -1
  62. package/dist/cjs/components/Workspace/WorkspaceContent.js.map +1 -1
  63. package/dist/cjs/components/index.js +18 -0
  64. package/dist/cjs/components/index.js.map +1 -0
  65. package/dist/cjs/index.js +7 -17
  66. package/dist/cjs/index.js.map +1 -1
  67. package/dist/esm/cmem/ActivityControl/ActivityControlWidget.js.map +1 -1
  68. package/dist/esm/cmem/react-flow/ReactFlow/ReactFlow.js +7 -2
  69. package/dist/esm/cmem/react-flow/ReactFlow/ReactFlow.js.map +1 -1
  70. package/dist/esm/cmem/react-flow/StickyNoteModal/StickyNoteModal.js +3 -6
  71. package/dist/esm/cmem/react-flow/StickyNoteModal/StickyNoteModal.js.map +1 -1
  72. package/dist/esm/cmem/react-flow/extensions/scrollOnDragHook.js +194 -0
  73. package/dist/esm/cmem/react-flow/extensions/scrollOnDragHook.js.map +1 -0
  74. package/dist/esm/common/Intent/index.js +5 -13
  75. package/dist/esm/common/Intent/index.js.map +1 -1
  76. package/dist/esm/common/utils/characters.js +96 -0
  77. package/dist/esm/common/utils/characters.js.map +1 -0
  78. package/dist/esm/components/Application/ApplicationTitle.js +2 -2
  79. package/dist/esm/components/Application/ApplicationTitle.js.map +1 -1
  80. package/dist/esm/components/Badge/Badge.js +48 -0
  81. package/dist/esm/components/Badge/Badge.js.map +1 -0
  82. package/dist/esm/components/Depiction/Depiction.js +96 -0
  83. package/dist/esm/components/Depiction/Depiction.js.map +1 -0
  84. package/dist/esm/components/Grid/Grid.js +7 -2
  85. package/dist/esm/components/Grid/Grid.js.map +1 -1
  86. package/dist/esm/components/Grid/GridColumn.js +6 -2
  87. package/dist/esm/components/Grid/GridColumn.js.map +1 -1
  88. package/dist/esm/components/Grid/GridRow.js +3 -0
  89. package/dist/esm/components/Grid/GridRow.js.map +1 -1
  90. package/dist/esm/components/Icon/BaseIcon.js +44 -0
  91. package/dist/esm/components/Icon/BaseIcon.js.map +1 -0
  92. package/dist/esm/components/Icon/Icon.js +9 -24
  93. package/dist/esm/components/Icon/Icon.js.map +1 -1
  94. package/dist/esm/components/Icon/IconButton.js +8 -1
  95. package/dist/esm/components/Icon/IconButton.js.map +1 -1
  96. package/dist/esm/components/Icon/TestIcon.js +41 -0
  97. package/dist/esm/components/Icon/TestIcon.js.map +1 -0
  98. package/dist/esm/components/Icon/canonicalIconNames.js +123 -621
  99. package/dist/esm/components/Icon/canonicalIconNames.js.map +1 -1
  100. package/dist/esm/components/Icon/index.js +4 -0
  101. package/dist/esm/components/Icon/index.js.map +1 -0
  102. package/dist/esm/components/Menu/MenuItem.js +1 -1
  103. package/dist/esm/components/Menu/MenuItem.js.map +1 -1
  104. package/dist/esm/components/MultiSelect/MultiSelect.js +61 -44
  105. package/dist/esm/components/MultiSelect/MultiSelect.js.map +1 -1
  106. package/dist/esm/components/Notification/Notification.js +12 -4
  107. package/dist/esm/components/Notification/Notification.js.map +1 -1
  108. package/dist/esm/components/OverviewItem/OverviewItemDepiction.js +24 -0
  109. package/dist/esm/components/OverviewItem/OverviewItemDepiction.js.map +1 -1
  110. package/dist/esm/components/Tag/Tag.js +6 -2
  111. package/dist/esm/components/Tag/Tag.js.map +1 -1
  112. package/dist/esm/components/TextField/TextArea.js +4 -2
  113. package/dist/esm/components/TextField/TextArea.js.map +1 -1
  114. package/dist/esm/components/TextField/TextField.js +4 -2
  115. package/dist/esm/components/TextField/TextField.js.map +1 -1
  116. package/dist/esm/components/TextField/useTextValidation.js +78 -0
  117. package/dist/esm/components/TextField/useTextValidation.js.map +1 -0
  118. package/dist/esm/components/Tree/Tree.js.map +1 -1
  119. package/dist/esm/components/Typography/Highlighter.js.map +1 -1
  120. package/dist/esm/components/Typography/OverflowText.js.map +1 -1
  121. package/dist/esm/components/Typography/WhiteSpaceContainer.js +16 -14
  122. package/dist/esm/components/Typography/WhiteSpaceContainer.js.map +1 -1
  123. package/dist/esm/components/Typography/index.js +12 -0
  124. package/dist/esm/components/Typography/index.js.map +1 -0
  125. package/dist/esm/components/Workspace/WorkspaceContent.js +1 -1
  126. package/dist/esm/components/Workspace/WorkspaceContent.js.map +1 -1
  127. package/dist/esm/components/index.js +6 -0
  128. package/dist/esm/components/index.js.map +1 -0
  129. package/dist/esm/index.js +5 -10
  130. package/dist/esm/index.js.map +1 -1
  131. package/dist/types/cmem/ActivityControl/ActivityControlWidget.d.ts +2 -1
  132. package/dist/types/cmem/react-flow/ReactFlow/ReactFlow.d.ts +14 -0
  133. package/dist/types/cmem/react-flow/extensions/scrollOnDragHook.d.ts +22 -0
  134. package/dist/types/common/Intent/index.d.ts +4 -3
  135. package/dist/types/common/utils/characters.d.ts +19 -0
  136. package/dist/types/components/Badge/Badge.d.ts +42 -0
  137. package/dist/types/components/Depiction/Depiction.d.ts +71 -0
  138. package/dist/types/components/Grid/Grid.d.ts +21 -2
  139. package/dist/types/components/Grid/GridColumn.d.ts +20 -2
  140. package/dist/types/components/Grid/GridRow.d.ts +17 -1
  141. package/dist/types/components/Icon/BaseIcon.d.ts +45 -0
  142. package/dist/types/components/Icon/Icon.d.ts +7 -34
  143. package/dist/types/components/Icon/IconButton.d.ts +3 -2
  144. package/dist/types/components/Icon/TestIcon.d.ts +20 -0
  145. package/dist/types/components/Icon/canonicalIconNames.d.ts +9 -7
  146. package/dist/types/components/Icon/index.d.ts +4 -0
  147. package/dist/types/components/Menu/MenuItem.d.ts +2 -1
  148. package/dist/types/components/MultiSelect/MultiSelect.d.ts +3 -1
  149. package/dist/types/components/Notification/Notification.d.ts +13 -4
  150. package/dist/types/components/Tabs/Tab.d.ts +2 -0
  151. package/dist/types/components/Tag/Tag.d.ts +16 -3
  152. package/dist/types/components/TextField/TextArea.d.ts +7 -2
  153. package/dist/types/components/TextField/TextField.d.ts +6 -1
  154. package/dist/types/components/TextField/useTextValidation.d.ts +28 -0
  155. package/dist/types/components/Tree/Tree.d.ts +2 -1
  156. package/dist/types/components/Typography/Highlighter.d.ts +2 -2
  157. package/dist/types/components/Typography/OverflowText.d.ts +2 -2
  158. package/dist/types/components/Typography/WhiteSpaceContainer.d.ts +45 -4
  159. package/dist/types/components/Typography/index.d.ts +12 -0
  160. package/dist/types/components/index.d.ts +5 -0
  161. package/dist/types/index.d.ts +6 -11
  162. package/package.json +13 -16
  163. package/scripts/compile-sass.ts +9 -1
  164. package/src/_shame.scss +1 -1
  165. package/src/cmem/ActivityControl/ActivityControlWidget.stories.tsx +6 -4
  166. package/src/cmem/ActivityControl/ActivityControlWidget.tsx +3 -2
  167. package/src/cmem/react-flow/ReactFlow/ReactFlow.tsx +26 -1
  168. package/src/cmem/react-flow/StickyNoteModal/StickyNoteModal.tsx +10 -6
  169. package/src/cmem/react-flow/extensions/scrollOnDragHook.ts +247 -0
  170. package/src/common/Intent/index.ts +16 -12
  171. package/src/common/utils/characters.ts +111 -0
  172. package/src/components/Accordion/accordion.scss +4 -3
  173. package/src/components/Application/ApplicationTitle.tsx +2 -2
  174. package/src/components/Application/_config.scss +1 -1
  175. package/src/components/Application/_content.scss +1 -1
  176. package/src/components/Application/_header.scss +2 -2
  177. package/src/components/Application/_sidebar.scss +2 -9
  178. package/src/components/Application/_toolbar.scss +1 -1
  179. package/src/components/Application/application.scss +4 -4
  180. package/src/components/AutocompleteField/autoCompleteFieldUtils.tsx +13 -8
  181. package/src/components/Badge/Badge.stories.tsx +47 -0
  182. package/src/components/Badge/Badge.tsx +93 -0
  183. package/src/components/Badge/badge.scss +44 -0
  184. package/src/components/Depiction/Depiction.tsx +198 -0
  185. package/src/components/Depiction/depiction.scss +176 -0
  186. package/src/components/Depiction/stories/Depiction.stories.tsx +69 -0
  187. package/src/components/Depiction/stories/test-16to9.png +0 -0
  188. package/src/components/Depiction/stories/test-16to9.svg +41 -0
  189. package/src/components/Depiction/stories/test-16to9.tobase64.svg +41 -0
  190. package/src/components/Depiction/stories/test-16to9.tsx +44 -0
  191. package/src/components/Depiction/stories/test-9to16.png +0 -0
  192. package/src/components/Depiction/stories/test-9to16.svg +44 -0
  193. package/src/components/Depiction/stories/test-9to16.tobase64.svg +44 -0
  194. package/src/components/Depiction/stories/test-9to16.tsx +48 -0
  195. package/src/components/Grid/Grid.tsx +22 -4
  196. package/src/components/Grid/GridColumn.tsx +23 -6
  197. package/src/components/Grid/GridRow.tsx +17 -2
  198. package/src/components/Grid/grid.scss +8 -11
  199. package/src/components/Grid/stories/Grid.stories.tsx +27 -0
  200. package/src/components/Grid/stories/GridColumn.stories.tsx +66 -0
  201. package/src/components/Grid/stories/GridRow.stories.tsx +47 -0
  202. package/src/components/Icon/BaseIcon.tsx +84 -0
  203. package/src/components/Icon/Icon.tsx +23 -82
  204. package/src/components/Icon/IconButton.tsx +18 -14
  205. package/src/components/Icon/TestIcon.tsx +39 -0
  206. package/src/components/Icon/canonicalIconNames.tsx +132 -633
  207. package/src/components/Icon/index.ts +5 -0
  208. package/src/components/Icon/stories/Icon.stories.tsx +13 -0
  209. package/src/components/Icon/stories/IconButton.stories.tsx +14 -7
  210. package/src/components/Icon/stories/TestIcon.stories.tsx +28 -0
  211. package/src/components/Link/link.scss +2 -1
  212. package/src/components/Menu/MenuItem.tsx +14 -4
  213. package/src/components/Menu/Stories/MenuItem.stories.tsx +16 -2
  214. package/src/components/MultiSelect/MultiSelect.tsx +58 -27
  215. package/src/components/Notification/Notification.stories.tsx +4 -0
  216. package/src/components/Notification/Notification.tsx +26 -6
  217. package/src/components/OverviewItem/OverviewItemDepiction.tsx +31 -0
  218. package/src/components/OverviewItem/overviewitem.scss +2 -1
  219. package/src/components/OverviewItem/stories/OverviewItem.stories.tsx +22 -1
  220. package/src/components/OverviewItem/stories/OverviewItemDepiction.stories.tsx +8 -3
  221. package/src/components/Pagination/pagination.scss +3 -2
  222. package/src/components/SimpleTable/simpletable.scss +11 -12
  223. package/src/components/Tag/Tag.stories.tsx +7 -2
  224. package/src/components/Tag/Tag.tsx +24 -4
  225. package/src/components/Tag/tag.scss +84 -3
  226. package/src/components/TagInput/taginput.scss +6 -0
  227. package/src/components/TextField/TextArea.tsx +10 -1
  228. package/src/components/TextField/TextField.tsx +9 -0
  229. package/src/components/TextField/stories/SearchField.stories.tsx +1 -1
  230. package/src/components/TextField/textfield.scss +12 -0
  231. package/src/components/TextField/useTextValidation.ts +103 -0
  232. package/src/components/Tooltip/tooltip.scss +1 -1
  233. package/src/components/Tree/Tree.stories.tsx +7 -1
  234. package/src/components/Tree/Tree.tsx +2 -1
  235. package/src/components/Typography/Highlighter.tsx +2 -2
  236. package/src/components/Typography/OverflowText.tsx +2 -2
  237. package/src/components/Typography/WhiteSpaceContainer.tsx +69 -21
  238. package/src/components/Typography/index.ts +25 -0
  239. package/src/components/Typography/stories/WhiteSpaceContainer.stories.tsx +55 -0
  240. package/src/components/Typography/typography.scss +3 -2
  241. package/src/components/Workspace/WorkspaceContent.tsx +1 -1
  242. package/src/components/index.scss +5 -0
  243. package/src/components/index.ts +5 -0
  244. package/src/includes/carbon-components/_components.scss +11 -0
  245. package/src/includes/carbon-components/_requisits.scss +18 -0
  246. package/src/includes/carbon-components/_variables.scss +50 -53
  247. package/src/index.scss +4 -105
  248. package/src/index.ts +6 -16
@@ -0,0 +1,47 @@
1
+ import React from "react";
2
+ import { ComponentStory, ComponentMeta } from "@storybook/react";
3
+ import { LogoReact } from "@carbon/icons-react";
4
+ import { Badge, Icon, TestIcon } from "../../../index";
5
+ import { helpersArgTypes } from "../../../.storybook/helpers";
6
+
7
+ export default {
8
+ title: "Components/Badge",
9
+ component: Badge,
10
+ argTypes: {
11
+ children: {
12
+ control: "select",
13
+ options: ["Number", "Text", "Named icon", "Test icon"],
14
+ mapping: {
15
+ "Number": 123123,
16
+ "Text": "Label text",
17
+ "Named icon": <Icon name="item-viewdetails" />,
18
+ "Test icon": <TestIcon tryout={LogoReact} />,
19
+ },
20
+ },
21
+ intent: {
22
+ ...helpersArgTypes.exampleIntent,
23
+ },
24
+ },
25
+ } as ComponentMeta<typeof Badge>;
26
+
27
+ const TemplateFull: ComponentStory<typeof Badge> = (args) => (
28
+ <div style={{position: "relative", border: "solid 1px", width: "10rem"}}>
29
+ Element area
30
+ {" "}
31
+ <Badge {...args} />
32
+ </div>
33
+ );
34
+
35
+ export const FullExample = TemplateFull.bind({});
36
+ FullExample.args = {
37
+ children: "123"
38
+ };
39
+
40
+ export const WithTitletip = TemplateFull.bind({});
41
+ WithTitletip.args = {
42
+ position: "bottom-right",
43
+ children: 1000,
44
+ maxLength: 3,
45
+ intent: "info",
46
+ tagProps: {htmlTitle: "1000 messages available"},
47
+ }
@@ -0,0 +1,93 @@
1
+ import React from "react";
2
+ import Tag, { TagProps } from "../Tag/Tag";
3
+ import { IconProps } from "../Icon/Icon";
4
+ import { TestIconProps } from "../Icon/TestIcon";
5
+ import { IntentTypes } from "../../common/Intent";
6
+ import { CLASSPREFIX as eccgui } from "../../configuration/constants";
7
+
8
+ export interface BadgeProps extends Omit<React.HTMLAttributes<HTMLSpanElement>, "children"> {
9
+ /**
10
+ * The badge only accepts numbers, text and ions as valid content.
11
+ */
12
+ children: string | number | React.ReactElement<IconProps> | React.ReactElement<TestIconProps>;
13
+ /**
14
+ * Position relative to the parent element where the badge is displayed.
15
+ * `top-right` and `bottom-right` relate to the closest parent element that uses a `relative` or similar positioning.
16
+ */
17
+ position?: "inline" | "top-right" | "bottom-right";
18
+ /**
19
+ * Size of the badge.
20
+ */
21
+ size?: "small" | "medium" | "large"
22
+ /**
23
+ * Maximum characters used by the badge.
24
+ * Text will be ellipsed, a number is displayed for example a 99+.
25
+ * `maxLength` need to be at least 2, otherwise it's ignored.
26
+ * For text it is only a raw measurement, not always an exact character count.
27
+ */
28
+ maxLength?: number;
29
+ /**
30
+ * Meaning of the badge.
31
+ */
32
+ intent?: IntentTypes;
33
+ /**
34
+ * Internally the `<Tag/>` element is used for the badge.
35
+ * Forward other options to the tag.
36
+ * This may overwrite properties set by the badge, use it with care.
37
+ */
38
+ tagProps?: TagProps;
39
+ }
40
+
41
+ /**
42
+ * Display a badge element to add more context to another element.
43
+ * It can display icons, text and numbers.
44
+ */
45
+ export function Badge({
46
+ children,
47
+ className = "",
48
+ position = "inline",
49
+ size = "medium",
50
+ maxLength,
51
+ intent,
52
+ tagProps,
53
+ ...spanProps
54
+ }: BadgeProps) {
55
+ let badgeContent = children;
56
+ // shorten number values
57
+ // for maxLength=3 display 99+ instead of 1023.
58
+ if (
59
+ typeof children === "number" &&
60
+ maxLength &&
61
+ maxLength > 1 &&
62
+ children >= Math.pow(10, maxLength-1)
63
+ ) {
64
+ badgeContent = `${Math.pow(10, maxLength-1) - 1}+`
65
+ }
66
+ if (typeof children === "object") {
67
+ badgeContent = "";
68
+ }
69
+ return (
70
+ <span
71
+ className={
72
+ `${eccgui}-badge ${eccgui}-badge--${position}` +
73
+ (typeof children === "object" ? ` ${eccgui}-badge--icon` : '')
74
+ }
75
+ {...spanProps}
76
+ >
77
+ <Tag
78
+ className={`${eccgui}-badge__tag`}
79
+ round
80
+ small={size === "small"}
81
+ large={size === "large"}
82
+ emphasis={!intent ? "stronger" : undefined}
83
+ intent={intent}
84
+ minimal={!!intent ? false : true}
85
+ icon={typeof children === "object" ? children : undefined}
86
+ style={(typeof children === "string" && maxLength && maxLength > 1) ? {maxWidth: `calc((${maxLength-1}em + ${maxLength-1}ch)/2)`} : {}}
87
+ {...tagProps}
88
+ >
89
+ {badgeContent}
90
+ </Tag>
91
+ </span>
92
+ );
93
+ }
@@ -0,0 +1,44 @@
1
+ .#{$eccgui}-badge__tag {
2
+ padding: 0 $tag-padding-top * 0.5;
3
+ text-align: center;
4
+
5
+ &.#{$ns}-round {
6
+ padding: 0 $tag-padding-top * 0.5;
7
+ }
8
+
9
+ .#{$eccgui}-badge--icon & {
10
+ padding: 0;
11
+ min-height: 0;
12
+ min-width: 0;
13
+ }
14
+ }
15
+
16
+ .#{$eccgui}-badge--inline {
17
+ display: inline-block;
18
+
19
+ &.#{$eccgui}-badge--icon {
20
+ vertical-align: middle;
21
+ }
22
+ }
23
+
24
+ .#{$eccgui}-badge--bottom-right {
25
+ position: absolute;
26
+ bottom: 0;
27
+ right: 0;
28
+
29
+ .#{$eccgui}-badge__tag {
30
+ right: -50%;
31
+ bottom: -0.5 * $eccgui-size-inline-whitespace;
32
+ }
33
+ }
34
+
35
+ .#{$eccgui}-badge--top-right {
36
+ position: absolute;
37
+ top: 0;
38
+ right: 0;
39
+
40
+ .#{$eccgui}-badge__tag {
41
+ right: -50%;
42
+ top: -0.5 * $eccgui-size-inline-whitespace;
43
+ }
44
+ }
@@ -0,0 +1,198 @@
1
+ import React, {useCallback, useEffect, useRef} from "react";
2
+ import Color from "color";
3
+ import SVG from 'react-inlinesvg';
4
+ import { BadgeProps } from "../Badge/Badge";
5
+ import { IconProps } from "../Icon/Icon";
6
+ import { TestIconProps } from "../Icon/TestIcon";
7
+ import Tooltip, { TooltipProps } from "../Tooltip/Tooltip";
8
+ import decideContrastColorValue from "./../../common/utils/colorDecideContrastvalue";
9
+ import {CLASSPREFIX as eccgui} from "../../configuration/constants";
10
+
11
+ export interface DepictionProps extends React.HTMLAttributes<HTMLElement> {
12
+ /**
13
+ * Image that should be used as depiction.
14
+ */
15
+ image: React.ReactElement<IconProps | TestIconProps | React.ImgHTMLAttributes<HTMLImageElement> | React.SVGProps<SVGSVGElement>>;
16
+ /**
17
+ * 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
+ * Should be work with Base64 and URL encoded data URIs.
19
+ */
20
+ forceInlineSvg?: boolean;
21
+ /**
22
+ * Sets the height of the depiction, not the dimension (width x height).
23
+ */
24
+ size?: "tiny" | "small" | "medium" | "large" | "xlarge" | "source";
25
+ /**
26
+ * Resizing strategy for image to match the given ratio.
27
+ * * contain: image is fully visible in the depiction
28
+ * * cover: the image fully covers the depition area but it may displayed only partially
29
+ * * stretch: image is streched to fill the depiction area
30
+ */
31
+ resizing?: "contain" | "cover" | "stretch";
32
+ /**
33
+ * Aspect ration of the depiction.
34
+ */
35
+ ratio?: "1:1" | "source"; // | "3:2" | "5:4" | "16:9"
36
+ /**
37
+ * Use a fully rounded shape on the depiction edges.
38
+ * Combined with `ratio="1:1"` its displayed within a circular shape.
39
+ */
40
+ rounded?: boolean;
41
+ /**
42
+ * Color that is used for the depiction background.
43
+ * This may be important if you use PNG, SVG or other image types that can have transparent background areas.
44
+ */
45
+ backgroundColor?: Color | string | "light" | "dark";
46
+ /**
47
+ * The depiction is displayed with a border around it.
48
+ */
49
+ border?: boolean;
50
+ /**
51
+ * Add padding around the image inside the depiction.
52
+ * The amount of padding is defined relative to the depiction size, so a small padding on a small depiction is displayed smaller than a small padding on a large depiction.
53
+ */
54
+ padding?: "none" | "tiny" | "small" | "medium" | "large";
55
+ /**
56
+ * Description of the depiction.
57
+ */
58
+ caption?: string | JSX.Element;
59
+ /**
60
+ * How is the caption displayed.
61
+ */
62
+ captionPosition?: "none" | "tooltip";
63
+ /**
64
+ * In case of `captionPosition="tooltip"` this can be used to set the properties of the Tooltip element.
65
+ */
66
+ tooltipProps?: TooltipProps;
67
+ /**
68
+ * Attach a `<Badge />` element to the depiction.
69
+ */
70
+ badge?: React.ReactElement<BadgeProps>,
71
+ }
72
+
73
+ /**
74
+ * Display a graphical representation and attache a caption or a badge to it.
75
+ */
76
+ export function Depiction({
77
+ className = "",
78
+ image,
79
+ forceInlineSvg = false,
80
+ size="medium",
81
+ resizing="cover",
82
+ ratio="source",
83
+ caption,
84
+ captionPosition="none",
85
+ backgroundColor,
86
+ border,
87
+ rounded,
88
+ padding = "none",
89
+ badge,
90
+ tooltipProps,
91
+ ...otherFigureProps
92
+ }: DepictionProps) {
93
+ const containerRef = useRef<HTMLDivElement>(null);
94
+
95
+ useEffect(() => {
96
+ if (!!backgroundColor && backgroundColor !== "light" && backgroundColor !== "dark") {
97
+ let color = Color("#ffffff")
98
+ try {
99
+ color = Color(backgroundColor);
100
+ } catch(ex) {
101
+ console.warn("Received invalid background color for depiction: " + backgroundColor)
102
+ }
103
+ containerRef.current!.style.setProperty(`--${eccgui}-depiction-background`, color.rgb().toString());
104
+ containerRef.current!.style.setProperty(`--${eccgui}-depiction-color`, decideContrastColorValue({testColor: color}));
105
+ }
106
+ }, [backgroundColor]);
107
+
108
+ const updateSvgResizing = React.useCallback((el: SVGElement) => {
109
+ let preserveAspectRatio = "";
110
+ switch (resizing) {
111
+ case "cover":
112
+ preserveAspectRatio = "xMidYMid slice";
113
+ break;
114
+ case "stretch":
115
+ preserveAspectRatio = "none";
116
+ break;
117
+ }
118
+ el.setAttribute("preserveAspectRatio", preserveAspectRatio);
119
+ }, [resizing])
120
+
121
+ const inlineSvgCall = useCallback((svgElement: SVGElement) => {
122
+ if(svgElement) {
123
+ updateSvgResizing(svgElement)
124
+ }
125
+ }, [updateSvgResizing]);
126
+
127
+ useEffect(() => {
128
+ // Resize element after every render
129
+ const svgElement = containerRef.current!.getElementsByTagName("svg");
130
+ if (svgElement.length > 0) {
131
+ updateSvgResizing(svgElement[0]);
132
+ }
133
+ })
134
+
135
+ let depiction = image;
136
+ if (
137
+ forceInlineSvg &&
138
+ image.type === "img" &&
139
+ "src" in image.props &&
140
+ !!image.props.src &&
141
+ image.props.src.startsWith("data:image/svg+xml")
142
+ ) {
143
+ depiction = (
144
+ <SVG
145
+ src={image.props.src}
146
+ innerRef={inlineSvgCall}
147
+ >
148
+ {image}
149
+ </SVG>
150
+ )
151
+ }
152
+
153
+ const depictionContainer = (
154
+ <div
155
+ ref={containerRef}
156
+ className={
157
+ `${eccgui}-depiction__image` +
158
+ ` ${eccgui}-depiction__image--${size}` +
159
+ ` ${eccgui}-depiction__image--${resizing}-sizing` +
160
+ ` ${eccgui}-depiction__image--ratio-${ratio.replace(":", "to")}` +
161
+ (backgroundColor === "light" || backgroundColor === "dark" ? ` ${eccgui}-depiction__image--color-${backgroundColor}` : '') +
162
+ (!!backgroundColor ? ` ${eccgui}-depiction__image--color-config` : '') +
163
+ (border ? ` ${eccgui}-depiction__image--hasborder` : '') +
164
+ (rounded ? ` ${eccgui}-depiction__image--roundedborder` : '') +
165
+ (padding && padding !== "none" ? ` ${eccgui}-depiction__image--padding-${padding}` : '')
166
+ }
167
+ >
168
+ {depiction}
169
+ </div>
170
+ );
171
+
172
+ return (
173
+ <figure
174
+ className={
175
+ `${eccgui}-depiction` +
176
+ (className ? ` ${className}` : '')
177
+ }
178
+ {...otherFigureProps}
179
+ >
180
+ { captionPosition === "tooltip" && !!caption ? (
181
+ <Tooltip content={caption} size="medium" {...tooltipProps}>{depictionContainer}</Tooltip>
182
+ ) : (
183
+ depictionContainer
184
+ )}
185
+ {!!caption && (
186
+ <figcaption
187
+ className={
188
+ `${eccgui}-depiction__caption` +
189
+ ` ${eccgui}-depiction__caption--${captionPosition}`
190
+ }
191
+ >
192
+ {caption}
193
+ </figcaption>
194
+ )}
195
+ {badge}
196
+ </figure>
197
+ );
198
+ }
@@ -0,0 +1,176 @@
1
+ $eccgui-size-depiction-height-tiny: mini-units(3) !default;
2
+ $eccgui-size-depiction-height-small: mini-units(6) !default;
3
+ $eccgui-size-depiction-height-medium: mini-units(12) !default;
4
+ $eccgui-size-depiction-height-large: mini-units(24) !default;
5
+ $eccgui-size-depiction-height-xlarge: mini-units(48) !default;
6
+
7
+ $eccgui-color-depiction-background: $eccgui-color-workspace-text !default;
8
+ $eccgui-color-depiction-text: $eccgui-color-workspace-background !default;
9
+ $eccgui-size-depiction-border-radius: $pt-border-radius !default;
10
+
11
+
12
+ .#{$eccgui}-depiction {
13
+ max-width: 100%;
14
+ display: inline-flex;
15
+ position: relative;
16
+
17
+ .#{$eccgui}-overviewitem__item > & {
18
+ flex-grow: 0;
19
+ flex-shrink: 0;
20
+ align-self: stretch;
21
+ }
22
+
23
+ & + .#{$eccgui}-overviewitem__description {
24
+ margin-left: mini-units(1);
25
+ }
26
+ }
27
+
28
+ .#{$eccgui}-depiction__image {
29
+ overflow: hidden;
30
+ max-width: 100%;
31
+ max-height: 100%;
32
+ border-radius: $eccgui-size-depiction-border-radius;
33
+
34
+ img, svg {
35
+ width: 100%;
36
+ height: 100%;
37
+ }
38
+
39
+ .#{$eccgui}-icon {
40
+ vertical-align: initial;
41
+ }
42
+
43
+ /*
44
+ Fix for Firefox,
45
+ the width of .#{$eccgui}-depiction container is not reduced to its content
46
+ when .#{$eccgui}-depiction__image updated to the available height.
47
+ */
48
+ .#{$eccgui}-overviewitem__item > .#{$eccgui}-depiction & {
49
+ height: mini-units(6);
50
+ }
51
+ .#{$eccgui}-overviewitem__item--highdensity > .#{$eccgui}-depiction &,
52
+ .#{$eccgui}-overviewitem__list--highdensity > li > .#{$eccgui}-overviewitem__item & {
53
+ height: $button-height;
54
+ }
55
+ }
56
+
57
+ .#{$eccgui}-depiction__image--ratio-source {
58
+ aspect-ratio: auto;
59
+
60
+ img, svg {
61
+ max-width: 100%;
62
+ max-height: 100%;
63
+ }
64
+ }
65
+
66
+ .#{$eccgui}-depiction__image--ratio-1to1 {
67
+ aspect-ratio: 1/1;
68
+ }
69
+
70
+ .#{$eccgui}-depiction__image--contain-sizing {
71
+ img, svg {
72
+ object-fit: contain;
73
+ }
74
+ }
75
+
76
+ .#{$eccgui}-depiction__image--cover-sizing {
77
+ img, svg {
78
+ object-fit: cover;
79
+ }
80
+ }
81
+
82
+ .#{$eccgui}-depiction__image--stretch-sizing {
83
+ img, svg {
84
+ object-fit: fill;
85
+ }
86
+ }
87
+
88
+ .#{$eccgui}-depiction__image--tiny {
89
+ height: $eccgui-size-depiction-height-tiny;
90
+
91
+ &.#{$eccgui}-depiction__image--roundedborder {
92
+ border-radius: 0.5 * $eccgui-size-depiction-height-tiny;
93
+ }
94
+ }
95
+ .#{$eccgui}-depiction__image--small {
96
+ height: $eccgui-size-depiction-height-small;
97
+
98
+ &.#{$eccgui}-depiction__image--roundedborder {
99
+ border-radius: 0.5 * $eccgui-size-depiction-height-small;
100
+ }
101
+ }
102
+ .#{$eccgui}-depiction__image--medium {
103
+ height: $eccgui-size-depiction-height-medium;
104
+
105
+ &.#{$eccgui}-depiction__image--roundedborder {
106
+ border-radius: 0.5 * $eccgui-size-depiction-height-medium;
107
+ }
108
+ }
109
+ .#{$eccgui}-depiction__image--large {
110
+ height: $eccgui-size-depiction-height-large;
111
+
112
+ &.#{$eccgui}-depiction__image--roundedborder {
113
+ border-radius: 0.5 * $eccgui-size-depiction-height-large;
114
+ }
115
+ }
116
+ .#{$eccgui}-depiction__image--xlarge {
117
+ height: $eccgui-size-depiction-height-xlarge;
118
+
119
+ &.#{$eccgui}-depiction__image--roundedborder {
120
+ border-radius: 0.5 * $eccgui-size-depiction-height-xlarge;
121
+ }
122
+ }
123
+ .#{$eccgui}-depiction__image--source {
124
+ height: auto;
125
+
126
+ &.#{$eccgui}-depiction__image--roundedborder {
127
+ border-radius: 0.5 * $eccgui-size-depiction-height-xlarge;
128
+ }
129
+ }
130
+
131
+ .#{$eccgui}-depiction__image--padding-tiny {
132
+ padding: 5%;
133
+ }
134
+
135
+ .#{$eccgui}-depiction__image--padding-small {
136
+ padding: 8%;
137
+ }
138
+
139
+ .#{$eccgui}-depiction__image--padding-medium {
140
+ padding: 13%;
141
+ }
142
+
143
+ .#{$eccgui}-depiction__image--padding-large {
144
+ padding: 21%;
145
+ }
146
+
147
+ .#{$eccgui}-depiction__image--color-dark {
148
+ --#{$eccgui}-depiction-background: #{$eccgui-color-depiction-background};
149
+ --#{$eccgui}-depiction-color: #{$eccgui-color-depiction-text};
150
+ }
151
+ .#{$eccgui}-depiction__image--color-light {
152
+ --#{$eccgui}-depiction-background: #{$eccgui-color-depiction-text};
153
+ --#{$eccgui}-depiction-color: #{$eccgui-color-depiction-background};
154
+ }
155
+ .#{$eccgui}-depiction__image--color-config {
156
+ background: var(--#{$eccgui}-depiction-background);
157
+ color: var(--#{$eccgui}-depiction-color);
158
+
159
+ /*
160
+ Lead to more problems, even with our Carbon icons, that it "heals" unknown SVGs
161
+ svg, path, circle, ellipse, line, polygon, polyline, rect {
162
+ fill: currentColor;
163
+ stroke: transparent;
164
+ }
165
+ */
166
+ }
167
+
168
+ .#{$eccgui}-depiction__image--hasborder {
169
+ border: 1px solid currentColor;
170
+ }
171
+
172
+ .#{$eccgui}-depiction__caption--none,
173
+ .#{$eccgui}-depiction__caption--tooltip {
174
+ position: fixed;
175
+ left: -5000rem;
176
+ }
@@ -0,0 +1,69 @@
1
+ import React from "react";
2
+ import { ComponentStory, ComponentMeta } from "@storybook/react";
3
+ import { LogoReact } from "@carbon/icons-react";
4
+ import { Badge, Depiction, Icon, TestIcon } from "../../../index";
5
+ import canonicalIcons from "./../../Icon/canonicalIconNames";
6
+ import png16to9 from "./test-16to9.png";
7
+ import png9to16 from "./test-9to16.png";
8
+ import svg16to9 from "./test-16to9.svg";
9
+ import svg9to16 from "./test-9to16.svg";
10
+ import svg16to9base64 from "./test-16to9.tobase64.svg";
11
+ import svg9to16base64 from "./test-9to16.tobase64.svg";
12
+ import { Svg16to9 } from "./test-16to9";
13
+ import { Svg9to16 } from "./test-9to16";
14
+
15
+ const allIcons = new Map([
16
+ ...Object.keys(canonicalIcons).map((keyId) => { return [`Icon: ${keyId}`, <Icon name={keyId} />] })
17
+ ]);
18
+
19
+ const exampleImages = {
20
+ "PNG 16:9 as URL": <img src={png16to9} />,
21
+ "PNG 9:16 as URL": <img src={png9to16} />,
22
+ "SVG 16:9 as URL": <img src={svg16to9} />,
23
+ "SVG 9:16 as URL": <img src={svg9to16} />,
24
+ "SVG 16:9 as Base64": <img src={svg16to9base64} />,
25
+ "SVG 9:16 as Base64": <img src={svg9to16base64} />,
26
+ "SVG 16:9 as React element": <Svg16to9 />,
27
+ "SVG 9:16 as React element": <Svg9to16 />,
28
+ // "PNG 16:9 as Base64": <img src={`${base64Reader.result}`} />,
29
+ // "SVG 16:9 as Base64": <img src={`${base64Reader.result}`} />,
30
+ "Test icon": <TestIcon tryout={LogoReact} />,
31
+ ...Object.fromEntries(allIcons),
32
+ };
33
+
34
+ const exampleBadges = {
35
+ "No badge": undefined,
36
+ "Text badge (small, danger, bottom-right)": <Badge maxLength={5} intent="danger" position="bottom-right" size="small">Problem occured!</Badge>,
37
+ "Icon badge (accent, inline, bottom-right)": <Badge intent="info" position="bottom-right"><Icon name="application-useraccount" /></Badge>,
38
+ "Number badge (large, info, top-right)": <Badge maxLength={2} intent="info" position="top-right" size="large" children={123} />,
39
+ }
40
+
41
+ export default {
42
+ title: "Components/Depiction",
43
+ component: Depiction,
44
+ argTypes: {
45
+ image: {
46
+ control: "select",
47
+ options: Object.keys(exampleImages),
48
+ mapping: exampleImages,
49
+ },
50
+ backgroundColor: {
51
+ control: "color",
52
+ },
53
+ badge: {
54
+ control: "select",
55
+ options: Object.keys(exampleBadges),
56
+ mapping: exampleBadges,
57
+ },
58
+ },
59
+ } as ComponentMeta<typeof Depiction>;
60
+
61
+ const TemplateFull: ComponentStory<typeof Depiction> = (args) => (
62
+ <Depiction {...args} />
63
+ );
64
+
65
+ export const FullExample = TemplateFull.bind({});
66
+ FullExample.args = {
67
+ image: <img src={png16to9} />,
68
+ caption: "This is a test description for the image."
69
+ };
@@ -0,0 +1,41 @@
1
+ <?xml version="1.0" encoding="UTF-8" standalone="no"?>
2
+ <!-- Created with Inkscape (http://www.inkscape.org/) -->
3
+
4
+ <svg
5
+ width="1920"
6
+ height="1080"
7
+ viewBox="0 0 1920 1080"
8
+ version="1.1"
9
+ xmlns="http://www.w3.org/2000/svg"
10
+ xmlns:svg="http://www.w3.org/2000/svg">
11
+ <g>
12
+ <rect
13
+ style="fill:#ffeeaa;stroke:none;stroke-width:10.8677;stroke-linecap:square;stroke-linejoin:miter;stroke-dasharray:none"
14
+ width="1920"
15
+ height="1080"
16
+ x="0"
17
+ y="0" />
18
+ <rect
19
+ style="fill:#fff6d5;stroke:#ffcc00;stroke-width:10;stroke-linecap:square;stroke-linejoin:miter;stroke-dasharray:none"
20
+ width="1810"
21
+ height="970"
22
+ x="55"
23
+ y="55" />
24
+ <path
25
+ style="fill:none;stroke:#ffcc00;stroke-width:10;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;stroke-dasharray:none"
26
+ d="m 55,55 1810,970"
27
+ />
28
+ <path
29
+ style="fill:none;stroke:#ffcc00;stroke-width:10;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;stroke-dasharray:none"
30
+ d="M 55,1025 1865,55"
31
+ />
32
+ <text
33
+ xml:space="preserve"
34
+ style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:133.333px;line-height:1.25;font-family:Roboto;-inkscape-font-specification:Roboto"
35
+ x="592.71484"
36
+ y="587.39581"
37
+ ><tspan
38
+ x="592.71484"
39
+ y="587.39581">1920 x 1080</tspan></text>
40
+ </g>
41
+ </svg>