Skip to content

Commit 4e8aea6

Browse files
authored
Merge pull request #222 from dockersamples/os-conditional-blocks
Add OS-conditional support to conditionalDisplay directive
2 parents 8cf2686 + ba9007b commit 4e8aea6

4 files changed

Lines changed: 120 additions & 8 deletions

File tree

components/interface/client/src/components/WorkshopPanel/markdown/ConditionalDisplay.jsx

Lines changed: 44 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,36 @@
11
import { useVariables } from "../../../WorkshopContext";
22
import { useMemo } from "react";
3+
import { detectOs } from "./detectOs";
34

45
/**
5-
* This custom markdown directive provides the ability to conditionally show content based on variable values.
6+
* This custom markdown directive provides the ability to conditionally show content based on variable values
7+
* or the detected operating system of the user's browser.
68
*
7-
* Usage example:
8-
* :::conditionalDisplay{variable="variable" requiredValue="value to match"}
9-
* Content to conditionally display goes here.
10-
* :::
9+
* Usage examples:
10+
*
11+
* :::conditionalDisplay{variable="variable" requiredValue="value to match"}
12+
* Content to conditionally display goes here.
13+
* :::
14+
*
15+
* :::conditionalDisplay{os="mac,linux"}
16+
* Content shown to Mac and Linux users.
17+
* :::
18+
*
19+
* :::conditionalDisplay{os="unix"}
20+
* Equivalent shorthand for mac + linux.
21+
* :::
22+
*
23+
* :::conditionalDisplay{os="windows"}
24+
* Content shown to Windows users.
25+
* :::
1126
*
1227
* The following props can be used to control the display logic:
1328
* - `requiredValue`: the value to match
1429
* - `hasValue`: if set, the content will be shown if the variable has any value
1530
* - `hasNoValue`: if set, the content will be shown if the variable is undefined or empty
31+
* - `os`: comma-separated list of operating systems (`mac`, `linux`, `windows`, or alias `unix` = mac+linux)
32+
*
33+
* When both `variable` and `os` are set, both conditions must be satisfied for content to render.
1634
*
1735
* @returns
1836
*/
@@ -22,20 +40,38 @@ export function ConditionalDisplay({
2240
requiredValue,
2341
hasValue,
2442
hasNoValue,
25-
...rest
43+
os,
2644
}) {
2745
const { variables } = useVariables();
28-
const currentValue = variables[variable] || undefined;
46+
const currentValue = variable ? variables[variable] || undefined : undefined;
2947

3048
const shouldDisplay = useMemo(() => {
49+
if (os !== undefined) {
50+
const allowed = new Set(
51+
String(os)
52+
.split(",")
53+
.flatMap((token) => {
54+
const t = token.trim().toLowerCase();
55+
if (!t) return [];
56+
if (t === "unix") return ["mac", "linux"];
57+
return [t];
58+
}),
59+
);
60+
if (!allowed.has(detectOs())) return false;
61+
}
62+
63+
if (variable === undefined) {
64+
return os !== undefined;
65+
}
66+
3167
if (hasValue !== undefined) {
3268
return currentValue !== undefined && currentValue !== "";
3369
}
3470
if (hasNoValue !== undefined) {
3571
return currentValue === undefined || currentValue === "";
3672
}
3773
return currentValue === requiredValue;
38-
}, [currentValue, variable, requiredValue, hasValue]);
74+
}, [currentValue, variable, requiredValue, hasValue, hasNoValue, os]);
3975

4076
if (!shouldDisplay) {
4177
return null;
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
/**
2+
* Detects the OS of the browser running the labspace interface.
3+
*
4+
* Prefers the modern `navigator.userAgentData.platform` when available,
5+
* falling back to `navigator.platform` and finally `navigator.userAgent`.
6+
*
7+
* @returns {"mac" | "linux" | "windows" | "unknown"}
8+
*/
9+
export function detectOs() {
10+
if (typeof navigator === "undefined") return "unknown";
11+
12+
const raw = (
13+
navigator.userAgentData?.platform ||
14+
navigator.platform ||
15+
navigator.userAgent ||
16+
""
17+
).toLowerCase();
18+
19+
if (raw.includes("win")) return "windows";
20+
if (raw.includes("mac") || raw.includes("darwin")) return "mac";
21+
if (raw.includes("linux") || raw.includes("x11")) return "linux";
22+
return "unknown";
23+
}

docs/markdown-options.md

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -184,6 +184,39 @@ For values, the following options are available:
184184
- `hasValue`: if set, the content will be shown if the variable has any value
185185
- `hasNoValue`: if set, the content will be shown if the variable is undefined or empty
186186

187+
### OS-conditional displays
188+
189+
The `:::conditionalDisplay` directive also supports filtering by the operating system of the user's browser using the `os` parameter. This is useful when commands must run natively on the user's machine and differ between platforms.
190+
191+
Example:
192+
193+
:::conditionalDisplay{os="unix"}
194+
On Mac/Linux, run:
195+
196+
```bash
197+
echo "Hello from a Unix-like shell"
198+
```
199+
:::
200+
201+
:::conditionalDisplay{os="windows"}
202+
On Windows, run:
203+
204+
```powershell
205+
Write-Host "Hello from PowerShell"
206+
```
207+
:::
208+
209+
Supported `os` values (comma-separated for multiple):
210+
211+
- `mac` — macOS
212+
- `linux` — Linux
213+
- `windows` — Windows
214+
- `unix` — alias for `mac,linux`
215+
216+
The `os` parameter can be combined with `variable`, `requiredValue`, `hasValue`, or `hasNoValue`. When both are present, the content is shown only if *both* the OS and variable conditions match.
217+
218+
OS detection uses `navigator.userAgentData.platform` when available, falling back to `navigator.platform`. Detection happens in the user's browser, so the result reflects where the browser is running — which is what matters for commands meant to run natively on the user's machine.
219+
187220
### Labspace-defined variables
188221

189222
To support easier maintenance for values that may need to be updated in multiple locations, variables can also be defined in the `labspace.yaml` file.

sample-content-repo/labspace/04-variables.md

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,26 @@ Variables can be used to support the conditional displaying of text.
5858
> It appears the conditional is set and this content is displayed!
5959
:::
6060

61+
## OS-conditional display
62+
63+
Content can also be filtered by the operating system the user is viewing from. This is useful for showing commands that run natively on the user's machine.
64+
65+
:::conditionalDisplay{os="unix"}
66+
You appear to be on Mac or Linux. Try this:
67+
68+
```bash
69+
echo "Hello from a Unix-like shell"
70+
```
71+
:::
72+
73+
:::conditionalDisplay{os="windows"}
74+
You appear to be on Windows. Try this:
75+
76+
```powershell
77+
Write-Host "Hello from PowerShell"
78+
```
79+
:::
80+
6181
## Default Labspace variables
6282

6383
As a help to authors, variables can also be defined in the `labspace.yaml` file to reduce maintenance where a value may appear in multiple places throughout the writeup.

0 commit comments

Comments
 (0)