@eccenca/gui-elements 25.0.0 → 25.1.0-featurev2510colorfield.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.
Files changed (221) hide show
  1. package/CHANGELOG.md +69 -0
  2. package/dist/cjs/cmem/ActivityControl/ActivityControlWidget.js +17 -13
  3. package/dist/cjs/cmem/ActivityControl/ActivityControlWidget.js.map +1 -1
  4. package/dist/cjs/cmem/ActivityControl/SilkActivityControl.js +1 -3
  5. package/dist/cjs/cmem/ActivityControl/SilkActivityControl.js.map +1 -1
  6. package/dist/cjs/cmem/ContentBlobToggler/ContentBlobToggler.js +1 -0
  7. package/dist/cjs/cmem/ContentBlobToggler/ContentBlobToggler.js.map +1 -1
  8. package/dist/cjs/cmem/ContentBlobToggler/StringPreviewContentBlobToggler.js +34 -11
  9. package/dist/cjs/cmem/ContentBlobToggler/StringPreviewContentBlobToggler.js.map +1 -1
  10. package/dist/cjs/cmem/react-flow/ReactFlow/ReactFlowV12.js.map +1 -1
  11. package/dist/cjs/common/Intent/index.js +1 -1
  12. package/dist/cjs/common/Intent/index.js.map +1 -1
  13. package/dist/cjs/common/index.js +1 -0
  14. package/dist/cjs/common/index.js.map +1 -1
  15. package/dist/cjs/common/utils/colorHash.js +25 -11
  16. package/dist/cjs/common/utils/colorHash.js.map +1 -1
  17. package/dist/cjs/components/Application/ApplicationViewability.js +33 -0
  18. package/dist/cjs/components/Application/ApplicationViewability.js.map +1 -0
  19. package/dist/cjs/components/Application/index.js +1 -0
  20. package/dist/cjs/components/Application/index.js.map +1 -1
  21. package/dist/cjs/components/ColorField/ColorField.js +115 -0
  22. package/dist/cjs/components/ColorField/ColorField.js.map +1 -0
  23. package/dist/cjs/components/ContextOverlay/ContextOverlay.js +6 -6
  24. package/dist/cjs/components/ContextOverlay/ContextOverlay.js.map +1 -1
  25. package/dist/cjs/components/DecoupledOverlay/DecoupledOverlay.js +47 -0
  26. package/dist/cjs/components/DecoupledOverlay/DecoupledOverlay.js.map +1 -0
  27. package/dist/cjs/components/Icon/IconButton.js.map +1 -1
  28. package/dist/cjs/components/Icon/canonicalIconNames.js +3 -0
  29. package/dist/cjs/components/Icon/canonicalIconNames.js.map +1 -1
  30. package/dist/cjs/components/Icon/transformIcon.js +14 -0
  31. package/dist/cjs/components/Icon/transformIcon.js.map +1 -0
  32. package/dist/cjs/components/MultiSelect/MultiSelect.js +2 -1
  33. package/dist/cjs/components/MultiSelect/MultiSelect.js.map +1 -1
  34. package/dist/cjs/components/RadioButton/RadioButton.js +5 -2
  35. package/dist/cjs/components/RadioButton/RadioButton.js.map +1 -1
  36. package/dist/cjs/components/Typography/InlineText.js +29 -0
  37. package/dist/cjs/components/Typography/InlineText.js.map +1 -0
  38. package/dist/cjs/components/Typography/index.js +1 -0
  39. package/dist/cjs/components/Typography/index.js.map +1 -1
  40. package/dist/cjs/components/VisualTour/VisualTour.js +24 -32
  41. package/dist/cjs/components/VisualTour/VisualTour.js.map +1 -1
  42. package/dist/cjs/components/index.js +2 -0
  43. package/dist/cjs/components/index.js.map +1 -1
  44. package/dist/cjs/extensions/codemirror/CodeMirror.js +18 -6
  45. package/dist/cjs/extensions/codemirror/CodeMirror.js.map +1 -1
  46. package/dist/cjs/extensions/codemirror/hooks/useCodemirrorModeExtension.hooks.js +1 -1
  47. package/dist/cjs/extensions/codemirror/hooks/useCodemirrorModeExtension.hooks.js.map +1 -1
  48. package/dist/cjs/extensions/codemirror/tests/codemirrorTestHelper.js +2 -2
  49. package/dist/cjs/extensions/codemirror/tests/codemirrorTestHelper.js.map +1 -1
  50. package/dist/cjs/extensions/react-flow/edges/EdgeLabel.js +1 -1
  51. package/dist/cjs/extensions/react-flow/edges/EdgeLabel.js.map +1 -1
  52. package/dist/cjs/extensions/react-flow/edges/EdgeNew.js +1 -1
  53. package/dist/cjs/extensions/react-flow/edges/EdgeNew.js.map +1 -1
  54. package/dist/cjs/extensions/react-flow/handles/HandleDefault.js +1 -1
  55. package/dist/cjs/extensions/react-flow/handles/HandleDefault.js.map +1 -1
  56. package/dist/cjs/extensions/react-flow/minimap/MiniMap.js +1 -1
  57. package/dist/cjs/extensions/react-flow/minimap/MiniMap.js.map +1 -1
  58. package/dist/cjs/extensions/react-flow/minimap/MiniMapV12.js.map +1 -1
  59. package/dist/cjs/extensions/react-flow/nodes/nodeUtils.js.map +1 -1
  60. package/dist/esm/cmem/ActivityControl/ActivityControlWidget.js +19 -14
  61. package/dist/esm/cmem/ActivityControl/ActivityControlWidget.js.map +1 -1
  62. package/dist/esm/cmem/ActivityControl/SilkActivityControl.js +1 -3
  63. package/dist/esm/cmem/ActivityControl/SilkActivityControl.js.map +1 -1
  64. package/dist/esm/cmem/ContentBlobToggler/ContentBlobToggler.js +1 -0
  65. package/dist/esm/cmem/ContentBlobToggler/ContentBlobToggler.js.map +1 -1
  66. package/dist/esm/cmem/ContentBlobToggler/StringPreviewContentBlobToggler.js +32 -9
  67. package/dist/esm/cmem/ContentBlobToggler/StringPreviewContentBlobToggler.js.map +1 -1
  68. package/dist/esm/cmem/react-flow/ReactFlow/ReactFlowV12.js.map +1 -1
  69. package/dist/esm/common/Intent/index.js +1 -1
  70. package/dist/esm/common/Intent/index.js.map +1 -1
  71. package/dist/esm/common/index.js +2 -1
  72. package/dist/esm/common/index.js.map +1 -1
  73. package/dist/esm/common/utils/colorHash.js +25 -12
  74. package/dist/esm/common/utils/colorHash.js.map +1 -1
  75. package/dist/esm/components/Application/ApplicationViewability.js +28 -0
  76. package/dist/esm/components/Application/ApplicationViewability.js.map +1 -0
  77. package/dist/esm/components/Application/index.js +1 -0
  78. package/dist/esm/components/Application/index.js.map +1 -1
  79. package/dist/esm/components/ColorField/ColorField.js +141 -0
  80. package/dist/esm/components/ColorField/ColorField.js.map +1 -0
  81. package/dist/esm/components/ContextOverlay/ContextOverlay.js +3 -3
  82. package/dist/esm/components/ContextOverlay/ContextOverlay.js.map +1 -1
  83. package/dist/esm/components/DecoupledOverlay/DecoupledOverlay.js +41 -0
  84. package/dist/esm/components/DecoupledOverlay/DecoupledOverlay.js.map +1 -0
  85. package/dist/esm/components/Icon/IconButton.js.map +1 -1
  86. package/dist/esm/components/Icon/canonicalIconNames.js +3 -0
  87. package/dist/esm/components/Icon/canonicalIconNames.js.map +1 -1
  88. package/dist/esm/components/Icon/transformIcon.js +21 -0
  89. package/dist/esm/components/Icon/transformIcon.js.map +1 -0
  90. package/dist/esm/components/MultiSelect/MultiSelect.js +3 -2
  91. package/dist/esm/components/MultiSelect/MultiSelect.js.map +1 -1
  92. package/dist/esm/components/RadioButton/RadioButton.js +6 -2
  93. package/dist/esm/components/RadioButton/RadioButton.js.map +1 -1
  94. package/dist/esm/components/Typography/InlineText.js +33 -0
  95. package/dist/esm/components/Typography/InlineText.js.map +1 -0
  96. package/dist/esm/components/Typography/index.js +1 -0
  97. package/dist/esm/components/Typography/index.js.map +1 -1
  98. package/dist/esm/components/VisualTour/VisualTour.js +25 -33
  99. package/dist/esm/components/VisualTour/VisualTour.js.map +1 -1
  100. package/dist/esm/components/index.js +2 -0
  101. package/dist/esm/components/index.js.map +1 -1
  102. package/dist/esm/extensions/codemirror/CodeMirror.js +19 -7
  103. package/dist/esm/extensions/codemirror/CodeMirror.js.map +1 -1
  104. package/dist/esm/extensions/codemirror/hooks/useCodemirrorModeExtension.hooks.js +1 -1
  105. package/dist/esm/extensions/codemirror/hooks/useCodemirrorModeExtension.hooks.js.map +1 -1
  106. package/dist/esm/extensions/codemirror/tests/codemirrorTestHelper.js +3 -3
  107. package/dist/esm/extensions/codemirror/tests/codemirrorTestHelper.js.map +1 -1
  108. package/dist/esm/extensions/react-flow/edges/EdgeLabel.js +1 -1
  109. package/dist/esm/extensions/react-flow/edges/EdgeLabel.js.map +1 -1
  110. package/dist/esm/extensions/react-flow/edges/EdgeNew.js +1 -1
  111. package/dist/esm/extensions/react-flow/edges/EdgeNew.js.map +1 -1
  112. package/dist/esm/extensions/react-flow/handles/HandleDefault.js +1 -1
  113. package/dist/esm/extensions/react-flow/handles/HandleDefault.js.map +1 -1
  114. package/dist/esm/extensions/react-flow/minimap/MiniMap.js +1 -1
  115. package/dist/esm/extensions/react-flow/minimap/MiniMap.js.map +1 -1
  116. package/dist/esm/extensions/react-flow/minimap/MiniMapV12.js.map +1 -1
  117. package/dist/esm/extensions/react-flow/nodes/nodeUtils.js.map +1 -1
  118. package/dist/types/cmem/ActivityControl/ActivityControlWidget.d.ts +9 -0
  119. package/dist/types/cmem/ContentBlobToggler/StringPreviewContentBlobToggler.d.ts +26 -10
  120. package/dist/types/common/index.d.ts +2 -1
  121. package/dist/types/common/utils/colorHash.d.ts +4 -3
  122. package/dist/types/components/Application/ApplicationViewability.d.ts +36 -0
  123. package/dist/types/components/Application/index.d.ts +1 -0
  124. package/dist/types/components/ColorField/ColorField.d.ts +31 -0
  125. package/dist/types/components/ContextOverlay/ContextOverlay.d.ts +7 -1
  126. package/dist/types/components/DecoupledOverlay/DecoupledOverlay.d.ts +20 -0
  127. package/dist/types/components/Icon/IconButton.d.ts +1 -1
  128. package/dist/types/components/Icon/canonicalIconNames.d.ts +2 -0
  129. package/dist/types/components/Icon/transformIcon.d.ts +2 -0
  130. package/dist/types/components/MultiSelect/MultiSelect.d.ts +1 -1
  131. package/dist/types/components/RadioButton/RadioButton.d.ts +8 -2
  132. package/dist/types/components/Structure/TitleSubsection.d.ts +1 -1
  133. package/dist/types/components/Tabs/Tab.d.ts +2 -2
  134. package/dist/types/components/Typography/InlineText.d.ts +13 -0
  135. package/dist/types/components/Typography/index.d.ts +1 -0
  136. package/dist/types/components/index.d.ts +2 -0
  137. package/dist/types/extensions/codemirror/hooks/useCodemirrorModeExtension.hooks.d.ts +1 -1
  138. package/dist/types/extensions/codemirror/tests/codemirrorTestHelper.d.ts +1 -1
  139. package/package.json +50 -51
  140. package/src/cmem/ActivityControl/ActivityControlWidget.tsx +68 -35
  141. package/src/cmem/ActivityControl/SilkActivityControl.tsx +1 -1
  142. package/src/cmem/ContentBlobToggler/ContentBlobToggler.tsx +1 -1
  143. package/src/cmem/ContentBlobToggler/StringPreviewContentBlobToggler.tsx +66 -18
  144. package/src/cmem/ContentBlobToggler/stories/StringPreviewContentBlobToggler.stories.tsx +27 -0
  145. package/src/cmem/ContentBlobToggler/tests/StringPreviewContentBlobToggler.test.tsx +98 -0
  146. package/src/cmem/react-flow/ReactFlow/ReactFlowV12.tsx +1 -0
  147. package/src/common/Intent/index.ts +2 -1
  148. package/src/common/index.ts +2 -1
  149. package/src/common/utils/colorHash.ts +36 -18
  150. package/src/components/Application/ApplicationViewability.tsx +61 -0
  151. package/src/components/Application/_colors.scss +15 -0
  152. package/src/components/Application/_content.scss +7 -0
  153. package/src/components/Application/_header.scss +12 -3
  154. package/src/components/Application/_viewability.scss +13 -0
  155. package/src/components/Application/application.scss +1 -0
  156. package/src/components/Application/index.ts +1 -0
  157. package/src/components/Application/stories/ApplicationViewability.stories.tsx +37 -0
  158. package/src/components/Application/tests/ApplicationViewability.test.tsx +43 -0
  159. package/src/components/AutoSuggestion/tests/ExtendedCodeEditor.test.tsx +1 -1
  160. package/src/components/Card/card.scss +6 -0
  161. package/src/components/Checkbox/checkbox.scss +14 -2
  162. package/src/components/ColorField/ColorField.stories.tsx +69 -0
  163. package/src/components/ColorField/ColorField.test.tsx +125 -0
  164. package/src/components/ColorField/ColorField.tsx +200 -0
  165. package/src/components/ColorField/_colorfield.scss +56 -0
  166. package/src/components/ContentGroup/_contentgroup.scss +9 -0
  167. package/src/components/ContextOverlay/ContextOverlay.tsx +20 -1
  168. package/src/components/DecoupledOverlay/DecoupledOverlay.stories.tsx +30 -0
  169. package/src/components/DecoupledOverlay/DecoupledOverlay.tsx +97 -0
  170. package/src/components/DecoupledOverlay/_decoupledoverlay.scss +46 -0
  171. package/src/components/Depiction/depiction.scss +6 -0
  172. package/src/components/FlexibleLayout/flexiblelayout.scss +16 -0
  173. package/src/components/Grid/grid.scss +17 -0
  174. package/src/components/Grid/stories/Grid.stories.tsx +10 -7
  175. package/src/components/Grid/stories/GridRow.stories.tsx +13 -7
  176. package/src/components/Icon/IconButton.tsx +1 -1
  177. package/src/components/Icon/canonicalIconNames.tsx +3 -0
  178. package/src/components/Icon/transformIcon.tsx +17 -0
  179. package/src/components/Link/Link.stories.tsx +30 -0
  180. package/src/components/Link/link.scss +28 -2
  181. package/src/components/MultiSelect/MultiSelect.tsx +12 -3
  182. package/src/components/Notification/notification.scss +6 -0
  183. package/src/components/OverviewItem/overviewitem.scss +9 -0
  184. package/src/components/OverviewItem/stories/OverviewItem.stories.tsx +28 -0
  185. package/src/components/OverviewItem/stories/OverviewItemActions.stories.tsx +2 -2
  186. package/src/components/OverviewItem/stories/OverviewItemDescription.stories.tsx +1 -1
  187. package/src/components/OverviewItem/stories/OverviewItemLine.stories.tsx +1 -1
  188. package/src/components/PropertyValuePair/propertyvalue.scss +23 -1
  189. package/src/components/RadioButton/RadioButton.tsx +15 -3
  190. package/src/components/RadioButton/radiobutton.scss +13 -0
  191. package/src/components/Separation/separation.scss +6 -0
  192. package/src/components/Table/table.scss +22 -0
  193. package/src/components/Tabs/stories/TabTitle.stories.tsx +7 -2
  194. package/src/components/Tag/stories/TagList.stories.tsx +2 -2
  195. package/src/components/Tag/tag.scss +19 -9
  196. package/src/components/TextReducer/TextReducer.test.tsx +3 -3
  197. package/src/components/Typography/InlineText.tsx +24 -0
  198. package/src/components/Typography/_reset.scss +1 -0
  199. package/src/components/Typography/index.ts +1 -0
  200. package/src/components/Typography/stories/InlineText.stories.tsx +27 -0
  201. package/src/components/Typography/typography.scss +28 -2
  202. package/src/components/VisualTour/VisualTour.tsx +30 -50
  203. package/src/components/VisualTour/visualTour.scss +0 -34
  204. package/src/components/index.scss +2 -0
  205. package/src/components/index.ts +2 -0
  206. package/src/configuration/_customproperties.scss +32 -0
  207. package/src/configuration/stories/customproperties.stories.tsx +118 -0
  208. package/src/extensions/codemirror/CodeMirror.tsx +20 -9
  209. package/src/extensions/codemirror/hooks/useCodemirrorModeExtension.hooks.ts +1 -2
  210. package/src/extensions/codemirror/tests/codemirrorTestHelper.ts +3 -3
  211. package/src/extensions/react-flow/_config.scss +3 -3
  212. package/src/extensions/react-flow/edges/EdgeLabel.tsx +5 -3
  213. package/src/extensions/react-flow/edges/EdgeNew.tsx +2 -1
  214. package/src/extensions/react-flow/edges/_edges.scss +3 -2
  215. package/src/extensions/react-flow/handles/HandleDefault.tsx +2 -2
  216. package/src/extensions/react-flow/minimap/MiniMap.tsx +2 -1
  217. package/src/extensions/react-flow/minimap/MiniMapV12.tsx +1 -1
  218. package/src/extensions/react-flow/nodes/_nodes.scss +4 -3
  219. package/src/extensions/react-flow/nodes/nodeUtils.tsx +1 -0
  220. package/src/extensions/react-flow/nodes/stories/NodeContent.stories.tsx +2 -2
  221. package/src/index.scss +1 -0
