@repobit/dex-system-design 0.24.4 → 0.24.6
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 +15 -0
- package/package.json +4 -4
- package/src/components/accordion/accordion.css.js +40 -0
- package/src/components/accordion/accordion.js +31 -0
- package/src/components/accordion/accordion.stories.js +147 -4
- package/src/components/agent-endpoints/agent-endpoints.css.js +92 -0
- package/src/components/agent-endpoints/agent-endpoints.js +86 -0
- package/src/components/agent-endpoints/agent-endpoints.stories.js +148 -0
- package/src/components/ai-guardian-demo.stories.js +848 -0
- package/src/components/awards/awards-flex.css.js +169 -0
- package/src/components/awards/awards-flex.js +269 -0
- package/src/components/awards/awards-flex.stories.js +657 -0
- package/src/components/bento-grid/bento-grid.css.js +57 -0
- package/src/components/bento-grid/bento-grid.js +186 -0
- package/src/components/bento-grid/bento-grid.stories.js +440 -0
- package/src/components/bento-grid/bento-item.css.js +105 -0
- package/src/components/bento-grid/bento-item.js +57 -0
- package/src/components/button/button.css.js +26 -0
- package/src/components/button/button.js +8 -0
- package/src/components/button/button.stories.js +12 -0
- package/src/components/comparison-panel/comparison-panel.css.js +104 -0
- package/src/components/comparison-panel/comparison-panel.js +100 -0
- package/src/components/comparison-panel/comparison-panel.stories.js +223 -0
- package/src/components/compatibility-table/compatibility-table.css.js +243 -0
- package/src/components/compatibility-table/compatibility-table.js +123 -0
- package/src/components/compatibility-table/compatibility-table.stories.js +189 -0
- package/src/components/cta-banner/cta-banner.css.js +60 -0
- package/src/components/cta-banner/cta-banner.js +63 -0
- package/src/components/dropdown/dropdown.css.js +1 -1
- package/src/components/footer/footer.css.js +0 -1
- package/src/components/header/header-code.css.js +125 -0
- package/src/components/header/header-code.js +69 -0
- package/src/components/header/header-code.stories.js +226 -0
- package/src/components/heading/heading.css.js +3 -0
- package/src/components/icons/bd-ai-icon.js +27 -0
- package/src/components/icons/quote-icon.js +28 -0
- package/src/components/install-options/install-options.css.js +276 -0
- package/src/components/install-options/install-options.js +184 -0
- package/src/components/list/list-item/list-item.css.js +3 -3
- package/src/components/list/list-item/list-item.js +10 -4
- package/src/components/overview/overview.css.js +121 -0
- package/src/components/overview/overview.js +63 -0
- package/src/components/overview/overview.stories.js +193 -0
- package/src/components/page-switcher/page-switcher.css.js +100 -0
- package/src/components/page-switcher/page-switcher.js +42 -0
- package/src/components/paragraph/paragraph.css.js +1 -5
- package/src/components/paragraph/paragraph.js +7 -3
- package/src/components/process-steps/process-steps.css.js +95 -0
- package/src/components/process-steps/process-steps.js +72 -0
- package/src/components/process-steps/process-steps.stories.js +144 -0
- package/src/components/quick-answer/quick-answer.css.js +67 -0
- package/src/components/quick-answer/quick-answer.js +59 -0
- package/src/components/quick-answer/quick-answer.stories.js +160 -0
- package/src/components/review/review-grid.css.js +34 -0
- package/src/components/review/review-grid.js +63 -0
- package/src/components/review/review.css.js +50 -0
- package/src/components/review/review.js +58 -0
- package/src/components/review/review.stories.js +228 -0
- package/src/components/terminal/terminal-cursor.js +49 -0
- package/src/components/terminal/terminal-message.css.js +161 -0
- package/src/components/terminal/terminal-message.js +169 -0
- package/src/components/terminal/terminal-message.stories.js +321 -0
- package/src/components/trust-panel/trust-panel.css.js +167 -0
- package/src/components/trust-panel/trust-panel.js +116 -0
- package/src/components/trust-panel/trust-panel.stories.js +234 -0
- package/src/tokens/tokens.css +1 -1
- package/src/components/tabsComponent/tabsComponent.css.js +0 -267
- package/src/components/tabsComponent/tabsComponent.js +0 -193
- package/src/components/tabsComponent/tabsComponent.stories.js +0 -134
- package/src/components/tabsComponentFamily/tabsComponentFamily.css.js +0 -181
- package/src/components/tabsComponentFamily/tabsComponentFamily.js +0 -180
- package/src/components/tabsComponentFamily/tabsComponentFamily.stories.js +0 -319
|
@@ -0,0 +1,228 @@
|
|
|
1
|
+
import { html } from "lit";
|
|
2
|
+
import "./review-grid.js";
|
|
3
|
+
import "./review.js";
|
|
4
|
+
|
|
5
|
+
export default {
|
|
6
|
+
title : "Components/Review",
|
|
7
|
+
tags : ["autodocs"],
|
|
8
|
+
parameters: {
|
|
9
|
+
layout: "padded",
|
|
10
|
+
docs : {
|
|
11
|
+
description: {
|
|
12
|
+
component: `
|
|
13
|
+
Testimonial / review card (\`bd-review\`) plus a responsive grid wrapper
|
|
14
|
+
(\`bd-review-grid\`) that auto-sizes columns from how many cards are
|
|
15
|
+
slotted in.
|
|
16
|
+
|
|
17
|
+
\`\`\`html
|
|
18
|
+
<bd-review-grid title="What They Say">
|
|
19
|
+
<bd-review variant="tint">
|
|
20
|
+
<span slot="quote">If you're looking to buy a security suite, our experts and readers agree: Bitdefender should be your top choice.</span>
|
|
21
|
+
<span slot="source">PCMag</span>
|
|
22
|
+
<span slot="date">February 3, 2026</span>
|
|
23
|
+
</bd-review>
|
|
24
|
+
|
|
25
|
+
<bd-review variant="tint">
|
|
26
|
+
<span slot="quote">Bitdefender Premium Security combines award-winning security with a scam-detection chatbot, server-level email protection, and a VPN with no bandwidth or server limits.</span>
|
|
27
|
+
<span slot="source">PCMag</span>
|
|
28
|
+
<span slot="date">April 20, 2026</span>
|
|
29
|
+
</bd-review>
|
|
30
|
+
</bd-review-grid>
|
|
31
|
+
\`\`\`
|
|
32
|
+
|
|
33
|
+
### Column count (bd-review-grid)
|
|
34
|
+
Derived automatically from how many \`bd-review\` children are slotted in,
|
|
35
|
+
capped at 3 per row — extra cards wrap onto further rows at 3-per-row:
|
|
36
|
+
|
|
37
|
+
| Cards | Columns | Each card |
|
|
38
|
+
|---|---|---|
|
|
39
|
+
| 1 | 1 | full width ("col-md-12") |
|
|
40
|
+
| 2 | 2 | half each ("col-md-6") |
|
|
41
|
+
| 3+ | 3 | third each ("col-md-4") |
|
|
42
|
+
|
|
43
|
+
Below the md breakpoint (899px), every count collapses to a single column.
|
|
44
|
+
|
|
45
|
+
### Attributes \`bd-review\`
|
|
46
|
+
| Attribute | Type | Default | Description |
|
|
47
|
+
|---|---|---|---|
|
|
48
|
+
| \`variant\` | String | \`"tint"\` | \`"tint"\` (light blue) or \`"neutral"\` (light grey, #fafafa) |
|
|
49
|
+
|
|
50
|
+
### Slots \`bd-review\`
|
|
51
|
+
| Slot | Description |
|
|
52
|
+
|---|---|
|
|
53
|
+
| \`quote\` | The testimonial text |
|
|
54
|
+
| \`source\` | Publication / attribution (bold) |
|
|
55
|
+
| \`date\` | Date line, under the source |
|
|
56
|
+
|
|
57
|
+
### Attributes \`bd-review-grid\`
|
|
58
|
+
| Attribute | Type | Default | Description |
|
|
59
|
+
|---|---|---|---|
|
|
60
|
+
| \`title\` | String | — | Optional centred heading above the grid |
|
|
61
|
+
`
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
};
|
|
66
|
+
|
|
67
|
+
// ─── Un singur card (full width) ──────────────────────────────────────────
|
|
68
|
+
|
|
69
|
+
export const OneCard = {
|
|
70
|
+
name : "1 card — full width",
|
|
71
|
+
render: () => html`
|
|
72
|
+
<bd-review-grid title="What They Say">
|
|
73
|
+
<bd-review variant="tint">
|
|
74
|
+
<span slot="quote">If you're looking to buy a security suite, our experts and readers agree: Bitdefender should be your top choice.</span>
|
|
75
|
+
<span slot="source">PCMag</span>
|
|
76
|
+
<span slot="date">February 3, 2026</span>
|
|
77
|
+
</bd-review>
|
|
78
|
+
</bd-review-grid>
|
|
79
|
+
`
|
|
80
|
+
};
|
|
81
|
+
|
|
82
|
+
// ─── Doua carduri (jumatate fiecare) ──────────────────────────────────────
|
|
83
|
+
|
|
84
|
+
export const TwoCards = {
|
|
85
|
+
name : "2 carduri — jumătate fiecare",
|
|
86
|
+
render: () => html`
|
|
87
|
+
<bd-review-grid title="What They Say">
|
|
88
|
+
<bd-review variant="tint">
|
|
89
|
+
<span slot="quote">If you're looking to buy a security suite, our experts and readers agree: Bitdefender should be your top choice.</span>
|
|
90
|
+
<span slot="source">PCMag</span>
|
|
91
|
+
<span slot="date">February 3, 2026</span>
|
|
92
|
+
</bd-review>
|
|
93
|
+
|
|
94
|
+
<bd-review variant="tint">
|
|
95
|
+
<span slot="quote">Bitdefender Premium Security combines award-winning security with a scam-detection chatbot, server-level email protection, and a VPN with no bandwidth or server limits.</span>
|
|
96
|
+
<span slot="source">PCMag</span>
|
|
97
|
+
<span slot="date">April 20, 2026</span>
|
|
98
|
+
</bd-review>
|
|
99
|
+
</bd-review-grid>
|
|
100
|
+
`
|
|
101
|
+
};
|
|
102
|
+
|
|
103
|
+
// ─── Trei carduri (o treime fiecare) ──────────────────────────────────────
|
|
104
|
+
|
|
105
|
+
export const ThreeCards = {
|
|
106
|
+
name : "3 carduri — o treime fiecare",
|
|
107
|
+
render: () => html`
|
|
108
|
+
<bd-review-grid title="What They Say">
|
|
109
|
+
<bd-review variant="tint">
|
|
110
|
+
<span slot="quote">If you're looking to buy a security suite, our experts and readers agree: Bitdefender should be your top choice.</span>
|
|
111
|
+
<span slot="source">PCMag</span>
|
|
112
|
+
<span slot="date">February 3, 2026</span>
|
|
113
|
+
</bd-review>
|
|
114
|
+
|
|
115
|
+
<bd-review variant="neutral">
|
|
116
|
+
<span slot="quote">Bitdefender Premium Security combines award-winning security with a scam-detection chatbot, server-level email protection, and a VPN with no bandwidth or server limits.</span>
|
|
117
|
+
<span slot="source">PCMag</span>
|
|
118
|
+
<span slot="date">April 20, 2026</span>
|
|
119
|
+
</bd-review>
|
|
120
|
+
|
|
121
|
+
<bd-review variant="tint">
|
|
122
|
+
<span slot="quote">Consistently top-ranked by the world's leading independent testing labs and tech publications.</span>
|
|
123
|
+
<span slot="source">AV-Comparatives</span>
|
|
124
|
+
<span slot="date">June 12, 2026</span>
|
|
125
|
+
</bd-review>
|
|
126
|
+
</bd-review-grid>
|
|
127
|
+
`
|
|
128
|
+
};
|
|
129
|
+
|
|
130
|
+
// ─── Cinci carduri (wrap la 3 pe rand) ────────────────────────────────────
|
|
131
|
+
|
|
132
|
+
export const FiveCardsWrapping = {
|
|
133
|
+
name : "5 carduri — se leagă la maxim 3 pe rând",
|
|
134
|
+
parameters: {
|
|
135
|
+
docs: {
|
|
136
|
+
description: {
|
|
137
|
+
story: "Peste 3 carduri, grid-ul rămâne la 3 coloane și cardurile suplimentare trec pe rândul următor, tot la o treime fiecare — regula \"maxim 3 pe rând\" se aplică indiferent de câte carduri sunt slotate."
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
},
|
|
141
|
+
render: () => html`
|
|
142
|
+
<bd-review-grid title="What They Say">
|
|
143
|
+
${[1, 2, 3, 4, 5].map(
|
|
144
|
+
(n) => html`
|
|
145
|
+
<bd-review variant=${n % 2 === 0 ? "neutral" : "tint"}>
|
|
146
|
+
<span slot="quote">Review number ${n} — placeholder testimonial text to show how the grid wraps once more than three cards are slotted in.</span>
|
|
147
|
+
<span slot="source">Publication ${n}</span>
|
|
148
|
+
<span slot="date">2026</span>
|
|
149
|
+
</bd-review>
|
|
150
|
+
`
|
|
151
|
+
)}
|
|
152
|
+
</bd-review-grid>
|
|
153
|
+
`
|
|
154
|
+
};
|
|
155
|
+
|
|
156
|
+
// ─── Text mai lung (verifica wrapping și înălțimea egală pe rând) ─────────
|
|
157
|
+
|
|
158
|
+
export const LongQuotes = {
|
|
159
|
+
name : "Text mai lung — wrapping și înălțime egală",
|
|
160
|
+
parameters: {
|
|
161
|
+
docs: {
|
|
162
|
+
description: {
|
|
163
|
+
story: "Citate mult mai lungi decât în exemplele scurte, ca să se vadă comportarea reală a cardurilor: textul se leagă pe mai multe rânduri, iar cardurile de pe același rând rămân la aceeași înălțime (citatul se întinde cu flex-grow, meta-ul rămâne lipit de jos)."
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
},
|
|
167
|
+
render: () => html`
|
|
168
|
+
<bd-review-grid title="What They Say">
|
|
169
|
+
<bd-review variant="tint">
|
|
170
|
+
<span slot="quote">If you're looking to buy a security suite, our experts and readers agree: Bitdefender should be your top choice. It combines consistently excellent malware protection with a surprisingly light footprint on system performance, and the extras — VPN, password manager, parental controls — are genuinely useful rather than bolted-on filler.</span>
|
|
171
|
+
<span slot="source">PCMag</span>
|
|
172
|
+
<span slot="date">February 3, 2026</span>
|
|
173
|
+
</bd-review>
|
|
174
|
+
|
|
175
|
+
<bd-review variant="neutral">
|
|
176
|
+
<span slot="quote">Bitdefender Premium Security combines award-winning security with a scam-detection chatbot, server-level email protection, and a VPN with no bandwidth or server limits. In our testing across three months and multiple platforms, it caught every real-world threat we threw at it without a single false positive on legitimate software.</span>
|
|
177
|
+
<span slot="source">PCMag</span>
|
|
178
|
+
<span slot="date">April 20, 2026</span>
|
|
179
|
+
</bd-review>
|
|
180
|
+
|
|
181
|
+
<bd-review variant="tint">
|
|
182
|
+
<span slot="quote">Consistently top-ranked by the world's leading independent testing labs and tech publications, year after year, across every category we measure: protection, performance, usability, and — increasingly relevant for households with kids — how well it handles parental controls without becoming a nuisance to manage.</span>
|
|
183
|
+
<span slot="source">AV-Comparatives</span>
|
|
184
|
+
<span slot="date">June 12, 2026</span>
|
|
185
|
+
</bd-review>
|
|
186
|
+
</bd-review-grid>
|
|
187
|
+
`
|
|
188
|
+
};
|
|
189
|
+
|
|
190
|
+
// ─── Text mai lung, doar doua carduri (verifica jumatate-jumatate) ────────
|
|
191
|
+
|
|
192
|
+
export const LongQuotesTwoCards = {
|
|
193
|
+
name : "Text mai lung — 2 carduri",
|
|
194
|
+
render: () => html`
|
|
195
|
+
<bd-review-grid title="What They Say">
|
|
196
|
+
<bd-review variant="tint">
|
|
197
|
+
<span slot="quote">If you're looking to buy a security suite, our experts and readers agree: Bitdefender should be your top choice. It combines consistently excellent malware protection with a surprisingly light footprint on system performance.</span>
|
|
198
|
+
<span slot="source">PCMag</span>
|
|
199
|
+
<span slot="date">February 3, 2026</span>
|
|
200
|
+
</bd-review>
|
|
201
|
+
|
|
202
|
+
<bd-review variant="neutral">
|
|
203
|
+
<span slot="quote">Bitdefender Premium Security combines award-winning security with a scam-detection chatbot, server-level email protection, and a VPN with no bandwidth or server limits — a genuinely complete package rather than a marketing checklist.</span>
|
|
204
|
+
<span slot="source">PCMag</span>
|
|
205
|
+
<span slot="date">April 20, 2026</span>
|
|
206
|
+
</bd-review>
|
|
207
|
+
</bd-review-grid>
|
|
208
|
+
`
|
|
209
|
+
};
|
|
210
|
+
|
|
211
|
+
export const NoTitle = {
|
|
212
|
+
name : "Fără titlu",
|
|
213
|
+
render: () => html`
|
|
214
|
+
<bd-review-grid>
|
|
215
|
+
<bd-review variant="neutral">
|
|
216
|
+
<span slot="quote">If you're looking to buy a security suite, our experts and readers agree: Bitdefender should be your top choice.</span>
|
|
217
|
+
<span slot="source">PCMag</span>
|
|
218
|
+
<span slot="date">February 3, 2026</span>
|
|
219
|
+
</bd-review>
|
|
220
|
+
|
|
221
|
+
<bd-review variant="neutral">
|
|
222
|
+
<span slot="quote">Bitdefender Premium Security combines award-winning security with a scam-detection chatbot, server-level email protection, and a VPN with no bandwidth or server limits.</span>
|
|
223
|
+
<span slot="source">PCMag</span>
|
|
224
|
+
<span slot="date">April 20, 2026</span>
|
|
225
|
+
</bd-review>
|
|
226
|
+
</bd-review-grid>
|
|
227
|
+
`
|
|
228
|
+
};
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import { LitElement, css, html } from "lit";
|
|
2
|
+
import { tokens } from "../../tokens/tokens.js";
|
|
3
|
+
|
|
4
|
+
class TerminalCursor extends LitElement {
|
|
5
|
+
static properties = {
|
|
6
|
+
color: { type: String }
|
|
7
|
+
};
|
|
8
|
+
|
|
9
|
+
static styles = [
|
|
10
|
+
tokens,
|
|
11
|
+
css`
|
|
12
|
+
:host {
|
|
13
|
+
display: inline-block;
|
|
14
|
+
width: 8px;
|
|
15
|
+
height: 16px;
|
|
16
|
+
vertical-align: middle;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
.bd-terminal-cursor {
|
|
20
|
+
width: 100%;
|
|
21
|
+
height: 100%;
|
|
22
|
+
background: var(--bd-terminal-cursor-color, var(--color-blue-400));
|
|
23
|
+
animation: bd-terminal-cursor-blink 1s steps(1) infinite;
|
|
24
|
+
display: block;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
@keyframes bd-terminal-cursor-blink {
|
|
28
|
+
0%, 50% {
|
|
29
|
+
opacity: 1;
|
|
30
|
+
}
|
|
31
|
+
50.01%, 100% {
|
|
32
|
+
opacity: 0;
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
`
|
|
36
|
+
];
|
|
37
|
+
|
|
38
|
+
constructor() {
|
|
39
|
+
super();
|
|
40
|
+
this.color = "";
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
render() {
|
|
44
|
+
const style = this.color ? `background: ${this.color};` : "";
|
|
45
|
+
return html`<span class="bd-terminal-cursor" style="${style}"></span>`;
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
customElements.define("bd-terminal-cursor", TerminalCursor);
|
|
@@ -0,0 +1,161 @@
|
|
|
1
|
+
import { css } from "lit";
|
|
2
|
+
|
|
3
|
+
export default css`
|
|
4
|
+
:host {
|
|
5
|
+
display: block;
|
|
6
|
+
font-family: var(--typography-fontFamily-mono, monospace);
|
|
7
|
+
color: var(--color-neutral-0, #fff);
|
|
8
|
+
background: #151719;
|
|
9
|
+
border-radius: var(--radius-xl, 12px);
|
|
10
|
+
padding: var(--spacing-14) var(--spacing-16) var(--spacing-32);
|
|
11
|
+
box-sizing: border-box;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
/* === TITLEBAR (traffic-light dots only, no label) === */
|
|
15
|
+
.bd-terminalmsg-titlebar {
|
|
16
|
+
display: flex;
|
|
17
|
+
align-items: center;
|
|
18
|
+
gap: var(--spacing-8);
|
|
19
|
+
padding-bottom: var(--spacing-16);
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
.bd-terminalmsg-dot {
|
|
23
|
+
width: var(--spacing-8);
|
|
24
|
+
height: var(--spacing-8);
|
|
25
|
+
border-radius: 50%;
|
|
26
|
+
display: inline-block;
|
|
27
|
+
flex-shrink: 0;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
.bd-terminalmsg-dot--red {
|
|
31
|
+
background: #ff5f56;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
.bd-terminalmsg-dot--yellow {
|
|
35
|
+
background: #ffbd2e;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
.bd-terminalmsg-dot--green {
|
|
39
|
+
background: #27c93f;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
/* === PANEL === */
|
|
43
|
+
.bd-terminalmsg-panel {
|
|
44
|
+
position: relative;
|
|
45
|
+
border: 1px solid rgba(255, 255, 255, 0.12);
|
|
46
|
+
border-radius: var(--radius-lg, 10px);
|
|
47
|
+
padding: var(--spacing-20) var(--spacing-20) calc(var(--spacing-20) + var(--spacing-8));
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
/* Top "legend": text sitting on the top border line, background matching the
|
|
51
|
+
panel's own bg color masks the border behind the text. */
|
|
52
|
+
.bd-terminalmsg-panel-label {
|
|
53
|
+
position: absolute;
|
|
54
|
+
top: 0;
|
|
55
|
+
left: var(--spacing-16);
|
|
56
|
+
transform: translateY(-50%);
|
|
57
|
+
background: #151719;
|
|
58
|
+
padding: 0 var(--spacing-8);
|
|
59
|
+
color: rgba(255, 255, 255, 0.4);
|
|
60
|
+
font-family: var(--typography-fontFamily-mono, monospace);
|
|
61
|
+
font-size: var(--typography-fontSize-xs);
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
.bd-terminalmsg-body {
|
|
65
|
+
font-size: var(--typography-fontSize-sm);
|
|
66
|
+
line-height: var(--typography-lineHeight-normal);
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
.bd-terminalmsg-greeting-text {
|
|
70
|
+
color: var(--color-blue-400, #7ab8ff);
|
|
71
|
+
font-weight: var(--typography-fontWeight-bold);
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
.bd-terminalmsg-intro {
|
|
75
|
+
color: var(--color-neutral-0, #fff);
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
.bd-terminalmsg-list {
|
|
79
|
+
display: block;
|
|
80
|
+
padding-left: var(--spacing-16);
|
|
81
|
+
margin: 0 0 var(--spacing-12);
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
.bd-terminalmsg-footer {
|
|
85
|
+
color: var(--color-neutral-0, #fff);
|
|
86
|
+
margin: 0;
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
/* === HINT ("legend" sitting on the bottom border line, mirrors panel-label) === */
|
|
90
|
+
.bd-terminalmsg-hint {
|
|
91
|
+
position: absolute;
|
|
92
|
+
bottom: 0;
|
|
93
|
+
left: var(--spacing-16);
|
|
94
|
+
transform: translateY(50%);
|
|
95
|
+
background: #151719;
|
|
96
|
+
padding: 0 var(--spacing-8);
|
|
97
|
+
color: rgba(255, 255, 255, 0.5);
|
|
98
|
+
font-family: var(--typography-fontFamily-mono, monospace);
|
|
99
|
+
font-size: var(--typography-fontSize-xs);
|
|
100
|
+
white-space: nowrap;
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
/* Bracketed key labels inside the hint (e.g. "[Enter]", "[esc]") — bold + white,
|
|
104
|
+
standing out from the rest of the dimmer hint text. */
|
|
105
|
+
.bd-terminalmsg-hint-key {
|
|
106
|
+
color: #fff;
|
|
107
|
+
font-weight: var(--typography-fontWeight-bold, 700);
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
/* === TYPED-LINE API (bd-terminal-message .lines=...) ===
|
|
111
|
+
A literal sequence of terminal lines, each with its own semantic
|
|
112
|
+
color/weight — for content like:
|
|
113
|
+
$ npx skills add bitdefender/agent-skill-scanner → cmd
|
|
114
|
+
✓ agent-skill-scanner installed → ok
|
|
115
|
+
──────────────────────────────── → sep
|
|
116
|
+
> scan the my-skill skill for security risks → ask
|
|
117
|
+
──────────────────────────────── → sep
|
|
118
|
+
# Skill Scan: my-skill → strong
|
|
119
|
+
- Severity: CLEAN → dim
|
|
120
|
+
- Scan Date: 2026-06-15 → dim
|
|
121
|
+
No security findings detected. → dim
|
|
122
|
+
*/
|
|
123
|
+
.bd-terminalmsg-lines {
|
|
124
|
+
display: block;
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
.bd-terminalmsg-l-cmd {
|
|
128
|
+
color: var(--color-neutral-0, #fff);
|
|
129
|
+
font-weight: var(--typography-fontWeight-bold, 700);
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
.bd-terminalmsg-l-ok {
|
|
133
|
+
color: #27c93f;
|
|
134
|
+
padding-bottom: var(--spacing-12);
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
.bd-terminalmsg-l-ask {
|
|
138
|
+
color: var(--color-blue-400, #7ab8ff);
|
|
139
|
+
padding: var(--spacing-12) 0;
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
.bd-terminalmsg-l-strong {
|
|
143
|
+
color: var(--color-neutral-0, #fff);
|
|
144
|
+
font-weight: var(--typography-fontWeight-bold, 700);
|
|
145
|
+
padding-top: var(--spacing-12);
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
.bd-terminalmsg-l-dim {
|
|
149
|
+
color: rgba(255, 255, 255, 0.5);
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
.bd-terminalmsg-l-space {
|
|
153
|
+
height: var(--spacing-12);
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
.bd-terminalmsg-l-sep {
|
|
157
|
+
border: none;
|
|
158
|
+
border-top: 1px solid rgba(255, 255, 255, 0.12);
|
|
159
|
+
margin: var(--spacing-8) 0;
|
|
160
|
+
}
|
|
161
|
+
`;
|
|
@@ -0,0 +1,169 @@
|
|
|
1
|
+
import { LitElement, html, nothing } from "lit";
|
|
2
|
+
import { tokens } from "../../tokens/tokens.js";
|
|
3
|
+
import "../heading/heading.js";
|
|
4
|
+
import "../list/list-item/list-item.js";
|
|
5
|
+
import "../list/list.js";
|
|
6
|
+
import "../paragraph/paragraph.js";
|
|
7
|
+
import "./terminal-cursor.js";
|
|
8
|
+
import terminalMessageCSS from "./terminal-message.css.js";
|
|
9
|
+
|
|
10
|
+
class TerminalMessage extends LitElement {
|
|
11
|
+
static properties = {
|
|
12
|
+
showTitlebar: { type: Boolean, attribute: "show-titlebar" },
|
|
13
|
+
panelLabel : { type: String, attribute: "panel-label" },
|
|
14
|
+
dimText : { type: String, attribute: "dim-text" },
|
|
15
|
+
greeting : { type: String },
|
|
16
|
+
icon : { type: String },
|
|
17
|
+
intro : { type: String },
|
|
18
|
+
items : { type: Array },
|
|
19
|
+
footer : { type: String },
|
|
20
|
+
footerBold : { type: String, attribute: "footer-bold" },
|
|
21
|
+
showCursor : { type: Boolean, attribute: "show-cursor" },
|
|
22
|
+
hint : { type: String },
|
|
23
|
+
// New: raw typed-line API, for terminals that are a literal sequence of
|
|
24
|
+
// command/result lines (unlike greeting/intro/items, which model a
|
|
25
|
+
// single chat-style message). Each entry: { type, text }.
|
|
26
|
+
// type: "cmd" | "ok" | "ask" | "strong" | "dim" | "sep" | "space"
|
|
27
|
+
// "sep" and "space" ignore `text`.
|
|
28
|
+
lines : { type: Array }
|
|
29
|
+
};
|
|
30
|
+
|
|
31
|
+
static styles = [tokens, terminalMessageCSS];
|
|
32
|
+
|
|
33
|
+
constructor() {
|
|
34
|
+
super();
|
|
35
|
+
this.showTitlebar = false;
|
|
36
|
+
this.panelLabel = "";
|
|
37
|
+
this.dimText = "";
|
|
38
|
+
this.greeting = "";
|
|
39
|
+
this.icon = "";
|
|
40
|
+
this.intro = "";
|
|
41
|
+
this.items = [];
|
|
42
|
+
this.footer = "";
|
|
43
|
+
this.footerBold = "";
|
|
44
|
+
this.showCursor = false;
|
|
45
|
+
this.hint = "";
|
|
46
|
+
this.lines = [];
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
_renderTitlebar() {
|
|
50
|
+
if (!this.showTitlebar) return nothing;
|
|
51
|
+
return html`
|
|
52
|
+
<div class="bd-terminalmsg-titlebar">
|
|
53
|
+
<span class="bd-terminalmsg-dot bd-terminalmsg-dot--red"></span>
|
|
54
|
+
<span class="bd-terminalmsg-dot bd-terminalmsg-dot--yellow"></span>
|
|
55
|
+
<span class="bd-terminalmsg-dot bd-terminalmsg-dot--green"></span>
|
|
56
|
+
</div>
|
|
57
|
+
`;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
// Splits the hint text on bracketed key labels like "[Enter]" or "[esc]" and
|
|
61
|
+
// wraps each one in a <strong> so it renders bold + white, while the rest of
|
|
62
|
+
// the text keeps the dim hint color. Works with the plain string prop as-is —
|
|
63
|
+
// no need to pass markup through `hint`.
|
|
64
|
+
_renderHint() {
|
|
65
|
+
if (!this.hint) return nothing;
|
|
66
|
+
|
|
67
|
+
const parts = this.hint.split(/(\[[^\]]+\])/g);
|
|
68
|
+
|
|
69
|
+
return html`
|
|
70
|
+
<span class="bd-terminalmsg-hint">
|
|
71
|
+
${parts.map((part) =>
|
|
72
|
+
/^\[[^\]]+\]$/.test(part)
|
|
73
|
+
? html`<strong class="bd-terminalmsg-hint-key">${part}</strong>`
|
|
74
|
+
: part
|
|
75
|
+
)}
|
|
76
|
+
</span>
|
|
77
|
+
`;
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
_renderLines() {
|
|
81
|
+
if (!this.lines || !this.lines.length) return nothing;
|
|
82
|
+
|
|
83
|
+
return html`
|
|
84
|
+
<div class="bd-terminalmsg-lines">
|
|
85
|
+
${this.lines.map(({ type, text }) => {
|
|
86
|
+
switch (type) {
|
|
87
|
+
case "sep":
|
|
88
|
+
return html`<hr class="bd-terminalmsg-l-sep" />`;
|
|
89
|
+
case "space":
|
|
90
|
+
return html`<div class="bd-terminalmsg-l-space" aria-hidden="true"> </div>`;
|
|
91
|
+
case "cmd":
|
|
92
|
+
return html`<div class="bd-terminalmsg-l-cmd">${text}</div>`;
|
|
93
|
+
case "ok":
|
|
94
|
+
return html`<div class="bd-terminalmsg-l-ok">${text}</div>`;
|
|
95
|
+
case "ask":
|
|
96
|
+
return html`<div class="bd-terminalmsg-l-ask">${text}</div>`;
|
|
97
|
+
case "strong":
|
|
98
|
+
return html`<div class="bd-terminalmsg-l-strong">${text}</div>`;
|
|
99
|
+
case "dim":
|
|
100
|
+
return html`<div class="bd-terminalmsg-l-dim">${text}</div>`;
|
|
101
|
+
default:
|
|
102
|
+
return html`<div class="bd-terminalmsg-l-dim">${text}</div>`;
|
|
103
|
+
}
|
|
104
|
+
})}
|
|
105
|
+
</div>
|
|
106
|
+
`;
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
render() {
|
|
110
|
+
return html`
|
|
111
|
+
${this._renderTitlebar()}
|
|
112
|
+
|
|
113
|
+
<div class="bd-terminalmsg-panel">
|
|
114
|
+
${this.panelLabel
|
|
115
|
+
? html`<span class="bd-terminalmsg-panel-label">${this.panelLabel}</span>`
|
|
116
|
+
: nothing}
|
|
117
|
+
|
|
118
|
+
<div class="bd-terminalmsg-body">
|
|
119
|
+
${this._renderLines()}
|
|
120
|
+
|
|
121
|
+
${this.dimText
|
|
122
|
+
? html`<bd-p kind="small" font-family="var(--font-family-mono)" paddingBottom="var(--spacing-12)" class="bd-terminalmsg-dim">${this.dimText}</bd-p>`
|
|
123
|
+
: nothing}
|
|
124
|
+
|
|
125
|
+
${this.greeting
|
|
126
|
+
? html`
|
|
127
|
+
<bd-p kind="regular" font-family="var(--font-family-mono)" paddingBottom="var(--spacing-12)" class="bd-terminalmsg-greeting">
|
|
128
|
+
${this.icon ? html`${this.icon} ` : nothing}
|
|
129
|
+
<span class="bd-terminalmsg-greeting-text">${this.greeting}</span>
|
|
130
|
+
</bd-p>
|
|
131
|
+
`
|
|
132
|
+
: nothing}
|
|
133
|
+
|
|
134
|
+
${this.intro
|
|
135
|
+
? html`<bd-p kind="regular" font-family="var(--font-family-mono)" paddingBottom="var(--spacing-12)" class="bd-terminalmsg-intro">${this.intro}</bd-p>`
|
|
136
|
+
: nothing}
|
|
137
|
+
|
|
138
|
+
${this.items && this.items.length
|
|
139
|
+
? html`
|
|
140
|
+
<bd-list class="bd-terminalmsg-list">
|
|
141
|
+
${this.items.map((item) => html`<bd-li kind="bullet" size="sm" color="#fff">${item}</bd-li>`)}
|
|
142
|
+
</bd-list>
|
|
143
|
+
`
|
|
144
|
+
: nothing}
|
|
145
|
+
|
|
146
|
+
${this.footer || this.footerBold
|
|
147
|
+
? html`
|
|
148
|
+
<bd-p kind="regular" font-family="var(--font-family-mono)" class="bd-terminalmsg-footer">
|
|
149
|
+
${this.footerBold
|
|
150
|
+
? html`<strong>${this.footerBold}</strong> `
|
|
151
|
+
: nothing}
|
|
152
|
+
${this.footer}
|
|
153
|
+
${this.showCursor
|
|
154
|
+
? html`<bd-terminal-cursor></bd-terminal-cursor>`
|
|
155
|
+
: nothing}
|
|
156
|
+
</bd-p>
|
|
157
|
+
`
|
|
158
|
+
: nothing}
|
|
159
|
+
|
|
160
|
+
<slot></slot>
|
|
161
|
+
</div>
|
|
162
|
+
|
|
163
|
+
${this._renderHint()}
|
|
164
|
+
</div>
|
|
165
|
+
`;
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
customElements.define("bd-terminal-message", TerminalMessage);
|