@orangesk/orange-design-system 3.7.0 → 3.9.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +0 -6
- package/build/components/Alert/style.css +1 -1
- package/build/components/Alert/style.css.map +1 -1
- package/build/components/Bar/style.css +1 -1
- package/build/components/Bar/style.css.map +1 -1
- package/build/components/Drawer/style.css +2 -0
- package/build/components/Drawer/style.css.map +1 -0
- package/build/components/Footer/style.css +1 -1
- package/build/components/Footer/style.css.map +1 -1
- package/build/components/Megamenu/style.css +1 -1
- package/build/components/Megamenu/style.css.map +1 -1
- package/build/components/Modal/style.css +1 -1
- package/build/components/Modal/style.css.map +1 -1
- package/build/components/StatusIndicator/style.css +2 -0
- package/build/components/StatusIndicator/style.css.map +1 -0
- package/build/components/Table/style.css +1 -1
- package/build/components/Table/style.css.map +1 -1
- package/build/components/index.js +1 -1
- package/build/components/index.js.map +1 -1
- package/build/components/types/index.d.ts +55 -3
- package/build/lib/base.css +1 -1
- package/build/lib/base.css.map +1 -1
- package/build/lib/components.css +1 -1
- package/build/lib/components.css.map +1 -1
- package/build/lib/footer.css +1 -1
- package/build/lib/footer.css.map +1 -1
- package/build/lib/footer.js +1 -1
- package/build/lib/footer.js.map +1 -1
- package/build/lib/megamenu.css +1 -1
- package/build/lib/megamenu.css.map +1 -1
- package/build/lib/megamenu.js +1 -1
- package/build/lib/megamenu.js.map +1 -1
- package/build/lib/reset.css +2 -0
- package/build/lib/reset.css.map +1 -0
- package/build/lib/reset.js +3 -0
- package/build/lib/scripts.js +1 -1
- package/build/lib/scripts.js.map +1 -1
- package/build/lib/style.css +1 -1
- package/build/lib/style.css.map +1 -1
- package/build/lib/utilities.css +1 -1
- package/build/lib/utilities.css.map +1 -1
- package/package.json +27 -33
- package/src/components/Alert/Alert.tsx +2 -2
- package/src/components/Alert/data.ts +8 -5
- package/src/components/Alert/styles/config.scss +4 -4
- package/src/components/Alert/styles/mixins.scss +8 -1
- package/src/components/Alert/tests/Alert.test.jsx +11 -1
- package/src/components/Bar/Bar.tsx +1 -1
- package/src/components/Bar/styles/config.scss +1 -0
- package/src/components/Bar/tests/Bar.unit.test.jsx +1 -1
- package/src/components/Carousel/Carousel.static.ts +103 -12
- package/src/components/Carousel/tests/Carousel.static.test.jsx +134 -0
- package/src/components/DocumentationSidebar/DocumentationSidebar.tsx +12 -4
- package/src/components/Drawer/Drawer.static.ts +281 -0
- package/src/components/Drawer/Drawer.tsx +82 -0
- package/src/components/Drawer/DrawerBody.tsx +21 -0
- package/src/components/Drawer/DrawerFooter.tsx +21 -0
- package/src/components/Drawer/DrawerHeader.tsx +21 -0
- package/src/components/Drawer/index.ts +5 -0
- package/src/components/Drawer/styles/config.scss +17 -0
- package/src/components/Drawer/styles/mixins.scss +119 -0
- package/src/components/Drawer/styles/style.scss +71 -0
- package/src/components/Drawer/tests/Drawer.unit.test.jsx +149 -0
- package/src/components/Footer/Footer.tsx +1 -4
- package/src/components/Footer/styles/mixins.scss +3 -1
- package/src/components/Footer/styles/style.scss +31 -0
- package/src/components/Footer/tests/Footer.styles.unit.test.jsx +62 -0
- package/src/components/Forms/SegmentedControl/SegmentedControl.tsx +122 -0
- package/src/components/Forms/SegmentedControl/index.ts +5 -0
- package/src/components/Forms/SegmentedControl/styles/mixins.scss +52 -0
- package/src/components/Forms/SegmentedControl/styles/style.scss +35 -0
- package/src/components/Forms/SegmentedControl/tests/SegmentedControl.conformance.test.jsx +36 -0
- package/src/components/Forms/SegmentedControl/tests/SegmentedControl.unit.test.jsx +125 -0
- package/src/components/Forms/index.ts +1 -0
- package/src/components/Icon/index.ts +1 -0
- package/src/components/Megamenu/styles/mixins.scss +24 -18
- package/src/components/Modal/styles/config.scss +3 -2
- package/src/components/StatusIndicator/StatusIndicator.tsx +29 -0
- package/src/components/StatusIndicator/index.ts +2 -0
- package/src/components/StatusIndicator/styles/config.scss +12 -0
- package/src/components/StatusIndicator/styles/mixins.scss +36 -0
- package/src/components/StatusIndicator/styles/style.scss +16 -0
- package/src/components/StatusIndicator/tests/StatusIndicator.conformance.test.jsx +22 -0
- package/src/components/StatusIndicator/tests/StatusIndicator.unit.test.jsx +70 -0
- package/src/components/Table/Table.static.ts +23 -10
- package/src/components/Table/Table.tsx +7 -2
- package/src/components/Table/styles/mixins.scss +59 -0
- package/src/components/Table/styles/style.scss +25 -0
- package/src/components/Table/tests/Table.static.unit.test.jsx +72 -0
- package/src/components/Table/tests/Table.unit.test.jsx +33 -0
- package/src/components/index.ts +11 -0
- package/src/styles/tokens/overlay.scss +3 -0
- package/src/styles/typography/style.scss +0 -13
- package/src/styles/utilities/border.scss +4 -0
- package/src/styles/utilities/border.styles.unit.test.jsx +9 -0
- package/src/styles/utilities/text.scss +12 -0
- package/src/components/Alert/tests/Alert.visual.test.jsx +0 -137
- package/src/components/Alert/tests/__screenshots__/Alert.visual.test.jsx/alert-preview-custom-title-chromium-linux.png +0 -0
- package/src/components/Alert/tests/__screenshots__/Alert.visual.test.jsx/alert-preview-danger-chromium-linux.png +0 -0
- package/src/components/Alert/tests/__screenshots__/Alert.visual.test.jsx/alert-preview-full-width-chromium-linux.png +0 -0
- package/src/components/Alert/tests/__screenshots__/Alert.visual.test.jsx/alert-preview-success-chromium-linux.png +0 -0
- package/src/components/Alert/tests/__screenshots__/Alert.visual.test.jsx/alert-preview-title-buttons-chromium-linux.png +0 -0
- package/src/components/Alert/tests/__screenshots__/Alert.visual.test.jsx/alert-preview-title-chromium-linux.png +0 -0
- package/src/components/Alert/tests/__screenshots__/Alert.visual.test.jsx/alert-preview-title-description-buttons-chromium-linux.png +0 -0
- package/src/components/Alert/tests/__screenshots__/Alert.visual.test.jsx/alert-preview-title-description-chromium-linux.png +0 -0
- package/src/components/Alert/tests/__screenshots__/Alert.visual.test.jsx/alert-preview-warning-chromium-linux.png +0 -0
- package/src/components/Carousel/CHANGELOG.md +0 -11
- package/src/components/CarouselHero/tests/CarouselHero.visual.test.jsx +0 -90
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
import { render } from "@testing-library/react";
|
|
2
|
+
|
|
3
|
+
import * as components from "../../";
|
|
4
|
+
|
|
5
|
+
describe("StatusIndicator", () => {
|
|
6
|
+
it("is available from the public component entry point", () => {
|
|
7
|
+
expect(components.StatusIndicator).toBeTypeOf("function");
|
|
8
|
+
});
|
|
9
|
+
|
|
10
|
+
it.each([
|
|
11
|
+
["success", "status-indicator--success"],
|
|
12
|
+
["warning", "status-indicator--warning"],
|
|
13
|
+
["danger", "status-indicator--danger"],
|
|
14
|
+
])("renders the %s type", (type, expectedClass) => {
|
|
15
|
+
const { getByText } = render(
|
|
16
|
+
<components.StatusIndicator type={type}>
|
|
17
|
+
{type}
|
|
18
|
+
</components.StatusIndicator>,
|
|
19
|
+
);
|
|
20
|
+
|
|
21
|
+
expect(getByText(type).closest(".status-indicator")).toHaveClass(
|
|
22
|
+
"status-indicator",
|
|
23
|
+
expectedClass,
|
|
24
|
+
);
|
|
25
|
+
});
|
|
26
|
+
|
|
27
|
+
it("renders a decorative marker before the label", () => {
|
|
28
|
+
const { getByTestId } = render(
|
|
29
|
+
<components.StatusIndicator data-testid="status" type="success">
|
|
30
|
+
Available
|
|
31
|
+
</components.StatusIndicator>,
|
|
32
|
+
);
|
|
33
|
+
const statusIndicator = getByTestId("status");
|
|
34
|
+
const marker = statusIndicator.firstElementChild;
|
|
35
|
+
|
|
36
|
+
expect(marker).toHaveClass("status-indicator__marker");
|
|
37
|
+
expect(marker).toHaveAttribute("aria-hidden", "true");
|
|
38
|
+
});
|
|
39
|
+
|
|
40
|
+
it("groups text and inline controls in one wrapping content item", () => {
|
|
41
|
+
const { getByTestId, getByRole } = render(
|
|
42
|
+
<components.StatusIndicator data-testid="status" type="danger">
|
|
43
|
+
Temporarily unavailable <button type="button">More information</button>
|
|
44
|
+
</components.StatusIndicator>,
|
|
45
|
+
);
|
|
46
|
+
const content = getByTestId("status").querySelector(
|
|
47
|
+
".status-indicator__content",
|
|
48
|
+
);
|
|
49
|
+
|
|
50
|
+
expect(content).toHaveTextContent("Temporarily unavailable");
|
|
51
|
+
expect(content).toContainElement(
|
|
52
|
+
getByRole("button", { name: "More information" }),
|
|
53
|
+
);
|
|
54
|
+
});
|
|
55
|
+
|
|
56
|
+
it("passes native span props and additional classes", () => {
|
|
57
|
+
const { getByTestId } = render(
|
|
58
|
+
<components.StatusIndicator
|
|
59
|
+
className="custom-class"
|
|
60
|
+
data-testid="status"
|
|
61
|
+
type="warning"
|
|
62
|
+
>
|
|
63
|
+
Limited
|
|
64
|
+
</components.StatusIndicator>,
|
|
65
|
+
);
|
|
66
|
+
|
|
67
|
+
expect(getByTestId("status")).toHaveClass("custom-class");
|
|
68
|
+
expect(getByTestId("status")).toHaveTextContent("Limited");
|
|
69
|
+
});
|
|
70
|
+
});
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
import toggle from "../../scripts/modules/toggleUtil";
|
|
2
2
|
|
|
3
|
+
const SCROLLABLE_OVERFLOW_CLASS = "table-scrollable--overflowing";
|
|
4
|
+
|
|
3
5
|
interface TableConfig {
|
|
4
6
|
expandButtonSelector: string;
|
|
5
7
|
scrollableContainerSelector: string;
|
|
@@ -32,18 +34,26 @@ export default class Table {
|
|
|
32
34
|
|
|
33
35
|
(this.element as any).ODS_Table = this;
|
|
34
36
|
|
|
35
|
-
this.resizeObserver = new ResizeObserver((
|
|
37
|
+
this.resizeObserver = new ResizeObserver(() => {
|
|
36
38
|
if (!this.scrollableContainer) return;
|
|
37
39
|
|
|
38
|
-
const
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
40
|
+
const overflowX = getComputedStyle(this.scrollableContainer).overflowX;
|
|
41
|
+
const canScroll = overflowX === "auto" || overflowX === "scroll";
|
|
42
|
+
const hasOverflow =
|
|
43
|
+
this.scrollableContainer.scrollWidth >
|
|
44
|
+
this.scrollableContainer.clientWidth;
|
|
45
|
+
const isScrollable = canScroll && hasOverflow;
|
|
46
|
+
|
|
47
|
+
this.scrollableContainer.classList.toggle(
|
|
48
|
+
SCROLLABLE_OVERFLOW_CLASS,
|
|
49
|
+
isScrollable,
|
|
50
|
+
);
|
|
51
|
+
|
|
52
|
+
if (isScrollable) {
|
|
53
|
+
this.scrollableContainer.setAttribute("tabindex", "0");
|
|
54
|
+
} else {
|
|
55
|
+
this.scrollableContainer.removeAttribute("tabindex");
|
|
56
|
+
}
|
|
47
57
|
});
|
|
48
58
|
|
|
49
59
|
this.init();
|
|
@@ -120,6 +130,7 @@ export default class Table {
|
|
|
120
130
|
);
|
|
121
131
|
if (this.scrollableContainer) {
|
|
122
132
|
this.resizeObserver.observe(this.element);
|
|
133
|
+
this.resizeObserver.observe(this.scrollableContainer);
|
|
123
134
|
return true;
|
|
124
135
|
}
|
|
125
136
|
return undefined;
|
|
@@ -131,6 +142,8 @@ export default class Table {
|
|
|
131
142
|
});
|
|
132
143
|
|
|
133
144
|
this.resizeObserver.disconnect();
|
|
145
|
+
this.scrollableContainer?.classList.remove(SCROLLABLE_OVERFLOW_CLASS);
|
|
146
|
+
this.scrollableContainer?.removeAttribute("tabindex");
|
|
134
147
|
|
|
135
148
|
this.expandButtons = [];
|
|
136
149
|
}
|
|
@@ -26,6 +26,8 @@ interface TableProps extends React.TableHTMLAttributes<HTMLTableElement> {
|
|
|
26
26
|
isResponsive?: boolean;
|
|
27
27
|
/** If table has horizontal scrollbar */
|
|
28
28
|
isScrollable?: boolean;
|
|
29
|
+
/** Keep the first column visible while the table scrolls horizontally */
|
|
30
|
+
isFirstColumnPinned?: boolean;
|
|
29
31
|
/** Different colors for even and odd rows. */
|
|
30
32
|
isStriped?: boolean;
|
|
31
33
|
/** rows to print out in the table. */
|
|
@@ -45,6 +47,7 @@ const Table: React.FC<TableProps> = ({
|
|
|
45
47
|
isResponsive,
|
|
46
48
|
isStriped,
|
|
47
49
|
isScrollable,
|
|
50
|
+
isFirstColumnPinned,
|
|
48
51
|
expandableRowsCaptions = {
|
|
49
52
|
header: "Rozšíriteľný",
|
|
50
53
|
emptyRow: "Nerozšíriteľný riadok",
|
|
@@ -60,11 +63,13 @@ const Table: React.FC<TableProps> = ({
|
|
|
60
63
|
[`${CLASS_ROOT}--striped`]: isStriped,
|
|
61
64
|
[`${CLASS_ROOT}--compact`]: isCompact,
|
|
62
65
|
[`${CLASS_ROOT}--responsive`]: isResponsive,
|
|
66
|
+
[`${CLASS_ROOT}--pinned-first-column`]: isFirstColumnPinned,
|
|
63
67
|
},
|
|
64
68
|
className,
|
|
65
69
|
);
|
|
66
70
|
|
|
67
71
|
const captionId = `${idPrefix}-caption`;
|
|
72
|
+
const hasScrollableRegion = isScrollable || isFirstColumnPinned;
|
|
68
73
|
|
|
69
74
|
const expandableRows = {
|
|
70
75
|
hasExpandableRows: rows.some(
|
|
@@ -98,7 +103,7 @@ const Table: React.FC<TableProps> = ({
|
|
|
98
103
|
const table = (
|
|
99
104
|
<TableContext.Provider value={context}>
|
|
100
105
|
<ConditionalWrapper
|
|
101
|
-
condition={
|
|
106
|
+
condition={hasScrollableRegion || false}
|
|
102
107
|
wrapper={
|
|
103
108
|
<div
|
|
104
109
|
className={`${CLASS_ROOT}-scrollable`}
|
|
@@ -114,7 +119,7 @@ const Table: React.FC<TableProps> = ({
|
|
|
114
119
|
{...other}
|
|
115
120
|
>
|
|
116
121
|
{caption && (
|
|
117
|
-
<caption {...(
|
|
122
|
+
<caption {...(hasScrollableRegion && { id: captionId })}>
|
|
118
123
|
{caption}
|
|
119
124
|
</caption>
|
|
120
125
|
)}
|
|
@@ -57,17 +57,33 @@
|
|
|
57
57
|
}
|
|
58
58
|
|
|
59
59
|
@mixin scrollable-wrapper {
|
|
60
|
+
container-type: inline-size;
|
|
60
61
|
display: block;
|
|
61
62
|
width: 100%;
|
|
62
63
|
overflow-x: auto;
|
|
63
64
|
-webkit-overflow-scrolling: touch;
|
|
64
65
|
|
|
66
|
+
caption {
|
|
67
|
+
position: sticky;
|
|
68
|
+
left: 0;
|
|
69
|
+
width: 100cqw;
|
|
70
|
+
}
|
|
71
|
+
|
|
65
72
|
td,
|
|
66
73
|
th {
|
|
67
74
|
white-space: nowrap;
|
|
68
75
|
}
|
|
69
76
|
}
|
|
70
77
|
|
|
78
|
+
@mixin responsive-scrollable-wrapper {
|
|
79
|
+
overflow-x: visible;
|
|
80
|
+
|
|
81
|
+
td,
|
|
82
|
+
th {
|
|
83
|
+
white-space: normal;
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
|
|
71
87
|
@mixin sort-button {
|
|
72
88
|
position: relative;
|
|
73
89
|
display: inline-block;
|
|
@@ -117,6 +133,49 @@
|
|
|
117
133
|
width: auto;
|
|
118
134
|
}
|
|
119
135
|
|
|
136
|
+
@mixin pinned-first-column {
|
|
137
|
+
tr > :first-child {
|
|
138
|
+
position: sticky;
|
|
139
|
+
left: 0;
|
|
140
|
+
z-index: 1;
|
|
141
|
+
background: var(
|
|
142
|
+
--table-pinned-column-background,
|
|
143
|
+
var(--color-background-primary)
|
|
144
|
+
);
|
|
145
|
+
|
|
146
|
+
&::after {
|
|
147
|
+
content: "";
|
|
148
|
+
display: none;
|
|
149
|
+
position: absolute;
|
|
150
|
+
top: 0;
|
|
151
|
+
right: -12px;
|
|
152
|
+
bottom: 0;
|
|
153
|
+
width: 12px;
|
|
154
|
+
background: linear-gradient(
|
|
155
|
+
to right,
|
|
156
|
+
color-mix(in srgb, var(--color-text-default) 10%, transparent),
|
|
157
|
+
transparent
|
|
158
|
+
);
|
|
159
|
+
pointer-events: none;
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
thead > tr > :first-child {
|
|
164
|
+
z-index: 2;
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
@mixin unpin-first-column {
|
|
169
|
+
tr > :first-child {
|
|
170
|
+
position: static;
|
|
171
|
+
background: transparent;
|
|
172
|
+
|
|
173
|
+
&::after {
|
|
174
|
+
display: none;
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
|
|
120
179
|
@mixin responsive-table {
|
|
121
180
|
thead {
|
|
122
181
|
display: none;
|
|
@@ -38,20 +38,39 @@
|
|
|
38
38
|
|
|
39
39
|
&--striped tbody tr:nth-of-type(odd) {
|
|
40
40
|
@include mixins.odd-row;
|
|
41
|
+
--table-pinned-column-background: var(--color-background-secondary);
|
|
41
42
|
}
|
|
42
43
|
|
|
43
44
|
&--striped.background-secondary tbody tr:nth-of-type(odd),
|
|
44
45
|
.background-secondary &--striped tbody tr:nth-of-type(odd) {
|
|
45
46
|
background-color: config.$striped-color-on-secondary;
|
|
47
|
+
--table-pinned-column-background: var(--color-background-primary);
|
|
46
48
|
}
|
|
47
49
|
|
|
48
50
|
&--compact {
|
|
49
51
|
@include mixins.compact;
|
|
50
52
|
}
|
|
51
53
|
|
|
54
|
+
&--pinned-first-column {
|
|
55
|
+
@include mixins.pinned-first-column;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
&--pinned-first-column.background-secondary,
|
|
59
|
+
.background-secondary &--pinned-first-column {
|
|
60
|
+
--table-pinned-column-background: var(--color-background-secondary);
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
&-scrollable--overflowing &--pinned-first-column tr > :first-child::after {
|
|
64
|
+
display: block;
|
|
65
|
+
}
|
|
66
|
+
|
|
52
67
|
&--responsive {
|
|
53
68
|
@include breakpoint.get("md", "down") {
|
|
54
69
|
@include mixins.responsive-table;
|
|
70
|
+
|
|
71
|
+
&.table--pinned-first-column {
|
|
72
|
+
@include mixins.unpin-first-column;
|
|
73
|
+
}
|
|
55
74
|
}
|
|
56
75
|
}
|
|
57
76
|
|
|
@@ -63,6 +82,12 @@
|
|
|
63
82
|
}
|
|
64
83
|
}
|
|
65
84
|
|
|
85
|
+
@include breakpoint.get("md", "down") {
|
|
86
|
+
&-scrollable:has(> &--responsive) {
|
|
87
|
+
@include mixins.responsive-scrollable-wrapper;
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
|
|
66
91
|
&__sort-button {
|
|
67
92
|
@include mixins.sort-button;
|
|
68
93
|
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
import { afterEach, beforeEach, expect, it, vi } from "vitest";
|
|
2
|
+
|
|
3
|
+
import Table from "../Table.static";
|
|
4
|
+
|
|
5
|
+
let resizeCallback;
|
|
6
|
+
let observe;
|
|
7
|
+
|
|
8
|
+
beforeEach(() => {
|
|
9
|
+
observe = vi.fn();
|
|
10
|
+
vi.stubGlobal(
|
|
11
|
+
"ResizeObserver",
|
|
12
|
+
vi.fn(function (callback) {
|
|
13
|
+
resizeCallback = callback;
|
|
14
|
+
this.observe = observe;
|
|
15
|
+
this.unobserve = vi.fn();
|
|
16
|
+
this.disconnect = vi.fn();
|
|
17
|
+
}),
|
|
18
|
+
);
|
|
19
|
+
});
|
|
20
|
+
|
|
21
|
+
afterEach(() => {
|
|
22
|
+
vi.unstubAllGlobals();
|
|
23
|
+
document.body.innerHTML = "";
|
|
24
|
+
});
|
|
25
|
+
|
|
26
|
+
it("does not make a responsive non-scrolling wrapper focusable", () => {
|
|
27
|
+
document.body.innerHTML = `
|
|
28
|
+
<div class="table-scrollable table-scrollable--overflowing" style="overflow-x: visible" tabindex="0">
|
|
29
|
+
<table class="table table--responsive"></table>
|
|
30
|
+
</div>
|
|
31
|
+
`;
|
|
32
|
+
const table = document.querySelector("table");
|
|
33
|
+
const scrollableRegion = document.querySelector(".table-scrollable");
|
|
34
|
+
Object.defineProperties(scrollableRegion, {
|
|
35
|
+
clientWidth: { configurable: true, value: 400 },
|
|
36
|
+
scrollWidth: { configurable: true, value: 800 },
|
|
37
|
+
});
|
|
38
|
+
new Table(table);
|
|
39
|
+
|
|
40
|
+
resizeCallback([{ target: table, contentRect: { width: 800 } }]);
|
|
41
|
+
|
|
42
|
+
expect(scrollableRegion).not.toHaveAttribute("tabindex");
|
|
43
|
+
expect(scrollableRegion).not.toHaveClass("table-scrollable--overflowing");
|
|
44
|
+
});
|
|
45
|
+
|
|
46
|
+
it("marks a horizontally overflowing wrapper", () => {
|
|
47
|
+
document.body.innerHTML = `
|
|
48
|
+
<div class="table-scrollable" style="overflow-x: auto">
|
|
49
|
+
<table class="table table--pinned-first-column"></table>
|
|
50
|
+
</div>
|
|
51
|
+
`;
|
|
52
|
+
const table = document.querySelector("table");
|
|
53
|
+
const scrollableRegion = document.querySelector(".table-scrollable");
|
|
54
|
+
Object.defineProperties(scrollableRegion, {
|
|
55
|
+
clientWidth: { configurable: true, value: 400 },
|
|
56
|
+
scrollWidth: { configurable: true, value: 800 },
|
|
57
|
+
});
|
|
58
|
+
const instance = new Table(table);
|
|
59
|
+
|
|
60
|
+
expect(observe).toHaveBeenCalledWith(table);
|
|
61
|
+
expect(observe).toHaveBeenCalledWith(scrollableRegion);
|
|
62
|
+
|
|
63
|
+
resizeCallback([{ target: table, contentRect: { width: 800 } }]);
|
|
64
|
+
|
|
65
|
+
expect(scrollableRegion).toHaveClass("table-scrollable--overflowing");
|
|
66
|
+
expect(scrollableRegion).toHaveAttribute("tabindex", "0");
|
|
67
|
+
|
|
68
|
+
instance.destroy();
|
|
69
|
+
|
|
70
|
+
expect(scrollableRegion).not.toHaveClass("table-scrollable--overflowing");
|
|
71
|
+
expect(scrollableRegion).not.toHaveAttribute("tabindex");
|
|
72
|
+
});
|
|
@@ -194,6 +194,39 @@ describe("rendering Table", () => {
|
|
|
194
194
|
expect(getByTestId("test-id")).toHaveClass("table");
|
|
195
195
|
expect(getByTestId("test-id")).toHaveClass("table--compact");
|
|
196
196
|
});
|
|
197
|
+
it("pins the first column and enables overflow handling when isFirstColumnPinned is passed", () => {
|
|
198
|
+
const { container, getByTestId } = render(
|
|
199
|
+
<Table
|
|
200
|
+
data-testid="test-id"
|
|
201
|
+
headers={[]}
|
|
202
|
+
rows={[]}
|
|
203
|
+
isFirstColumnPinned
|
|
204
|
+
/>,
|
|
205
|
+
);
|
|
206
|
+
|
|
207
|
+
expect(getByTestId("test-id")).toHaveClass("table--pinned-first-column");
|
|
208
|
+
expect(container.querySelector(".table-scrollable")).toContainElement(
|
|
209
|
+
getByTestId("test-id"),
|
|
210
|
+
);
|
|
211
|
+
});
|
|
212
|
+
it("labels the pinned-column scroll region with its caption", () => {
|
|
213
|
+
const { container } = render(
|
|
214
|
+
<Table
|
|
215
|
+
headers={[]}
|
|
216
|
+
rows={[]}
|
|
217
|
+
caption="Pinned table"
|
|
218
|
+
isFirstColumnPinned
|
|
219
|
+
/>,
|
|
220
|
+
);
|
|
221
|
+
const scrollableRegion = container.querySelector(".table-scrollable");
|
|
222
|
+
const caption = container.querySelector("caption");
|
|
223
|
+
|
|
224
|
+
expect(caption).toHaveAttribute(
|
|
225
|
+
"id",
|
|
226
|
+
scrollableRegion.getAttribute("aria-labelledby"),
|
|
227
|
+
);
|
|
228
|
+
expect(caption).toHaveTextContent("Pinned table");
|
|
229
|
+
});
|
|
197
230
|
it("renders div wrapper with class table-scrollable when isScrollable is passed", () => {
|
|
198
231
|
const { container } = render(
|
|
199
232
|
<Table headers={[]} rows={[]} isScrollable />,
|
package/src/components/index.ts
CHANGED
|
@@ -29,6 +29,7 @@ import { Controls } from "./Controls";
|
|
|
29
29
|
import { Countdown, CountdownTag } from "./Countdown";
|
|
30
30
|
import { Cover } from "./Cover";
|
|
31
31
|
import { Divider } from "./Divider";
|
|
32
|
+
import { Drawer, DrawerBody, DrawerFooter, DrawerHeader } from "./Drawer";
|
|
32
33
|
import {
|
|
33
34
|
Dropdown,
|
|
34
35
|
DropdownDivider,
|
|
@@ -50,6 +51,8 @@ import {
|
|
|
50
51
|
Message,
|
|
51
52
|
Radio,
|
|
52
53
|
RangeSlider,
|
|
54
|
+
SegmentedControl,
|
|
55
|
+
SegmentedControlItem,
|
|
53
56
|
Select,
|
|
54
57
|
SelectionTile,
|
|
55
58
|
TextArea,
|
|
@@ -89,6 +92,7 @@ import { Skeleton } from "./Skeleton";
|
|
|
89
92
|
import { SkipLink } from "./SkipLink";
|
|
90
93
|
import { SocialButton } from "./SocialButton";
|
|
91
94
|
import { StarRating } from "./StarRating";
|
|
95
|
+
import { StatusIndicator } from "./StatusIndicator";
|
|
92
96
|
import { Stepbar } from "./Stepbar";
|
|
93
97
|
import { Sticker } from "./Sticker";
|
|
94
98
|
import { Table } from "./Table";
|
|
@@ -135,6 +139,10 @@ export {
|
|
|
135
139
|
CountdownTag,
|
|
136
140
|
Cover,
|
|
137
141
|
Divider,
|
|
142
|
+
Drawer,
|
|
143
|
+
DrawerBody,
|
|
144
|
+
DrawerFooter,
|
|
145
|
+
DrawerHeader,
|
|
138
146
|
Dropdown,
|
|
139
147
|
DropdownDivider,
|
|
140
148
|
DropdownItem,
|
|
@@ -186,6 +194,8 @@ export {
|
|
|
186
194
|
Radio,
|
|
187
195
|
RangeSlider,
|
|
188
196
|
Section,
|
|
197
|
+
SegmentedControl,
|
|
198
|
+
SegmentedControlItem,
|
|
189
199
|
Select,
|
|
190
200
|
SelectionTile,
|
|
191
201
|
Skeleton,
|
|
@@ -194,6 +204,7 @@ export {
|
|
|
194
204
|
SpritePathContext,
|
|
195
205
|
SpritePathProvider,
|
|
196
206
|
StarRating,
|
|
207
|
+
StatusIndicator,
|
|
197
208
|
Stepbar,
|
|
198
209
|
Sticker,
|
|
199
210
|
Tab,
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
@use "../tools/generate";
|
|
2
2
|
@use "config" as *;
|
|
3
3
|
@use "mixins" as *;
|
|
4
|
-
@use "sass:map" as sass-map;
|
|
5
4
|
|
|
6
5
|
// Headings pre elementy h1, h2, h3 atď.
|
|
7
6
|
@include headings-base($headings, "h$", $heading-base);
|
|
@@ -16,18 +15,6 @@
|
|
|
16
15
|
@include body-text($body-text);
|
|
17
16
|
@include readability();
|
|
18
17
|
|
|
19
|
-
.caption {
|
|
20
|
-
@include generate.css-map(sass-map.get($caption, "default"));
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
.caption--small {
|
|
24
|
-
@include generate.css-map(sass-map.get($caption, "small"));
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
.caption--large {
|
|
28
|
-
@include generate.css-map(sass-map.get($caption, "large"));
|
|
29
|
-
}
|
|
30
|
-
|
|
31
18
|
ol,
|
|
32
19
|
ul {
|
|
33
20
|
@include list-base();
|
|
@@ -67,6 +67,18 @@
|
|
|
67
67
|
);
|
|
68
68
|
}
|
|
69
69
|
|
|
70
|
+
.caption {
|
|
71
|
+
@include generate.css-map(map.get(typographyConfig.$caption, "default"));
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
.caption--small {
|
|
75
|
+
@include generate.css-map(map.get(typographyConfig.$caption, "small"));
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
.caption--large {
|
|
79
|
+
@include generate.css-map(map.get(typographyConfig.$caption, "large"));
|
|
80
|
+
}
|
|
81
|
+
|
|
70
82
|
.text-nowrap {
|
|
71
83
|
white-space: nowrap !important;
|
|
72
84
|
}
|
|
@@ -1,137 +0,0 @@
|
|
|
1
|
-
import { beforeEach, describe, expect, test } from "vitest";
|
|
2
|
-
import { page } from "vitest/browser";
|
|
3
|
-
import { render } from "vitest-browser-react";
|
|
4
|
-
import { Button } from "../../Button";
|
|
5
|
-
import { Alert } from "../";
|
|
6
|
-
|
|
7
|
-
describe("Alert visual regression", () => {
|
|
8
|
-
beforeEach(async () => {
|
|
9
|
-
await page.viewport(1280, 720);
|
|
10
|
-
});
|
|
11
|
-
|
|
12
|
-
test("Preview: title", async () => {
|
|
13
|
-
render(
|
|
14
|
-
<Alert data-testid="alert-title" title="Toto je jednoduchá sprava" />,
|
|
15
|
-
);
|
|
16
|
-
|
|
17
|
-
await expect(page.getByTestId("alert-title")).toMatchScreenshot(
|
|
18
|
-
"alert-preview-title",
|
|
19
|
-
);
|
|
20
|
-
});
|
|
21
|
-
|
|
22
|
-
test("Preview: title and description", async () => {
|
|
23
|
-
render(
|
|
24
|
-
<Alert
|
|
25
|
-
data-testid="alert-title-description"
|
|
26
|
-
title="Dobre vediet!"
|
|
27
|
-
description="Popis toho co by bolo dobre vysvetlit. Aj na viac riadkov."
|
|
28
|
-
/>,
|
|
29
|
-
);
|
|
30
|
-
|
|
31
|
-
await expect(page.getByTestId("alert-title-description")).toMatchScreenshot(
|
|
32
|
-
"alert-preview-title-description",
|
|
33
|
-
);
|
|
34
|
-
});
|
|
35
|
-
|
|
36
|
-
test("Preview: title and buttons", async () => {
|
|
37
|
-
render(
|
|
38
|
-
<Alert
|
|
39
|
-
data-testid="alert-title-buttons"
|
|
40
|
-
title="Prosim prihlaste sa."
|
|
41
|
-
actionButtons={[
|
|
42
|
-
<Button key="login">Prihlasit sa</Button>,
|
|
43
|
-
<Button key="hide">Skryt</Button>,
|
|
44
|
-
]}
|
|
45
|
-
/>,
|
|
46
|
-
);
|
|
47
|
-
|
|
48
|
-
await expect(page.getByTestId("alert-title-buttons")).toMatchScreenshot(
|
|
49
|
-
"alert-preview-title-buttons",
|
|
50
|
-
);
|
|
51
|
-
});
|
|
52
|
-
|
|
53
|
-
test("Preview: title, description and buttons", async () => {
|
|
54
|
-
render(
|
|
55
|
-
<Alert
|
|
56
|
-
data-testid="alert-title-description-buttons"
|
|
57
|
-
title="Prihlasit sa je jednoduche a rozumne"
|
|
58
|
-
description="Napr. prihlaseni pouzivatelia vidia krajsie ceny."
|
|
59
|
-
actionButtons={<Button>Prihlasit sa</Button>}
|
|
60
|
-
/>,
|
|
61
|
-
);
|
|
62
|
-
|
|
63
|
-
await expect(
|
|
64
|
-
page.getByTestId("alert-title-description-buttons"),
|
|
65
|
-
).toMatchScreenshot("alert-preview-title-description-buttons");
|
|
66
|
-
});
|
|
67
|
-
|
|
68
|
-
test("Preview: success type", async () => {
|
|
69
|
-
render(
|
|
70
|
-
<Alert
|
|
71
|
-
data-testid="alert-success"
|
|
72
|
-
type="success"
|
|
73
|
-
title="Vyborne. Vsetko prebehlo rychlo a hladko"
|
|
74
|
-
/>,
|
|
75
|
-
);
|
|
76
|
-
|
|
77
|
-
await expect(page.getByTestId("alert-success")).toMatchScreenshot(
|
|
78
|
-
"alert-preview-success",
|
|
79
|
-
);
|
|
80
|
-
});
|
|
81
|
-
|
|
82
|
-
test("Preview: warning type", async () => {
|
|
83
|
-
render(
|
|
84
|
-
<Alert
|
|
85
|
-
data-testid="alert-warning"
|
|
86
|
-
type="warning"
|
|
87
|
-
title="Na toto si daj pozor!"
|
|
88
|
-
/>,
|
|
89
|
-
);
|
|
90
|
-
|
|
91
|
-
await expect(page.getByTestId("alert-warning")).toMatchScreenshot(
|
|
92
|
-
"alert-preview-warning",
|
|
93
|
-
);
|
|
94
|
-
});
|
|
95
|
-
|
|
96
|
-
test("Preview: danger type", async () => {
|
|
97
|
-
render(
|
|
98
|
-
<Alert data-testid="alert-danger" type="danger" title="Stala sa chyba" />,
|
|
99
|
-
);
|
|
100
|
-
|
|
101
|
-
await expect(page.getByTestId("alert-danger")).toMatchScreenshot(
|
|
102
|
-
"alert-preview-danger",
|
|
103
|
-
);
|
|
104
|
-
});
|
|
105
|
-
|
|
106
|
-
test("Preview: custom title renderer", async () => {
|
|
107
|
-
render(
|
|
108
|
-
<Alert
|
|
109
|
-
data-testid="alert-custom-title"
|
|
110
|
-
title="Prihlasit sa je jednoduche a rozumne"
|
|
111
|
-
renderTitle={(props) => (
|
|
112
|
-
<h3 className="alert__title mb-medium">{props.title}</h3>
|
|
113
|
-
)}
|
|
114
|
-
description="Popis toho co by bolo dobre vysvetlit. Aj na viac riadkov."
|
|
115
|
-
/>,
|
|
116
|
-
);
|
|
117
|
-
|
|
118
|
-
await expect(page.getByTestId("alert-custom-title")).toMatchScreenshot(
|
|
119
|
-
"alert-preview-custom-title",
|
|
120
|
-
);
|
|
121
|
-
});
|
|
122
|
-
|
|
123
|
-
test("Preview: full width", async () => {
|
|
124
|
-
render(
|
|
125
|
-
<Alert
|
|
126
|
-
data-testid="alert-full-width"
|
|
127
|
-
isFullWidth
|
|
128
|
-
title="Dobre vediet!"
|
|
129
|
-
description="Popis toho co by bolo dobre vysvetlit. Aj na viac riadkov."
|
|
130
|
-
/>,
|
|
131
|
-
);
|
|
132
|
-
|
|
133
|
-
await expect(page.getByTestId("alert-full-width")).toMatchScreenshot(
|
|
134
|
-
"alert-preview-full-width",
|
|
135
|
-
);
|
|
136
|
-
});
|
|
137
|
-
});
|
|
Binary file
|