@orangesk/orange-design-system 2.0.0-beta.13 → 2.0.0-beta.15
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/build/components/index.js +4 -4
- package/build/components/index.js.map +1 -1
- package/build/components/tsconfig.tsbuildinfo +1 -1
- package/build/components/types/index.d.ts +20 -17
- package/build/components/types/src/components/AnchorNavigation/AnchorNavigation.d.ts +1 -1
- package/build/components/types/src/components/BodyBanner/BodyBanner.d.ts +10 -10
- package/build/components/types/src/components/Button/index.d.ts +3 -4
- package/build/components/types/src/components/FeatureAccordion/FeatureAccordion.d.ts +1 -1
- package/build/components/types/src/components/Forms/Select/index.d.ts +1 -1
- package/build/components/types/src/components/Grid/GridCol.d.ts +1 -1
- package/build/components/types/src/components/Icon/IconSearch.d.ts +2 -2
- package/build/components/types/src/components/Icon/IconSearchWrapper.d.ts +1 -1
- package/build/components/types/src/components/Link/Link.d.ts +2 -0
- package/build/components/types/src/components/Megamenu/Megamenu.d.ts +1 -1
- package/build/components/types/src/components/Megamenu/MegamenuBlog.d.ts +1 -1
- package/build/components/types/src/components/Pagination/Separator.d.ts +2 -2
- package/build/components/types/src/components/Preview/Preview.d.ts +1 -1
- package/build/components/types/src/components/Preview/index.d.ts +1 -1
- package/build/components/types/src/components/PromoBanner/PromoBanner.d.ts +1 -1
- package/build/components/types/src/components/Table/Row.d.ts +1 -2
- package/build/components/types/src/components/Tooltip/tests/BaseWrapper.d.ts +1 -1
- package/build/components/types/src/docs/utils/SpacePreview.d.ts +1 -2
- package/build/components/types/src/styles/export/color.d.ts +23 -0
- package/build/lib/after-components.css +1 -1
- package/build/lib/after-components.css.map +1 -1
- package/build/lib/before-components.css +1 -1
- package/build/lib/before-components.css.map +1 -1
- package/build/lib/components.css +1 -1
- package/build/lib/components.css.map +1 -1
- package/build/lib/megamenu.css +1 -1
- package/build/lib/megamenu.css.map +1 -1
- package/build/lib/scripts.js +4 -4
- 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/tsconfig.tsbuildinfo +1 -1
- package/package.json +17 -15
- package/src/components/BodyBanner/BodyBanner.tsx +52 -73
- package/src/components/BodyBanner/styles/mixins.scss +39 -33
- package/src/components/BodyBanner/styles/style.scss +4 -18
- package/src/components/BodyBanner/tests/BodyBanner.conformance.test.js +67 -0
- package/src/components/BodyBanner/tests/BodyBanner.unit.test.js +194 -0
- package/src/components/Carousel/Carousel.static.ts +1 -0
- package/src/components/Carousel/styles/mixins.scss +11 -5
- package/src/components/DocumentationSidebar/styles/style.scss +3 -3
- package/src/components/FeatureAccordion/FeatureAccordion.tsx +1 -1
- package/src/components/Link/Link.tsx +4 -0
- package/src/components/Link/styles/mixins.scss +8 -2
- package/src/components/Link/styles/style.scss +8 -1
- package/src/components/PromoBanner/styles/mixins.scss +1 -1
- package/src/components/Tag/styles/config.scss +18 -22
- package/src/components/Tag/styles/style.scss +1 -1
- package/src/styles/base/globals.scss +7 -0
- package/src/styles/tokens/tag-colors.scss +20 -0
- package/src/styles/typography/mixins.scss +0 -5
- package/src/styles/utilities/layout.scss +19 -0
- package/src/styles/utilities/visibility.scss +2 -4
- package/build/components/index.css +0 -2
- package/build/components/index.css.map +0 -1
- package/build/lib/scripts.css +0 -2
- package/build/lib/scripts.css.map +0 -1
|
@@ -3,13 +3,17 @@
|
|
|
3
3
|
@use "../../../styles/tools/generate";
|
|
4
4
|
@use "../../../styles/tokens/space";
|
|
5
5
|
@use "../../../styles/tokens/breakpoint";
|
|
6
|
-
// @use "./config";
|
|
7
6
|
|
|
8
7
|
@mixin body-banner {
|
|
9
8
|
display: flex;
|
|
10
9
|
color: var(--color-text-default);
|
|
11
10
|
background-color: var(--color-background-primary);
|
|
12
11
|
border: 1px solid var(--color-border-subtle);
|
|
12
|
+
|
|
13
|
+
&.grid {
|
|
14
|
+
margin-left: 0 !important;
|
|
15
|
+
margin-right: 0 !important;
|
|
16
|
+
}
|
|
13
17
|
}
|
|
14
18
|
|
|
15
19
|
@mixin content {
|
|
@@ -30,20 +34,9 @@
|
|
|
30
34
|
> div:not(.body-banner__button) {
|
|
31
35
|
flex: 1;
|
|
32
36
|
min-width: 0;
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
&.is-large {
|
|
36
|
-
display: flex;
|
|
37
|
-
flex-direction: column;
|
|
38
|
-
gap: 16px;
|
|
39
|
-
padding: space.get("xlarge");
|
|
40
|
-
|
|
41
|
-
@include breakpoint.get("lg", "down") {
|
|
42
|
-
padding: space.get("xlarge") space.get("large");
|
|
43
|
-
}
|
|
44
37
|
|
|
45
|
-
|
|
46
|
-
|
|
38
|
+
> *:last-child {
|
|
39
|
+
margin-bottom: 0;
|
|
47
40
|
}
|
|
48
41
|
}
|
|
49
42
|
|
|
@@ -60,28 +53,13 @@
|
|
|
60
53
|
|
|
61
54
|
@mixin image {
|
|
62
55
|
padding: 0 !important;
|
|
56
|
+
|
|
63
57
|
img {
|
|
64
58
|
width: 80px;
|
|
65
59
|
height: 80px;
|
|
66
60
|
object-fit: cover;
|
|
67
61
|
margin: 0 space.get("large") !important;
|
|
68
62
|
|
|
69
|
-
&.is-large {
|
|
70
|
-
width: 100%;
|
|
71
|
-
height: auto;
|
|
72
|
-
object-fit: cover;
|
|
73
|
-
object-position: left center;
|
|
74
|
-
margin: 0px !important;
|
|
75
|
-
|
|
76
|
-
@include breakpoint.get("xl", "down") {
|
|
77
|
-
height: 100%;
|
|
78
|
-
}
|
|
79
|
-
|
|
80
|
-
@include breakpoint.get("sm", "down") {
|
|
81
|
-
height: auto;
|
|
82
|
-
}
|
|
83
|
-
}
|
|
84
|
-
|
|
85
63
|
@include breakpoint.get("sm", "down") {
|
|
86
64
|
margin: 15px !important;
|
|
87
65
|
}
|
|
@@ -91,15 +69,43 @@
|
|
|
91
69
|
@mixin button {
|
|
92
70
|
display: flex;
|
|
93
71
|
align-items: center;
|
|
94
|
-
padding: 0 space.get("xlarge");
|
|
72
|
+
padding: 0 0 0 space.get("xlarge");
|
|
95
73
|
margin: 0 !important;
|
|
96
74
|
|
|
97
|
-
|
|
75
|
+
@include breakpoint.get("lg", "down") {
|
|
98
76
|
padding: 0;
|
|
99
77
|
margin-top: space.get("small") !important;
|
|
100
78
|
}
|
|
79
|
+
}
|
|
101
80
|
|
|
102
|
-
|
|
81
|
+
@mixin large {
|
|
82
|
+
.body-banner__content-inner {
|
|
83
|
+
display: flex;
|
|
84
|
+
flex-direction: column;
|
|
85
|
+
gap: 16px;
|
|
86
|
+
padding: space.get("xlarge");
|
|
87
|
+
|
|
88
|
+
@include breakpoint.get("lg", "down") {
|
|
89
|
+
padding: space.get("xlarge") space.get("large");
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
@include breakpoint.get("sm", "down") {
|
|
93
|
+
padding: space.get("large") 10px;
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
.body-banner__image {
|
|
98
|
+
img {
|
|
99
|
+
width: 100%;
|
|
100
|
+
height: 100%;
|
|
101
|
+
object-fit: cover;
|
|
102
|
+
object-position: center;
|
|
103
|
+
margin: 0 !important;
|
|
104
|
+
display: block;
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
.body-banner__button {
|
|
103
109
|
padding: 0;
|
|
104
110
|
margin-top: space.get("small") !important;
|
|
105
111
|
}
|
|
@@ -4,24 +4,6 @@
|
|
|
4
4
|
.body-banner {
|
|
5
5
|
@include mixins.body-banner();
|
|
6
6
|
|
|
7
|
-
&.is-gray {
|
|
8
|
-
--color-background-primary: var(--color-fill-subtle);
|
|
9
|
-
border: none !important;
|
|
10
|
-
}
|
|
11
|
-
|
|
12
|
-
&.is-orange {
|
|
13
|
-
// TODO: change to color token
|
|
14
|
-
--color-background-primary: #fff0e0;
|
|
15
|
-
border: none !important;
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
&.is-dark {
|
|
19
|
-
&.is-orange {
|
|
20
|
-
// TODO: change to color token
|
|
21
|
-
color: #000000 !important;
|
|
22
|
-
}
|
|
23
|
-
}
|
|
24
|
-
|
|
25
7
|
&__content {
|
|
26
8
|
@include mixins.content();
|
|
27
9
|
|
|
@@ -37,5 +19,9 @@
|
|
|
37
19
|
&__button {
|
|
38
20
|
@include mixins.button();
|
|
39
21
|
}
|
|
22
|
+
|
|
23
|
+
&--large {
|
|
24
|
+
@include mixins.large();
|
|
25
|
+
}
|
|
40
26
|
}
|
|
41
27
|
}
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
import { render } from "@testing-library/react";
|
|
2
|
+
import { axe } from "jest-axe";
|
|
3
|
+
|
|
4
|
+
import { BodyBanner } from "../";
|
|
5
|
+
|
|
6
|
+
const example = (
|
|
7
|
+
<>
|
|
8
|
+
<BodyBanner size="small" buttonText="Learn More">
|
|
9
|
+
<h3>Small Banner Example</h3>
|
|
10
|
+
<p>This is a small banner with image and call-to-action button.</p>
|
|
11
|
+
</BodyBanner>
|
|
12
|
+
|
|
13
|
+
<BodyBanner
|
|
14
|
+
size="large"
|
|
15
|
+
buttonText="Get Started"
|
|
16
|
+
imageUrl="https://picsum.photos/seed/test/640/380"
|
|
17
|
+
>
|
|
18
|
+
<h3>Large Banner Example</h3>
|
|
19
|
+
<p>This is a large banner with two-column layout.</p>
|
|
20
|
+
</BodyBanner>
|
|
21
|
+
|
|
22
|
+
<BodyBanner
|
|
23
|
+
size="small"
|
|
24
|
+
color="background-accent"
|
|
25
|
+
buttonText="Discover"
|
|
26
|
+
imageUrl="https://picsum.photos/seed/test2/640/380"
|
|
27
|
+
>
|
|
28
|
+
<h3>Accent Background</h3>
|
|
29
|
+
<p>Brand accent background banner.</p>
|
|
30
|
+
</BodyBanner>
|
|
31
|
+
|
|
32
|
+
<BodyBanner
|
|
33
|
+
size="small"
|
|
34
|
+
color="surface-subtle"
|
|
35
|
+
buttonText="Explore"
|
|
36
|
+
imageUrl="https://picsum.photos/seed/test3/640/380"
|
|
37
|
+
>
|
|
38
|
+
<h3>Subtle Surface</h3>
|
|
39
|
+
<p>Gentle background color banner.</p>
|
|
40
|
+
</BodyBanner>
|
|
41
|
+
|
|
42
|
+
<BodyBanner size="small" buttonText="Learn More">
|
|
43
|
+
<h3>Text-Only Banner</h3>
|
|
44
|
+
<p>Banner without image focusing on text content.</p>
|
|
45
|
+
</BodyBanner>
|
|
46
|
+
|
|
47
|
+
<BodyBanner
|
|
48
|
+
size="large"
|
|
49
|
+
color="background-primary"
|
|
50
|
+
buttonText="Start Now"
|
|
51
|
+
imageUrl="https://picsum.photos/seed/test4/640/380"
|
|
52
|
+
>
|
|
53
|
+
<h3>Primary Background</h3>
|
|
54
|
+
<p>Clean white background banner.</p>
|
|
55
|
+
</BodyBanner>
|
|
56
|
+
</>
|
|
57
|
+
);
|
|
58
|
+
|
|
59
|
+
it("is valid html", () => {
|
|
60
|
+
const { container } = render(example);
|
|
61
|
+
expect(container).toHTMLValidate();
|
|
62
|
+
});
|
|
63
|
+
|
|
64
|
+
it("is accessible", async () => {
|
|
65
|
+
const { container } = render(example);
|
|
66
|
+
expect(await axe(container)).toHaveNoViolations();
|
|
67
|
+
});
|
|
@@ -0,0 +1,194 @@
|
|
|
1
|
+
import { render } from "@testing-library/react";
|
|
2
|
+
|
|
3
|
+
import { BodyBanner } from "../";
|
|
4
|
+
|
|
5
|
+
describe("rendering BodyBanner", () => {
|
|
6
|
+
describe("initial state", () => {
|
|
7
|
+
it("has default className body-banner", () => {
|
|
8
|
+
const { container } = render(<BodyBanner />);
|
|
9
|
+
expect(container.querySelector(".body-banner")).toBeInTheDocument();
|
|
10
|
+
expect(container.querySelector(".body-banner")).toHaveClass(
|
|
11
|
+
"body-banner",
|
|
12
|
+
);
|
|
13
|
+
});
|
|
14
|
+
});
|
|
15
|
+
|
|
16
|
+
describe("sizes", () => {
|
|
17
|
+
it("doesn't have body-banner--small class when size is small (default)", () => {
|
|
18
|
+
const { container } = render(<BodyBanner />);
|
|
19
|
+
expect(container.querySelector(".body-banner")).not.toHaveClass(
|
|
20
|
+
"body-banner--small",
|
|
21
|
+
);
|
|
22
|
+
});
|
|
23
|
+
|
|
24
|
+
it("has body-banner--large class when size is large", () => {
|
|
25
|
+
const { container } = render(<BodyBanner size="large" />);
|
|
26
|
+
expect(container.querySelector(".body-banner")).toHaveClass(
|
|
27
|
+
"body-banner--large",
|
|
28
|
+
);
|
|
29
|
+
});
|
|
30
|
+
});
|
|
31
|
+
|
|
32
|
+
describe("colors", () => {
|
|
33
|
+
it("doesn't have color class when color is background-primary (default)", () => {
|
|
34
|
+
const { container } = render(<BodyBanner color="background-primary" />);
|
|
35
|
+
expect(container.querySelector(".body-banner")).not.toHaveClass(
|
|
36
|
+
"background-primary",
|
|
37
|
+
);
|
|
38
|
+
});
|
|
39
|
+
|
|
40
|
+
it("has background-primary class by default (when no color specified)", () => {
|
|
41
|
+
const { container } = render(<BodyBanner />);
|
|
42
|
+
expect(container.querySelector(".body-banner")).toHaveClass(
|
|
43
|
+
"body-banner",
|
|
44
|
+
);
|
|
45
|
+
});
|
|
46
|
+
|
|
47
|
+
it("has background-accent class when color is background-accent", () => {
|
|
48
|
+
const { container } = render(<BodyBanner color="background-accent" />);
|
|
49
|
+
expect(container.querySelector(".body-banner")).toHaveClass(
|
|
50
|
+
"background-accent",
|
|
51
|
+
);
|
|
52
|
+
});
|
|
53
|
+
|
|
54
|
+
it("has surface-subtle class when color is surface-subtle", () => {
|
|
55
|
+
const { container } = render(<BodyBanner color="surface-subtle" />);
|
|
56
|
+
expect(container.querySelector(".body-banner")).toHaveClass(
|
|
57
|
+
"surface-subtle",
|
|
58
|
+
);
|
|
59
|
+
});
|
|
60
|
+
|
|
61
|
+
it("supports all available colors", () => {
|
|
62
|
+
const colors = [
|
|
63
|
+
"background-primary",
|
|
64
|
+
"background-accent",
|
|
65
|
+
"surface-subtle",
|
|
66
|
+
];
|
|
67
|
+
|
|
68
|
+
colors.forEach((color) => {
|
|
69
|
+
const { container } = render(<BodyBanner color={color} />);
|
|
70
|
+
|
|
71
|
+
if (color !== "background-primary") {
|
|
72
|
+
expect(container.querySelector(".body-banner")).toHaveClass(color);
|
|
73
|
+
}
|
|
74
|
+
});
|
|
75
|
+
});
|
|
76
|
+
});
|
|
77
|
+
|
|
78
|
+
describe("children and button", () => {
|
|
79
|
+
it("renders children content", () => {
|
|
80
|
+
const { getByText } = render(
|
|
81
|
+
<BodyBanner>
|
|
82
|
+
<h3>Test Title</h3>
|
|
83
|
+
<p>Test Description</p>
|
|
84
|
+
</BodyBanner>,
|
|
85
|
+
);
|
|
86
|
+
expect(getByText("Test Title")).toBeInTheDocument();
|
|
87
|
+
expect(getByText("Test Description")).toBeInTheDocument();
|
|
88
|
+
});
|
|
89
|
+
|
|
90
|
+
it("renders button text", () => {
|
|
91
|
+
const { getByText } = render(<BodyBanner buttonText="Learn More" />);
|
|
92
|
+
expect(getByText("Learn More")).toBeInTheDocument();
|
|
93
|
+
});
|
|
94
|
+
|
|
95
|
+
it("renders both children and button", () => {
|
|
96
|
+
const { getByText } = render(
|
|
97
|
+
<BodyBanner buttonText="Click Me">
|
|
98
|
+
<h3>Content</h3>
|
|
99
|
+
</BodyBanner>,
|
|
100
|
+
);
|
|
101
|
+
expect(getByText("Content")).toBeInTheDocument();
|
|
102
|
+
expect(getByText("Click Me")).toBeInTheDocument();
|
|
103
|
+
});
|
|
104
|
+
});
|
|
105
|
+
|
|
106
|
+
describe("image", () => {
|
|
107
|
+
it("renders image when imageUrl is provided", () => {
|
|
108
|
+
const { getByRole } = render(
|
|
109
|
+
<BodyBanner imageUrl="https://example.com/image.jpg" />,
|
|
110
|
+
);
|
|
111
|
+
const image = getByRole("img");
|
|
112
|
+
expect(image).toBeInTheDocument();
|
|
113
|
+
expect(image).toHaveAttribute("src", "https://example.com/image.jpg");
|
|
114
|
+
});
|
|
115
|
+
|
|
116
|
+
it("doesn't render image when imageUrl is not provided", () => {
|
|
117
|
+
const { queryByRole } = render(<BodyBanner />);
|
|
118
|
+
const image = queryByRole("img");
|
|
119
|
+
expect(image).not.toBeInTheDocument();
|
|
120
|
+
});
|
|
121
|
+
|
|
122
|
+
it("renders image in separate column when size is large", () => {
|
|
123
|
+
const { container, getAllByRole } = render(
|
|
124
|
+
<BodyBanner size="large" imageUrl="https://example.com/image.jpg" />,
|
|
125
|
+
);
|
|
126
|
+
const images = getAllByRole("img");
|
|
127
|
+
expect(images.length).toBe(1);
|
|
128
|
+
const imageContainer = container.querySelector(".body-banner__image");
|
|
129
|
+
expect(imageContainer).toBeInTheDocument();
|
|
130
|
+
});
|
|
131
|
+
|
|
132
|
+
it("renders image in content when size is small", () => {
|
|
133
|
+
const { container, getByRole } = render(
|
|
134
|
+
<BodyBanner size="small" imageUrl="https://example.com/image.jpg" />,
|
|
135
|
+
);
|
|
136
|
+
const imageContainer = container.querySelector(".body-banner__image");
|
|
137
|
+
expect(imageContainer).toBeInTheDocument();
|
|
138
|
+
const image = getByRole("img");
|
|
139
|
+
expect(image).toBeInTheDocument();
|
|
140
|
+
});
|
|
141
|
+
});
|
|
142
|
+
|
|
143
|
+
describe("className prop", () => {
|
|
144
|
+
it("has additional class when className is set", () => {
|
|
145
|
+
const { container } = render(<BodyBanner className="custom-class" />);
|
|
146
|
+
expect(container.querySelector(".body-banner")).toHaveClass(
|
|
147
|
+
"body-banner",
|
|
148
|
+
);
|
|
149
|
+
expect(container.querySelector(".body-banner")).toHaveClass(
|
|
150
|
+
"custom-class",
|
|
151
|
+
);
|
|
152
|
+
});
|
|
153
|
+
});
|
|
154
|
+
|
|
155
|
+
describe("button className prop", () => {
|
|
156
|
+
it("applies buttonClassName to the button", () => {
|
|
157
|
+
const { getByRole } = render(
|
|
158
|
+
<BodyBanner buttonText="Click" buttonClassName="custom-button-class" />,
|
|
159
|
+
);
|
|
160
|
+
const button = getByRole("button");
|
|
161
|
+
expect(button).toHaveClass("custom-button-class");
|
|
162
|
+
});
|
|
163
|
+
});
|
|
164
|
+
|
|
165
|
+
describe("responsive layout", () => {
|
|
166
|
+
it("renders grid structure with proper content column", () => {
|
|
167
|
+
const { container } = render(
|
|
168
|
+
<BodyBanner size="small">
|
|
169
|
+
<h3>Test</h3>
|
|
170
|
+
</BodyBanner>,
|
|
171
|
+
);
|
|
172
|
+
const gridCol = container.querySelector(".body-banner__content");
|
|
173
|
+
expect(gridCol).toBeInTheDocument();
|
|
174
|
+
});
|
|
175
|
+
|
|
176
|
+
it("has button container", () => {
|
|
177
|
+
const { container } = render(<BodyBanner buttonText="Click" />);
|
|
178
|
+
const buttonContainer = container.querySelector(".body-banner__button");
|
|
179
|
+
expect(buttonContainer).toBeInTheDocument();
|
|
180
|
+
});
|
|
181
|
+
|
|
182
|
+
it("has content-inner container", () => {
|
|
183
|
+
const { container } = render(
|
|
184
|
+
<BodyBanner>
|
|
185
|
+
<h3>Test</h3>
|
|
186
|
+
</BodyBanner>,
|
|
187
|
+
);
|
|
188
|
+
const contentInner = container.querySelector(
|
|
189
|
+
".body-banner__content-inner",
|
|
190
|
+
);
|
|
191
|
+
expect(contentInner).toBeInTheDocument();
|
|
192
|
+
});
|
|
193
|
+
});
|
|
194
|
+
});
|
|
@@ -210,6 +210,7 @@ export default class Carousel {
|
|
|
210
210
|
// Only add offset if there's actual bleeding (positive value)
|
|
211
211
|
if (bleedAmount > 0) {
|
|
212
212
|
// Update the Swiper configuration
|
|
213
|
+
// Add offset only on the right side for right bleed effect
|
|
213
214
|
this.instance.params.slidesOffsetAfter = bleedAmount;
|
|
214
215
|
this.instance.update();
|
|
215
216
|
} else {
|
|
@@ -211,15 +211,21 @@
|
|
|
211
211
|
}
|
|
212
212
|
|
|
213
213
|
@mixin bleed-right-variant {
|
|
214
|
+
// Allow overflow on the left side at the carousel container level
|
|
215
|
+
overflow: visible;
|
|
216
|
+
|
|
217
|
+
.carousel__viewport-wrapper {
|
|
218
|
+
// Allow overflow from viewport
|
|
219
|
+
overflow: visible;
|
|
220
|
+
}
|
|
221
|
+
|
|
214
222
|
.carousel__viewport {
|
|
215
223
|
// Extend the viewport to the right edge of the screen
|
|
216
224
|
width: calc(100% + 50vw - 50%);
|
|
217
225
|
margin-right: 0;
|
|
218
|
-
|
|
219
|
-
//
|
|
220
|
-
|
|
221
|
-
margin-left: convert.to-rem(50px);
|
|
222
|
-
}
|
|
226
|
+
margin-left: 0 !important; // Don't add left margin - let content flow naturally
|
|
227
|
+
overflow: visible !important; // Allow content to overflow on left side
|
|
228
|
+
overflow-y: hidden; // Still hide vertical overflow
|
|
223
229
|
|
|
224
230
|
// On very large screens (above 2K), stop the bleeding effect entirely
|
|
225
231
|
@media (min-width: 2560px) {
|
|
@@ -18,6 +18,8 @@ export interface LinkProps {
|
|
|
18
18
|
isUnderline?: boolean;
|
|
19
19
|
/** whether the link should have normal font weight */
|
|
20
20
|
isNormal?: boolean;
|
|
21
|
+
/** when true, adds the .link--no-accent modifier to disable orange accent color on hover (useful for dark backgrounds) */
|
|
22
|
+
noAccent?: boolean;
|
|
21
23
|
}
|
|
22
24
|
|
|
23
25
|
export const Link: React.FC<LinkProps & React.HTMLAttributes<HTMLElement>> = ({
|
|
@@ -26,6 +28,7 @@ export const Link: React.FC<LinkProps & React.HTMLAttributes<HTMLElement>> = ({
|
|
|
26
28
|
colorScheme,
|
|
27
29
|
isUnderline,
|
|
28
30
|
isNormal,
|
|
31
|
+
noAccent,
|
|
29
32
|
tag = "a",
|
|
30
33
|
href,
|
|
31
34
|
...other
|
|
@@ -37,6 +40,7 @@ export const Link: React.FC<LinkProps & React.HTMLAttributes<HTMLElement>> = ({
|
|
|
37
40
|
"is-light": colorScheme === "light",
|
|
38
41
|
underline: isUnderline,
|
|
39
42
|
normal: isNormal,
|
|
43
|
+
"link--no-accent": noAccent,
|
|
40
44
|
},
|
|
41
45
|
className,
|
|
42
46
|
);
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
@mixin base {
|
|
5
5
|
font-weight: bold;
|
|
6
6
|
text-decoration: underline;
|
|
7
|
-
color:
|
|
7
|
+
color: inherit;
|
|
8
8
|
background: none;
|
|
9
9
|
text-decoration: none;
|
|
10
10
|
cursor: pointer;
|
|
@@ -14,7 +14,13 @@
|
|
|
14
14
|
p &,
|
|
15
15
|
li &,
|
|
16
16
|
dt &,
|
|
17
|
-
dd
|
|
17
|
+
dd &,
|
|
18
|
+
h1 &,
|
|
19
|
+
h2 &,
|
|
20
|
+
h3 &,
|
|
21
|
+
h4 &,
|
|
22
|
+
h5 &,
|
|
23
|
+
h6 & {
|
|
18
24
|
font-weight: inherit;
|
|
19
25
|
}
|
|
20
26
|
}
|
|
@@ -24,7 +24,7 @@
|
|
|
24
24
|
@include mixins.base-inherit();
|
|
25
25
|
|
|
26
26
|
&:hover {
|
|
27
|
-
color: var(--color-text-accent)
|
|
27
|
+
color: var(--color-text-accent);
|
|
28
28
|
text-decoration: underline;
|
|
29
29
|
}
|
|
30
30
|
&:focus {
|
|
@@ -44,3 +44,10 @@
|
|
|
44
44
|
@include mixins.icon-right;
|
|
45
45
|
}
|
|
46
46
|
}
|
|
47
|
+
|
|
48
|
+
@layer utilities {
|
|
49
|
+
.link--no-accent:hover {
|
|
50
|
+
color: inherit !important;
|
|
51
|
+
text-decoration: underline;
|
|
52
|
+
}
|
|
53
|
+
}
|
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
@use "../../../styles/tokens/space";
|
|
2
|
-
@use "../../../styles/tokens/color";
|
|
3
2
|
@use "../../../styles/tools/convert";
|
|
4
3
|
@use "sass:map";
|
|
5
4
|
|
|
@@ -46,43 +45,40 @@ $colors: (
|
|
|
46
45
|
color: var(--color-text-default),
|
|
47
46
|
),
|
|
48
47
|
"orange": (
|
|
49
|
-
background-color:
|
|
50
|
-
color:
|
|
48
|
+
background-color: var(--tag-orange),
|
|
49
|
+
color: var(--tag-text-dark),
|
|
51
50
|
),
|
|
52
51
|
"black": (
|
|
53
|
-
background-color:
|
|
54
|
-
color:
|
|
52
|
+
background-color: var(--tag-black),
|
|
53
|
+
color: var(--tag-text-light),
|
|
55
54
|
),
|
|
56
55
|
"yellow": (
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
color: color.$black,
|
|
56
|
+
background-color: var(--tag-yellow),
|
|
57
|
+
color: var(--tag-text-dark),
|
|
60
58
|
),
|
|
61
59
|
"green": (
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
color: color.$black,
|
|
60
|
+
background-color: var(--tag-green),
|
|
61
|
+
color: var(--tag-text-dark),
|
|
65
62
|
),
|
|
66
63
|
"blue": (
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
color: color.$black,
|
|
64
|
+
background-color: var(--tag-blue),
|
|
65
|
+
color: var(--tag-text-dark),
|
|
70
66
|
),
|
|
71
67
|
"success": (
|
|
72
|
-
background-color:
|
|
73
|
-
color:
|
|
68
|
+
background-color: var(--tag-success),
|
|
69
|
+
color: var(--tag-text-light),
|
|
74
70
|
),
|
|
75
71
|
"danger": (
|
|
76
|
-
background-color:
|
|
77
|
-
color:
|
|
72
|
+
background-color: var(--tag-danger),
|
|
73
|
+
color: var(--tag-text-light),
|
|
78
74
|
),
|
|
79
75
|
"info": (
|
|
80
|
-
background-color:
|
|
81
|
-
color:
|
|
76
|
+
background-color: var(--tag-info),
|
|
77
|
+
color: var(--tag-text-light),
|
|
82
78
|
),
|
|
83
79
|
"warning": (
|
|
84
|
-
background-color:
|
|
85
|
-
color:
|
|
80
|
+
background-color: var(--tag-warning),
|
|
81
|
+
color: var(--tag-text-dark),
|
|
86
82
|
),
|
|
87
83
|
"transparent": (
|
|
88
84
|
background-color: transparent,
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
@use "../tokens/base";
|
|
2
2
|
@use "../tokens/space";
|
|
3
3
|
@use "../tokens/color";
|
|
4
|
+
@use "../tokens/tag-colors";
|
|
4
5
|
|
|
5
6
|
// Consider to add more conditions for light and dark themes
|
|
6
7
|
:root,
|
|
@@ -15,6 +16,9 @@
|
|
|
15
16
|
@each $name, $value in color.$colors-light {
|
|
16
17
|
--color-#{$name}: #{$value};
|
|
17
18
|
}
|
|
19
|
+
@each $name, $value in tag-colors.$tag-colors-light {
|
|
20
|
+
--#{$name}: #{$value};
|
|
21
|
+
}
|
|
18
22
|
color: var(--color-text-default);
|
|
19
23
|
}
|
|
20
24
|
|
|
@@ -28,6 +32,9 @@
|
|
|
28
32
|
@each $name, $value in color.$colors-dark {
|
|
29
33
|
--color-#{$name}: #{$value};
|
|
30
34
|
}
|
|
35
|
+
@each $name, $value in tag-colors.$tag-colors-dark {
|
|
36
|
+
--#{$name}: #{$value};
|
|
37
|
+
}
|
|
31
38
|
color: var(--color-text-default);
|
|
32
39
|
}
|
|
33
40
|
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
// Tag-specific color palette for variants that exist outside the main semantic system.
|
|
2
|
+
// Tags intentionally keep the same colors in both light and dark themes, so we expose
|
|
3
|
+
// a shared palette that is applied regardless of theme context.
|
|
4
|
+
|
|
5
|
+
$tag-shared-tag-colors: (
|
|
6
|
+
tag-orange: #ffc48f,
|
|
7
|
+
tag-black: #333333,
|
|
8
|
+
tag-yellow: #fff6b6,
|
|
9
|
+
tag-green: #b8ebd6,
|
|
10
|
+
tag-blue: #b5e8f7,
|
|
11
|
+
tag-success: #228722,
|
|
12
|
+
tag-danger: #cd3c14,
|
|
13
|
+
tag-info: #4170d8,
|
|
14
|
+
tag-warning: #ffcc00,
|
|
15
|
+
tag-text-dark: #000000,
|
|
16
|
+
tag-text-light: #ffffff,
|
|
17
|
+
);
|
|
18
|
+
|
|
19
|
+
$tag-colors-light: $tag-shared-tag-colors;
|
|
20
|
+
$tag-colors-dark: $tag-shared-tag-colors;
|