Skip to content

Commit 85cc278

Browse files
committed
New example view with tabs
1 parent f275326 commit 85cc278

File tree

3 files changed

+136
-13
lines changed

3 files changed

+136
-13
lines changed

web/src/components/CodeExamplesSection.astro

Lines changed: 119 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import NeedsExample from '@src/components/NeedsExample.astro';
66
export interface CodeExample {
77
description?: string;
88
luaCode: string;
9+
side: string;
910
}
1011
1112
export interface Props {
@@ -18,18 +19,126 @@ const { codeExamples } = Astro.props;
1819
<div class="examples-section">
1920
<h4>Code Examples</h4>
2021

21-
{codeExamples.length > 0 ? (
22-
codeExamples.map((example) => (
23-
<div class="code-example">
24-
{example.description && (
25-
<Fragment set:html={marked(example.description)} />
26-
)}
27-
<Code code={example.luaCode} lang="lua" />
28-
</div>
29-
))
30-
) : (
22+
{codeExamples.length === 0 ? (
3123
<NeedsExample />
24+
) : (
25+
<div class="examples-tabs-box">
26+
{codeExamples.length > 1 && (
27+
<div class="tab-buttons" id="code-tabs">
28+
{codeExamples.map((example, index) => (
29+
<button
30+
class={`tab-btn ${index === 0 ? 'active' : ''} side-${example.side}`}
31+
data-tab={index}
32+
type="button"
33+
>
34+
Example {index + 1}
35+
</button>
36+
))}
37+
</div>
38+
)}
39+
40+
{codeExamples.map((example, index) => (
41+
<div class="tab-content" data-tab={index} style={{ display: index === 0 ? 'block' : 'none' }}>
42+
{example.description && <Fragment set:html={marked(example.description)} />}
43+
<div class="code-example">
44+
<Code code={example.luaCode} lang="lua" />
45+
</div>
46+
</div>
47+
))}
48+
</div>
3249
)}
3350
</div>
3451

52+
<style>
53+
.tab-buttons {
54+
display: flex;
55+
gap: 1rem;
56+
overflow-x: auto;
57+
white-space: nowrap;
58+
}
59+
60+
.tab-buttons.has-scrollbar {
61+
padding-bottom: 1rem;
62+
}
63+
64+
.tab-btn {
65+
padding: 0.4rem 0.8rem;
66+
margin: 0;
67+
border: 1px solid var(--sl-color-gray-4);
68+
background: none;
69+
border-radius: 10px;
70+
cursor: pointer;
71+
color: var(--sl-color-text);
72+
transition: background-color 0.2s ease;
73+
}
74+
75+
.tab-btn.active {
76+
color: white;
77+
font-weight: bold;
78+
}
79+
80+
.side-client {
81+
background-color: var(--color-type-client-background);
82+
border-color: var(--color-type-client);
83+
}
84+
85+
.side-client.active {
86+
background-color: var(--color-type-client-background-high);
87+
}
88+
89+
.side-server {
90+
background-color: var(--color-type-server-background);
91+
border-color: var(--color-type-server);
92+
}
93+
94+
.side-server.active {
95+
background-color: var(--color-type-server-background-high);
96+
}
97+
98+
.side-shared {
99+
background-color: var(--color-type-shared-background);
100+
border-color: var(--color-type-shared);
101+
}
102+
103+
.side-shared.active {
104+
background-color: var(--color-type-shared-background-high);
105+
}
106+
107+
.tab-content {
108+
background-color: var(--sl-color-bg-nav);
109+
padding: 1rem;
110+
box-shadow: var(--ec-frm-frameBoxShdCssVal);
111+
}
112+
</style>
113+
114+
<script>
115+
document.addEventListener('DOMContentLoaded', () => {
116+
const buttons = document.querySelectorAll('.tab-btn');
117+
const tabs = document.querySelectorAll('.tab-content');
118+
119+
buttons.forEach((btn) => {
120+
btn.addEventListener('click', () => {
121+
const tab = btn.dataset.tab;
122+
123+
buttons.forEach((b) => b.classList.toggle('active', b.dataset.tab === tab));
124+
tabs.forEach((t) => (t.style.display = t.dataset.tab === tab ? 'block' : 'none'));
125+
});
126+
});
127+
128+
function checkOverflow() {
129+
const tabButtons = document.querySelector('.tab-buttons');
130+
if (!tabButtons) return;
131+
132+
if (tabButtons.scrollWidth > tabButtons.clientWidth) {
133+
tabButtons.classList.add('has-scrollbar');
134+
} else {
135+
tabButtons.classList.remove('has-scrollbar');
136+
}
137+
}
138+
139+
checkOverflow();
140+
window.addEventListener('resize', checkOverflow);
141+
});
142+
</script>
143+
35144
<script type="module" src="/mta-keyword_linker.js"></script>

web/src/pages/[func].astro

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -35,13 +35,24 @@ const funcPath = path.dirname(func.filePath ?? "");
3535
// join shared, client and server examples (in func.data) if any
3636
let funcExamples: any[] = [];
3737
if (func.data.shared && func.data.shared.examples) {
38-
funcExamples = [...funcExamples, ...func.data.shared.examples];
38+
funcExamples = [
39+
...funcExamples,
40+
...func.data.shared.examples.map((ex: any) => ({ ...ex, side: 'shared' })),
41+
];
3942
}
43+
4044
if (func.data.client && func.data.client.examples) {
41-
funcExamples = [...funcExamples, ...func.data.client.examples];
45+
funcExamples = [
46+
...funcExamples,
47+
...func.data.client.examples.map((ex: any) => ({ ...ex, side: 'client' })),
48+
];
4249
}
50+
4351
if (func.data.server && func.data.server.examples) {
44-
funcExamples = [...funcExamples, ...func.data.server.examples];
52+
funcExamples = [
53+
...funcExamples,
54+
...func.data.server.examples.map((ex: any) => ({ ...ex, side: 'server' })),
55+
];
4556
}
4657
funcExamples = funcExamples.map((example: any) => {
4758
try {

web/src/styles/custom.css

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,13 @@
22
:root {
33
--color-type-shared: rgba(117, 117, 255, 1);
44
--color-type-shared-background: rgba(117, 117, 255, 0.05);
5+
--color-type-shared-background-high: rgba(117, 117, 255, 0.5);
56
--color-type-client: rgba(255, 50, 50, 1);
67
--color-type-client-background: rgba(255, 50, 50, 0.05);
8+
--color-type-client-background-high: rgba(255, 50, 50, 0.5);
79
--color-type-server: rgba(232, 115, 0, 1);
810
--color-type-server-background: rgba(232, 115, 0, 0.05);
11+
--color-type-server-background-high: rgba(232, 115, 0, 0.5);
912

1013
/* Override Starlight styling */
1114
--sl-content-width: 70rem;

0 commit comments

Comments
 (0)