@eccenca/gui-elements 25.1.0-rc.0 → 25.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 (71) hide show
  1. package/CHANGELOG.md +31 -5
  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/components/ContextOverlay/ContextOverlay.js +6 -6
  5. package/dist/cjs/components/ContextOverlay/ContextOverlay.js.map +1 -1
  6. package/dist/cjs/components/DecoupledOverlay/DecoupledOverlay.js +47 -0
  7. package/dist/cjs/components/DecoupledOverlay/DecoupledOverlay.js.map +1 -0
  8. package/dist/cjs/components/Icon/canonicalIconNames.js +3 -0
  9. package/dist/cjs/components/Icon/canonicalIconNames.js.map +1 -1
  10. package/dist/cjs/components/Icon/transformIcon.js +14 -0
  11. package/dist/cjs/components/Icon/transformIcon.js.map +1 -0
  12. package/dist/cjs/components/MultiSelect/MultiSelect.js +2 -1
  13. package/dist/cjs/components/MultiSelect/MultiSelect.js.map +1 -1
  14. package/dist/cjs/components/VisualTour/VisualTour.js +24 -32
  15. package/dist/cjs/components/VisualTour/VisualTour.js.map +1 -1
  16. package/dist/cjs/components/index.js +1 -0
  17. package/dist/cjs/components/index.js.map +1 -1
  18. package/dist/cjs/extensions/codemirror/CodeMirror.js +16 -4
  19. package/dist/cjs/extensions/codemirror/CodeMirror.js.map +1 -1
  20. package/dist/cjs/extensions/react-flow/edges/EdgeLabel.js +1 -1
  21. package/dist/cjs/extensions/react-flow/edges/EdgeLabel.js.map +1 -1
  22. package/dist/esm/cmem/ActivityControl/ActivityControlWidget.js +19 -14
  23. package/dist/esm/cmem/ActivityControl/ActivityControlWidget.js.map +1 -1
  24. package/dist/esm/components/ContextOverlay/ContextOverlay.js +3 -3
  25. package/dist/esm/components/ContextOverlay/ContextOverlay.js.map +1 -1
  26. package/dist/esm/components/DecoupledOverlay/DecoupledOverlay.js +41 -0
  27. package/dist/esm/components/DecoupledOverlay/DecoupledOverlay.js.map +1 -0
  28. package/dist/esm/components/Icon/canonicalIconNames.js +3 -0
  29. package/dist/esm/components/Icon/canonicalIconNames.js.map +1 -1
  30. package/dist/esm/components/Icon/transformIcon.js +21 -0
  31. package/dist/esm/components/Icon/transformIcon.js.map +1 -0
  32. package/dist/esm/components/MultiSelect/MultiSelect.js +3 -2
  33. package/dist/esm/components/MultiSelect/MultiSelect.js.map +1 -1
  34. package/dist/esm/components/VisualTour/VisualTour.js +25 -33
  35. package/dist/esm/components/VisualTour/VisualTour.js.map +1 -1
  36. package/dist/esm/components/index.js +1 -0
  37. package/dist/esm/components/index.js.map +1 -1
  38. package/dist/esm/extensions/codemirror/CodeMirror.js +16 -4
  39. package/dist/esm/extensions/codemirror/CodeMirror.js.map +1 -1
  40. package/dist/esm/extensions/react-flow/edges/EdgeLabel.js +1 -1
  41. package/dist/esm/extensions/react-flow/edges/EdgeLabel.js.map +1 -1
  42. package/dist/types/cmem/ActivityControl/ActivityControlWidget.d.ts +9 -0
  43. package/dist/types/components/ContextOverlay/ContextOverlay.d.ts +7 -1
  44. package/dist/types/components/DecoupledOverlay/DecoupledOverlay.d.ts +20 -0
  45. package/dist/types/components/Icon/canonicalIconNames.d.ts +2 -0
  46. package/dist/types/components/Icon/transformIcon.d.ts +2 -0
  47. package/dist/types/components/MultiSelect/MultiSelect.d.ts +1 -1
  48. package/dist/types/components/index.d.ts +1 -0
  49. package/package.json +1 -1
  50. package/src/cmem/ActivityControl/ActivityControlWidget.tsx +68 -35
  51. package/src/components/Application/_colors.scss +15 -0
  52. package/src/components/ContextOverlay/ContextOverlay.tsx +20 -1
  53. package/src/components/DecoupledOverlay/DecoupledOverlay.stories.tsx +30 -0
  54. package/src/components/DecoupledOverlay/DecoupledOverlay.tsx +97 -0
  55. package/src/components/DecoupledOverlay/_decoupledoverlay.scss +46 -0
  56. package/src/components/Icon/canonicalIconNames.tsx +3 -0
  57. package/src/components/Icon/transformIcon.tsx +17 -0
  58. package/src/components/Link/Link.stories.tsx +30 -0
  59. package/src/components/Link/link.scss +28 -2
  60. package/src/components/MultiSelect/MultiSelect.tsx +12 -3
  61. package/src/components/VisualTour/VisualTour.tsx +30 -50
  62. package/src/components/VisualTour/visualTour.scss +0 -34
  63. package/src/components/index.scss +1 -0
  64. package/src/components/index.ts +1 -0
  65. package/src/configuration/_customproperties.scss +32 -0
  66. package/src/configuration/stories/customproperties.stories.tsx +118 -0
  67. package/src/extensions/codemirror/CodeMirror.tsx +16 -5
  68. package/src/extensions/react-flow/_config.scss +3 -3
  69. package/src/extensions/react-flow/edges/EdgeLabel.tsx +5 -3
  70. package/src/extensions/react-flow/edges/_edges.scss +3 -2
  71. package/src/index.scss +1 -0
