@repobit/dex-system-design 0.4.0 → 0.6.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/CHANGELOG.md +18 -0
- package/package.json +4 -3
- package/src/assets/images/bd-header-img.jpg +0 -0
- package/src/assets/images/bd-header-us.jpg +0 -0
- package/src/components/Button/Button.js +115 -3
- package/src/components/Button/button.css.js +48 -10
- package/src/components/Button/button.stories.js +83 -7
- package/src/components/FAQ/faq.css.js +27 -16
- package/src/components/FAQ/faq.js +23 -114
- package/src/components/FAQ/faq.stories.js +41 -20
- package/src/components/Input/Input.js +2 -2
- package/src/components/Input/input.css.js +1 -1
- package/src/components/anchor/anchor-nav.css.js +92 -0
- package/src/components/anchor/anchor-nav.js +121 -0
- package/src/components/anchor/anchor.stories.js +134 -0
- package/src/components/badge/badge.css.js +27 -0
- package/src/components/badge/badge.js +30 -0
- package/src/components/badge/badge.stories.js +36 -0
- package/src/components/carousel/carousel.css.js +36 -19
- package/src/components/carousel/carousel.js +149 -99
- package/src/components/carousel/carousel.stories.js +202 -46
- package/src/components/checkbox/checkbox.css.js +132 -0
- package/src/components/checkbox/checkbox.js +130 -0
- package/src/components/checkbox/checkbox.stories.js +63 -0
- package/src/components/divider/divider-horizontal.js +29 -0
- package/src/components/divider/divider-vertical.js +32 -0
- package/src/components/divider/divider.css.js +0 -0
- package/src/components/divider/divider.stories.js +77 -0
- package/src/components/header/header.css.js +248 -0
- package/src/components/header/header.js +87 -0
- package/src/components/header/header.stories.js +57 -0
- package/src/components/highlight/highlight-s.css.js +88 -0
- package/src/components/highlight/highlight-s.js +35 -0
- package/src/components/highlight/highlight-s.stories.js +22 -0
- package/src/components/highlight/highlight.css.js +119 -0
- package/src/components/highlight/highlight.js +60 -0
- package/src/components/highlight/highlight.stories.js +53 -0
- package/src/components/light-carousel/light-carousel.css.js +18 -10
- package/src/components/light-carousel/light-carousel.js +29 -16
- package/src/components/light-carousel/light-carousel.stories.js +9 -7
- package/src/components/paragraph/paragraph.css.js +1 -1
- package/src/components/pricing-cards/pricing-card.css.js +138 -3
- package/src/components/pricing-cards/pricing-card.js +63 -82
- package/src/components/pricing-cards/pricing-card.stories.js +1 -0
- package/src/components/radio/radio.css.js +168 -0
- package/src/components/radio/radio.js +222 -0
- package/src/components/radio/radio.stories.js +103 -0
- package/src/components/tabs/tabs.css.js +26 -8
- package/src/components/tabs/tabs.js +19 -12
- package/src/components/termsOfUse/terms.css.js +7 -1
- package/src/tokens/fonts.stories.js +73 -0
- package/src/tokens/spacing.stories.js +56 -0
- package/src/tokens/tokens-grid.stories.js +83 -0
- package/src/tokens/tokens.css +116 -1
- package/src/tokens/tokens.stories.js +67 -0
- package/src/tokens/typography.stories.js +69 -0
- /package/src/assets/{icons → images}/tabs-img1.png +0 -0
- /package/src/assets/{icons → images}/tabs-img2.png +0 -0
- /package/src/assets/{icons → images}/tabs-img3.png +0 -0
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import { html } from 'lit';
|
|
2
|
+
import './badge.js';
|
|
3
|
+
|
|
4
|
+
export default {
|
|
5
|
+
title: 'Atoms/Badge',
|
|
6
|
+
component: 'bd-badge',
|
|
7
|
+
argTypes: {
|
|
8
|
+
text: {
|
|
9
|
+
control: 'text',
|
|
10
|
+
description: 'Textul afișat în badge',
|
|
11
|
+
defaultValue: 'Badge',
|
|
12
|
+
},
|
|
13
|
+
color: {
|
|
14
|
+
control: 'color',
|
|
15
|
+
description: 'Culoarea de fundal a badge-ului',
|
|
16
|
+
defaultValue: '#026DFF',
|
|
17
|
+
},
|
|
18
|
+
},
|
|
19
|
+
parameters: {
|
|
20
|
+
docs: {
|
|
21
|
+
description: {
|
|
22
|
+
component: 'Un badge simplu care afișează un text cu o culoare de fundal configurabilă.',
|
|
23
|
+
},
|
|
24
|
+
},
|
|
25
|
+
},
|
|
26
|
+
};
|
|
27
|
+
|
|
28
|
+
const Template = ({ text, color }) => html`
|
|
29
|
+
<bd-badge text="${text}" color="${color}"></bd-badge>
|
|
30
|
+
`;
|
|
31
|
+
|
|
32
|
+
export const Default = Template.bind({});
|
|
33
|
+
Default.args = {
|
|
34
|
+
text: 'Badge',
|
|
35
|
+
color: '#026DFF',
|
|
36
|
+
};
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { css } from "lit";
|
|
1
|
+
import { css } from "../lit";
|
|
2
2
|
|
|
3
3
|
export default css`
|
|
4
4
|
:host {
|
|
@@ -6,6 +6,7 @@ export default css`
|
|
|
6
6
|
--background-card-grey: var(--color-neutral-25);
|
|
7
7
|
--border-card-grey: var(--color-neutral-50);
|
|
8
8
|
--bd-blue-color: var(--color-blue-500);
|
|
9
|
+
--bd-accesibility-focus: var(--color-blue-800);
|
|
9
10
|
}
|
|
10
11
|
|
|
11
12
|
.bd-carousel {
|
|
@@ -16,7 +17,11 @@ export default css`
|
|
|
16
17
|
max-width: 100%;
|
|
17
18
|
flex-direction: column;
|
|
18
19
|
}
|
|
19
|
-
|
|
20
|
+
.bd-carousel-track.dragging {
|
|
21
|
+
cursor: grabbing;
|
|
22
|
+
user-select: none;
|
|
23
|
+
}
|
|
24
|
+
|
|
20
25
|
.bd-section-title {
|
|
21
26
|
font-family: var(--font-family-sans);
|
|
22
27
|
font-weight: var(--font-weight-sans-semibold);
|
|
@@ -24,7 +29,17 @@ export default css`
|
|
|
24
29
|
}
|
|
25
30
|
div.bd-arrow {
|
|
26
31
|
padding: var(--size-2);
|
|
32
|
+
visibility: visible;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
.bd-box:focus-visible,
|
|
36
|
+
.bd-arrow:focus-visible,
|
|
37
|
+
.bd-plus-button:focus-visible,
|
|
38
|
+
.bd-modal-content button:focus-visible {
|
|
39
|
+
outline: var(--size-2) solid var(--bd-accesibility-focus);
|
|
40
|
+
outline-offset: var(--size-2);
|
|
27
41
|
}
|
|
42
|
+
|
|
28
43
|
.bd-header-carousel {
|
|
29
44
|
display: block;
|
|
30
45
|
align-items: center;
|
|
@@ -57,42 +72,42 @@ export default css`
|
|
|
57
72
|
}
|
|
58
73
|
|
|
59
74
|
.bd-left-arrow {
|
|
60
|
-
content: url("
|
|
75
|
+
content: url("icons/left_normal.png");
|
|
61
76
|
}
|
|
62
77
|
|
|
63
78
|
.bd-left-arrow:hover {
|
|
64
|
-
content: url("
|
|
79
|
+
content: url("icons/left_hover.png");
|
|
65
80
|
}
|
|
66
81
|
|
|
67
82
|
.bd-left-arrow:active {
|
|
68
|
-
content: url("
|
|
83
|
+
content: url("icons/left_clicked.png");
|
|
69
84
|
}
|
|
70
85
|
|
|
71
86
|
.bd-left-arrow:disabled {
|
|
72
|
-
content: url("
|
|
87
|
+
content: url("icons/left_disabled.png");
|
|
73
88
|
}
|
|
74
89
|
|
|
75
90
|
.bd-right-arrow {
|
|
76
|
-
content: url("
|
|
91
|
+
content: url("icons/right_normal.png");
|
|
77
92
|
}
|
|
78
93
|
|
|
79
94
|
.bd-right-arrow:hover {
|
|
80
|
-
content: url("
|
|
95
|
+
content: url("icons/right_hover.png");
|
|
81
96
|
}
|
|
82
97
|
|
|
83
98
|
.bd-right-arrow:active {
|
|
84
|
-
content: url("
|
|
99
|
+
content: url("icons/right_clicked.png");
|
|
85
100
|
}
|
|
86
101
|
|
|
87
102
|
.bd-right-arrow:disabled {
|
|
88
|
-
content: url("
|
|
103
|
+
content: url("icons/right_disabled.png");
|
|
89
104
|
}
|
|
90
105
|
.bd-right-arrow.bd-disabled {
|
|
91
|
-
content: url("
|
|
106
|
+
content: url("icons/right_disabled.png");
|
|
92
107
|
cursor: not-allowed;
|
|
93
108
|
}
|
|
94
109
|
.bd-left-arrow.bd-disabled {
|
|
95
|
-
content: url("
|
|
110
|
+
content: url("icons/left_disabled.png");
|
|
96
111
|
cursor: not-allowed;
|
|
97
112
|
}
|
|
98
113
|
.bd-disabled {
|
|
@@ -112,14 +127,12 @@ export default css`
|
|
|
112
127
|
.bd-carousel-track {
|
|
113
128
|
display: flex;
|
|
114
129
|
gap: 2em;
|
|
115
|
-
scroll-behavior: smooth;
|
|
116
130
|
flex: 1;
|
|
117
131
|
padding: var(--size-0) var(--size-20);
|
|
118
132
|
position: relative;
|
|
119
133
|
overflow-x: hidden;
|
|
120
134
|
overflow-y: hidden;
|
|
121
135
|
z-index: 1;
|
|
122
|
-
scroll-behavior: smooth;
|
|
123
136
|
scroll-snap-type: x mandatory;
|
|
124
137
|
-webkit-overflow-scrolling: touch;
|
|
125
138
|
transition: scroll-snap-align 0.6s cubic-bezier(0.23, 1, 0.32, 1);
|
|
@@ -127,7 +140,6 @@ export default css`
|
|
|
127
140
|
|
|
128
141
|
.bd-carousel-icon {
|
|
129
142
|
position: relative;
|
|
130
|
-
bottom: 30px;
|
|
131
143
|
max-width: 100%;
|
|
132
144
|
height: var(--size-40);
|
|
133
145
|
width: var(--size-40);
|
|
@@ -155,7 +167,7 @@ export default css`
|
|
|
155
167
|
text-align: start;
|
|
156
168
|
cursor: pointer;
|
|
157
169
|
transition: transform 0.2s ease-in-out;
|
|
158
|
-
|
|
170
|
+
font-family: var(--font-family-sans);
|
|
159
171
|
position: relative;
|
|
160
172
|
z-index: 2;
|
|
161
173
|
}
|
|
@@ -222,7 +234,7 @@ export default css`
|
|
|
222
234
|
}
|
|
223
235
|
|
|
224
236
|
.bd-plus-button {
|
|
225
|
-
content: url("
|
|
237
|
+
content: url("icons/more_normal.png");
|
|
226
238
|
position: absolute;
|
|
227
239
|
bottom: var(--size-10);
|
|
228
240
|
right: var(--size-10);
|
|
@@ -238,10 +250,15 @@ export default css`
|
|
|
238
250
|
cursor: pointer;
|
|
239
251
|
}
|
|
240
252
|
.bd-plus-button:hover {
|
|
241
|
-
content: url("
|
|
253
|
+
content: url("icons/more_hover.png");
|
|
242
254
|
}
|
|
255
|
+
|
|
256
|
+
bd-carousel-item::part(content) {
|
|
257
|
+
font-family: var(--font-family-sans);
|
|
258
|
+
}
|
|
259
|
+
|
|
243
260
|
.bd-plus-button:active {
|
|
244
|
-
content: url("
|
|
261
|
+
content: url("icons/more_pressed.png");
|
|
245
262
|
}
|
|
246
263
|
|
|
247
264
|
.bd-left-arrow {
|
|
@@ -1,20 +1,31 @@
|
|
|
1
1
|
import { LitElement, html } from "lit";
|
|
2
2
|
import carouselCSS from "../carousel/carousel.css.js";
|
|
3
3
|
|
|
4
|
-
class CarouselItem extends LitElement {
|
|
4
|
+
export class CarouselItem extends LitElement {
|
|
5
5
|
static properties = {
|
|
6
|
+
icon: { type: String },
|
|
6
7
|
title: { type: String },
|
|
7
|
-
subTitle: { type: String },
|
|
8
8
|
modalText: { type: String },
|
|
9
|
-
icon: { type: String },
|
|
10
9
|
};
|
|
11
10
|
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
11
|
+
_onKeydown(event) {
|
|
12
|
+
if (event.key === "Enter" || event.key === " ") {
|
|
13
|
+
this._openModal();
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
_openModal() {
|
|
18
|
+
this.dispatchEvent(
|
|
19
|
+
new CustomEvent("open-modal", {
|
|
20
|
+
detail: {
|
|
21
|
+
title: this.title,
|
|
22
|
+
modalText: this.modalText,
|
|
23
|
+
icon: this.icon,
|
|
24
|
+
},
|
|
25
|
+
bubbles: true,
|
|
26
|
+
composed: true,
|
|
27
|
+
})
|
|
28
|
+
);
|
|
18
29
|
}
|
|
19
30
|
|
|
20
31
|
render() {
|
|
@@ -23,53 +34,52 @@ class CarouselItem extends LitElement {
|
|
|
23
34
|
${this.icon
|
|
24
35
|
? html`<img src="${this.icon}" alt="icon" class="bd-carousel-icon" />`
|
|
25
36
|
: ""}
|
|
26
|
-
|
|
27
|
-
|
|
37
|
+
<div class="bd-content">
|
|
38
|
+
<slot></slot>
|
|
39
|
+
</div>
|
|
28
40
|
<div
|
|
29
41
|
class="bd-plus-button"
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
bubbles: true,
|
|
39
|
-
composed: true,
|
|
40
|
-
})
|
|
41
|
-
)}"
|
|
42
|
-
></div>
|
|
42
|
+
role="button"
|
|
43
|
+
aria-label="Open modal for ${this.title}"
|
|
44
|
+
@click="${this._openModal}"
|
|
45
|
+
@keydown="${this._onKeydown}"
|
|
46
|
+
tabindex="0"
|
|
47
|
+
>
|
|
48
|
+
+
|
|
49
|
+
</div>
|
|
43
50
|
</div>
|
|
44
51
|
`;
|
|
45
52
|
}
|
|
53
|
+
|
|
54
|
+
static styles = [carouselCSS];
|
|
46
55
|
}
|
|
47
56
|
|
|
48
57
|
class CustomCarousel extends LitElement {
|
|
49
58
|
static properties = {
|
|
59
|
+
title: { type: String },
|
|
50
60
|
selectedItem: { type: Object },
|
|
51
61
|
};
|
|
52
62
|
|
|
53
63
|
constructor() {
|
|
54
64
|
super();
|
|
55
65
|
this.selectedItem = null;
|
|
66
|
+
this.title = "";
|
|
56
67
|
}
|
|
57
68
|
|
|
58
69
|
firstUpdated() {
|
|
59
|
-
|
|
60
|
-
|
|
70
|
+
this.track = this.shadowRoot.querySelector(".bd-carousel-track");
|
|
71
|
+
this.slotElement = this.shadowRoot.querySelector("slot");
|
|
72
|
+
this.leftArrow = this.shadowRoot.querySelector(".bd-left-arrow");
|
|
73
|
+
this.rightArrow = this.shadowRoot.querySelector(".bd-right-arrow");
|
|
61
74
|
|
|
62
|
-
|
|
63
|
-
track.addEventListener("scroll", () => this.updateArrowStates());
|
|
75
|
+
this.track.addEventListener("scroll", () => this.updateArrowStates());
|
|
64
76
|
|
|
65
|
-
|
|
66
|
-
slot.addEventListener("slotchange", () => {
|
|
77
|
+
this.slotElement.addEventListener("slotchange", () => {
|
|
67
78
|
this.waitForImagesToLoad().then(() => {
|
|
68
79
|
this.updateArrowStates();
|
|
69
80
|
});
|
|
70
81
|
});
|
|
71
82
|
|
|
72
|
-
// Așteaptă un layout complet înainte de prima verificare
|
|
73
83
|
setTimeout(() => {
|
|
74
84
|
this.waitForImagesToLoad().then(() => {
|
|
75
85
|
this.updateArrowStates();
|
|
@@ -78,92 +88,65 @@ class CustomCarousel extends LitElement {
|
|
|
78
88
|
|
|
79
89
|
const arrows = this.shadowRoot.querySelectorAll(".bd-arrow");
|
|
80
90
|
arrows.forEach((arrow) => {
|
|
81
|
-
arrow.addEventListener("mousedown", () =>
|
|
82
|
-
|
|
83
|
-
);
|
|
84
|
-
arrow.addEventListener("
|
|
85
|
-
arrow.classList.remove("bd-active")
|
|
86
|
-
);
|
|
87
|
-
arrow.addEventListener("mouseleave", () =>
|
|
88
|
-
arrow.classList.remove("bd-active")
|
|
89
|
-
);
|
|
91
|
+
arrow.addEventListener("mousedown", () => arrow.classList.add("bd-active"));
|
|
92
|
+
arrow.addEventListener("mouseup", () => arrow.classList.remove("bd-active"));
|
|
93
|
+
arrow.addEventListener("mouseleave", () => arrow.classList.remove("bd-active"));
|
|
94
|
+
arrow.addEventListener("keydown", (e) => this._onArrowKeydown(e, arrow));
|
|
90
95
|
});
|
|
91
96
|
|
|
92
97
|
this.addEventListener("open-modal", (e) => this.openModal(e.detail));
|
|
98
|
+
this.enableDragAndTouchScroll(this.track);
|
|
93
99
|
}
|
|
94
100
|
|
|
95
101
|
waitForImagesToLoad() {
|
|
96
|
-
const assignedElements = this.
|
|
97
|
-
.querySelector("slot")
|
|
98
|
-
.assignedElements({ flatten: true });
|
|
99
|
-
|
|
102
|
+
const assignedElements = this.slotElement.assignedElements({ flatten: true });
|
|
100
103
|
const images = assignedElements
|
|
101
104
|
.map((el) => el.shadowRoot?.querySelector("img"))
|
|
102
105
|
.filter((img) => img);
|
|
103
|
-
|
|
104
106
|
const promises = images.map(
|
|
105
107
|
(img) =>
|
|
106
108
|
new Promise((resolve) => {
|
|
107
|
-
if (img.complete)
|
|
108
|
-
|
|
109
|
-
} else {
|
|
109
|
+
if (img.complete) resolve();
|
|
110
|
+
else {
|
|
110
111
|
img.addEventListener("load", resolve, { once: true });
|
|
111
|
-
img.addEventListener("error", resolve, { once: true });
|
|
112
|
+
img.addEventListener("error", resolve, { once: true });
|
|
112
113
|
}
|
|
113
114
|
})
|
|
114
115
|
);
|
|
115
|
-
|
|
116
116
|
return Promise.all(promises);
|
|
117
117
|
}
|
|
118
118
|
|
|
119
119
|
scrollCarousel(direction) {
|
|
120
|
-
const
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
if (!assignedElements.length) {
|
|
124
|
-
console.warn("No items found in slot!");
|
|
125
|
-
return;
|
|
126
|
-
}
|
|
127
|
-
|
|
120
|
+
const assignedElements = this.slotElement.assignedElements({ flatten: true });
|
|
121
|
+
if (!assignedElements.length) return;
|
|
128
122
|
const itemWidth = assignedElements[0].offsetWidth || 300;
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
if (!track) {
|
|
132
|
-
console.warn("No track found!");
|
|
133
|
-
return;
|
|
134
|
-
}
|
|
123
|
+
if (!this.track) return;
|
|
135
124
|
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
}
|
|
125
|
+
this.track.scrollBy({
|
|
126
|
+
left: direction === "left" ? -itemWidth : itemWidth,
|
|
127
|
+
behavior: "smooth",
|
|
128
|
+
});
|
|
141
129
|
|
|
142
|
-
// Așteaptă animația scroll-ului și actualizează săgețile
|
|
143
130
|
setTimeout(() => this.updateArrowStates(), 300);
|
|
144
131
|
}
|
|
145
132
|
|
|
146
133
|
updateArrowStates() {
|
|
147
|
-
const
|
|
148
|
-
const
|
|
149
|
-
const
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
leftArrow.classList.add("bd-disabled");
|
|
159
|
-
} else {
|
|
160
|
-
leftArrow.classList.remove("bd-disabled");
|
|
161
|
-
}
|
|
134
|
+
const trackWidth = this.track.offsetWidth;
|
|
135
|
+
const totalWidth = this.track.scrollWidth;
|
|
136
|
+
const scrollPosition = this.track.scrollLeft;
|
|
137
|
+
if (!this.leftArrow || !this.rightArrow) return;
|
|
138
|
+
|
|
139
|
+
this.leftArrow.classList.toggle("bd-disabled", scrollPosition <= 0);
|
|
140
|
+
this.rightArrow.classList.toggle(
|
|
141
|
+
"bd-disabled",
|
|
142
|
+
scrollPosition + trackWidth >= totalWidth - 1
|
|
143
|
+
);
|
|
144
|
+
}
|
|
162
145
|
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
146
|
+
_onArrowKeydown(e, arrow) {
|
|
147
|
+
if (e.key === "Enter" || e.key === " ") {
|
|
148
|
+
e.preventDefault();
|
|
149
|
+
arrow.click();
|
|
167
150
|
}
|
|
168
151
|
}
|
|
169
152
|
|
|
@@ -175,52 +158,119 @@ class CustomCarousel extends LitElement {
|
|
|
175
158
|
this.selectedItem = null;
|
|
176
159
|
}
|
|
177
160
|
|
|
161
|
+
enableDragAndTouchScroll(element) {
|
|
162
|
+
let isDown = false;
|
|
163
|
+
let startX;
|
|
164
|
+
let scrollLeft;
|
|
165
|
+
|
|
166
|
+
element.addEventListener("mousedown", (e) => {
|
|
167
|
+
isDown = true;
|
|
168
|
+
element.classList.add("dragging");
|
|
169
|
+
startX = e.pageX - element.offsetLeft;
|
|
170
|
+
scrollLeft = element.scrollLeft;
|
|
171
|
+
});
|
|
172
|
+
|
|
173
|
+
element.addEventListener("mouseleave", () => {
|
|
174
|
+
isDown = false;
|
|
175
|
+
element.classList.remove("dragging");
|
|
176
|
+
});
|
|
177
|
+
|
|
178
|
+
element.addEventListener("mouseup", () => {
|
|
179
|
+
isDown = false;
|
|
180
|
+
element.classList.remove("dragging");
|
|
181
|
+
});
|
|
182
|
+
|
|
183
|
+
element.addEventListener("mousemove", (e) => {
|
|
184
|
+
if (!isDown) return;
|
|
185
|
+
e.preventDefault();
|
|
186
|
+
const x = e.pageX - element.offsetLeft;
|
|
187
|
+
const walk = (x - startX) * 1.5;
|
|
188
|
+
element.scrollLeft = scrollLeft - walk;
|
|
189
|
+
});
|
|
190
|
+
|
|
191
|
+
element.addEventListener("touchstart", (e) => {
|
|
192
|
+
isDown = true;
|
|
193
|
+
startX = e.touches[0].pageX - element.offsetLeft;
|
|
194
|
+
scrollLeft = element.scrollLeft;
|
|
195
|
+
});
|
|
196
|
+
|
|
197
|
+
element.addEventListener("touchend", () => {
|
|
198
|
+
isDown = false;
|
|
199
|
+
});
|
|
200
|
+
|
|
201
|
+
element.addEventListener("touchmove", (e) => {
|
|
202
|
+
if (!isDown) return;
|
|
203
|
+
const x = e.touches[0].pageX - element.offsetLeft;
|
|
204
|
+
const walk = (x - startX) * 1.5;
|
|
205
|
+
element.scrollLeft = scrollLeft - walk;
|
|
206
|
+
});
|
|
207
|
+
}
|
|
208
|
+
|
|
178
209
|
render() {
|
|
179
210
|
return html`
|
|
180
211
|
<div class="bd-carousel">
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
212
|
+
${this.title
|
|
213
|
+
? html`<div class="bd-header-carousel">
|
|
214
|
+
<h1 class="bd-section-title">${this.title}</h1>
|
|
215
|
+
</div>`
|
|
216
|
+
: ""}
|
|
217
|
+
|
|
184
218
|
<img
|
|
219
|
+
src="left-arrow.svg"
|
|
185
220
|
alt="Left Arrow"
|
|
186
221
|
class="bd-arrow bd-left-arrow"
|
|
222
|
+
role="button"
|
|
223
|
+
aria-label="Scroll left"
|
|
187
224
|
@click="${() => this.scrollCarousel("left")}"
|
|
225
|
+
tabindex="0"
|
|
188
226
|
/>
|
|
189
227
|
<div class="bd-carousel-track">
|
|
190
228
|
<slot></slot>
|
|
191
229
|
</div>
|
|
192
230
|
<img
|
|
231
|
+
src="right-arrow.svg"
|
|
193
232
|
alt="Right Arrow"
|
|
194
233
|
class="bd-arrow bd-right-arrow"
|
|
234
|
+
role="button"
|
|
235
|
+
aria-label="Scroll right"
|
|
195
236
|
@click="${() => this.scrollCarousel("right")}"
|
|
237
|
+
tabindex="0"
|
|
196
238
|
/>
|
|
197
239
|
</div>
|
|
198
240
|
|
|
199
241
|
${this.selectedItem
|
|
200
242
|
? html`
|
|
201
|
-
<div
|
|
243
|
+
<div
|
|
244
|
+
class="bd-modal"
|
|
245
|
+
@click="${this.closeModal}"
|
|
246
|
+
aria-hidden="${!this.selectedItem}"
|
|
247
|
+
?open="${true}"
|
|
248
|
+
>
|
|
202
249
|
<div
|
|
203
250
|
class="bd-modal-content"
|
|
204
251
|
@click="${(e) => e.stopPropagation()}"
|
|
252
|
+
aria-labelledby="modal-title"
|
|
253
|
+
aria-describedby="modal-description"
|
|
205
254
|
>
|
|
206
255
|
<img
|
|
207
256
|
src="${this.selectedItem.icon}"
|
|
208
257
|
alt="icon"
|
|
209
258
|
class="bd-carousel-modal-icon"
|
|
210
259
|
/>
|
|
211
|
-
<h2>${this.selectedItem.title}</h2>
|
|
212
|
-
<p>${this.selectedItem.modalText}</p>
|
|
213
|
-
<button @click="${this.closeModal}"
|
|
260
|
+
<h2 id="modal-title">${this.selectedItem.title}</h2>
|
|
261
|
+
<p id="modal-description">${this.selectedItem.modalText}</p>
|
|
262
|
+
<button @click="${this.closeModal}" aria-label="Close modal">
|
|
263
|
+
Close
|
|
264
|
+
</button>
|
|
214
265
|
</div>
|
|
215
266
|
</div>
|
|
216
267
|
`
|
|
217
268
|
: ""}
|
|
218
269
|
`;
|
|
219
270
|
}
|
|
220
|
-
}
|
|
221
271
|
|
|
222
|
-
|
|
223
|
-
|
|
272
|
+
static styles = [carouselCSS];
|
|
273
|
+
}
|
|
224
274
|
|
|
225
275
|
customElements.define("bd-carousel-item", CarouselItem);
|
|
226
276
|
customElements.define("bd-carousel-section", CustomCarousel);
|