Skip to content

Commit e2edb7f

Browse files
committed
Final version - working
1 parent 4434b9d commit e2edb7f

File tree

3 files changed

+37
-77
lines changed

3 files changed

+37
-77
lines changed

docs/quick-start.mdx

Lines changed: 7 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -13,23 +13,18 @@ import TabItem from '@theme/TabItem';
1313
import CodeBlock from '@theme/CodeBlock';
1414
import {VerticalStepper} from '@clickhouse/click-ui/bundled';
1515

16-
_Welcome to ClickHouse!_
16+
**Welcome to ClickHouse!**
1717

18-
In this quick-start tutorial we'll get you set-up in 8
18+
In this quick-start tutorial, we'll get you set up in 8
1919
easy steps. You'll download an appropriate binary for your OS,
2020
learn to run ClickHouse server, and use the ClickHouse client to create a table,
21-
insert data into it and run a query to select that data.
21+
then insert data into it and run a query to select that data.
2222

23-
All you'll need to follow along is:
24-
- your laptop
25-
- curl or another command-line
26-
HTTP client to fetch the ClickHouse binary
23+
Let's get started?
2724

28-
_Let's get started, shall we?_
25+
<VerticalStepper>
2926

30-
<VerticalStepper type="numbered">
31-
32-
## Download the binary
27+
## Download ClickHouse
3328