@@ -0,0 +1,97 @@
1
+ import React from "react";
2
+ import { createPortal } from "react-dom";
3
+ import { Classes as BlueprintClasses } from "@blueprintjs/core";
4
+ import { createPopper } from "@popperjs/core";
5
+
6
+ import { CLASSPREFIX as eccgui, ContextOverlayProps, TestableComponent, TooltipSize, WhiteSpaceContainer } from "../../index";
7
+
8
+ export interface DecoupledOverlayProps
9
+ extends React.HTMLAttributes<HTMLDivElement>,
10
+ TestableComponent,
11
+ Pick<ContextOverlayProps, "usePortal" | "portalContainer" | "placement" | "minimal" | "paddingSize"> {
12
+ /**
13
+ * Element that should be used. The step content is displayed as a tooltip instead of a modal.
14
+ * In case of an array, the first match is highlighted. */
15
+ targetSelectorOrElement: string | Element;
16
+ /**
17
+ * The size of the overlay.
18
+ * */
19
+ size?: TooltipSize;
20
+ }
21
+
22
+ /**
23
+ * Use an overlay popover without the necessity to use a target that need to be rendered in place.
24
+ * The target is referenced by a selector string or element object.
25
+ * It can exist somewhere in the DOM, but it must exist when the overlay is rendered.
26
+ * It is always displayed, close it by removement.
27
+ */
28
+ export const DecoupledOverlay = ({
29
+ targetSelectorOrElement,
30
+ usePortal = true,
31
+ portalContainer = document.body,
32
+ minimal = false,
33
+ placement = "auto",
34
+ size = "large",
35
+ paddingSize,
36
+ children,
37
+ }: DecoupledOverlayProps) => {
38
+ const overlayRef = React.useCallback(
39
+ (overlay: HTMLDivElement | null) => {
40
+ const target =
41
+ typeof targetSelectorOrElement === "string"
42
+ ? document.querySelector(targetSelectorOrElement)
43
+ : targetSelectorOrElement;
44
+ if (overlay && target) {
45
+ createPopper(target, overlay, {
46
+ placement: placement,
47
+ modifiers: [
48
+ {
49
+ name: "offset",
50
+ options: {
51
+ offset: [0, 15],
52
+ },
53
+ },
54
+ ],
55
+ });
56
+ }
57
+ },
58
+ [targetSelectorOrElement]
59
+ );
60
+
61
+ const overlay = (
62
+ <div
63
+ className={
64
+ `${eccgui}-decoupled-overlay` +
65
+ ` ${eccgui}-decoupled-overlay--${size}` +
66
+ ` ${BlueprintClasses.POPOVER}` +
67
+ (minimal ? ` ${BlueprintClasses.MINIMAL}` : "")
68
+ }
69
+ role="tooltip"
70
+ ref={overlayRef}
71
+ >
72
+ {!minimal && (
73
+ <div
74
+ className={`${eccgui}-decoupled-overlay__arrow ${BlueprintClasses.POPOVER_ARROW}`}
75
+ data-popper-arrow
76
+ aria-hidden
77
+ />
78
+ )}
79
+ <div className={`${BlueprintClasses.POPOVER_CONTENT} ${eccgui}-decoupled-overlay__content`}>
80
+ {paddingSize ? (
81
+ <WhiteSpaceContainer
82
+ paddingTop={paddingSize}
83
+ paddingRight={paddingSize}
84
+ paddingBottom={paddingSize}
85
+ paddingLeft={paddingSize}
86
+ >
87
+ {children}
88
+ </WhiteSpaceContainer>
89
+ ) : children}
90
+ </div>
91
+ </div>
92
+ );
93
+
94
+ return usePortal ? createPortal(overlay, portalContainer) : overlay;
95
+ };
96
+
97
+ export default DecoupledOverlay;
@@ -0,0 +1,46 @@
1
+ .#{$eccgui}-decoupled-overlay__arrow {
2
+ &::before {
3
+ background: $card-background-color;
4
+ }
5
+
6
+ .#{$eccgui}-decoupled-overlay[data-popper-placement="top"] & {
7
+ bottom: -0.5 * $eccgui-size-block-whitespace;
8
+ }
9
+ .#{$eccgui}-decoupled-overlay[data-popper-placement="right"] & {
10
+ left: -0.5 * $eccgui-size-block-whitespace;
11
+ }
12
+ .#{$eccgui}-decoupled-overlay[data-popper-placement="bottom"] & {
13
+ top: -0.5 * $eccgui-size-block-whitespace;
14
+ }
15
+ .#{$eccgui}-decoupled-overlay[data-popper-placement="left"] & {
16
+ right: -0.5 * $eccgui-size-block-whitespace;
17
+ }
18
+ }
19
+
20
+ .#{$eccgui}-decoupled-overlay {
21
+ &.#{$prefix-blueprintjs}-popover {
22
+ z-index: 8001;
23
+ }
24
+
25
+ &--small {
26
+ @extend .#{$eccgui}-tooltip--small;
27
+ }
28
+
29
+ &--medium {
30
+ @extend .#{$eccgui}-tooltip--medium;
31
+ }
32
+
33
+ &--large {
34
+ @extend .#{$eccgui}-tooltip--large;
35
+ }
36
+
37
+ &:has(.#{$eccgui}-decoupled-overlay__arrow) {
38
+ .#{$eccgui}-decoupled-overlay__content {
39
+ min-height: 30px; // height of blueprint arrow
40
+ }
41
+ }
42
+ }
43
+
44
+ .#{$eccgui}-decoupled-overlay__content {
45
+ padding: 0.1px; // force margins of children to stay inside
46
+ }
@@ -1,5 +1,6 @@
1
1
  import * as icons from "@carbon/react/icons";