@@ -25,3 +25,10 @@ $ui-02: $eccgui-color-workspace-background !default;
25
25
  .#{$eccgui}-application__content--railsidebar {
26
26
  margin-left: mini-units(8);
27
27
  }
28
+
29
+ @media print {
30
+ .#{$eccgui}-application__content {
31
+ padding: $eccgui-size-block-whitespace 0 0 0 !important;
32
+ margin: 0;
33
+ }
34
+ }
@@ -98,10 +98,10 @@ span.#{$prefix}--header__name {
98
98
  .#{$eccgui}-application__title--content {
99
99
  display: inline-block;
100
100
  overflow: hidden;
101
+ text-overflow: ellipsis;
101
102
  font-size: $eccgui-size-typo-caption;
102
103
  font-weight: $eccgui-font-weight-bold;
103
104
  line-height: $eccgui-size-typo-caption-lineheight;
104
- text-overflow: ellipsis;
105
105
  letter-spacing: $eccgui-font-spacing-wide;
106
106
  white-space: nowrap;
107
107
  }
@@ -122,7 +122,7 @@ span.#{$prefix}--header__name {
122
122
  height: auto;
123
123
  max-height: mini-units(5);
124
124
  padding: 0;
125
- margin: mini-units(1.4) 0 mini-units(1.6) 0;
125
+ margin: mini-units(1.4) 0 mini-units(1.6);
126
126
  vertical-align: middle;
