Skip to content

Commit ee1beb0

Browse files
committed
Add applies-switch component
1 parent a6a0df6 commit ee1beb0

File tree

19 files changed

+873
-4
lines changed

19 files changed

+873
-4
lines changed

docs/_docset.yml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,7 @@ toc:
9292
- file: headings.md
9393
- file: admonitions.md
9494
- file: applies.md
95+
- file: applies-switch.md
9596
- file: automated_settings.md
9697
- file: code.md
9798
- file: comments.md
@@ -156,4 +157,4 @@ toc:
156157
- file: bar.md
157158
- folder: baz
158159
children:
159-
- file: qux.md
160+
- file: qux.md

docs/syntax/applies-switch.md

Lines changed: 163 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,163 @@
1+
# Applies Switch
2+
3+
The applies-switch directive creates tabbed content where each tab displays an applies_to badge instead of a text title. This is useful for showing content that varies by deployment type, version, or other applicability criteria.
4+
5+
## Basic Usage
6+
7+
### Example
8+
9+
#### Syntax
10+
11+
```markdown
12+
:::::{applies-switch}
13+
14+
::::{applies-item} stack: preview 9.1
15+
:::{tip}
16+
This feature is in preview for Elastic Stack 9.1.
17+
:::
18+
::::
19+
20+
::::{applies-item} ess: preview 9.1
21+
:::{note}
22+
This feature is available for Elastic Cloud.
23+
:::
24+
::::
25+
26+
::::{applies-item} ece: removed
27+
:::{warning}
28+
This feature has been removed from Elastic Cloud Enterprise.
29+
:::
30+
::::
31+
32+
:::::
33+
```
34+
35+
#### Result
36+
37+
:::::{applies-switch}
38+
39+
::::{applies-item} stack: preview 9.1
40+
:::{tip}
41+
This feature is in preview for Elastic Stack 9.1.
42+
:::
43+
::::
44+
45+
::::{applies-item} ess: preview 9.1
46+
:::{note}
47+
This feature is available for Elastic Cloud.
48+
:::
49+
::::
50+
51+
::::{applies-item} ece: removed
52+
:::{warning}
53+
This feature has been removed from Elastic Cloud Enterprise.
54+
:::
55+
::::
56+
57+
:::::
58+
59+
## Automatic Grouping
60+
61+
Applies switches are automatically grouped together by default. This means all applies switches on a page will sync with each other - when you select a version in one switch, all other switches will automatically switch to the same version.
62+
63+
Items with the same applies_to definition will sync together across all switches on the page. For example, if you have `stack: preview 9.1` in multiple switches, selecting it in one will select it in all others.
64+
65+
### Example
66+
67+
In the following example we have two applies switch sets that are automatically grouped together.
68+
Hence, both switch sets will be in sync.
69+
70+
#### Syntax
71+
72+
```markdown
73+
::::{applies-switch}
74+
:::{applies-item} stack: ga 8.11
75+
Content for GA version
76+
:::
77+
78+
:::{applies-item} stack: preview 9.1
79+
Content for preview version
80+
:::
81+
82+
::::
83+
84+
::::{applies-switch}
85+
:::{applies-item} stack: ga 8.11
86+
Other content for GA version
87+
:::
88+
89+
:::{applies-item} stack: preview 9.1
90+
Other content for preview version
91+
:::
92+
93+
::::
94+
```
95+
96+
#### Result
97+
98+
##### Automatically Grouped Applies Switches
99+
100+
::::{applies-switch}
101+
:::{applies-item} stack: ga 8.11
102+
Content for GA version
103+
:::
104+
105+
:::{applies-item} stack: preview 9.1
106+
Content for preview version
107+
:::
108+
109+
::::
110+
111+
::::{applies-switch}
112+
:::{applies-item} stack: ga 8.11
113+
Other content for GA version
114+
:::
115+
116+
:::{applies-item} stack: preview 9.1
117+
Other content for preview version
118+
:::
119+
120+
::::
121+
122+
## Supported Applies To Definitions
123+
124+
The `applies-item` directive accepts any valid applies_to definition that would work with the `{applies_to}` role. This includes:
125+
126+
- **Stack versions**: `stack: ga 8.11`, `stack: preview 9.1`
127+
- **Deployment types**: `ess: preview 9.1`, `ece: removed`, `eck: ga 8.11`
128+
- **Product versions**: `product: preview 9.1`
129+
- **Serverless projects**: `serverless: observability: preview 9.1`
130+
131+
## Best Practices
132+
133+
**DOs**<br>
134+
**Do:** Use clear, descriptive applies_to definitions<br>
135+
**Do:** Make sure all switch items have the same type of content and similar goals<br>
136+
**Do:** Keep switch content scannable and self-contained<br>
137+
**Do:** Include other block elements in switches, like [admonitions](admonitions.md)<br>
138+
**Do:** Use applies_to definitions that are meaningful to your users
139+
140+
**DON'Ts**<br>
141+
**Don't:** Nest applies switches<br>
142+
**Don't:** Split step-by-step procedures across switches<br>
143+
**Don't:** Use more than 6 switch items (use as few as possible)<br>
144+
**Don't:** Use applies switches in [dropdowns](dropdowns.md)<br>
145+
**Don't:** Use applies_to definitions that are too similar or confusing
146+
147+
## When to Use
148+
149+
Use applies switches when:
150+
151+
- Content varies significantly by deployment type, version, or other applicability criteria
152+
- You want to show applies_to badges as tab titles instead of text
153+
- You need to group related content that differs by applicability
154+
- You want to provide a clear visual indication of what each content section applies to
155+
156+
## Comparison with Regular Tabs
157+
158+
| Feature | Regular Tabs | Applies Switch |
159+
|---------|--------------|----------------|
160+
| Tab titles | Text labels | Applies_to badges |
161+
| Use case | General content organization | Content that varies by applicability |
162+
| Visual indication | Text | Badge with version/deployment info |
163+
| Best for | General content grouping | Version-specific or deployment-specific content |
Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,88 @@
1+
// TODO: refactor to typescript. this was copied from the tabs implementation
2+
3+
// @ts-check
4+
5+
// Extra JS capability for selected applies switches to be synced
6+
// The selection is stored in local storage so that it persists across page loads.
7+
8+
const as_id_to_elements = {}
9+
const storageKeyPrefix = 'sphinx-design-applies-switch-id-'
10+
11+
function create_key(el: HTMLElement) {
12+
const syncId = el.getAttribute('data-sync-id')
13+
const syncGroup = el.getAttribute('data-sync-group')
14+
if (!syncId || !syncGroup) return null
15+
return [syncGroup, syncId, syncGroup + '--' + syncId]
16+
}
17+
18+
/**
19+
* Initialize the applies switch selection.
20+
*
21+
*/
22+
function ready() {
23+
// Find all applies switches with sync data
24+
25+
const groups = []
26+
27+
document.querySelectorAll('.applies-switch-label').forEach((label) => {
28+
if (label instanceof HTMLElement) {
29+
const data = create_key(label)
30+
if (data) {
31+
const [group, id, key] = data
32+
33+
// add click event listener
34+
label.onclick = onAppliesSwitchLabelClick
35+
36+
// store map of key to elements
37+
if (!as_id_to_elements[key]) {
38+
as_id_to_elements[key] = []
39+
}
40+
as_id_to_elements[key].push(label)
41+
42+
if (groups.indexOf(group) === -1) {
43+
groups.push(group)
44+
// Check if a specific switch has been selected via URL parameter
45+
const switchParam = new URLSearchParams(
46+
window.location.search
47+
).get(group)
48+
if (switchParam) {
49+
window.sessionStorage.setItem(
50+
storageKeyPrefix + group,
51+
switchParam
52+
)
53+
}
54+
}
55+
56+
// Check is a specific switch has been selected previously
57+
const previousId = window.sessionStorage.getItem(
58+
storageKeyPrefix + group
59+
)
60+
if (previousId === id) {
61+
;(
62+
label.previousElementSibling as HTMLInputElement
63+
).checked = true
64+
}
65+
}
66+
}
67+
})
68+
}
69+
70+
/**
71+
* Activate other switches with the same sync id.
72+
*
73+
* @this {HTMLElement} - The element that was clicked.
74+
*/
75+
function onAppliesSwitchLabelClick() {
76+
const data = create_key(this)
77+
if (!data) return
78+
const [group, id, key] = data
79+
for (const label of as_id_to_elements[key]) {
80+
if (label === this) continue
81+
label.previousElementSibling.checked = true
82+
}
83+
window.sessionStorage.setItem(storageKeyPrefix + group, id)
84+
}
85+
86+
export function initAppliesSwitch() {
87+
ready()
88+
}
Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,88 @@
1+
// TODO: refactor to typescript. this was copied from the tabs implementation
2+
3+
// @ts-check
4+
5+
// Extra JS capability for selected applies switches to be synced
6+
// The selection is stored in local storage so that it persists across page loads.
7+
8+
const as_id_to_elements = {}
9+
const storageKeyPrefix = 'sphinx-design-applies-switch-id-'
10+
11+
function create_key(el: HTMLElement) {
12+
const syncId = el.getAttribute('data-sync-id')
13+
const syncGroup = el.getAttribute('data-sync-group')
14+
if (!syncId || !syncGroup) return null
15+
return [syncGroup, syncId, syncGroup + '--' + syncId]
16+
}
17+
18+
/**
19+
* Initialize the applies switch selection.
20+
*
21+
*/
22+
function ready() {
23+
// Find all applies switches with sync data
24+
25+
const groups = []
26+
27+
document.querySelectorAll('.applies-switch-label').forEach((label) => {
28+
if (label instanceof HTMLElement) {
29+
const data = create_key(label)
30+
if (data) {
31+
const [group, id, key] = data
32+
33+
// add click event listener
34+
label.onclick = onAppliesSwitchLabelClick
35+
36+
// store map of key to elements
37+
if (!as_id_to_elements[key]) {
38+
as_id_to_elements[key] = []
39+
}
40+
as_id_to_elements[key].push(label)
41+
42+
if (groups.indexOf(group) === -1) {
43+
groups.push(group)
44+
// Check if a specific switch has been selected via URL parameter
45+
const switchParam = new URLSearchParams(
46+
window.location.search
47+
).get(group)
48+
if (switchParam) {
49+
window.sessionStorage.setItem(
50+
storageKeyPrefix + group,
51+
switchParam
52+
)
53+
}
54+
}
55+
56+
// Check is a specific switch has been selected previously
57+
const previousId = window.sessionStorage.getItem(
58+
storageKeyPrefix + group
59+
)
60+
if (previousId === id) {
61+
;(
62+
label.previousElementSibling as HTMLInputElement
63+
).checked = true
64+
}
65+
}
66+
}
67+
})
68+
}
69+
70+
/**
71+
* Activate other switches with the same sync id.
72+
*
73+
* @this {HTMLElement} - The element that was clicked.
74+
*/
75+
function onAppliesSwitchLabelClick() {
76+
const data = create_key(this)
77+
if (!data) return
78+
const [group, id, key] = data
79+
for (const label of as_id_to_elements[key]) {
80+
if (label === this) continue
81+
label.previousElementSibling.checked = true
82+
}
83+
window.sessionStorage.setItem(storageKeyPrefix + group, id)
84+
}
85+
86+
export function initAppliesSwitch() {
87+
ready()
88+
}

src/Elastic.Documentation.Site/Assets/main.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import { openDetailsWithAnchor } from './open-details-with-anchor'
66
import { initNav } from './pages-nav'
77
import { initSmoothScroll } from './smooth-scroll'
88
import { initTabs } from './tabs'
9+
import { initAppliesSwitch } from './applies-switch'
910
import { initTocNav } from './toc-nav'
1011
import 'htmx-ext-head-support'
1112
import 'htmx-ext-preload'
@@ -21,6 +22,7 @@ document.addEventListener('htmx:load', function (event) {
2122
initHighlight()
2223
initCopyButton()
2324
initTabs()
25+
initAppliesSwitch()
2426

2527
// We do this so that the navigation is not initialized twice
2628
if (isLazyLoadNavigationEnabled) {

0 commit comments

Comments
 (0)