2
2
  import { CarbonIconType as IconType } from "@carbon/react/icons";
3
+ import { transform} from "./transformIcon";
3
4
 
4
5
  const canonicalIcons = {
5
6
  "application-activities": icons.Activity,
@@ -172,8 +173,10 @@ const canonicalIcons = {
172
173
  "state-checked": icons.CheckboxChecked,
173
174
  "state-checkedsimple": icons.Checkmark,
174
175
  "state-confirmed": icons.ThumbsUp,
176
+ "state-confirmed-all": icons.ThumbsUpDouble,
175
177
  "state-danger": icons.ErrorFilled,
176
178
  "state-declined": icons.ThumbsDown,
179
+ "state-declined-all": transform(icons.ThumbsUpDouble, 0, false, true),
177
180
  "state-flagged": icons.Flag,
178
181
  "state-info": icons.InformationFilled,
179
182
  "state-locked": icons.Locked,
@@ -0,0 +1,17 @@
1
+ import React from "react";
2
+ import { CarbonIconType, CarbonIconProps } from "@carbon/react/icons";
3
+
4
+ export const transform = (IconSymbol: CarbonIconType, rotate: number = 0, flipH: boolean = false, flipV: boolean = false) : CarbonIconType => {
5
+ return React.forwardRef((props: CarbonIconProps, ref: React.ForwardedRef<React.ReactSVGElement>) => {
6
+ return (
7
+ <IconSymbol
8
+ {...props}
9
+ ref={ref}
10
+ transform={
11
+ `scale(${flipH ? "-1" : "1"}, ${flipV ? "-1" : "1"}) rotate(${rotate})`
12
+ }
13
+ />
14
+ );
15
+ })
16
+ }
17
+
@@ -0,0 +1,30 @@
1
+ import React from "react";
2
+ import { Meta, StoryFn } from "@storybook/react";
3
+
4
+ import { Link } from "../../../index";
5
+
6
+ export default {
7
+ title: "Components/Link",
8
+ component: Link,
9
+ argTypes: {
10
+ target: {
11
+ control: "select",
12
+ options: ["_self", "_blank", "_parent", "_top"],
13
+ },
14
+ },
15
+ } as Meta<typeof Link>;
16
+
17
+ const Template: StoryFn<typeof Link> = (args) => <Link {...args} />;
18
+
19
+ export const Default = Template.bind({});
20
+ Default.args = {
21
+ children: "Example link",
22
+ href: "https://example.com/",
23
+ };
24
+
25
+ export const Disabled = Template.bind({});
26
+ Disabled.args = {
27
+ children: "Disabled link",
28
+ href: "https://example.com/",
29
+ disabled: true,
30
+ };
@@ -2,8 +2,34 @@
2
2
  @include link.link;
3
3
 
4
4
  .#{$prefix}--link {
5
- font-size: 1em;
6
- line-height: inherit;
5
+ &,
6
+ &:hover {
7
+ // default case: use font size from context
8
+ font-size: inherit;
9
+ line-height: inherit;
10
+ }
11
+
12
+ &.#{$prefix}--link--sm {
13
+ &,
14
+ &:hover {
15
+ font-size: $eccgui-size-typo-caption;
16
+ line-height: $eccgui-size-typo-caption-lineheight;
17
+ }
18
+ }
19
+ &.#{$prefix}--link--md {
20
+ &,
21
+ &:hover {
22
+ font-size: $eccgui-size-typo-text;
23
+ line-height: $eccgui-size-typo-text-lineheight;
24
+ }
25
+ }
26
+ &.#{$prefix}--link--lg {
27
+ &,
28
+ &:hover {
29
+ font-size: $eccgui-size-typo-subtitle;
30
+ line-height: $eccgui-size-typo-subtitle-lineheight;
31
+ }
32
+ }
7
33
 