127
127
  }
128
128
  }
@@ -195,9 +195,9 @@ a.#{$prefix}--header__menu-item:active {
195
195
  .#{$prefix}--header__action.#{$prefix}--btn--primary:focus,
196
196
  a.#{$prefix}--header__name:focus,
197
197
  a.#{$prefix}--header__menu-item:focus {
198
- border: none;
199
198
  outline: 1px dotted $shell-header-focus;
200
199
  outline-offset: -1px;
200
+ border: none;
201
201
  box-shadow: none;
202
202
  }
203
203
  .#{$prefix}--header__menu-title[aria-expanded="true"] {
@@ -267,3 +267,12 @@ a.#{$prefix}--header__menu-item:focus > svg {
267
267
  margin: 0;
268
268
  }
269
269
  }
270
+
271
+ @media print {
272
+ .#{$eccgui}-application__header {
273
+ position: relative;
274
+ & > :not(.#{$eccgui}-workspace__header) {
275
+ display: none;
276
+ }
277
+ }
278
+ }
@@ -0,0 +1,13 @@
1
+ @media print {
2
+ .#{eccgui}-application__hide--print,
3
+ .#{eccgui}-application__show--screen {
4
+ display: none !important;
5
+ }
6
+ }
7
+
8
+ @media screen {
9
+ .#{eccgui}-application__hide--screen,
10
+ .#{eccgui}-application__show--print {
11
+ display: none !important;
12
+ }
13
+ }
@@ -10,3 +10,4 @@
10
10
  // @import '~@carbon/react/scss/components/ui-shell/navigation-menu';
