@eccenca/gui-elements 25.1.0-rc.2 → 25.1.0-rc.4
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 +14 -0
- package/dist/cjs/components/Button/Button.js +1 -1
- package/dist/cjs/components/Button/Button.js.map +1 -1
- package/dist/cjs/components/MultiSelect/MultiSelect.js +24 -6
- package/dist/cjs/components/MultiSelect/MultiSelect.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/esm/components/Button/Button.js +1 -1
- package/dist/esm/components/Button/Button.js.map +1 -1
- package/dist/esm/components/MultiSelect/MultiSelect.js +25 -7
- package/dist/esm/components/MultiSelect/MultiSelect.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/types/components/MultiSelect/MultiSelect.d.ts +1 -0
- package/package.json +1 -1
- package/src/_shame.scss +1 -35
- package/src/cmem/markdown/Markdown.stories.tsx +2 -2
- package/src/common/scss/_accessibility-defaults.scss +101 -0
- 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/Badge/Badge.test.tsx +22 -0
- package/src/components/Button/Button.test.tsx +16 -2
- package/src/components/Button/Button.tsx +1 -1
- package/src/components/Checkbox/checkbox.scss +9 -1
- package/src/components/Dialog/dialog.scss +10 -2
- package/src/components/Link/link.scss +5 -6
- package/src/components/MultiSelect/MultiSelect.tsx +37 -9
- package/src/components/MultiSuggestField/MultiSuggestField.stories.tsx +40 -1
- package/src/components/MultiSuggestField/_multisuggestfield.scss +18 -0
- package/src/components/MultiSuggestField/tests/MultiSuggestField.test.tsx +88 -3
- package/src/components/RadioButton/radiobutton.scss +5 -1
- package/src/components/Tag/tag.scss +2 -2
- package/src/components/TextField/textfield.scss +20 -0
- package/src/components/Tooltip/Tooltip.test.tsx +40 -5
- package/src/components/Tooltip/Tooltip.tsx +14 -10
- package/src/components/Typography/typography.scss +10 -4
- package/src/configuration/stories/customproperties.stories.tsx +4 -0
- package/src/extensions/codemirror/_codemirror.scss +18 -28
- package/src/index.scss +1 -0
|
@@ -30,8 +30,6 @@ $tag-round-adjustment: 0 !default;
|
|
|
30
30
|
@import "~@blueprintjs/core/src/components/tag/tag";
|
|
31
31
|
|
|
32
32
|
.#{$eccgui}-tag__item {
|
|
33
|
-
--eccgui-tag-border-width: 1px;
|
|
34
|
-
|
|
35
33
|
flex-grow: 0;
|
|
36
34
|
flex-shrink: 0;
|
|
37
35
|
min-width: calc(#{$tag-height} - 2px);
|
|
@@ -141,6 +139,8 @@ $tag-round-adjustment: 0 !default;
|
|
|
141
139
|
}
|
|
142
140
|
|
|
143
141
|
.#{$ns}-tag {
|
|
142
|
+
--eccgui-tag-border-width: 1px;
|
|
143
|
+
|
|
144
144
|
border-style: solid;
|
|
145
145
|
border-width: var(--eccgui-tag-border-width);
|
|
146
146
|
|
|
@@ -103,6 +103,8 @@ $eccgui-map-intent-bgcolors: (
|
|
|
103
103
|
}
|
|
104
104
|
|
|
105
105
|
.#{$ns}-input {
|
|
106
|
+
--#{$eccgui}-a11y-outline-color: #{$eccgui-color-accent};
|
|
107
|
+
|
|
106
108
|
.#{$ns}-input-group[class*="#{$eccgui}-intent--"] & {
|
|
107
109
|
animation-duration: 1s;
|
|
108
110
|
animation-delay: 0.5s;
|
|
@@ -111,16 +113,23 @@ $eccgui-map-intent-bgcolors: (
|
|
|
111
113
|
@each $each-intent, $each-bgcolor in $eccgui-map-intent-bgcolors {
|
|
112
114
|
.#{$ns}-input-group.#{$ns}-intent-#{$each-intent} & {
|
|
113
115
|
background-color: eccgui-color-var("semantic", $each-intent, "100");
|
|
116
|
+
|
|
117
|
+
--#{$eccgui}-a11y-outline-color: eccgui-color-var("semantic", $each-intent, "900");
|
|
118
|
+
|
|
114
119
|
animation-name: intent-state-flash-#{$each-intent};
|
|
115
120
|
}
|
|
116
121
|
}
|
|
117
122
|
|
|
118
123
|
.#{$ns}-input-group.#{$eccgui}-intent--info & {
|
|
119
124
|
@include pt-input-intent($eccgui-color-info-text);
|
|
125
|
+
|
|
126
|
+
--#{$eccgui}-a11y-outline-color: #{$eccgui-color-info-text};
|
|
120
127
|
}
|
|
121
128
|
|
|
122
129
|
.#{$ns}-input-group.#{$eccgui}-intent--accent & {
|
|
123
130
|
@include pt-input-intent($eccgui-color-primary);
|
|
131
|
+
|
|
132
|
+
--#{$eccgui}-a11y-outline-color: #{$eccgui-color-primary};
|
|
124
133
|
}
|
|
125
134
|
|
|
126
135
|
.#{$ns}-input-group.#{$eccgui}-intent--neutral & {
|
|
@@ -138,6 +147,10 @@ $eccgui-map-intent-bgcolors: (
|
|
|
138
147
|
|
|
139
148
|
text-decoration: line-through $eccgui-color-danger-text 2px;
|
|
140
149
|
}
|
|
150
|
+
|
|
151
|
+
&:focus-visible {
|
|
152
|
+
@extend .#{$eccgui}-a11y-focus-by-keyboard-static;
|
|
153
|
+
}
|
|
141
154
|
}
|
|
142
155
|
|
|
143
156
|
.#{$eccgui}-textarea {
|
|
@@ -151,16 +164,23 @@ $eccgui-map-intent-bgcolors: (
|
|
|
151
164
|
@each $each-intent, $each-bgcolor in $eccgui-map-intent-bgcolors {
|
|
152
165
|
&.#{$eccgui}-intent--#{$each-intent} {
|
|
153
166
|
background-color: eccgui-color-var("semantic", $each-intent, "100");
|
|
167
|
+
|
|
168
|
+
--#{$eccgui}-a11y-outline-color: eccgui-color-var("semantic", $each-intent, "900");
|
|
169
|
+
|
|
154
170
|
animation-name: intent-state-flash-#{$each-intent};
|
|
155
171
|
}
|
|
156
172
|
}
|
|
157
173
|
|
|
158
174
|
&.#{$eccgui}-intent--info {
|
|
159
175
|
@include pt-input-intent($eccgui-color-info-text);
|
|
176
|
+
|
|
177
|
+
--#{$eccgui}-a11y-outline-color: #{$eccgui-color-info-text};
|
|
160
178
|
}
|
|
161
179
|
|
|
162
180
|
&.#{$eccgui}-intent--accent {
|
|
163
181
|
@include pt-input-intent($eccgui-color-primary);
|
|
182
|
+
|
|
183
|
+
--#{$eccgui}-a11y-outline-color: #{$eccgui-color-primary};
|
|
164
184
|
}
|
|
165
185
|
|
|
166
186
|
&.#{$eccgui}-intent--neutral {
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import React from "react";
|
|
2
2
|
import { fireEvent, render, screen, waitFor } from "@testing-library/react";
|
|
3
|
+
import userEvent from "@testing-library/user-event";
|
|
3
4
|
|
|
4
5
|
import "@testing-library/jest-dom";
|
|
5
6
|
|
|
@@ -45,19 +46,53 @@ describe("Tooltip", () => {
|
|
|
45
46
|
fireEvent.mouseEnter(container.getElementsByClassName(`${eccgui}-tooltip__wrapper--placeholder`)[0]);
|
|
46
47
|
checkForPlaceholderClass(container, 1);
|
|
47
48
|
await waitFor(() => {
|
|
48
|
-
expect(screen.queryAllByText(TooltipStory.args.content)).toHaveLength(0);
|
|
49
49
|
checkForPlaceholderClass(container, 0);
|
|
50
50
|
});
|
|
51
|
+
expect(screen.queryAllByText(TooltipStory.args.content as string)).toHaveLength(0);
|
|
51
52
|
});
|
|
52
53
|
it("should be displayed on two continues mouse hover when placeholder is used", async () => {
|
|
53
54
|
const { container } = render(<Tooltip {...TooltipStory.args} usePlaceholder={true} />);
|
|
54
55
|
fireEvent.mouseEnter(container.getElementsByClassName(`${eccgui}-tooltip__wrapper`)[0]);
|
|
55
56
|
checkForPlaceholderClass(container, 1);
|
|
56
|
-
await waitFor(
|
|
57
|
-
|
|
57
|
+
await waitFor(() => {
|
|
58
|
+
checkForPlaceholderClass(container, 0);
|
|
59
|
+
});
|
|
60
|
+
expect(screen.queryAllByText(TooltipStory.args.content as string)).toHaveLength(0);
|
|
61
|
+
fireEvent.mouseEnter(container.getElementsByClassName(`${eccgui}-tooltip__wrapper`)[0]);
|
|
62
|
+
expect(await screen.findByText(TooltipStory.args.content as string)).toBeVisible();
|
|
63
|
+
});
|
|
64
|
+
it("should be displayed on focus when no placeholder is used", async () => {
|
|
65
|
+
// Blueprint ignores focus events with null relatedTarget (page-refocus guard), so we tab
|
|
66
|
+
// from a preceding element to produce a non-null relatedTarget.
|
|
67
|
+
render(
|
|
68
|
+
<>
|
|
69
|
+
<button>previous element</button>
|
|
70
|
+
<Tooltip {...TooltipStory.args} usePlaceholder={false} />
|
|
71
|
+
</>
|
|
72
|
+
);
|
|
73
|
+
const user = userEvent.setup();
|
|
74
|
+
await user.tab(); // focuses "previous element"
|
|
75
|
+
await user.tab(); // focuses tooltip target, relatedTarget is non-null → Blueprint opens
|
|
76
|
+
expect(await screen.findByText(TooltipStory.args.content as string)).toBeVisible();
|
|
77
|
+
});
|
|
78
|
+
it("should be displayed after keyboard focus when placeholder is used", async () => {
|
|
79
|
+
// Use a focusable button child so refocus() can call .focus() on it after the swap.
|
|
80
|
+
// Tab from a preceding element so relatedTarget is non-null when Blueprint handles focus.
|
|
81
|
+
const { container } = render(
|
|
82
|
+
<>
|
|
83
|
+
<button>previous element</button>
|
|
84
|
+
<Tooltip {...TooltipStory.args} usePlaceholder={true}>
|
|
85
|
+
<button>tooltip target</button>
|
|
86
|
+
</Tooltip>
|
|
87
|
+
</>
|
|
88
|
+
);
|
|
89
|
+
const user = userEvent.setup();
|
|
90
|
+
await user.tab(); // focuses "previous element"
|
|
91
|
+
await user.tab(); // focuses placeholder inner button, triggers focusin swap
|
|
92
|
+
checkForPlaceholderClass(container, 1);
|
|
93
|
+
await waitFor(() => {
|
|
58
94
|
checkForPlaceholderClass(container, 0);
|
|
59
|
-
fireEvent.mouseOver(container.getElementsByClassName(`${eccgui}-tooltip__wrapper`)[0]);
|
|
60
|
-
expect(await screen.findByText(TooltipStory.args.content)).toBeVisible();
|
|
61
95
|
});
|
|
96
|
+
expect(await screen.findByText(TooltipStory.args.content as string)).toBeVisible();
|
|
62
97
|
});
|
|
63
98
|
});
|
|
@@ -50,7 +50,7 @@ export interface TooltipProps extends Omit<BlueprintTooltipProps, "position"> {
|
|
|
50
50
|
swapPlaceholderDelay?: number;
|
|
51
51
|
}
|
|
52
52
|
|
|
53
|
-
export type TooltipSize = "small" | "medium" | "large"
|
|
53
|
+
export type TooltipSize = "small" | "medium" | "large";
|
|
54
54
|
|
|
55
55
|
export const Tooltip = ({
|
|
56
56
|
children,
|
|
@@ -100,15 +100,19 @@ export const Tooltip = ({
|
|
|
100
100
|
}, swapDelayTime);
|
|
101
101
|
if (placeholderRef.current !== null) {
|
|
102
102
|
const eventType = ev.type === "focusin" ? "focusout" : "mouseleave";
|
|
103
|
-
(placeholderRef.current as HTMLElement).
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
103
|
+
const innerFocusTarget = (placeholderRef.current as HTMLElement).querySelector("[tabindex='0']")
|
|
104
|
+
?.children[0];
|
|
105
|
+
if (innerFocusTarget) {
|
|
106
|
+
(innerFocusTarget as HTMLElement).addEventListener(eventType, () => {
|
|
107
|
+
if (
|
|
108
|
+
(eventType === "focusout" && eventMemory.current === "afterfocus") ||
|
|
109
|
+
(eventType === "mouseleave" && eventMemory.current === "afterhover")
|
|
110
|
+
) {
|
|
111
|
+
eventMemory.current = null;
|
|
112
|
+
}
|
|
113
|
+
clearTimeout(swapDelay.current as NodeJS.Timeout);
|
|
114
|
+
});
|
|
115
|
+
}
|
|
112
116
|
}
|
|
113
117
|
};
|
|
114
118
|
(placeholderRef.current as HTMLElement).addEventListener("mouseenter", swap);
|
|
@@ -13,20 +13,26 @@ html {
|
|
|
13
13
|
|
|
14
14
|
body {
|
|
15
15
|
font-family: $eccgui-font-family-default;
|
|
16
|
-
|
|
17
|
-
text-rendering: optimizelegibility;
|
|
18
|
-
-webkit-font-smoothing: antialiased;
|
|
19
|
-
-moz-osx-font-smoothing: grayscale;
|
|
16
|
+
|
|
20
17
|
// User-facing text may contain Unicode symbols (e.g. "★") that fall outside the primary font stack.
|
|
21
18
|
// Browsers pick different system fallback fonts for such characters, causing glyphs to render at
|
|
22
19
|
// different optical sizes (smaller in Firefox). font-size-adjust normalises the fallback font size
|
|
23
20
|
// by matching the primary font's x-height, reducing the visual size discrepancy across browsers.
|
|
24
21
|
font-size-adjust: from-font;
|
|
22
|
+
font-weight: $eccgui-font-weight-regular;
|
|
23
|
+
text-rendering: optimizelegibility;
|
|
24
|
+
-webkit-font-smoothing: antialiased;
|
|
25
|
+
-moz-osx-font-smoothing: grayscale;
|
|
25
26
|
}
|
|
26
27
|
|
|
27
28
|
code {
|
|
28
29
|
font-family: $eccgui-font-family-monospace;
|
|
29
30
|
font-size: 0.9em;
|
|
31
|
+
|
|
32
|
+
.#{$eccgui}-typography__contentblock &,
|
|
33
|
+
&.#{$eccgui}-typography__text {
|
|
34
|
+
background-color: $eccgui-color-workspace-background;
|
|
35
|
+
}
|
|
30
36
|
}
|
|
31
37
|
|
|
32
38
|
strong {
|
|
@@ -34,6 +34,10 @@ const groups: { title: string; filterName: (name: string) => boolean }[] = [
|
|
|
34
34
|
title: "Color aliases",
|
|
35
35
|
filterName: (name) => name.startsWith(`--${eccgui}-color`) && !name.startsWith(`--${eccgui}-color-palette`),
|
|
36
36
|
},
|
|
37
|
+
{
|
|
38
|
+
title: "Accessibility",
|
|
39
|
+
filterName: (name) => name.startsWith(`--${eccgui}-a11y`),
|
|
40
|
+
},
|
|
37
41
|
{
|
|
38
42
|
title: "Opacity",
|
|
39
43
|
filterName: (name) => name.startsWith(`--${eccgui}-opacity`),
|
|
@@ -19,13 +19,13 @@ $eccgui-size-codeeditor-toolbar-height: $button-height !default;
|
|
|
19
19
|
|
|
20
20
|
&__toolbar {
|
|
21
21
|
position: absolute;
|
|
22
|
-
z-index: 3;
|
|
23
|
-
left: 1px;
|
|
24
|
-
right: 1px;
|
|
25
22
|
top: 1px;
|
|
26
|
-
|
|
27
|
-
|
|
23
|
+
right: 1px;
|
|
24
|
+
left: 1px;
|
|
25
|
+
z-index: 3;
|
|
28
26
|
background-color: $eccgui-color-codeeditor-background;
|
|
27
|
+
border-bottom: solid 1px $eccgui-color-codeeditor-separation;
|
|
28
|
+
border-radius: $pt-border-radius $pt-border-radius 0 0;
|
|
29
29
|
}
|
|
30
30
|
|
|
31
31
|
&--has-toolbar {
|
|
@@ -37,9 +37,9 @@ $eccgui-size-codeeditor-toolbar-height: $button-height !default;
|
|
|
37
37
|
&__preview {
|
|
38
38
|
position: absolute;
|
|
39
39
|
top: calc(#{$eccgui-size-codeeditor-toolbar-height} + 1px) !important;
|
|
40
|
-
left: 1px;
|
|
41
40
|
right: 1px;
|
|
42
41
|
bottom: 1px;
|
|
42
|
+
left: 1px;
|
|
43
43
|
z-index: 2;
|
|
44
44
|
padding: $button-padding;
|
|
45
45
|
overflow-y: auto;
|
|
@@ -50,12 +50,12 @@ $eccgui-size-codeeditor-toolbar-height: $button-height !default;
|
|
|
50
50
|
.cm-editor {
|
|
51
51
|
width: 100%;
|
|
52
52
|
height: $eccgui-size-codeeditor-height;
|
|
53
|
-
clip-path: unset !important; // we may check later why they set inset(0) now
|
|
54
53
|
background-color: $eccgui-color-codeeditor-background;
|
|
55
54
|
border-radius: $pt-border-radius;
|
|
56
55
|
|
|
57
56
|
// get them a "border" like input boxes from blueprintjs
|
|
58
57
|
box-shadow: input-transition-shadow($input-shadow-color-focus), $pt-input-box-shadow;
|
|
58
|
+
clip-path: unset !important; // we may check later why they set inset(0) now
|
|
59
59
|
|
|
60
60
|
&.#{eccgui}-disabled {
|
|
61
61
|
@extend .#{$ns}-input, .#{$ns}-disabled;
|
|
@@ -89,7 +89,7 @@ $eccgui-size-codeeditor-toolbar-height: $button-height !default;
|
|
|
89
89
|
}
|
|
90
90
|
|
|
91
91
|
&.#{eccgui}-intent--primary {
|
|
92
|
-
@include pt-input-intent($eccgui-color-
|
|
92
|
+
@include pt-input-intent($eccgui-color-primary);
|
|
93
93
|
}
|
|
94
94
|
|
|
95
95
|
&.#{eccgui}-intent--info {
|
|
@@ -97,7 +97,7 @@ $eccgui-size-codeeditor-toolbar-height: $button-height !default;
|
|
|
97
97
|
}
|
|
98
98
|
|
|
99
99
|
&.#{eccgui}-intent--accent {
|
|
100
|
-
@include pt-input-intent($eccgui-color-
|
|
100
|
+
@include pt-input-intent($eccgui-color-accent);
|
|
101
101
|
}
|
|
102
102
|
|
|
103
103
|
&.#{eccgui}-intent--neutral {
|
|
@@ -124,39 +124,29 @@ $eccgui-size-codeeditor-toolbar-height: $button-height !default;
|
|
|
124
124
|
}
|
|
125
125
|
|
|
126
126
|
&.cm-focused {
|
|
127
|
-
outline:
|
|
128
|
-
|
|
127
|
+
--#{$eccgui}-a11y-outline-color: #{$eccgui-color-accent};
|
|
128
|
+
--#{$eccgui}-a11y-outline-offset: 0;
|
|
129
|
+
|
|
130
|
+
@extend .#{$eccgui}-a11y-focus-by-keyboard-static;
|
|
129
131
|
|
|
130
132
|
&.#{eccgui}-intent--warning {
|
|
131
|
-
|
|
133
|
+
--#{$eccgui}-a11y-outline-color: #{$eccgui-color-warning-text};
|
|
132
134
|
}
|
|
133
135
|
|
|
134
136
|
&.#{eccgui}-intent--success {
|
|
135
|
-
|
|
137
|
+
--#{$eccgui}-a11y-outline-color: #{$eccgui-color-success-text};
|
|
136
138
|
}
|
|
137
139
|
|
|
138
140
|
&.#{eccgui}-intent--danger {
|
|
139
|
-
|
|
141
|
+
--#{$eccgui}-a11y-outline-color: #{$eccgui-color-danger-text};
|
|
140
142
|
}
|
|
141
143
|
|
|
142
144
|
&.#{eccgui}-intent--primary {
|
|
143
|
-
|
|
145
|
+
--#{$eccgui}-a11y-outline-color: #{$eccgui-color-primary};
|
|
144
146
|
}
|
|
145
147
|
|
|
146
148
|
&.#{eccgui}-intent--info {
|
|
147
|
-
|
|
148
|
-
}
|
|
149
|
-
|
|
150
|
-
&.#{eccgui}-intent--accent {
|
|
151
|
-
box-shadow: input-transition-shadow($eccgui-color-warning-text, true), $input-box-shadow-focus;
|
|
152
|
-
}
|
|
153
|
-
|
|
154
|
-
&.#{eccgui}-intent--neutral {
|
|
155
|
-
box-shadow: input-transition-shadow($eccgui-color-workspace-text, true), $input-box-shadow-focus;
|
|
156
|
-
}
|
|
157
|
-
|
|
158
|
-
&.#{eccgui}-intent--edited {
|
|
159
|
-
box-shadow: input-transition-shadow($eccgui-color-info-text, true), $input-box-shadow-focus;
|
|
149
|
+
--#{$eccgui}-a11y-outline-color: #{$eccgui-color-info-text};
|
|
160
150
|
}
|
|
161
151
|
|
|
162
152
|
&.#{eccgui}-intent--removed {
|
package/src/index.scss
CHANGED