8
34
  &:focus {
9
35
  outline: none;
@@ -10,7 +10,15 @@ import { removeExtraSpaces } from "../../common/utils/stringUtils";
10
10
  import { CLASSPREFIX as eccgui } from "../../configuration/constants";
11
11
  import { TestableComponent } from "../interfaces";
12
12
 
13
- import { ContextOverlayProps, Highlighter, IconButton, MenuItem, OverflowText, Spinner } from "./../../index";
13
+ import {
14
+ ContextOverlayProps,
15
+ Highlighter,
16
+ highlighterUtils,
17
+ IconButton,
18
+ MenuItem,
19
+ OverflowText,
20
+ Spinner
21
+ } from "./../../index";
14
22
 
15
23
  export interface MultiSuggestFieldSelectionProps<T> {
16
24
  newlySelected?: T;
@@ -53,7 +61,7 @@ interface MultiSuggestFieldCommonProps<T>
53
61
  /**
54
62
  * prop to listen for query changes, when text is entered in the multi-select input
55
63
  */
56
- runOnQueryChange?: (query: string) => Promise<T[] | undefined>;
64
+ runOnQueryChange?: (query: string) => Promise<T[] | undefined> | (T[] | undefined);
57
65
  /**
58
66
  * Whether the component should take up the full width of its container.
59
67
  * This overrides `tagInputProps.fill`.
@@ -265,7 +273,8 @@ export function MultiSuggestField<T>({
265
273
  };
266
274
 
267
275
  const defaultFilterPredicate = (item: T, query: string) => {
268
- return itemLabel(item).toLowerCase().includes(query);
276
+ const searchWords = highlighterUtils.extractSearchWords(query, true)
277
+ return highlighterUtils.matchesAllWords(itemLabel(item).toLowerCase(), searchWords)
269
278
  };
270
279
 
271
280
  /**
@@ -1,7 +1,5 @@
1
1
  import React from "react";
2
2
  import { createPortal } from "react-dom";
3
- import { Classes as BlueprintClasses } from "@blueprintjs/core";
4
- import { createPopper } from "@popperjs/core";
5
3
 
6
4
  import { CLASSPREFIX as eccgui } from "../../configuration/constants";
7
5
  import {
@@ -14,6 +12,7 @@ import {
14
12
  CardHeader,
15
13
  CardOptions,
16
14
  CardTitle,
15
+ DecoupledOverlay,
17
16
  IconButton,
18
17
  Markdown,
19
18
  ModalSize,
@@ -130,7 +129,7 @@ export const VisualTour = ({
130
129
  <Button
131
130
  key={"next"}
132
131
  variant="outlined"
133
- intent={"primary"}
132
+ elevated
134
133
  onClick={() => {
135
134
  setCurrentStepIndex(currentStepIndex + 1);
136
135
  }}
@@ -144,7 +143,7 @@ export const VisualTour = ({
144
143
  text={closeLabel}
145
144
  onClick={closeTour}
146
145
  variant="outlined"
147
- intent={"primary"}
146
+ elevated
148
147
  rightIcon={"navigation-close"}
149
148
  />
150
149
  ),
@@ -292,25 +291,6 @@ interface StepPopoverProps {
292
291
 
293
292
  /** Popover that is displayed and points at the highlighted element. */
294
293
  const StepPopover = ({ highlightedElement, step, titleOption, actionButtons }: StepPopoverProps) => {
295
- const tooltipRef = React.useCallback(
296
- (tooltip: HTMLDivElement | null) => {
297
- if (tooltip) {
298
- createPopper(highlightedElement, tooltip, {
299
- placement: "auto",
300
- modifiers: [
301
- {
302
- name: "offset",
303
- options: {
304
- offset: [0, 15],
305
- },
306
- },
307
- ],
308
- });
309
- }
310
- },
311
- [highlightedElement]
312
- );
313
-
314
294
  const backdropRef = React.useCallback(
315
295
  (backdrop: HTMLDivElement | null) => {
316
296
  const highlightStencil = () => {
@@ -340,39 +320,39 @@ const StepPopover = ({ highlightedElement, step, titleOption, actionButtons }: S
340
320
  [highlightedElement]
341
321
  );
342
322
 
323
+ // map to only tooltip size because the `DecoupledOverlay` only supports them
324
+ let overlaySize: TooltipSize = "large";
325
+ switch (step.size) {
326
+ case "tiny":
327
+ overlaySize = "small";
328
+ break;
329
+ case "regular":
330
+ overlaySize = "medium";
331
+ break;
332
+ case "xlarge":
333
+ case "fullscreen":
334
+ overlaySize = "large";
335
+ break;
336
+ }
337
+
343
338
  return createPortal(
344
339
  <div className={`${eccgui}-visual-tour`}>
345
340
  <div className={`${eccgui}-visual-tour__focushelper`} ref={backdropRef} />
346
341
  <div>
347
342
  <div className={`${eccgui}-visual-tour__backdrop`} />
348
343
  </div>
349
- <div
350
- className={
351
- `${eccgui}-visual-tour__overlay` +
352
- ` ${eccgui}-visual-tour__overlay--${step.size ?? "large"}` +
353
- ` ${BlueprintClasses.POPOVER}`
354
- }
355
- role="tooltip"
356
- ref={tooltipRef}
357
- >
358
- <div
359
- className={`${eccgui}-visual-tour__arrow ${BlueprintClasses.POPOVER_ARROW}`}
360
- data-popper-arrow
361
- aria-hidden
362
- />
363
- <div className={`${BlueprintClasses.POPOVER_CONTENT} ${eccgui}-visual-tour__overlay__content`}>
364
- <Card isOnlyLayout elevation={-1} whitespaceAmount="small">
365
- <CardHeader>
366
- <CardTitle>{step.title}</CardTitle>
367
- <CardOptions>{titleOption}</CardOptions>
368
- </CardHeader>
369
- <CardContent>
370
- <StepContent step={step} />
371
- </CardContent>
372
- <CardActions inverseDirection>{actionButtons}</CardActions>
373
- </Card>
374
- </div>
375
- </div>
344
+ <DecoupledOverlay targetSelectorOrElement={highlightedElement} size={overlaySize} usePortal={false}>
345
+ <Card isOnlyLayout elevation={-1} whitespaceAmount="small">
346
+ <CardHeader>
347
+ <CardTitle>{step.title}</CardTitle>
348
+ <CardOptions>{titleOption}</CardOptions>
349
+ </CardHeader>
350
+ <CardContent>
351
+ <StepContent step={step} />
352
+ </CardContent>
353
+ <CardActions inverseDirection>{actionButtons}</CardActions>
354
+ </Card>
355
+ </DecoupledOverlay>
376
356
  </div>,
377
357
  document.body
378
358
  );
@@ -31,40 +31,6 @@
31
31
  opacity: 0;
32
32
  }
33
33
 
34
- .#{$eccgui}-visual-tour__arrow {
35
- &::before {
36
- background: $card-background-color;
37
- }
38
-
39
- .#{$eccgui}-visual-tour__overlay[data-popper-placement="top"] & {
40
- bottom: -0.5 * $eccgui-size-block-whitespace;
41
- }
42
- .#{$eccgui}-visual-tour__overlay[data-popper-placement="right"] & {
43
- left: -0.5 * $eccgui-size-block-whitespace;
44
- }
45
- .#{$eccgui}-visual-tour__overlay[data-popper-placement="bottom"] & {
46
- top: -0.5 * $eccgui-size-block-whitespace;
47
- }
48
- .#{$eccgui}-visual-tour__overlay[data-popper-placement="left"] & {
49
- right: -0.5 * $eccgui-size-block-whitespace;
50
- }
51
- }
52
-
53
- .#{$eccgui}-visual-tour__overlay {
54
- z-index: 8002; // 2 over application header
55
- &--small {
56
- @extend .#{$eccgui}-tooltip--small;
57
- }
58
-
59
- &--medium {
60
- @extend .#{$eccgui}-tooltip--medium;
61
- }
62
-
63
- &--large {
64
- @extend .#{$eccgui}-tooltip--large;
65
- }
66
- }
67
-
68
34
  .#{$eccgui}-card__content {