11
11
  @import "content";
12
12
  @import "dropzone";
13
+ @import "viewability";
@@ -8,4 +8,5 @@ export * from "./ApplicationToolbar";
8
8
  export * from "./ApplicationToolbarSection";
9
9
  export * from "./ApplicationToolbarAction";
10
10
  export * from "./ApplicationToolbarPanel";
11
+ export * from "./ApplicationViewability";
11
12
  export * from "./helper";
@@ -0,0 +1,37 @@
1
+ import React from "react";
2
+ import { LoremIpsum } from "react-lorem-ipsum";
3
+ import { Meta, StoryFn } from "@storybook/react";
4
+
5
+ import { ApplicationViewability } from "../../../index";
6
+ export default {
7
+ title: "Components/Application/Viewability",
8
+ component: ApplicationViewability,
9
+ argTypes: {
10
+ children: {
11
+ control: false,
12
+ },
13
+ hide: {
14
+ control: {
15
+ type: "radio",
16
+ },
17
+ options: ["print", "screen"],
18
+ },
19
+ show: {
20
+ control: {
21
+ type: "radio",
22
+ },
23
+ options: ["print", "screen"],
24
+ },
25
+ },
26
+ } as Meta<typeof ApplicationViewability>;
27
+
28
+ const TemplateBasicExample: StoryFn<typeof ApplicationViewability> = (args) => <ApplicationViewability {...args} />;
29
+
30
+ export const Default = TemplateBasicExample.bind({});
31
+ Default.args = {
32
+ children: (
33
+ <div>
34
+ <LoremIpsum random={false} />
35
+ </div>
36
+ ),
37
+ };
@@ -0,0 +1,43 @@
1
+ import React from "react";
2
+ import { expect } from "@storybook/test";
3
+ import { render } from "@testing-library/react";
4
+
5
+ import "@testing-library/jest-dom";
6
+
7
+ import { ApplicationViewability, ApplicationViewabilityProps, CLASSPREFIX as eccgui } from "../../../index";
8
+
9
+ import { Default as ApplicationViewabilityStory } from "./../stories/ApplicationViewability.stories";
10
+
11
+ const applyViewabilityAndCheckClass = (props: Omit<ApplicationViewabilityProps, "children">) => {
12
+ const { container } = render(<ApplicationViewability {...ApplicationViewabilityStory.args} {...props} />);
13
+ const element = container.getElementsByClassName(
14
+ props.hide ? `${eccgui}-application__hide--${props.hide}` : `${eccgui}-application__show--${props.show}`
15
+ );
16
+ expect(element.length).toBe(1);
17
+ return element;
18
+ };
19
+
20
+ describe("ApplicationViewability", () => {
21
+ it("should be visible on `show=screen`", () => {
22
+ applyViewabilityAndCheckClass({ show: "screen" });
23
+ /**
24
+ * Currently we cannot really test visibility via jest if it is defined by S/CSS rules because those styles are not known.
25
+ * Looks like it is not too easy to include and test them.
26
+ * So we only test for the correct CSS class.
27
+ */
28
+ // console.log(window.getComputedStyle(element.item(0)??new Element).getPropertyValue("display"));
29
+ // waitFor(() => expect(element).toBeVisible());
30
+ });
31
+ it("should not be visible on `hide=screen`", () => {
32
+ applyViewabilityAndCheckClass({ hide: "screen" });
33
+ // waitFor(() => expect(element).not.toBeVisible());
34
+ });
35
+ it("should be visible on `hide=print`", () => {
36
+ applyViewabilityAndCheckClass({ hide: "print" });
37
+ // waitFor(() => expect(element).toBeVisible());
38
+ });
39
+ it("should not be visible on `show=print`", () => {
40
+ applyViewabilityAndCheckClass({ show: "print" });
41
+ // waitFor(() => expect(element).not.toBeVisible());
42
+ });
43
+ });
@@ -1,6 +1,6 @@
1
1
  import React from "react";
