@eccenca/gui-elements 25.1.0-rc.0 → 25.1.0-rc.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +43 -5
- package/dist/cjs/cmem/ActivityControl/ActivityControlWidget.js +17 -13
- package/dist/cjs/cmem/ActivityControl/ActivityControlWidget.js.map +1 -1
- package/dist/cjs/cmem/react-flow/StickyNoteModal/StickyNoteModal.js +1 -1
- package/dist/cjs/cmem/react-flow/StickyNoteModal/StickyNoteModal.js.map +1 -1
- package/dist/cjs/common/index.js +1 -0
- package/dist/cjs/common/index.js.map +1 -1
- package/dist/cjs/common/utils/CssCustomProperties.js.map +1 -1
- package/dist/cjs/common/utils/colorHash.js +26 -12
- package/dist/cjs/common/utils/colorHash.js.map +1 -1
- package/dist/cjs/components/ColorField/ColorField.js +114 -0
- package/dist/cjs/components/ColorField/ColorField.js.map +1 -0
- package/dist/cjs/components/ContextOverlay/ContextOverlay.js +6 -6
- package/dist/cjs/components/ContextOverlay/ContextOverlay.js.map +1 -1
- package/dist/cjs/components/DecoupledOverlay/DecoupledOverlay.js +47 -0
- package/dist/cjs/components/DecoupledOverlay/DecoupledOverlay.js.map +1 -0
- package/dist/cjs/components/Icon/canonicalIconNames.js +3 -0
- package/dist/cjs/components/Icon/canonicalIconNames.js.map +1 -1
- package/dist/cjs/components/Icon/transformIcon.js +14 -0
- package/dist/cjs/components/Icon/transformIcon.js.map +1 -0
- package/dist/cjs/components/MultiSelect/MultiSelect.js +2 -1
- package/dist/cjs/components/MultiSelect/MultiSelect.js.map +1 -1
- package/dist/cjs/components/RadioButton/RadioButton.js +5 -2
- package/dist/cjs/components/RadioButton/RadioButton.js.map +1 -1
- package/dist/cjs/components/TextField/useTextValidation.js +17 -8
- package/dist/cjs/components/TextField/useTextValidation.js.map +1 -1
- package/dist/cjs/components/VisualTour/VisualTour.js +24 -32
- package/dist/cjs/components/VisualTour/VisualTour.js.map +1 -1
- package/dist/cjs/components/index.js +2 -0
- package/dist/cjs/components/index.js.map +1 -1
- package/dist/cjs/extensions/codemirror/CodeMirror.js +56 -18
- package/dist/cjs/extensions/codemirror/CodeMirror.js.map +1 -1
- package/dist/cjs/extensions/codemirror/toolbars/EditorAppearanceConfigMenu.js +23 -0
- package/dist/cjs/extensions/codemirror/toolbars/EditorAppearanceConfigMenu.js.map +1 -0
- package/dist/cjs/extensions/codemirror/toolbars/markdown.toolbar.js +5 -2
- package/dist/cjs/extensions/codemirror/toolbars/markdown.toolbar.js.map +1 -1
- package/dist/cjs/extensions/react-flow/edges/EdgeLabel.js +1 -1
- package/dist/cjs/extensions/react-flow/edges/EdgeLabel.js.map +1 -1
- package/dist/esm/cmem/ActivityControl/ActivityControlWidget.js +19 -14
- package/dist/esm/cmem/ActivityControl/ActivityControlWidget.js.map +1 -1
- package/dist/esm/cmem/react-flow/StickyNoteModal/StickyNoteModal.js +1 -1
- package/dist/esm/cmem/react-flow/StickyNoteModal/StickyNoteModal.js.map +1 -1
- package/dist/esm/common/index.js +2 -1
- package/dist/esm/common/index.js.map +1 -1
- package/dist/esm/common/utils/CssCustomProperties.js.map +1 -1
- package/dist/esm/common/utils/colorHash.js +26 -13
- package/dist/esm/common/utils/colorHash.js.map +1 -1
- package/dist/esm/components/ColorField/ColorField.js +140 -0
- package/dist/esm/components/ColorField/ColorField.js.map +1 -0
- package/dist/esm/components/ContextOverlay/ContextOverlay.js +3 -3
- package/dist/esm/components/ContextOverlay/ContextOverlay.js.map +1 -1
- package/dist/esm/components/DecoupledOverlay/DecoupledOverlay.js +41 -0
- package/dist/esm/components/DecoupledOverlay/DecoupledOverlay.js.map +1 -0
- package/dist/esm/components/Icon/canonicalIconNames.js +3 -0
- package/dist/esm/components/Icon/canonicalIconNames.js.map +1 -1
- package/dist/esm/components/Icon/transformIcon.js +21 -0
- package/dist/esm/components/Icon/transformIcon.js.map +1 -0
- package/dist/esm/components/MultiSelect/MultiSelect.js +3 -2
- package/dist/esm/components/MultiSelect/MultiSelect.js.map +1 -1
- package/dist/esm/components/RadioButton/RadioButton.js +6 -2
- package/dist/esm/components/RadioButton/RadioButton.js.map +1 -1
- package/dist/esm/components/TextField/useTextValidation.js +39 -8
- package/dist/esm/components/TextField/useTextValidation.js.map +1 -1
- package/dist/esm/components/VisualTour/VisualTour.js +25 -33
- package/dist/esm/components/VisualTour/VisualTour.js.map +1 -1
- package/dist/esm/components/index.js +2 -0
- package/dist/esm/components/index.js.map +1 -1
- package/dist/esm/extensions/codemirror/CodeMirror.js +58 -20
- package/dist/esm/extensions/codemirror/CodeMirror.js.map +1 -1
- package/dist/esm/extensions/codemirror/toolbars/EditorAppearanceConfigMenu.js +47 -0
- package/dist/esm/extensions/codemirror/toolbars/EditorAppearanceConfigMenu.js.map +1 -0
- package/dist/esm/extensions/codemirror/toolbars/markdown.toolbar.js +16 -2
- package/dist/esm/extensions/codemirror/toolbars/markdown.toolbar.js.map +1 -1
- package/dist/esm/extensions/react-flow/edges/EdgeLabel.js +1 -1
- package/dist/esm/extensions/react-flow/edges/EdgeLabel.js.map +1 -1
- package/dist/types/cmem/ActivityControl/ActivityControlWidget.d.ts +9 -0
- package/dist/types/common/index.d.ts +2 -1
- package/dist/types/common/utils/CssCustomProperties.d.ts +2 -2
- package/dist/types/common/utils/colorHash.d.ts +5 -4
- package/dist/types/components/ColorField/ColorField.d.ts +30 -0
- package/dist/types/components/ContextOverlay/ContextOverlay.d.ts +7 -1
- package/dist/types/components/DecoupledOverlay/DecoupledOverlay.d.ts +20 -0
- package/dist/types/components/Icon/canonicalIconNames.d.ts +2 -0
- package/dist/types/components/Icon/transformIcon.d.ts +2 -0
- package/dist/types/components/MultiSelect/MultiSelect.d.ts +1 -1
- package/dist/types/components/RadioButton/RadioButton.d.ts +8 -2
- package/dist/types/components/index.d.ts +2 -0
- package/dist/types/extensions/codemirror/CodeMirror.d.ts +12 -9
- package/dist/types/extensions/codemirror/toolbars/EditorAppearanceConfigMenu.d.ts +24 -0
- package/dist/types/extensions/codemirror/toolbars/markdown.toolbar.d.ts +2 -0
- package/package.json +1 -1
- package/src/cmem/ActivityControl/ActivityControlWidget.tsx +68 -35
- package/src/cmem/react-flow/StickyNoteModal/StickyNoteModal.tsx +1 -1
- package/src/common/index.ts +2 -1
- package/src/common/utils/CssCustomProperties.ts +5 -3
- package/src/common/utils/colorHash.ts +38 -20
- package/src/components/Application/_colors.scss +15 -0
- package/src/components/ColorField/ColorField.stories.tsx +72 -0
- package/src/components/ColorField/ColorField.test.tsx +101 -0
- package/src/components/ColorField/ColorField.tsx +200 -0
- package/src/components/ColorField/_colorfield.scss +67 -0
- package/src/components/ContextOverlay/ContextOverlay.tsx +20 -1
- package/src/components/DecoupledOverlay/DecoupledOverlay.stories.tsx +30 -0
- package/src/components/DecoupledOverlay/DecoupledOverlay.tsx +97 -0
- package/src/components/DecoupledOverlay/_decoupledoverlay.scss +46 -0
- package/src/components/Icon/canonicalIconNames.tsx +3 -0
- package/src/components/Icon/transformIcon.tsx +17 -0
- package/src/components/Link/Link.stories.tsx +30 -0
- package/src/components/Link/link.scss +28 -2
- package/src/components/MultiSelect/MultiSelect.tsx +12 -3
- package/src/components/RadioButton/RadioButton.tsx +15 -3
- package/src/components/RadioButton/radiobutton.scss +13 -0
- package/src/components/TextField/stories/TextField.stories.tsx +23 -0
- package/src/components/TextField/tests/useTextValidation.test.tsx +83 -0
- package/src/components/TextField/useTextValidation.ts +17 -8
- package/src/components/VisualTour/VisualTour.tsx +30 -50
- package/src/components/VisualTour/visualTour.scss +0 -34
- package/src/components/index.scss +2 -0
- package/src/components/index.ts +2 -0
- package/src/configuration/_customproperties.scss +32 -0
- package/src/configuration/stories/customproperties.stories.tsx +118 -0
- package/src/extensions/codemirror/CodeMirror.stories.tsx +9 -4
- package/src/extensions/codemirror/CodeMirror.tsx +87 -31
- package/src/extensions/codemirror/tests/CodeEditor.test.tsx +138 -0
- package/src/extensions/codemirror/tests/EditorAppearanceConfigMenu.test.tsx +131 -0
- package/src/extensions/codemirror/toolbars/EditorAppearanceConfigMenu.tsx +59 -0
- package/src/extensions/codemirror/toolbars/markdown.toolbar.tsx +17 -3
- package/src/extensions/react-flow/_config.scss +3 -3
- package/src/extensions/react-flow/edges/EdgeLabel.tsx +5 -3
- package/src/extensions/react-flow/edges/_edges.scss +3 -2
- package/src/index.scss +1 -0
|
@@ -61,3 +61,26 @@ const invisibleCharacterWarningProps: TextFieldProps = {
|
|
|
61
61
|
defaultValue: "Invisible character -><-",
|
|
62
62
|
};
|
|
63
63
|
InvisibleCharacterWarning.args = invisibleCharacterWarningProps;
|
|
64
|
+
|
|
65
|
+
/** Text field showing that emoji (✔️ variation-selector, 👨👩👧👦 ZWJ, #️⃣ keycap)
|
|
66
|
+
* are NOT reported as invisible characters, while a genuine ZWS still is. */
|
|
67
|
+
export const InvisibleCharacterWarningWithEmoji = Template.bind({});
|
|
68
|
+
|
|
69
|
+
const invisibleCharacterWarningWithEmojiProps: TextFieldProps = {
|
|
70
|
+
...Default.args,
|
|
71
|
+
invisibleCharacterWarning: {
|
|
72
|
+
callback: (codePoints) => {
|
|
73
|
+
if (codePoints.size) {
|
|
74
|
+
const codePointsString = [...codePoints]
|
|
75
|
+
.map((n) => characters.invisibleZeroWidthCharacters.codePointMap.get(n)?.fullLabel)
|
|
76
|
+
.join(", ");
|
|
77
|
+
alert("Invisible character detected in input string. Code points: " + codePointsString);
|
|
78
|
+
}
|
|
79
|
+
},
|
|
80
|
+
callbackDelay: 500,
|
|
81
|
+
},
|
|
82
|
+
onChange: () => {},
|
|
83
|
+
// ZWS should be flagged; ✔️ 👨👩👧👦 #️⃣ should NOT be flagged
|
|
84
|
+
defaultValue: "Check\u200B ✔️ 👨👩👧👦 #️⃣",
|
|
85
|
+
};
|
|
86
|
+
InvisibleCharacterWarningWithEmoji.args = invisibleCharacterWarningWithEmojiProps;
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
import { act, render } from "@testing-library/react";
|
|
3
|
+
|
|
4
|
+
import { useTextValidation } from "../useTextValidation";
|
|
5
|
+
|
|
6
|
+
const HookWrapper: React.FC<{ value: string; callback: jest.Mock; callbackDelay?: number }> = ({
|
|
7
|
+
value,
|
|
8
|
+
callback,
|
|
9
|
+
callbackDelay = 0,
|
|
10
|
+
}) => {
|
|
11
|
+
useTextValidation({
|
|
12
|
+
value,
|
|
13
|
+
onChange: jest.fn(),
|
|
14
|
+
invisibleCharacterWarning: { callback, callbackDelay },
|
|
15
|
+
});
|
|
16
|
+
return null;
|
|
17
|
+
};
|
|
18
|
+
|
|
19
|
+
describe("useTextValidation", () => {
|
|
20
|
+
beforeEach(() => {
|
|
21
|
+
jest.useFakeTimers();
|
|
22
|
+
});
|
|
23
|
+
|
|
24
|
+
afterEach(() => {
|
|
25
|
+
jest.useRealTimers();
|
|
26
|
+
});
|
|
27
|
+
|
|
28
|
+
/** Render the hook with a controlled value and flush the debounce timer. */
|
|
29
|
+
const runWithValue = (value: string, callbackDelay = 0) => {
|
|
30
|
+
const callback = jest.fn();
|
|
31
|
+
render(<HookWrapper value={value} callback={callback} callbackDelay={callbackDelay} />);
|
|
32
|
+
act(() => {
|
|
33
|
+
jest.runAllTimers();
|
|
34
|
+
});
|
|
35
|
+
return callback;
|
|
36
|
+
};
|
|
37
|
+
|
|
38
|
+
describe("invisible character detection", () => {
|
|
39
|
+
it("reports empty set for plain text", () => {
|
|
40
|
+
const callback = runWithValue("hello world");
|
|
41
|
+
expect(callback).toHaveBeenCalledWith(new Set());
|
|
42
|
+
});
|
|
43
|
+
|
|
44
|
+
it("detects zero-width space (U+200B)", () => {
|
|
45
|
+
const callback = runWithValue("hello\u200Bworld");
|
|
46
|
+
expect(callback).toHaveBeenCalledWith(new Set([0x200b]));
|
|
47
|
+
});
|
|
48
|
+
|
|
49
|
+
it("detects zero-width non-joiner (U+200C)", () => {
|
|
50
|
+
const callback = runWithValue("hello\u200Cworld");
|
|
51
|
+
expect(callback).toHaveBeenCalledWith(new Set([0x200c]));
|
|
52
|
+
});
|
|
53
|
+
});
|
|
54
|
+
|
|
55
|
+
describe("emoji false-positive prevention", () => {
|
|
56
|
+
it("does not flag ✔️ (base char + variation selector U+FE0F)", () => {
|
|
57
|
+
const callback = runWithValue("✔️");
|
|
58
|
+
expect(callback).toHaveBeenCalledWith(new Set());
|
|
59
|
+
});
|
|
60
|
+
|
|
61
|
+
it("does not flag ZWJ sequence emoji 👨👩👧👦", () => {
|
|
62
|
+
const callback = runWithValue("👨👩👧👦");
|
|
63
|
+
expect(callback).toHaveBeenCalledWith(new Set());
|
|
64
|
+
});
|
|
65
|
+
|
|
66
|
+
it("does not flag keycap emoji #️⃣", () => {
|
|
67
|
+
const callback = runWithValue("#️⃣");
|
|
68
|
+
expect(callback).toHaveBeenCalledWith(new Set());
|
|
69
|
+
});
|
|
70
|
+
});
|
|
71
|
+
|
|
72
|
+
describe("mixed content", () => {
|
|
73
|
+
it("detects ZWS while ignoring surrounding emoji", () => {
|
|
74
|
+
const callback = runWithValue("Check\u200B ✔️👨👩👧#️⃣");
|
|
75
|
+
expect(callback).toHaveBeenCalledWith(new Set([0x200b]));
|
|
76
|
+
});
|
|
77
|
+
|
|
78
|
+
it("reports empty set for text with only emoji", () => {
|
|
79
|
+
const callback = runWithValue("✔️ 👨👩👧👦#️⃣");
|
|
80
|
+
expect(callback).toHaveBeenCalledWith(new Set());
|
|
81
|
+
});
|
|
82
|
+
});
|
|
83
|
+
});
|
|
@@ -44,19 +44,28 @@ export const useTextValidation = <T>({ value, onChange, invisibleCharacterWarnin
|
|
|
44
44
|
state.current.detectedCodePoints = new Set();
|
|
45
45
|
}, []);
|
|
46
46
|
const detectionRegex = React.useMemo(() => chars.invisibleZeroWidthCharacters.createRegex(), []);
|
|
47
|
+
const segmenter = React.useMemo(() => new Intl.Segmenter(undefined, { granularity: "grapheme" }), []);
|
|
48
|
+
const emojiRegex = React.useMemo(() => new RegExp("\\p{Extended_Pictographic}|\\u20E3", "u"), []);
|
|
49
|
+
|
|
47
50
|
const detectIssues = React.useCallback(
|
|
48
51
|
(value: string): void => {
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
52
|
+
for (const { segment } of segmenter.segment(value)) {
|
|
53
|
+
if (emojiRegex.test(segment)) {
|
|
54
|
+
// skip emoji clusters since they legitimately contain variation selectors, ZWJ, tags, etc.
|
|
55
|
+
} else {
|
|
56
|
+
detectionRegex.lastIndex = 0;
|
|
57
|
+
let matchArray = detectionRegex.exec(segment);
|
|
58
|
+
while (matchArray) {
|
|
59
|
+
const codePoint = matchArray[0].codePointAt(0);
|
|
60
|
+
if (codePoint) {
|
|
61
|
+
state.current.detectedCodePoints.add(codePoint);
|
|
62
|
+
}
|
|
63
|
+
matchArray = detectionRegex.exec(segment);
|
|
64
|
+
}
|
|
55
65
|
}
|
|
56
|
-
matchArray = detectionRegex.exec(value);
|
|
57
66
|
}
|
|
58
67
|
},
|
|
59
|
-
[detectionRegex]
|
|
68
|
+
[detectionRegex, segmenter, emojiRegex]
|
|
60
69
|
);
|
|
61
70
|
// Checks if the value contains any problematic characters with a small delay.
|
|
62
71
|
const checkValue = React.useCallback(
|
|
@@ -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
|
-
|
|
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
|
-
|
|
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
|
-
<
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
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";
|
|
@@ -32,6 +33,7 @@
|
|
|
32
33
|
@import "./Tabs/tabs";
|
|
33
34
|
@import "./Tag/tag";
|
|
34
35
|
@import "./TextField/textfield";
|
|
36
|
+
@import "./ColorField/colorfield";
|
|
35
37
|
@import "./TagInput/taginput";
|
|
36
38
|
@import "./Toolbar/toolbar";
|
|
37
39
|
@import "./Tooltip/tooltip";
|
package/src/components/index.ts
CHANGED
|
@@ -7,8 +7,10 @@ export * from "./Card";
|
|
|
7
7
|
export * from "./Chat";
|
|
8
8
|
export * from "./Checkbox/Checkbox";
|
|
9
9
|
export * from "./CodeAutocompleteField";
|
|
10
|
+
export * from "./ColorField/ColorField";
|
|
10
11
|
export * from "./ContentGroup/ContentGroup";
|
|
11
12
|
export * from "./ContextOverlay";
|
|
13
|
+
export * from "./DecoupledOverlay/DecoupledOverlay";
|
|
12
14
|
export * from "./Depiction/Depiction";
|
|
13
15
|
export * from "./Dialog";
|
|
14
16
|
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 />;
|
|
@@ -24,17 +24,22 @@ const TemplateFull: StoryFn<typeof CodeEditor> = (args) => <CodeEditor {...args}
|
|
|
24
24
|
|
|
25
25
|
export const BasicExample = TemplateFull.bind({});
|
|
26
26
|
BasicExample.args = {
|
|
27
|
-
name: "
|
|
27
|
+
name: "jsinput",
|
|
28
|
+
mode: "json",
|
|
29
|
+
defaultValue: '{ json: "true" }',
|
|
30
|
+
};
|
|
31
|
+
|
|
32
|
+
export const MarkdownWithToolbar = TemplateFull.bind({});
|
|
33
|
+
MarkdownWithToolbar.args = {
|
|
34
|
+
name: "mdinput",
|
|
28
35
|
mode: "markdown",
|
|
29
36
|
defaultValue: "**test me**",
|
|
30
37
|
useToolbar: true,
|
|
31
|
-
disabled: false,
|
|
32
|
-
readOnly: true,
|
|
33
38
|
};
|
|
34
39
|
|
|
35
40
|
export const LinterExample = TemplateFull.bind({});
|
|
36
41
|
LinterExample.args = {
|
|
37
|
-
name: "
|
|
42
|
+
name: "lintinput",
|
|
38
43
|
defaultValue: "**test me**",
|
|
39
44
|
mode: "javascript",
|
|
40
45
|
useLinting: true,
|