69
35
  .#{$eccgui}-visual-tour__overlay__content & {
70
36
  max-height: 45vh;
@@ -5,6 +5,7 @@
5
5
  @import "./Card/card";
6
6
  @import "./Chat/chat";
7
7
  @import "./Checkbox/checkbox";
8
+ @import "./DecoupledOverlay/decoupledoverlay";
8
9
  @import "./Depiction/depiction";
9
10
  @import "./Dialog/dialog";
10
11
  @import "./FlexibleLayout/flexiblelayout";
@@ -9,6 +9,7 @@ export * from "./Checkbox/Checkbox";
9
9
  export * from "./CodeAutocompleteField";
10
10
  export * from "./ContentGroup/ContentGroup";
11
11
  export * from "./ContextOverlay";
12
+ export * from "./DecoupledOverlay/DecoupledOverlay";
12
13
  export * from "./Depiction/Depiction";
13
14
  export * from "./Dialog";
14
15
  export * from "./FlexibleLayout";
@@ -0,0 +1,32 @@
1
+ /**
2
+ * We mirror our SCSS variables here to improve availability in inline styles
3
+ * and module styles without included SCSS config stack.
4
+ * Colors are set in `src/components/Application/_colors.scss`.
5
+ */
6
+
7
+ :root {
8
+ --#{$eccgui}-size-typo-caption: #{$eccgui-size-typo-caption};
9
+ --#{$eccgui}-size-typo-caption-lineheight: #{$eccgui-size-typo-caption-lineheight};
10
+ --#{$eccgui}-size-typo-text: #{$eccgui-size-typo-text};
11
+ --#{$eccgui}-size-typo-text-lineheight: #{$eccgui-size-typo-text-lineheight};
12
+ --#{$eccgui}-size-typo-subtitle: #{$eccgui-size-typo-subtitle};
13
+ --#{$eccgui}-size-typo-subtitle-lineheight: #{$eccgui-size-typo-subtitle-lineheight};
14
+ --#{$eccgui}-size-typo-title: #{$eccgui-size-typo-title};
15
+ --#{$eccgui}-size-typo-title-lineheight: #{$eccgui-size-typo-title-lineheight};
16
+ --#{$eccgui}-size-typo-headline: #{$eccgui-size-typo-headline};
17
+ --#{$eccgui}-size-typo-headline-lineheight: #{$eccgui-size-typo-headline-lineheight};
18
+ --#{$eccgui}-font-weight-light: #{$eccgui-font-weight-light};
19
+ --#{$eccgui}-font-weight-regular: #{$eccgui-font-weight-regular};
20
+ --#{$eccgui}-font-weight-bold: #{$eccgui-font-weight-bold};
21
+ --#{$eccgui}-font-spacing-condensed: #{$eccgui-font-spacing-condensed};
22
+ --#{$eccgui}-font-spacing-regular: #{$eccgui-font-spacing-regular};
23
+ --#{$eccgui}-font-spacing-wide: #{$eccgui-font-spacing-wide};
24
+ --#{$eccgui}-size-block-whitespace: #{$eccgui-size-block-whitespace};
25
+ --#{$eccgui}-size-inline-whitespace: #{$eccgui-size-inline-whitespace};
26
+ --#{$eccgui}-opacity-regular: #{$eccgui-opacity-regular};
27
+ --#{$eccgui}-opacity-narrow: #{$eccgui-opacity-narrow};
28
+ --#{$eccgui}-opacity-muted: #{$eccgui-opacity-muted};
29
+ --#{$eccgui}-opacity-disabled: #{$eccgui-opacity-disabled};
30
+ --#{$eccgui}-opacity-ghostly: #{$eccgui-opacity-ghostly};
31
+ --#{$eccgui}-opacity-invisible: #{$eccgui-opacity-invisible};
32
+ }
@@ -0,0 +1,118 @@
1
+ import React from "react";
2
+ import { Meta, StoryFn } from "@storybook/react";
3
+
4
+ import CssCustomProperties from "../../common/utils/CssCustomProperties";
5
+ import {
6
+ Section,
7
+ SectionHeader,
8
+ Spacing,
9
+ Table,
10
+ TableBody,
11
+ TableCell,
12
+ TableContainer,
13
+ TableHead,
14
+ TableHeader,
15
+ TableRow,
16
+ TitleSubsection,
17
+ } from "../../components";
18
+ import { CLASSPREFIX as eccgui } from "../../index";
19
+
20
+ const groups: { title: string; filterName: (name: string) => boolean }[] = [
21
+ {
22
+ title: "Typography",
23
+ filterName: (name) => name.startsWith(`--${eccgui}-size-typo`),
24
+ },
25
+ {
26
+ title: "Font weights and spacing",
27
+ filterName: (name) => name.startsWith(`--${eccgui}-font`),
28
+ },
29
+ {
30
+ title: "Whitespace",
31
+ filterName: (name) => name.startsWith(`--${eccgui}-size-block`) || name.startsWith(`--${eccgui}-size-inline`),
32
+ },
33
+ {
34
+ title: "Color aliases",
35
+ filterName: (name) => name.startsWith(`--${eccgui}-color`) && !name.startsWith(`--${eccgui}-color-palette`),
36
+ },
37
+ {
38
+ title: "Opacity",
39
+ filterName: (name) => name.startsWith(`--${eccgui}-opacity`),
40
+ },
41
+ {
42
+ title: "Palette colors",
43
+ filterName: (name) => name.startsWith(`--${eccgui}-color-palette`),
44
+ },
45
+ ];
46
+
47
+ const CssCustomPropertiesOverview = () => {
48
+ return (
49
+ <>
50
+ {groups.map(({ title, filterName }) => {
51
+ const properties = new CssCustomProperties({
52
+ selectorText: ":root",
53
+ filterName,
54
+ removeDashPrefix: false,
55
+ returnObject: false,
56
+ }).customProperties() as string[][];
57
+
58
+ return (
59
+ <React.Fragment key={title}>
60
+ <Section>
61
+ <SectionHeader>
62
+ <TitleSubsection>{title}</TitleSubsection>
63
+ </SectionHeader>
64
+ <Spacing size="tiny" />
65
+ <TableContainer>
66
+ <Table columnWidths={["60%", "40%"]}>
67
+ <TableHead>
68
+ <TableRow>
69
+ <TableHeader>CSS custom property</TableHeader>
70
+ <TableHeader>Current value</TableHeader>
71
+ </TableRow>
72
+ </TableHead>
73
+ <TableBody>
74
+ {properties.map(([name, value]) => (
75
+ <TableRow key={name}>
76
+ <TableCell>
77
+ <code>{name}</code>
78
+ </TableCell>
79
+ <TableCell>
80
+ {name.startsWith(`--${eccgui}-color`) && (
81
+ <span
82
+ style={{
83
+ display: "inline-block",
84
+ width: `var(--${eccgui}-size-block-whitespace)`,
85
+ height: `var(--${eccgui}-size-block-whitespace)`,
86
+ backgroundColor: value,
87
+ verticalAlign: "middle",
88
+ marginRight: `var(--${eccgui}-size-inline-whitespace)`,
89
+ border: "1px solid currentColor",
90
+ }}
91
+ />
92
+ )}
93
+ <code>{value}</code>
94
+ </TableCell>
95
+ </TableRow>
96
+ ))}
97
+ </TableBody>
98
+ </Table>
99
+ </TableContainer>
100
+ </Section>
101
+ <Spacing size="large" />
102
+ </React.Fragment>
103
+ );
104
+ })}
105
+ </>
106
+ );
107
+ };
108
+
109
+ /**
110
+ * We mirror our SCSS configuration variables as CSS custom vars.
111
+ * This way they can be easily used for inline styles or in CSS modules without SCSS includes.
112
+ */
113
+ export default {
114
+ title: "Configuration/CSS Custom Properties",
115
+ component: CssCustomPropertiesOverview,
116
+ } as Meta<typeof CssCustomPropertiesOverview>;
117
+
118
+ export const Default: StoryFn = () => <CssCustomPropertiesOverview />;
@@ -231,6 +231,10 @@ export const CodeEditor = ({
231
231
  currentView.current = view
232
232
  const currentReadOnly = React.useRef(readOnly)
233
233
  currentReadOnly.current = readOnly
234
+ const currentOnChange = React.useRef(onChange)
235
+ currentOnChange.current = onChange
236
+ const currentDisabled = React.useRef(disabled)
237
+ currentDisabled.current = disabled
234
238
  const [showPreview, setShowPreview] = React.useState<boolean>(false);
235
239
  // CodeMirror Compartments in order to allow for re-configuration after initialization
236
240
  const readOnlyCompartment = React.useRef<Compartment>(compartment())
@@ -319,11 +323,11 @@ export const CodeEditor = ({
319
323
  disabledCompartment.current.of(EditorView?.editable.of(!disabled)),
320
324
  AdaptedEditorViewDomEventHandlers(domEventHandlers) as Extension,
321
325
  EditorView?.updateListener.of((v: ViewUpdate) => {
322
- if (disabled) return;
326
+ if (currentDisabled.current) return;
323
327
 
324
- if (onChange && v.docChanged) {
328
+ if (currentOnChange.current && v.docChanged) {
325
329
  // Only fire if the text has actually been changed
326
- onChange(v.state.doc.toString());
330
+ currentOnChange.current(v.state.doc.toString());
327
331
  }
328
332
 
329
333
  if (onSelection)
@@ -377,7 +381,7 @@ export const CodeEditor = ({
377
381
  }
378
382
 
379
383
  if (disabled) {
380
- view.dom.className += ` ${eccgui}-disabled`;
384
+ view.dom.classList.add(`${eccgui}-disabled`);
381
385
  }
382
386
 
383
387
  if (intent) {
@@ -432,7 +436,14 @@ export const CodeEditor = ({
432
436
  }, [tabIntentSize])
433
437
 
434
438
  React.useEffect(() => {
435
- updateExtension(EditorView?.editable.of(!disabled), disabledCompartment.current)
439
+ updateExtension(EditorView?.editable.of(!disabled), disabledCompartment.current);
440
+ if (view?.dom) {
441
+ if (disabled) {
442
+ view.dom.classList.add(`${eccgui}-disabled`);
443
+ } else {
444
+ view.dom.classList.remove(`${eccgui}-disabled`);
445
+ }
446
+ }
436
447
  }, [disabled])
437
448
 
438
449
  React.useEffect(() => {