2
- import { render } from "@testing-library/react";
3
2
  import { EditorView } from "@codemirror/view";
3
+ import { render } from "@testing-library/react";
4
4
 
5
5
  import "@testing-library/jest-dom";
6
6
 
@@ -288,3 +288,9 @@ $eccgui-size-card-spacing: $eccgui-size-typo-base !default;
288
288
  }
289
289
  }
290
290
  }
291
+
292
+ @media print {
293
+ .#{$eccgui}-card__actions {
294
+ display: none;
295
+ }
296
+ }
@@ -24,9 +24,15 @@ $control-indicator-spacing: $eccgui-size-inline-whitespace !default;
24
24
  // $switch-background-color-active: rgba($gray1, 0.5) !default;
25
25
  // $switch-background-color-disabled: $button-background-color-disabled !default;
26
26
  $switch-checked-background-color: $eccgui-color-accent !default;
27
- $switch-checked-background-color-hover: eccgui-color-rgba($switch-checked-background-color, $eccgui-opacity-narrow) !default;
27
+ $switch-checked-background-color-hover: eccgui-color-rgba(
28
+ $switch-checked-background-color,
29
+ $eccgui-opacity-narrow
30
+ ) !default;
28
31
  $switch-checked-background-color-active: $switch-checked-background-color-hover !default;
29
- $switch-checked-background-color-disabled: eccgui-color-rgba($switch-checked-background-color, $eccgui-opacity-disabled) !default;
32
+ $switch-checked-background-color-disabled: eccgui-color-rgba(
33
+ $switch-checked-background-color,
34
+ $eccgui-opacity-disabled
35
+ ) !default;
30
36
 
31
37
  @import "~@blueprintjs/core/src/components/forms/controls"; // Checkbox, Radio, Switch
32
38
 
@@ -73,3 +79,9 @@ $switch-checked-background-color-disabled: eccgui-color-rgba($switch-checked-bac
73
79
  display: inline-block;
74
80
  vertical-align: text-top;
75
81
  }