3429
ClickHouse runs natively on Linux, FreeBSD and macOS, and runs on Windows via
3530
the [WSL](https://learn.microsoft.com/en-us/windows/wsl/about). The simplest way to download ClickHouse locally is to run the
@@ -370,7 +365,7 @@ technologies that integrate with ClickHouse.
370365
</TabItem>
371366
</Tabs>
372367

373-
## Next steps
368+
## Explore
374369

375370
- Check out our [Core Concepts](/managing-data/core-concepts) section to learn some of the fundamentals of how ClickHouse works under the hood.
376371
- Check out the [Advanced Tutorial](tutorial.md) which takes a much deeper dive into the key concepts and capabilities of ClickHouse.

plugins/remark-custom-blocks.js

Lines changed: 9 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,3 @@
1-
// plugins/remark-custom-blocks.js
2-
// VERSION BEFORE anchorId/slug logic was added
3-
41
const { visit } = require('unist-util-visit');
52

63
// --- Helper Functions ---
@@ -23,26 +20,19 @@ const plugin = (options) => {
2320

2421
// Target JSX elements in the AST
2522
visit(tree, 'mdxJsxFlowElement', (node, index, parent) => {
26-
// Look specifically for the <VerticlStepper> tag used in Markdown source (as originally written)
27-
if (node.name === 'VerticalStepper') { // <-- Checks for VerticalStepper from original code
23+
// Look specifically for the <VerticlStepper> tag used in the markdown file
24+
if (node.name === 'VerticalStepper') {
2825
try {
29-
console.log('Processing VStepper tag'); // Log from original code
30-
31-
// --- 1. Parse <VStepper> Attributes ---
26+
// --- 1. Parse <VerticalStepper> Attributes ---
3227
const jsxAttributes = node.attributes || [];
3328
let type = "numbered"; // Default type
34-
let isExpanded = false; // Default not expanded (allExpanded)
29+
let isExpanded = true;
3530

3631
// Extract attributes
3732
jsxAttributes.forEach(attr => {
3833
if (attr.type === 'mdxJsxAttribute') {
3934
if (attr.name === 'type' && typeof attr.value === 'string') {
4035
type = attr.value;
41-
console.log(`Found type: ${type}`); // Log from original code
42-
}
43-
else if (attr.name === 'allExpanded') { // Check for allExpanded
44-
isExpanded = true;
45-
console.log('Found allExpanded attribute'); // Log from original code
4636
}
4737
}
4838
});
@@ -69,13 +59,12 @@ const plugin = (options) => {
6959

7060
if (node.children && node.children.length > 0) {
7161
node.children.forEach((child) => {
72-
console.log(child)
7362
if (child.type === 'heading' && child.depth === 2) {
7463
finalizeStep(); // Finalize the previous step first
7564
currentStepLabel = extractText(child.children);
7665
currentAnchorId = child.data.hProperties.id;
7766
currentStepId = `step-${stepsData.length + 1}`; // Generate step-X ID
78-
console.log(`Found heading: ${currentStepLabel} \{#${currentAnchorId}\}`); // Log from original code
67+
currentStepContent.push(child); // We need the header otherwise onBrokenAnchors fails
7968
} else if (currentStepLabel) {
8069
// Only collect content nodes *after* a heading has defined a step
8170
currentStepContent.push(child);
@@ -84,14 +73,12 @@ const plugin = (options) => {
8473
}
8574
finalizeStep(); // Finalize the last step found
8675

87-
console.log(`Found ${stepsData.length} steps`); // Log from original code
88-
8976
// --- 3. Transform Parent Node ---
90-
// Transforms to VerticalStepper to match MDXComponents.js
77+
// Transforms to <Stepper/> to match src/theme/MDXComponents.js
9178
node.name = 'Stepper';
9279
node.children = []; // Clear original children
9380

94-
// Set attributes - type and expanded (if isExpanded is true)
81+
// Set attributes
9582
node.attributes = [
9683
{ type: 'mdxJsxAttribute', name: 'type', value: type },
9784
];
@@ -122,44 +109,13 @@ const plugin = (options) => {
122109
});
123110
}
124111

125-
const anchorElement = {
126-
type: 'mdxJsxFlowElement',
127-
name: 'a',
128-
attributes: [
129-
{ type: 'mdxJsxAttribute', name: 'href', value: `#${step.anchorId}` },
130-
{ type: 'mdxJsxAttribute', name: 'className', value: 'hash-link' }
131-
],
132-
children: [
133-
// Add a link symbol or text
134-
{
135-
type: 'text',
136-
value: '🔗' // Or any other symbol/text you prefer
137-
}
138-
]
139-
};
140-
141-
const contentWithAnchor = [
142-
{
143-
type: 'mdxJsxFlowElement',
144-
name: 'div',
145-
attributes: [
146-
{ type: 'mdxJsxAttribute', name: 'id', value: step.anchorId }
147-
],
148-
children: [
149-
anchorElement, // Add the anchor element
150-
...step.content // Then add the regular content
151-
]
152-
}
153-
];
154-
155112
// Push the Step node
156113
node.children.push({
157114
type: 'mdxJsxFlowElement',
158115
name: 'Step', // Output Step tag
159116
attributes: stepAttributes,
160-
children: contentWithAnchor, // Pass content nodes as children
117+
children: [...step.content], // Pass content nodes as children
161118
});
162-
console.log(`Added step: ${step.label} with anchorId: ${step.anchorId || 'none'}`); // Log from original code
163119
});
164120
} catch (error) {
165121
const filePath = file?.path || 'unknown file';
@@ -172,4 +128,4 @@ const plugin = (options) => {
172128
return transformer;
173129
};
174130

175-
module.exports = plugin;
131+
module.exports = plugin;

src/components/Stepper/Stepper.tsx

Lines changed: 21 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,6 @@ const Step = ({
2222
...restProps
2323
}: StepProps) => {
2424

25-
// Logic from before anchor fixes:
2625
// Determine 'active' status based on props passed from parent
2726
const shouldBeActive = isFirstStep || isActiveStep || forceExpanded === 'true';
2827
const status: 'active' | 'complete' | 'incomplete' = shouldBeActive ? 'active' : 'incomplete';
@@ -31,7 +30,22 @@ const Step = ({
3130
// We pass collapsed=true, relying on status='active' to override it.
3231
const collapsed = true;
3332

34-
// console.log(`Step ${id}: isFirstStep=${isFirstStep}, isActiveStep=${isActiveStep}, status=${status}, collapsed=${collapsed}`);
33+
// Swap out the Click-UI Stepper label (shown next to the numbered circle) for the
34+
// H2 header so that Docusaurus doesn't fail on broken anchor checks
35+
useEffect(() => {
36+
try {
37+
const button = document.querySelectorAll(`button[id^=${id}]`)[0];
38+
const divChildren = Array.from(button.children).filter(el => el.tagName === 'DIV');
39+
const label = divChildren[1];
40+
const content = button.nextElementSibling;
41+
const header = content.querySelectorAll('h2')[0]
42+
header.style.margin = '0';
43+
button.append(header)
44+
label.remove()
45+
} catch (e) {
46+
console.log('Error occurred in Stepper.tsx while swapping H2 for Click-UI label')
47+
}
48+
}, []);
3549

3650
// Filter out props specific to this wrapper logic
3751
const {
@@ -46,7 +60,7 @@ const Step = ({
4660
label={label}
4761
status={status}
4862
collapsed={collapsed}
49-
id={id} // Pass step-X ID
63+
id={id}
5064
{...domSafeProps}
5165
>
5266
{children}
@@ -88,18 +102,17 @@ const VStepper = ({
88102
return childElement.props.id || `step-${index + 1}`;
89103
});
90104

91-
// --- Scroll Listener Effect (with CORRECT selectors) ---
105+
// --- Scroll Listener Effect ---
106+
// This is currently not used, but we may want to include it at a later stage
92107
useEffect(() => {
93108
if (isExpandedMode) return;
94109

95110
const handleScroll = () => {
96-
// --- Uses the CORRECT selectors ---
97111
const headers = document.querySelectorAll('button[id^="step-"]');
98112
if (headers.length === 0) {
99113
console.log('No step headers found using CORRECT selectors');
100114
return;
101115
}
102-
// console.log(`Found ${headers.length} step headers using CORRECT selectors`);
103116

104117
headers.forEach((header, index) => {
105118
if (index >= stepIds.length) return;
@@ -158,20 +171,16 @@ const VStepper = ({
158171
type={type}
159172
className={className}
160173
{...domProps}
161-
// --- onClick Handler (with CORRECT selectors) ---
162174
onClick={(e) => {
163175
if (isExpandedMode) return;
164176
const target = e.target as HTMLElement;
165-
// --- Uses the CORRECT selector ---
166177
const header = target.closest('button[id^="step-"]');
167178
if (header) {
168-
// --- Uses the CORRECT selector ---
169179
const allHeaders = document.querySelectorAll('button[id^="step-"]');
170180
const index = Array.from(allHeaders).indexOf(header as Element);
171181
if (index !== -1 && index < stepIds.length) {
172182
const stepId = stepIds[index];
173-
handleStepClick(stepId); // Call handler to update state
174-
// Removed stopPropagation unless needed
183+
handleStepClick(stepId);
175184
}
176185
}
177186
}}
@@ -185,4 +194,4 @@ const VStepper = ({
185194
VStepper.Step = Step;
186195

187196
// Export the main component
188-
export default VStepper;
197+
export default VStepper;

0 commit comments

Comments
 (0)