@eccenca/gui-elements 25.1.0-rc.1 → 25.1.0-rc.3
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 +16 -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/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/Tooltip/Tooltip.js +11 -7
- package/dist/cjs/components/Tooltip/Tooltip.js.map +1 -1
- package/dist/cjs/components/index.js +1 -0
- package/dist/cjs/components/index.js.map +1 -1
- package/dist/cjs/extensions/codemirror/CodeMirror.js +40 -14
- 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/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/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/Tooltip/Tooltip.js +11 -7
- package/dist/esm/components/Tooltip/Tooltip.js.map +1 -1
- package/dist/esm/components/index.js +1 -0
- package/dist/esm/components/index.js.map +1 -1
- package/dist/esm/extensions/codemirror/CodeMirror.js +42 -16
- 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/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/RadioButton/RadioButton.d.ts +8 -2
- package/dist/types/components/index.d.ts +1 -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/_shame.scss +1 -35
- package/src/cmem/react-flow/StickyNoteModal/StickyNoteModal.tsx +1 -1
- package/src/common/index.ts +2 -1
- package/src/common/scss/_accessibility-defaults.scss +101 -0
- package/src/common/utils/CssCustomProperties.ts +5 -3
- package/src/common/utils/colorHash.ts +38 -20
- package/src/components/Application/_header.scss +21 -9
- package/src/components/Application/_sidebar.scss +6 -0
- package/src/components/Application/_toolbar.scss +3 -3
- package/src/components/AutoSuggestion/AutoSuggestion.scss +3 -1
- package/src/components/Checkbox/checkbox.scss +9 -1
- 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/Dialog/dialog.scss +8 -0
- package/src/components/Link/link.scss +5 -6
- package/src/components/MultiSuggestField/_multisuggestfield.scss +18 -0
- package/src/components/RadioButton/RadioButton.tsx +15 -3
- package/src/components/RadioButton/radiobutton.scss +18 -1
- package/src/components/TextField/stories/TextField.stories.tsx +23 -0
- package/src/components/TextField/tests/useTextValidation.test.tsx +83 -0
- package/src/components/TextField/textfield.scss +20 -0
- package/src/components/TextField/useTextValidation.ts +17 -8
- package/src/components/Tooltip/Tooltip.test.tsx +40 -5
- package/src/components/Tooltip/Tooltip.tsx +14 -10
- package/src/components/index.scss +1 -0
- package/src/components/index.ts +1 -0
- package/src/configuration/stories/customproperties.stories.tsx +4 -0
- package/src/extensions/codemirror/CodeMirror.stories.tsx +9 -4
- package/src/extensions/codemirror/CodeMirror.tsx +71 -26
- package/src/extensions/codemirror/_codemirror.scss +18 -28
- 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/index.scss +1 -0
|
@@ -4,7 +4,15 @@ import { EditorView, Rect } from "@codemirror/view";
|
|
|
4
4
|
import { IntentTypes } from "../../common/Intent";
|
|
5
5
|
import { TestableComponent } from "../../components/interfaces";
|
|
6
6
|
import { SupportedCodeEditorModes } from "./hooks/useCodemirrorModeExtension.hooks";
|
|
7
|
-
|
|
7
|
+
interface EditorAppearance {
|
|
8
|
+
/**
|
|
9
|
+
* If enabled the code editor won't show numbers before each line.
|
|
10
|
+
*/
|
|
11
|
+
preventLineNumbers?: boolean;
|
|
12
|
+
/** Long lines are wrapped and displayed on multiple lines */
|
|
13
|
+
wrapLines?: boolean;
|
|
14
|
+
}
|
|
15
|
+
export interface CodeEditorProps extends EditorAppearance, Omit<React.HTMLAttributes<HTMLDivElement>, "translate" | "onChange" | "onKeyDown" | "onMouseDown" | "onScroll">, TestableComponent {
|
|
8
16
|
setEditorView?: (editor: EditorView | undefined) => void;
|
|
9
17
|
/**
|
|
10
18
|
* `name` attribute of connected textarea element.
|
|
@@ -55,18 +63,12 @@ export interface CodeEditorProps extends Omit<React.HTMLAttributes<HTMLDivElemen
|
|
|
55
63
|
* Default value used first when the editor is instanciated.
|
|
56
64
|
*/
|
|
57
65
|
defaultValue?: string;
|
|
58
|
-
/**
|
|
59
|
-
* If enabled the code editor won't show numbers before each line.
|
|
60
|
-
*/
|
|
61
|
-
preventLineNumbers?: boolean;
|
|
62
66
|
/** Set read-only mode. Default: false */
|
|
63
67
|
readOnly?: boolean;
|
|
64
68
|
/** Optional height of the component */
|
|
65
69
|
height?: number | string;
|
|
66
|
-
/** Long lines are wrapped and displayed on multiple lines */
|
|
67
|
-
wrapLines?: boolean;
|
|
68
70
|
/**
|
|
69
|
-
* Add properties to the `div` used as
|
|
71
|
+
* Add properties to the `div` used as wrapper element.
|
|
70
72
|
* @deprecated (v26) You can now use all properties directly on `CodeEditor`.
|
|
71
73
|
*/
|
|
72
74
|
outerDivAttributes?: Omit<React.HTMLAttributes<HTMLDivElement>, "id" | "data-test-id" | "data-testid" | "translate" | "onChange" | "onKeyDown" | "onMouseDown" | "onScroll">;
|
|
@@ -137,6 +139,7 @@ export interface CodeEditorProps extends Omit<React.HTMLAttributes<HTMLDivElemen
|
|
|
137
139
|
* Includes a code editor, currently we use CodeMirror library as base.
|
|
138
140
|
*/
|
|
139
141
|
export declare const CodeEditor: {
|
|
140
|
-
({ className, onChange, onSelection, onMouseDown, onFocusChange, onKeyDown, onCursorChange, name, id, mode, preventLineNumbers, defaultValue, readOnly, shouldHaveMinimalSetup,
|
|
142
|
+
({ className, onChange, onSelection, onMouseDown, onFocusChange, onKeyDown, onCursorChange, name, id, mode, preventLineNumbers, wrapLines, defaultValue, readOnly, shouldHaveMinimalSetup, onScroll, setEditorView, supportCodeFolding, shouldHighlightActiveLine, outerDivAttributes, tabIntentSize, tabIntentStyle, placeholder, additionalExtensions, tabForceSpaceForModes, enableTab, height, useLinting, autoFocus, disabled, intent, useToolbar, translate, ...otherCodeEditorProps }: CodeEditorProps): React.JSX.Element;
|
|
141
143
|
supportedModes: ("html" | "markdown" | "python" | "sparql" | "turtle" | "xml" | "yaml" | "jinja2" | "json" | "ntriples" | "mathematica" | "sql" | "javascript")[];
|
|
142
144
|
};
|
|
145
|
+
export {};
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
import { ContextMenuProps } from "../../../components";
|
|
3
|
+
export interface EditorAppearanceConfigMenuProps {
|
|
4
|
+
/** Object containing a `true`/`false` value for each property */
|
|
5
|
+
config: {
|
|
6
|
+
[s: string]: boolean;
|
|
7
|
+
};
|
|
8
|
+
/** Object containing `true` for each property that cannot be changed by user */
|
|
9
|
+
configLocked?: {
|
|
10
|
+
[s: string]: boolean | undefined;
|
|
11
|
+
};
|
|
12
|
+
/** Handler that returns a translation for each config property key */
|
|
13
|
+
configPropertyTranslate?: (key: string) => string | false;
|
|
14
|
+
/** Handler to update config after user changes */
|
|
15
|
+
setConfig: React.Dispatch<React.SetStateAction<{
|
|
16
|
+
[s: string]: boolean;
|
|
17
|
+
}>>;
|
|
18
|
+
/** Additional properties used for the included `ContextMenu` */
|
|
19
|
+
contextMenuProps?: ContextMenuProps;
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* Returns a simple context menu that provides switches to control the editor appearance.
|
|
23
|
+
*/
|
|
24
|
+
export declare function EditorAppearanceConfigMenu({ config, configLocked, configPropertyTranslate, setConfig, contextMenuProps, }: EditorAppearanceConfigMenuProps): React.JSX.Element;
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import React from "react";
|
|
2
2
|
import { EditorView } from "codemirror";
|
|
3
|
+
import { EditorAppearanceConfigMenu } from "./EditorAppearanceConfigMenu";
|
|
3
4
|
interface MarkdownToolbarProps {
|
|
4
5
|
view?: EditorView;
|
|
5
6
|
togglePreviewStatus: () => void;
|
|
@@ -7,6 +8,7 @@ interface MarkdownToolbarProps {
|
|
|
7
8
|
translate: (key: string) => string | false;
|
|
8
9
|
disabled?: boolean;
|
|
9
10
|
readonly?: boolean;
|
|
11
|
+
configMenu?: React.ReactElement<typeof EditorAppearanceConfigMenu>;
|
|
10
12
|
}
|
|
11
13
|
export declare const MarkdownToolbar: React.FC<MarkdownToolbarProps>;
|
|
12
14
|
export {};
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@eccenca/gui-elements",
|
|
3
3
|
"description": "GUI elements based on other libraries, usable in React application, written in Typescript.",
|
|
4
|
-
"version": "25.1.0-rc.
|
|
4
|
+
"version": "25.1.0-rc.3",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"homepage": "https://github.com/eccenca/gui-elements",
|
|
7
7
|
"bugs": "https://github.com/eccenca/gui-elements/issues",
|
package/src/_shame.scss
CHANGED
|
@@ -1,31 +1,13 @@
|
|
|
1
1
|
// Add stuff to test fast and dirty.
|
|
2
2
|
// This file should not contain any styles.
|
|
3
3
|
|
|
4
|
-
.#{$prefix}--assistive-text,
|
|
5
|
-
.#{$prefix}--visually-hidden {
|
|
6
|
-
/*
|
|
7
|
-
TODO: move to better place, originally from ~@carbon/styles/scss/css--helpers
|
|
8
|
-
but we cannot use it directly because of other included rules there.
|
|
9
|
-
*/
|
|
10
|
-
position: absolute;
|
|
11
|
-
width: 1px;
|
|
12
|
-
height: 1px;
|
|
13
|
-
padding: 0;
|
|
14
|
-
margin: -1px;
|
|
15
|
-
overflow: hidden;
|
|
16
|
-
clip: rect(0, 0, 0, 0);
|
|
17
|
-
white-space: nowrap;
|
|
18
|
-
visibility: inherit;
|
|
19
|
-
border: 0;
|
|
20
|
-
}
|
|
21
|
-
|
|
22
4
|
/*
|
|
23
5
|
WORKAROUND: thinner scrollbars
|
|
24
6
|
*/
|
|
25
7
|
|
|
26
8
|
* {
|
|
27
|
-
scrollbar-width: thin;
|
|
28
9
|
scrollbar-color: #bbb transparent;
|
|
10
|
+
scrollbar-width: thin;
|
|
29
11
|
|
|
30
12
|
&::-webkit-scrollbar {
|
|
31
13
|
width: 0.25rem;
|
|
@@ -38,19 +20,3 @@
|
|
|
38
20
|
border-radius: 0.125rem;
|
|
39
21
|
}
|
|
40
22
|
}
|
|
41
|
-
|
|
42
|
-
/*
|
|
43
|
-
CHANGE: default focus behaviour
|
|
44
|
-
*/
|
|
45
|
-
|
|
46
|
-
:focus,
|
|
47
|
-
input:focus-visible,
|
|
48
|
-
textarea:focus-visible {
|
|
49
|
-
outline: none;
|
|
50
|
-
outline-offset: 0;
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
:focus-visible {
|
|
54
|
-
outline: eccgui-color-rgba($eccgui-color-accent, $eccgui-opacity-muted) solid 2px;
|
|
55
|
-
outline-offset: 1px;
|
|
56
|
-
}
|
|
@@ -130,7 +130,7 @@ export const StickyNoteModal: React.FC<StickyNoteModalProps> = React.memo(
|
|
|
130
130
|
name={translate("noteLabel")}
|
|
131
131
|
id={"sticky-note-input"}
|
|
132
132
|
mode="markdown"
|
|
133
|
-
|
|
133
|
+
useToolbar
|
|
134
134
|
onChange={(value) => {
|
|
135
135
|
refNote.current = value;
|
|
136
136
|
}}
|
package/src/common/index.ts
CHANGED
|
@@ -3,7 +3,7 @@ import { decode } from "he";
|
|
|
3
3
|
import { invisibleZeroWidthCharacters } from "./utils/characters";
|
|
4
4
|
import { colorCalculateDistance } from "./utils/colorCalculateDistance";
|
|
5
5
|
import decideContrastColorValue from "./utils/colorDecideContrastvalue";
|
|
6
|
-
import { getEnabledColorsFromPalette, textToColorHash } from "./utils/colorHash";
|
|
6
|
+
import { getEnabledColorPropertiesFromPalette, getEnabledColorsFromPalette, textToColorHash } from "./utils/colorHash";
|
|
7
7
|
import getColorConfiguration from "./utils/getColorConfiguration";
|
|
8
8
|
import { getScrollParent } from "./utils/getScrollParent";
|
|
9
9
|
import { getGlobalVar, setGlobalVar } from "./utils/globalVars";
|
|
@@ -22,6 +22,7 @@ export const utils = {
|
|
|
22
22
|
setGlobalVar,
|
|
23
23
|
getScrollParent,
|
|
24
24
|
getEnabledColorsFromPalette,
|
|
25
|
+
getEnabledColorPropertiesFromPalette,
|
|
25
26
|
textToColorHash,
|
|
26
27
|
reduceToText,
|
|
27
28
|
decodeHtmlEntities: decode,
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
.#{$prefix}--assistive-text,
|
|
2
|
+
.#{$prefix}--visually-hidden {
|
|
3
|
+
/*
|
|
4
|
+
originally from ~@carbon/styles/scss/css--helpers
|
|
5
|
+
but we cannot use it directly because of other included rules there.
|
|
6
|
+
*/
|
|
7
|
+
position: absolute;
|
|
8
|
+
visibility: inherit;
|
|
9
|
+
width: 1px;
|
|
10
|
+
height: 1px;
|
|
11
|
+
padding: 0;
|
|
12
|
+
margin: -1px;
|
|
13
|
+
overflow: hidden;
|
|
14
|
+
white-space: nowrap;
|
|
15
|
+
border: 0;
|
|
16
|
+
clip-path: rect(0, 0, 0, 0);
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
/*
|
|
20
|
+
default focus indicator
|
|
21
|
+
*/
|
|
22
|
+
|
|
23
|
+
:root {
|
|
24
|
+
--#{$eccgui}-a11y-outline-color: #{eccgui-color-var("layout", "magenta", "900")};
|
|
25
|
+
--#{$eccgui}-a11y-outline-style: solid;
|
|
26
|
+
--#{$eccgui}-a11y-outline-width: #{0.25 * $eccgui-size-block-whitespace};
|
|
27
|
+
|
|
28
|
+
// shift outline min 2px inside element to have a minimum 2px outline even with hidden overflow
|
|
29
|
+
--#{$eccgui}-a11y-outline-offset: min(calc(var(--#{$eccgui}-a11y-outline-width) * -0.5), -2px);
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
@keyframes outline-bounce {
|
|
33
|
+
0% {
|
|
34
|
+
outline-width: calc(var(--#{$eccgui}-a11y-outline-width) * 0.5);
|
|
35
|
+
outline-color: var(--#{$eccgui}-a11y-outline-color);
|
|
36
|
+
outline-offset: var(--#{$eccgui}-a11y-outline-offset);
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
33.3% {
|
|
40
|
+
outline-color: var(--#{$eccgui}-a11y-outline-color);
|
|
41
|
+
outline-offset: calc(var(--#{$eccgui}-a11y-outline-width));
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
66.6% {
|
|
45
|
+
outline-color: currentcolor;
|
|
46
|
+
outline-offset: calc(var(--#{$eccgui}-a11y-outline-width) * -2);
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
100% {
|
|
50
|
+
outline-width: var(--#{$eccgui}-a11y-outline-width);
|
|
51
|
+
outline-color: var(--#{$eccgui}-a11y-outline-color);
|
|
52
|
+
outline-offset: var(--#{$eccgui}-a11y-outline-offset);
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
@mixin focus-by-keyboard-static {
|
|
57
|
+
// strong visual focus indication for keyboard devices
|
|
58
|
+
|
|
59
|
+
outline: var(--#{$eccgui}-a11y-outline-color) var(--#{$eccgui}-a11y-outline-style)
|
|
60
|
+
var(--#{$eccgui}-a11y-outline-width);
|
|
61
|
+
outline-offset: var(--#{$eccgui}-a11y-outline-offset);
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
@mixin focus-by-keyboard-animation {
|
|
65
|
+
@media (prefers-reduced-motion: no-preference) {
|
|
66
|
+
animation: outline-bounce 0.5s;
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
.#{$eccgui}-a11y-focus-by-keyboard-animated {
|
|
71
|
+
@include focus-by-keyboard-static;
|
|
72
|
+
@include focus-by-keyboard-animation;
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
.#{$eccgui}-a11y-focus-by-keyboard-static {
|
|
76
|
+
@include focus-by-keyboard-static;
|
|
77
|
+
|
|
78
|
+
animation: none;
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
@mixin focus-by-pointer {
|
|
82
|
+
// limited visual focus indication for pointer devices
|
|
83
|
+
|
|
84
|
+
outline: transparent none 0;
|
|
85
|
+
outline-offset: 0;
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
.#{$eccgui}-a11y-focus-by-pointer {
|
|
89
|
+
@include focus-by-pointer;
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
*[tabindex]:not([tabindex^="-"]):focus-visible,
|
|
93
|
+
:focus-visible {
|
|
94
|
+
@extend .#{$eccgui}-a11y-focus-by-keyboard-animated;
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
input:focus:not(:focus-visible),
|
|
98
|
+
textarea:focus:not(:focus-visible),
|
|
99
|
+
:focus:not(:focus-visible) {
|
|
100
|
+
@extend .#{$eccgui}-a11y-focus-by-pointer;
|
|
101
|
+
}
|
|
@@ -28,7 +28,7 @@ export default class CssCustomProperties {
|
|
|
28
28
|
|
|
29
29
|
// Methods
|
|
30
30
|
|
|
31
|
-
customProperties = (props: getCustomPropertiesProps = {}): string
|
|
31
|
+
customProperties = (props: getCustomPropertiesProps = {}): [string, string][] | Record<string, string> => {
|
|
32
32
|
// FIXME:
|
|
33
33
|
// in case of performance issues results should get saved at least into intern variables
|
|
34
34
|
// other cache strategies could be also tested
|
|
@@ -104,7 +104,9 @@ export default class CssCustomProperties {
|
|
|
104
104
|
});
|
|
105
105
|
};
|
|
106
106
|
|
|
107
|
-
static listCustomProperties = (
|
|
107
|
+
static listCustomProperties = (
|
|
108
|
+
props: getCustomPropertiesProps = {}
|
|
109
|
+
): [string, string][] | Record<string, string> => {
|
|
108
110
|
const { removeDashPrefix = true, returnObject = true, filterName = () => true, ...filterProps } = props;
|
|
109
111
|
|
|
110
112
|
const customProperties = CssCustomProperties.listLocalCssStyleRuleProperties({
|
|
@@ -123,6 +125,6 @@ export default class CssCustomProperties {
|
|
|
123
125
|
|
|
124
126
|
return returnObject
|
|
125
127
|
? (Object.fromEntries(customProperties) as Record<string, string>)
|
|
126
|
-
: (customProperties as string
|
|
128
|
+
: (customProperties as [string, string][]);
|
|
127
129
|
};
|
|
128
130
|
}
|
|
@@ -6,10 +6,10 @@ import { colorCalculateDistance } from "./colorCalculateDistance";
|
|
|
6
6
|
import CssCustomProperties from "./CssCustomProperties";
|
|
7
7
|
|
|
8
8
|
type ColorOrFalse = Color | false;
|
|
9
|
-
type ColorWeight = 100 | 300 | 500 | 700 | 900;
|
|
10
|
-
type PaletteGroup = "identity" | "semantic" | "layout" | "extra";
|
|
9
|
+
export type ColorWeight = 100 | 300 | 500 | 700 | 900;
|
|
10
|
+
export type PaletteGroup = "identity" | "semantic" | "layout" | "extra";
|
|
11
11
|
|
|
12
|
-
interface getEnabledColorsProps {
|
|
12
|
+
export interface getEnabledColorsProps {
|
|
13
13
|
/** Specify the palette groups used to define the set of colors. */
|
|
14
14
|
includePaletteGroup?: PaletteGroup[];
|
|
15
15
|
/** Use only some weights of a color tint. */
|
|
@@ -21,20 +21,43 @@ interface getEnabledColorsProps {
|
|
|
21
21
|
}
|
|
22
22
|
|
|
23
23
|
const getEnabledColorsFromPaletteCache = new Map<string, Color[]>();
|
|
24
|
+
const getEnabledColorPropertiesFromPaletteCache = new Map<string, [string, string][]>();
|
|
24
25
|
|
|
25
|
-
export function getEnabledColorsFromPalette({
|
|
26
|
+
export function getEnabledColorsFromPalette(props: getEnabledColorsProps): Color[] {
|
|
27
|
+
const configId = JSON.stringify({
|
|
28
|
+
includePaletteGroup: props.includePaletteGroup,
|
|
29
|
+
includeColorWeight: props.includeColorWeight,
|
|
30
|
+
});
|
|
31
|
+
|
|
32
|
+
if (getEnabledColorsFromPaletteCache.has(configId)) {
|
|
33
|
+
return getEnabledColorsFromPaletteCache.get(configId)!;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
const colorPropertiesFromPalette = Object.values(getEnabledColorPropertiesFromPalette(props));
|
|
37
|
+
|
|
38
|
+
getEnabledColorsFromPaletteCache.set(
|
|
39
|
+
configId,
|
|
40
|
+
colorPropertiesFromPalette.map((color) => {
|
|
41
|
+
return Color(color[1]);
|
|
42
|
+
})
|
|
43
|
+
);
|
|
44
|
+
|
|
45
|
+
return getEnabledColorsFromPaletteCache.get(configId)!;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
export function getEnabledColorPropertiesFromPalette({
|
|
26
49
|
includePaletteGroup = ["layout"],
|
|
27
50
|
includeColorWeight = [100, 300, 500, 700, 900],
|
|
28
|
-
//
|
|
51
|
+
// (planned for later): includeMixedColors = false,
|
|
29
52
|
minimalColorDistance = COLORMINDISTANCE,
|
|
30
|
-
}: getEnabledColorsProps):
|
|
53
|
+
}: getEnabledColorsProps): [string, string][] {
|
|
31
54
|
const configId = JSON.stringify({
|
|
32
55
|
includePaletteGroup,
|
|
33
56
|
includeColorWeight,
|
|
34
57
|
});
|
|
35
58
|
|
|
36
|
-
if (
|
|
37
|
-
return
|
|
59
|
+
if (getEnabledColorPropertiesFromPaletteCache.has(configId)) {
|
|
60
|
+
return getEnabledColorPropertiesFromPaletteCache.get(configId)!;
|
|
38
61
|
}
|
|
39
62
|
|
|
40
63
|
const colorsFromPalette = new CssCustomProperties({
|
|
@@ -50,18 +73,18 @@ export function getEnabledColorsFromPalette({
|
|
|
50
73
|
const weight = parseInt(tint[2], 10) as ColorWeight;
|
|
51
74
|
return includePaletteGroup.includes(group) && includeColorWeight.includes(weight);
|
|
52
75
|
},
|
|
53
|
-
removeDashPrefix:
|
|
76
|
+
removeDashPrefix: true,
|
|
54
77
|
returnObject: true,
|
|
55
78
|
}).customProperties();
|
|
56
79
|
|
|
57
|
-
const colorsFromPaletteValues = Object.
|
|
80
|
+
const colorsFromPaletteValues = Object.entries(colorsFromPalette) as [string, string][];
|
|
58
81
|
|
|
59
82
|
const colorsFromPaletteWithEnoughDistance =
|
|
60
83
|
minimalColorDistance > 0
|
|
61
|
-
? colorsFromPaletteValues.reduce((enoughDistance: string[], color: string) => {
|
|
84
|
+
? colorsFromPaletteValues.reduce((enoughDistance: [string, string][], color: [string, string]) => {
|
|
62
85
|
if (enoughDistance.includes(color)) {
|
|
63
86
|
return enoughDistance.filter((checkColor) => {
|
|
64
|
-
const distance = colorCalculateDistance({ color1: color, color2: checkColor });
|
|
87
|
+
const distance = colorCalculateDistance({ color1: color[1], color2: checkColor[1] });
|
|
65
88
|
return checkColor === color || (distance && minimalColorDistance <= distance);
|
|
66
89
|
});
|
|
67
90
|
} else {
|
|
@@ -70,14 +93,9 @@ export function getEnabledColorsFromPalette({
|
|
|
70
93
|
}, colorsFromPaletteValues)
|
|
71
94
|
: colorsFromPaletteValues;
|
|
72
95
|
|
|
73
|
-
|
|
74
|
-
configId,
|
|
75
|
-
colorsFromPaletteWithEnoughDistance.map((color: string) => {
|
|
76
|
-
return Color(color);
|
|
77
|
-
})
|
|
78
|
-
);
|
|
96
|
+
getEnabledColorPropertiesFromPaletteCache.set(configId, colorsFromPaletteWithEnoughDistance);
|
|
79
97
|
|
|
80
|
-
return
|
|
98
|
+
return getEnabledColorPropertiesFromPaletteCache.get(configId)!;
|
|
81
99
|
}
|
|
82
100
|
|
|
83
101
|
function getColorcode(text: string): ColorOrFalse {
|
|
@@ -148,7 +166,7 @@ export function textToColorHash({
|
|
|
148
166
|
}
|
|
149
167
|
|
|
150
168
|
function stringToIntegerHash(inputString: string): number {
|
|
151
|
-
/* this function is
|
|
169
|
+
/* this function is idempotent, meaning it retrieves the same result for the same input
|
|
152
170
|
no matter how many times it's called */
|
|
153
171
|
// Convert the string to a hash code
|
|
154
172
|
let hashCode = 0;
|
|
@@ -190,15 +190,27 @@ a.#{$prefix}--header__menu-item:active {
|
|
|
190
190
|
}
|
|
191
191
|
|
|
192
192
|
// $shell-header-focus
|
|
193
|
-
.#{$prefix}--header__action
|
|
194
|
-
.#{$prefix}--header__action.#{$prefix}--btn--icon-only
|
|
195
|
-
.#{$prefix}--header__action.#{$prefix}--btn--primary
|
|
196
|
-
a.#{$prefix}--header__name
|
|
197
|
-
a.#{$prefix}--header__menu-item
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
193
|
+
.#{$prefix}--header__action,
|
|
194
|
+
.#{$prefix}--header__action.#{$prefix}--btn--icon-only,
|
|
195
|
+
.#{$prefix}--header__action.#{$prefix}--btn--primary,
|
|
196
|
+
a.#{$prefix}--header__name,
|
|
197
|
+
a.#{$prefix}--header__menu-item {
|
|
198
|
+
&:focus {
|
|
199
|
+
@extend .#{$eccgui}-a11y-focus-by-pointer;
|
|
200
|
+
|
|
201
|
+
border: none;
|
|
202
|
+
box-shadow: none;
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
&,
|
|
206
|
+
.#{$prefix}--popover--open & {
|
|
207
|
+
&:focus-visible {
|
|
208
|
+
@extend .#{$eccgui}-a11y-focus-by-keyboard-animated;
|
|
209
|
+
|
|
210
|
+
border: none;
|
|
211
|
+
box-shadow: none;
|
|
212
|
+
}
|
|
213
|
+
}
|
|
202
214
|
}
|
|
203
215
|
.#{$prefix}--header__menu-title[aria-expanded="true"] {
|
|
204
216
|
color: $shell-header-focus;
|
|
@@ -28,3 +28,9 @@ $ui-02: $eccgui-color-workspace-background !default;
|
|
|
28
28
|
padding: $eccgui-size-block-whitespace calc(0.5 * (#{mini-units(8)} - 30px));
|
|
29
29
|
transition: none;
|
|
30
30
|
}
|
|
31
|
+
|
|
32
|
+
.#{$eccgui}-application__menu__toggler.cds--header__action {
|
|
33
|
+
&:focus-visible {
|
|
34
|
+
@extend .#{$eccgui}-a11y-focus-by-keyboard-animated;
|
|
35
|
+
}
|
|
36
|
+
}
|
|
@@ -51,18 +51,18 @@ $shell-panel-focus: $shell-header-focus !default;
|
|
|
51
51
|
.#{$eccgui}-application__toolbar__panel-backdrop--onleave,
|
|
52
52
|
.#{$eccgui}-application__toolbar__panel-backdrop--onoutsideclick {
|
|
53
53
|
position: fixed;
|
|
54
|
-
inset: mini-units(8) 0 0
|
|
54
|
+
inset: mini-units(8) 0 0;
|
|
55
55
|
}
|
|
56
56
|
|
|
57
57
|
.#{$eccgui}-application__toolbar__panel-backdrop--onoutsideclick {
|
|
58
58
|
top: 0;
|
|
59
59
|
}
|
|
60
60
|
|
|
61
|
-
// add rules for own class
|
|
61
|
+
// add rules for own class identifiers
|
|
62
62
|
|
|
63
63
|
.#{$eccgui}-application__toolbar {
|
|
64
|
-
flex-basis: auto;
|
|
65
64
|
flex-grow: 0;
|
|
65
|
+
flex-basis: auto;
|
|
66
66
|
|
|
67
67
|
.#{$prefix}--popover--bottom-right .#{$prefix}--popover-content {
|
|
68
68
|
// for some reason the original calculation still moves out the tooltip
|
|
@@ -39,7 +39,9 @@
|
|
|
39
39
|
}
|
|
40
40
|
|
|
41
41
|
&:has(.cm-editor.cm-focused) {
|
|
42
|
-
|
|
42
|
+
--#{$eccgui}-a11y-outline-color: #{$eccgui-color-accent};
|
|
43
|
+
|
|
44
|
+
@extend .#{$eccgui}-a11y-focus-by-keyboard-static;
|
|
43
45
|
}
|
|
44
46
|
|
|
45
47
|
.cm-editor {
|
|
@@ -47,7 +47,7 @@ $switch-checked-background-color-disabled: eccgui-color-rgba(
|
|
|
47
47
|
}
|
|
48
48
|
|
|
49
49
|
input:focus ~ .#{$ns}-control-indicator {
|
|
50
|
-
|
|
50
|
+
@extend .#{$eccgui}-a11y-focus-by-keyboard-static;
|
|
51
51
|
}
|
|
52
52
|
|
|
53
53
|
input:disabled ~ .#{$ns}-control-indicator,
|
|
@@ -72,6 +72,14 @@ $switch-checked-background-color-disabled: eccgui-color-rgba(
|
|
|
72
72
|
background-image: url("~@carbon/icons/svg/32/checkbox--indeterminate.svg");
|
|
73
73
|
}
|
|
74
74
|
}
|
|
75
|
+
|
|
76
|
+
&.#{$ns}-switch {
|
|
77
|
+
--#{$eccgui}-a11y-outline-offset: 1px;
|
|
78
|
+
|
|
79
|
+
input:focus ~ .#{$ns}-control-indicator {
|
|
80
|
+
@extend .#{$eccgui}-a11y-focus-by-keyboard-static;
|
|
81
|
+
}
|
|
82
|
+
}
|
|
75
83
|
}
|
|
76
84
|
|
|
77
85
|
.#{$ns}-control-indicator + *,
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
import { Meta, StoryFn } from "@storybook/react";
|
|
3
|
+
|
|
4
|
+
import { getEnabledColorsProps } from "../../common/utils/colorHash";
|
|
5
|
+
import textFieldTest from "../TextField/stories/TextField.stories";
|
|
6
|
+
|
|
7
|
+
import { ColorField, ColorFieldProps } from "./ColorField";
|
|
8
|
+
|
|
9
|
+
export default {
|
|
10
|
+
title: "Forms/ColorField",
|
|
11
|
+
component: ColorField,
|
|
12
|
+
argTypes: {
|
|
13
|
+
...textFieldTest.argTypes,
|
|
14
|
+
},
|
|
15
|
+
} as Meta<typeof ColorField>;
|
|
16
|
+
|
|
17
|
+
const Template: StoryFn<typeof ColorField> = (args) => <ColorField {...args}></ColorField>;
|
|
18
|
+
|
|
19
|
+
export const Default = Template.bind({});
|
|
20
|
+
Default.args = {
|
|
21
|
+
onChange: (e) => {
|
|
22
|
+
alert(e.target.value);
|
|
23
|
+
},
|
|
24
|
+
};
|
|
25
|
+
|
|
26
|
+
export const NoPalettePresets = Template.bind({});
|
|
27
|
+
NoPalettePresets.args = {
|
|
28
|
+
...Default.args,
|
|
29
|
+
allowCustomColor: true,
|
|
30
|
+
colorPresets: [],
|
|
31
|
+
};
|
|
32
|
+
|
|
33
|
+
type TemplateColorHashProps = { stringForColorHashValue: string } & Pick<
|
|
34
|
+
ColorFieldProps,
|
|
35
|
+
"onChange" | "allowCustomColor"
|
|
36
|
+
> &
|
|
37
|
+
Pick<getEnabledColorsProps, "includeColorWeight" | "includePaletteGroup">;
|
|
38
|
+
|
|
39
|
+
const TemplateColorHash: StoryFn<TemplateColorHashProps> = (args: TemplateColorHashProps) => (
|
|
40
|
+
<ColorField
|
|
41
|
+
allowCustomColor={args.allowCustomColor}
|
|
42
|
+
colorPresets={ColorField.listColorPalettePresets({
|
|
43
|
+
includeColorWeight: args.includeColorWeight,
|
|
44
|
+
includePaletteGroup: args.includePaletteGroup,
|
|
45
|
+
})}
|
|
46
|
+
value={ColorField.calculateColorHashValue(args.stringForColorHashValue, {
|
|
47
|
+
allowCustomColor: args.allowCustomColor,
|
|
48
|
+
includeColorWeight: args.includeColorWeight,
|
|
49
|
+
includePaletteGroup: args.includePaletteGroup,
|
|
50
|
+
})}
|
|
51
|
+
/>
|
|
52
|
+
);
|
|
53
|
+
|
|
54
|
+
/**
|
|
55
|
+
* Component provides a helper function to calculate a color hash from a text,
|
|
56
|
+
* that can be used as `value` or `defaultValue`.
|
|
57
|
+
*
|
|
58
|
+
* ```
|
|
59
|
+
* <ColorField value={ColorField.calculateColorHashValue("MyText")} />
|
|
60
|
+
* ```
|
|
61
|
+
*
|
|
62
|
+
* You can add `options` to set the config for the color palette filters.
|
|
63
|
+
* The same default values like on `ColorField` are used for them.
|
|
64
|
+
*/
|
|
65
|
+
export const ColorHashValue = TemplateColorHash.bind({});
|
|
66
|
+
ColorHashValue.args = {
|
|
67
|
+
...Default.args,
|
|
68
|
+
allowCustomColor: true,
|
|
69
|
+
includeColorWeight: [300, 500, 700],
|
|
70
|
+
includePaletteGroup: ["layout", "extra"],
|
|
71
|
+
stringForColorHashValue: "My text that will used to create a color hash as initial value.",
|
|
72
|
+
};
|