82
+
83
+ @media print {
84
+ .#{$ns}-control {
85
+ print-color-adjust: exact;
86
+ }
87
+ }
@@ -0,0 +1,69 @@
1
+ import React from "react";
2
+ import { Meta, StoryFn } from "@storybook/react";
3
+
4
+ import textFieldTest from "../TextField/stories/TextField.stories";
5
+
6
+ import { ColorField, ColorFieldProps } from "./ColorField";
7
+
8
+ export default {
9
+ title: "Forms/ColorField",
10
+ component: ColorField,
11
+ argTypes: {
12
+ ...textFieldTest.argTypes,
13
+ },
14
+ } as Meta<typeof ColorField>;
15
+
16
+ const Template: StoryFn<typeof ColorField> = (args) => <ColorField {...args}></ColorField>;
17
+
18
+ export const Default = Template.bind({});
19
+ Default.args = {
20
+ onChange: (e) => {
21
+ alert(e.target.value);
22
+ },
23
+ };
24
+
25
+ export const NoPalettePresets = Template.bind({});
26
+ NoPalettePresets.args = {
27
+ ...Default.args,
28
+ includeColorWeight: [],
29
+ includePaletteGroup: [],
30
+ allowCustomColor: true,
31
+ };
32
+
33
+ interface TemplateColorHashProps
34
+ extends Pick<ColorFieldProps, "onChange" | "allowCustomColor" | "includeColorWeight" | "includePaletteGroup"> {
35
+ stringForColorHashValue: string;
36
+ }
37
+
38
+ const TemplateColorHash: StoryFn<TemplateColorHashProps> = (args: TemplateColorHashProps) => (
39
+ <ColorField
40
+ allowCustomColor={args.allowCustomColor}
41
+ includeColorWeight={args.includeColorWeight}
42
+ includePaletteGroup={args.includePaletteGroup}
43
+ value={ColorField.calculateColorHashValue(args.stringForColorHashValue, {
44
+ allowCustomColor: args.allowCustomColor,
45
+ includeColorWeight: args.includeColorWeight,
46
+ includePaletteGroup: args.includePaletteGroup,
47
+ })}
48
+ />
49
+ );
50
+
51
+ /**
52
+ * Component provides a helper function to calculate a color hash from a text,
53
+ * that can be used as `value` or `defaultValue`.
54
+ *
55
+ * ```
56
+ * <ColorField value={ColorField.calculateColorHashValue("MyText")} />
57
+ * ```
58
+ *
59
+ * You can add `options` to set the config for the color palette filters.
60
+ * The same default values like on `ColorField` are used for them.
61
+ */
62
+ export const ColorHashValue = TemplateColorHash.bind({});
63
+ ColorHashValue.args = {
64
+ ...Default.args,
65
+ allowCustomColor: true,
66
+ includeColorWeight: [300, 500, 700],
67
+ includePaletteGroup: ["layout", "extra"],
68
+ stringForColorHashValue: "My text that will used to create a color hash as initial value.",
69
+ };
@@ -0,0 +1,125 @@
1
+ import React from "react";
2
+ import { render } from "@testing-library/react";
3
+ import userEvent from "@testing-library/user-event";
4
+
5
+ import "@testing-library/jest-dom";
6
+
7
+ import { CLASSPREFIX as eccgui } from "../../configuration/constants";
8
+
9
+ import { ColorField } from "./ColorField";
10
+
11
+ describe("ColorField", () => {
12
+ describe("rendering", () => {
13
+ it("renders without crashing, and correct component CSS class is applied", () => {
14
+ const { container } = render(<ColorField />);
15
+ expect(container).not.toBeEmptyDOMElement();
16
+ expect(container.getElementsByClassName(`${eccgui}-colorfield`).length).toBe(1);
17
+ });
18
+
19
+ it("renders a color input by default (no palette presets)", () => {
20
+ const { container } = render(
21
+ <ColorField includePaletteGroup={[]} includeColorWeight={[]} allowCustomColor={true} />
22
+ );
23
+ expect(container.querySelector("input[type='color']")).toBeInTheDocument();
24
+ });
25
+
26
+ // Jest cannot test this because it does not (cannot) load Styles where the palette isconfigured
27
+ /*
28
+ it("renders a readonly text input when palette colors are configured, and custom picker CSS class is applied", () => {
29
+ const { container } = render(<ColorField className="my-custom-class" />);
30
+ // With default palette settings, a text input with readOnly is shown
31
+ expect(container.querySelector("input[type='text']")).toBeInTheDocument();
32
+ expect(container.querySelector("input[readonly]")).toBeInTheDocument();
33
+ expect(container.querySelector(`.${eccgui}-colorfield--custom-picker`)).toBeInTheDocument();
34
+ });
35
+ */
36
+
37
+ it("applies additional className", () => {
38
+ render(
39
+ <ColorField
40
+ className="my-custom-class"
41
+ includePaletteGroup={[]}
42
+ includeColorWeight={[]}
43
+ allowCustomColor={true}
44
+ />
45
+ );
46
+ expect(document.querySelector(".my-custom-class")).toBeInTheDocument();
47
+ });
48
+ });
49
+
50
+ describe("value handling", () => {
51
+ it("uses defaultValue as initial color", () => {
52
+ render(
53
+ <ColorField
54
+ defaultValue="#ff0000"
55
+ includePaletteGroup={[]}
56
+ includeColorWeight={[]}
57
+ allowCustomColor={true}
58
+ />
59
+ );
60
+ const input = document.querySelector("input") as HTMLInputElement;
61
+ expect(input.value).toBe("#ff0000");
62
+ });
63
+
64
+ it("uses value prop as initial color", () => {
65
+ render(
66
+ <ColorField value="#00ff00" includePaletteGroup={[]} includeColorWeight={[]} allowCustomColor={true} />
67
+ );
68
+ const input = document.querySelector("input") as HTMLInputElement;
69
+ expect(input.value).toBe("#00ff00");
70
+ });
71
+
72
+ it("falls back to #000000 when no value or defaultValue is provided", () => {
73
+ render(<ColorField includePaletteGroup={[]} includeColorWeight={[]} allowCustomColor={true} />);
74
+ const input = document.querySelector("input") as HTMLInputElement;
75
+ expect(input.value).toBe("#000000");
76
+ });
77
+
78
+ it("updates displayed value when value prop changes", () => {
79
+ const { rerender } = render(
80
+ <ColorField value="#ff0000" includePaletteGroup={[]} includeColorWeight={[]} allowCustomColor={true} />
81
+ );
82
+ let input = document.querySelector("input") as HTMLInputElement;
83
+ expect(input.value).toBe("#ff0000");
84
+
85
+ rerender(
86
+ <ColorField value="#0000ff" includePaletteGroup={[]} includeColorWeight={[]} allowCustomColor={true} />
87
+ );
88
+ input = document.querySelector("input") as HTMLInputElement;
89
+ expect(input.value).toBe("#0000ff");
90
+ });
91
+ });
92
+
93
+ describe("disabled state", () => {
94
+ it("is disabled when disabled prop is true", () => {
95
+ render(<ColorField disabled includePaletteGroup={[]} includeColorWeight={[]} allowCustomColor={true} />);
96
+ const input = document.querySelector("input") as HTMLInputElement;
97
+ expect(input).toBeDisabled();
98
+ });
99
+
100
+ it("is disabled when no palette colors and allowCustomColor is false", () => {
101
+ render(<ColorField includePaletteGroup={[]} includeColorWeight={[]} allowCustomColor={false} />);
102
+ const input = document.querySelector("input") as HTMLInputElement;
103
+ expect(input).toBeDisabled();
104
+ });
105
+ });
106
+
107
+ describe("onChange callback", () => {
108
+ it("calls onChange when native color input changes", async () => {
109
+ const user = userEvent.setup();
110
+ const onChange = jest.fn();
111
+ render(
112
+ <ColorField
113
+ onChange={onChange}
114
+ includePaletteGroup={[]}
115
+ includeColorWeight={[]}
116
+ allowCustomColor={true}
117
+ />
118
+ );
119
+ const input = document.querySelector("input[type='color']") as HTMLInputElement;
120
+ input.type = "text"; // for unknown reasons Jest seems not able to test it on color inputs
121
+ await user.type(input, "#123456");
122
+ expect(onChange).toHaveBeenCalled();
123
+ });
124
+ });
125
+ });
@@ -0,0 +1,200 @@
1
+ import React, { CSSProperties } from "react";
2
+ import classNames from "classnames";
3
+
4
+ import { utils } from "../../common";
5
+ import { ColorWeight, PaletteGroup } from "../../common/utils/colorHash";
6
+ import { CLASSPREFIX as eccgui } from "../../configuration/constants";
7
+ import { ContextOverlay } from "../ContextOverlay";
8
+ import { FieldSet } from "../Form";
9
+ import { RadioButton } from "../RadioButton/RadioButton";
10
+ import { Spacing } from "../Separation/Spacing";
11
+ import { Tag, TagList } from "../Tag";
12
+ import { TextField, TextFieldProps } from "../TextField";
13
+ import { Tooltip } from "../Tooltip/Tooltip";
14
+ import { WhiteSpaceContainer } from "../Typography";
15
+
16
+ export interface ColorFieldProps extends Omit<TextFieldProps, "invisibleCharacterWarning"> {
17
+ /**
18
+ * Any color can be selected, not only from the configured color palette.
19
+ */
20
+ allowCustomColor?: boolean;
21
+ /**
22
+ * What color weights should be included in the set of allowed colors.
23
+ */
24
+ includeColorWeight?: ColorWeight[];
25
+ /**
26
+ * What palette groups should be included in the set of allowed colors.
27
+ */
28
+ includePaletteGroup?: PaletteGroup[];
29
+ }
30
+
31
+ /**
32
+ * Color input field that provides resets from the configured color palette.
33
+ * Use `includeColorWeight` and `includePaletteGroup` to filter them.
34
+ */
35
+ export const ColorField = ({
36
+ className = "",
37
+ allowCustomColor = false,
38
+ includeColorWeight = [100, 300, 700, 900], // on default, we only include color weights that can have enough contrasts to black/white
39
+ includePaletteGroup = ["layout"],
40
+ defaultValue,
41
+ value,
42
+ onChange,
43
+ fullWidth = false,
44
+ ...otherTextFieldProps
45
+ }: ColorFieldProps) => {
46
+ const ref = React.useRef(null);
47
+ const [colorValue, setColorValue] = React.useState<string>(defaultValue || value || "#000000");
48
+
49
+ let allowedPaletteColors, disableNativePicker, disabled;
50
+ const updateConfig = () => {
51
+ allowedPaletteColors = utils.getEnabledColorPropertiesFromPalette({
52
+ includePaletteGroup: includePaletteGroup,
53
+ includeColorWeight: includeColorWeight,
54
+ minimalColorDistance: 0, // we use all allowed colors, and do not check distances between them
55
+ });
56
+
57
+ disableNativePicker =
58
+ includeColorWeight.length > 0 && includePaletteGroup.length > 0 && allowedPaletteColors.length > 0;
59
+ disabled = (!disableNativePicker && !allowCustomColor) || otherTextFieldProps.disabled;
60
+ };
61
+ updateConfig();
62
+ React.useEffect(() => {
63
+ updateConfig();
64
+ }, [allowCustomColor, includeColorWeight, includePaletteGroup, otherTextFieldProps]);
65
+
66
+ React.useEffect(() => {
67
+ setColorValue(defaultValue || value || "#000000");
68
+ }, [defaultValue, value]);
69
+
70
+ const forwardOnChange = (forwardedEvent: React.ChangeEvent<HTMLInputElement>) => {
71
+ setColorValue(forwardedEvent.target.value);
72
+ if (onChange) {
73
+ onChange(forwardedEvent);
74
+ }
75
+ };
76
+
77
+ const colorInput = (
78
+ <TextField
79
+ inputRef={ref}
80
+ className={classNames(`${eccgui}-colorfield`, className, {
81
+ [`${eccgui}-colorfield--custom-picker`]: disableNativePicker,
82
+ })}
83
+ // we cannot use `color` type for the custom picker because we do not have control over it then
84
+ type={!disableNativePicker ? "color" : "text"}
85
+ readOnly={disableNativePicker}
86
+ disabled={disabled}
87
+ value={colorValue}
88
+ fullWidth={fullWidth}
89
+ {...otherTextFieldProps}
90
+ onChange={
91
+ !disableNativePicker
92
+ ? (e: React.ChangeEvent<HTMLInputElement>) => {
93
+ forwardOnChange(e);
94
+ }
95
+ : undefined
96
+ }
97
+ style={{ ...otherTextFieldProps.style, [`--eccgui-colorfield-background`]: colorValue } as CSSProperties}
98
+ />
99
+ );
100
+
101
+ return disableNativePicker && !disabled ? (
102
+ <ContextOverlay
103
+ fill={fullWidth}
104
+ content={
105
+ <WhiteSpaceContainer
106
+ paddingTop={"small"}
107
+ paddingRight={"small"}
108
+ paddingBottom={"small"}
109
+ paddingLeft={"small"}
110
+ className={`${eccgui}-colorfield__picker`}
111
+ >
112
+ {allowCustomColor && (
113
+ <>
114
+ <TextField
115
+ type={"color"}
116
+ value={colorValue}
117
+ onChange={(e: React.ChangeEvent<HTMLInputElement>) => {
118
+ forwardOnChange(e);
119
+ }}
120
+ />
121
+ <Spacing size={"small"} />
122
+ </>
123
+ )}
124
+ <FieldSet>
125
+ <TagList
126
+ className={`${eccgui}-colorfield__palette ${eccgui}-colorfield__palette--${
127
+ includeColorWeight.length >= 3 ? includeColorWeight.length * 2 : "8"
128
+ }col`}
129
+ >
130
+ {allowedPaletteColors!.map((color: [string, string], idx: number) => [
131
+ <RadioButton
132
+ className={`${eccgui}-colorfield__palette__color`}
133
+ hideIndicator
134
+ value={color[1]}
135
+ onChange={(e: React.ChangeEvent<HTMLInputElement>) => {
136
+ forwardOnChange(e);
137
+ }}
138
+ >
139
+ <Tooltip key={idx} content={color[0].replace(`${eccgui}-color-palette-`, "")}>
140
+ <Tag
141
+ large
142
+ style={{ [`--eccgui-colorfield-palette-color`]: color[1] } as CSSProperties}
143
+ >
144
+ {color[1]}
145
+ </Tag>
146
+ </Tooltip>
147
+ </RadioButton>,
148
+ // Looks like we cannot force some type of line break in the tag list via CSS only
149
+ (idx + 1) % (includeColorWeight.length >= 3 ? includeColorWeight.length * 2 : 8) ===
150
+ 0 && (
151
+ <>
152
+ <br className={`${eccgui}-colorfield__palette-linebreak`} />
153
+ </>
154
+ ),
155
+ ])}
156
+ </TagList>
157
+ </FieldSet>
158
+ </WhiteSpaceContainer>
159
+ }
160
+ >
161
+ {colorInput}
162
+ </ContextOverlay>
163
+ ) : (
164
+ colorInput
165
+ );
166
+ };
167
+
168
+ type calculateColorHashValueProps = Pick<
169
+ ColorFieldProps,
170
+ "allowCustomColor" | "includeColorWeight" | "includePaletteGroup"
171
+ >;
172
+
173
+ /**
174
+ * Simple helper function that provide simple access to color hash calculation.
175
+ * Using the same default values for the color palette filter.
176
+ */
177
+ ColorField.calculateColorHashValue = (
178
+ text: string,
179
+ options: calculateColorHashValueProps = {
180
+ allowCustomColor: false,
181
+ includeColorWeight: [100, 300, 700, 900],
182
+ includePaletteGroup: ["layout"],
183
+ }
184
+ ) => {
185
+ const hash = utils.textToColorHash({
186
+ text,
187
+ options: {
188
+ returnValidColorsDirectly: options.allowCustomColor as boolean,
189
+ enabledColors: utils.getEnabledColorsFromPalette({
190
+ includePaletteGroup: options.includePaletteGroup,
191
+ includeColorWeight: options.includeColorWeight,
192
+ minimalColorDistance: 0,
193
+ }),
194
+ },
195
+ });
196
+
197
+ return hash ? hash : undefined;
198
+ };
199
+
200
+ export default ColorField;
@@ -0,0 +1,56 @@
1
+ .#{$eccgui}-colorfield {
2
+ cursor: default;
3
+
4
+ &:not(.#{$ns}-fill) {
5
+ width: 100%;
6
+ max-width: 4 * $eccgui-size-textfield-height-regular;
7
+ }
8
+
9
+ .#{$ns}-input {
10
+ color: var(--#{$eccgui}-colorfield-background);
11
+ cursor: inherit;
12
+ background-color: var(--#{$eccgui}-colorfield-background);
13
+
14
+ &[type="color"] {
15
+ &::-webkit-color-swatch-wrapper {
16
+ display: none;
17
+ }
18
+
19
+ &::-moz-color-swatch {
20
+ display: none;
21
+ }
22
+ }
23
+ }
24
+
25
+ .#{$ns}-input-left-container {
26
+ top: 1px;
27
+ left: 1px !important;
28
+ height: calc(100% - 2px);
29
+ background-color: $eccgui-color-textfield-background;
30
+ }
31
+ .#{$ns}-input-action {
32
+ top: 1px;
33
+ right: 1px !important;
34
+ height: calc(100% - 2px);
35
+ background-color: $eccgui-color-textfield-background;
36
+ }
37
+ }
38
+
39
+ .#{$eccgui}-colorfield__palette {
40
+ & > li:has(.#{$eccgui}-colorfield__palette-linebreak) {
41
+ display: block;
42
+ width: 100%;
43
+ height: 0;
44
+ margin: 0;
45
+ overflow: hidden;
46
+ }
47
+ }
48
+
49
+ .#{$eccgui}-colorfield__palette__color {
50
+ margin: 0;
51
+ .#{$eccgui}-tag__item {
52
+ width: 3rem;
53
+ color: var(--#{$eccgui}-colorfield-palette-color) !important;
54
+ background-color: var(--#{$eccgui}-colorfield-palette-color) !important;
55
+ }
56
+ }
@@ -60,3 +60,12 @@ $eccgui-color-scontentgroup-border-sub: eccgui-color-rgba(
60
60
  flex-shrink: 1;
61
61
  width: 100%;
62
62
  }
63
+
64
+ @media print {
65
+ .#{$eccgui}-contentgroup__header__options {
66
+ display: none;
67
+ }
68
+ .#{$eccgui}-contentgroup--border-sub::after {
69
+ print-color-adjust: exact;
70
+ }
71
+ }