@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.
Files changed (108) hide show
  1. package/README.md +0 -6
  2. package/build/components/Alert/style.css +1 -1
  3. package/build/components/Alert/style.css.map +1 -1
  4. package/build/components/Bar/style.css +1 -1
  5. package/build/components/Bar/style.css.map +1 -1
  6. package/build/components/Drawer/style.css +2 -0
  7. package/build/components/Drawer/style.css.map +1 -0
  8. package/build/components/Footer/style.css +1 -1
  9. package/build/components/Footer/style.css.map +1 -1
  10. package/build/components/Megamenu/style.css +1 -1
  11. package/build/components/Megamenu/style.css.map +1 -1
  12. package/build/components/Modal/style.css +1 -1
  13. package/build/components/Modal/style.css.map +1 -1
  14. package/build/components/StatusIndicator/style.css +2 -0
  15. package/build/components/StatusIndicator/style.css.map +1 -0
  16. package/build/components/Table/style.css +1 -1
  17. package/build/components/Table/style.css.map +1 -1
  18. package/build/components/index.js +1 -1
  19. package/build/components/index.js.map +1 -1
  20. package/build/components/types/index.d.ts +55 -3
  21. package/build/lib/base.css +1 -1
  22. package/build/lib/base.css.map +1 -1
  23. package/build/lib/components.css +1 -1
  24. package/build/lib/components.css.map +1 -1
  25. package/build/lib/footer.css +1 -1
  26. package/build/lib/footer.css.map +1 -1
  27. package/build/lib/footer.js +1 -1
  28. package/build/lib/footer.js.map +1 -1
  29. package/build/lib/megamenu.css +1 -1
  30. package/build/lib/megamenu.css.map +1 -1
  31. package/build/lib/megamenu.js +1 -1
  32. package/build/lib/megamenu.js.map +1 -1
  33. package/build/lib/reset.css +2 -0
  34. package/build/lib/reset.css.map +1 -0
  35. package/build/lib/reset.js +3 -0
  36. package/build/lib/scripts.js +1 -1
  37. package/build/lib/scripts.js.map +1 -1
  38. package/build/lib/style.css +1 -1
  39. package/build/lib/style.css.map +1 -1
  40. package/build/lib/utilities.css +1 -1
  41. package/build/lib/utilities.css.map +1 -1
  42. package/package.json +27 -33
  43. package/src/components/Alert/Alert.tsx +2 -2
  44. package/src/components/Alert/data.ts +8 -5
  45. package/src/components/Alert/styles/config.scss +4 -4
  46. package/src/components/Alert/styles/mixins.scss +8 -1
  47. package/src/components/Alert/tests/Alert.test.jsx +11 -1
  48. package/src/components/Bar/Bar.tsx +1 -1
  49. package/src/components/Bar/styles/config.scss +1 -0
  50. package/src/components/Bar/tests/Bar.unit.test.jsx +1 -1
  51. package/src/components/Carousel/Carousel.static.ts +103 -12
  52. package/src/components/Carousel/tests/Carousel.static.test.jsx +134 -0
  53. package/src/components/DocumentationSidebar/DocumentationSidebar.tsx +12 -4
  54. package/src/components/Drawer/Drawer.static.ts +281 -0
  55. package/src/components/Drawer/Drawer.tsx +82 -0
  56. package/src/components/Drawer/DrawerBody.tsx +21 -0
  57. package/src/components/Drawer/DrawerFooter.tsx +21 -0
  58. package/src/components/Drawer/DrawerHeader.tsx +21 -0
  59. package/src/components/Drawer/index.ts +5 -0
  60. package/src/components/Drawer/styles/config.scss +17 -0
  61. package/src/components/Drawer/styles/mixins.scss +119 -0
  62. package/src/components/Drawer/styles/style.scss +71 -0
  63. package/src/components/Drawer/tests/Drawer.unit.test.jsx +149 -0
  64. package/src/components/Footer/Footer.tsx +1 -4
  65. package/src/components/Footer/styles/mixins.scss +3 -1
  66. package/src/components/Footer/styles/style.scss +31 -0
  67. package/src/components/Footer/tests/Footer.styles.unit.test.jsx +62 -0
  68. package/src/components/Forms/SegmentedControl/SegmentedControl.tsx +122 -0
  69. package/src/components/Forms/SegmentedControl/index.ts +5 -0
  70. package/src/components/Forms/SegmentedControl/styles/mixins.scss +52 -0
  71. package/src/components/Forms/SegmentedControl/styles/style.scss +35 -0
  72. package/src/components/Forms/SegmentedControl/tests/SegmentedControl.conformance.test.jsx +36 -0
  73. package/src/components/Forms/SegmentedControl/tests/SegmentedControl.unit.test.jsx +125 -0
  74. package/src/components/Forms/index.ts +1 -0
  75. package/src/components/Icon/index.ts +1 -0
  76. package/src/components/Megamenu/styles/mixins.scss +24 -18
  77. package/src/components/Modal/styles/config.scss +3 -2
  78. package/src/components/StatusIndicator/StatusIndicator.tsx +29 -0
  79. package/src/components/StatusIndicator/index.ts +2 -0
  80. package/src/components/StatusIndicator/styles/config.scss +12 -0
  81. package/src/components/StatusIndicator/styles/mixins.scss +36 -0
  82. package/src/components/StatusIndicator/styles/style.scss +16 -0
  83. package/src/components/StatusIndicator/tests/StatusIndicator.conformance.test.jsx +22 -0
  84. package/src/components/StatusIndicator/tests/StatusIndicator.unit.test.jsx +70 -0
  85. package/src/components/Table/Table.static.ts +23 -10
  86. package/src/components/Table/Table.tsx +7 -2
  87. package/src/components/Table/styles/mixins.scss +59 -0
  88. package/src/components/Table/styles/style.scss +25 -0
  89. package/src/components/Table/tests/Table.static.unit.test.jsx +72 -0
  90. package/src/components/Table/tests/Table.unit.test.jsx +33 -0
  91. package/src/components/index.ts +11 -0
  92. package/src/styles/tokens/overlay.scss +3 -0
  93. package/src/styles/typography/style.scss +0 -13
  94. package/src/styles/utilities/border.scss +4 -0
  95. package/src/styles/utilities/border.styles.unit.test.jsx +9 -0
  96. package/src/styles/utilities/text.scss +12 -0
  97. package/src/components/Alert/tests/Alert.visual.test.jsx +0 -137
  98. package/src/components/Alert/tests/__screenshots__/Alert.visual.test.jsx/alert-preview-custom-title-chromium-linux.png +0 -0
  99. package/src/components/Alert/tests/__screenshots__/Alert.visual.test.jsx/alert-preview-danger-chromium-linux.png +0 -0
  100. package/src/components/Alert/tests/__screenshots__/Alert.visual.test.jsx/alert-preview-full-width-chromium-linux.png +0 -0
  101. package/src/components/Alert/tests/__screenshots__/Alert.visual.test.jsx/alert-preview-success-chromium-linux.png +0 -0
  102. package/src/components/Alert/tests/__screenshots__/Alert.visual.test.jsx/alert-preview-title-buttons-chromium-linux.png +0 -0
  103. package/src/components/Alert/tests/__screenshots__/Alert.visual.test.jsx/alert-preview-title-chromium-linux.png +0 -0
  104. package/src/components/Alert/tests/__screenshots__/Alert.visual.test.jsx/alert-preview-title-description-buttons-chromium-linux.png +0 -0
  105. package/src/components/Alert/tests/__screenshots__/Alert.visual.test.jsx/alert-preview-title-description-chromium-linux.png +0 -0
  106. package/src/components/Alert/tests/__screenshots__/Alert.visual.test.jsx/alert-preview-warning-chromium-linux.png +0 -0
  107. package/src/components/Carousel/CHANGELOG.md +0 -11
  108. 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((entries) => {
37
+ this.resizeObserver = new ResizeObserver(() => {
36
38
  if (!this.scrollableContainer) return;
37
39
 
38
- const containerRect = this.scrollableContainer.getBoundingClientRect();
39
-
40
- entries.forEach((entry) => {
41
- if (entry.contentRect.width > containerRect.width) {
42
- this.scrollableContainer?.setAttribute("tabindex", "0");
43
- } else {
44
- this.scrollableContainer?.removeAttribute("tabindex");
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={isScrollable || false}
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 {...(isScrollable && { id: captionId })}>
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 />,
@@ -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,
@@ -0,0 +1,3 @@
1
+ $background: color-mix(in srgb, var(--color-surface-contrast) 75%, transparent);
2
+
3
+ $transition: 0.2s ease-out;
@@ -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();
@@ -13,6 +13,10 @@
13
13
  }
14
14
  }
15
15
 
16
+ .border--dashed {
17
+ border-style: dashed;
18
+ }
19
+
16
20
  .border--gray {
17
21
  border-color: var(--color-border-subtle);
18
22
 
@@ -0,0 +1,9 @@
1
+ import * as sass from "sass";
2
+
3
+ describe("Border utilities", () => {
4
+ it("changes the border style to dashed", () => {
5
+ const { css } = sass.compile("src/lib/style.scss");
6
+
7
+ expect(css).toMatch(/\.border--dashed \{\s+border-style: dashed;/);
8
+ });
9
+ });
@@ -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
- });