@amedia/brick-mcp 0.1.3 → 0.1.4
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/README.md +50 -1
- package/data/components/brick-mcp.md +259 -0
- package/data/components/brick-pill.md +362 -0
- package/data/components/brick-player.md +331 -0
- package/data/components/brick-published.md +219 -0
- package/data/components/brick-share.md +335 -0
- package/data/components/brick-stepper.md +319 -0
- package/data/components/brick-tab.md +241 -0
- package/data/components/brick-tabs.md +420 -0
- package/data/components/brick-tag.md +335 -0
- package/data/components/brick-teaser-player.md +248 -0
- package/data/components/brick-teaser-reels.md +190 -0
- package/data/components/brick-teaser.md +262 -0
- package/data/components/brick-template.md +226 -0
- package/data/components/brick-textarea.md +191 -0
- package/data/components/brick-themes.md +104 -0
- package/data/components/brick-toast.md +271 -0
- package/data/components/brick-toggle.md +268 -0
- package/data/components/brick-tokens.md +287 -0
- package/data/components/brick-tooltip.md +249 -0
- package/data/components-metadata.json +34 -34
- package/data/tokens.json +0 -7
- package/dist/data/components/brick-mcp.md +259 -0
- package/dist/data/components/brick-pill.md +362 -0
- package/dist/data/components/brick-player.md +331 -0
- package/dist/data/components/brick-published.md +219 -0
- package/dist/data/components/brick-share.md +335 -0
- package/dist/data/components/brick-stepper.md +319 -0
- package/dist/data/components/brick-tab.md +241 -0
- package/dist/data/components/brick-tabs.md +420 -0
- package/dist/data/components/brick-tag.md +335 -0
- package/dist/data/components/brick-teaser-player.md +248 -0
- package/dist/data/components/brick-teaser-reels.md +190 -0
- package/dist/data/components/brick-teaser.md +262 -0
- package/dist/data/components/brick-template.md +226 -0
- package/dist/data/components/brick-textarea.md +191 -0
- package/dist/data/components/brick-themes.md +104 -0
- package/dist/data/components/brick-toast.md +271 -0
- package/dist/data/components/brick-toggle.md +268 -0
- package/dist/data/components/brick-tokens.md +287 -0
- package/dist/data/components/brick-tooltip.md +249 -0
- package/dist/data/components-metadata.json +34 -34
- package/dist/data/tokens.json +0 -7
- package/package.json +37 -37
- package/data/components/brick-mcp.json +0 -6
- package/data/components/brick-pill.json +0 -6
- package/data/components/brick-player.json +0 -7
- package/data/components/brick-published.json +0 -7
- package/data/components/brick-share.json +0 -7
- package/data/components/brick-stepper.json +0 -7
- package/data/components/brick-tab.json +0 -7
- package/data/components/brick-tabs.json +0 -9
- package/data/components/brick-tag.json +0 -7
- package/data/components/brick-teaser-player.json +0 -9
- package/data/components/brick-teaser-reels.json +0 -9
- package/data/components/brick-teaser.json +0 -9
- package/data/components/brick-template.json +0 -9
- package/data/components/brick-textarea.json +0 -7
- package/data/components/brick-themes.json +0 -6
- package/data/components/brick-toast.json +0 -9
- package/data/components/brick-toggle.json +0 -7
- package/data/components/brick-tokens.json +0 -8
- package/data/components/brick-tooltip.json +0 -7
- package/dist/data/components/brick-mcp.json +0 -6
- package/dist/data/components/brick-pill.json +0 -6
- package/dist/data/components/brick-player.json +0 -7
- package/dist/data/components/brick-published.json +0 -7
- package/dist/data/components/brick-share.json +0 -7
- package/dist/data/components/brick-stepper.json +0 -7
- package/dist/data/components/brick-tab.json +0 -7
- package/dist/data/components/brick-tabs.json +0 -9
- package/dist/data/components/brick-tag.json +0 -7
- package/dist/data/components/brick-teaser-player.json +0 -9
- package/dist/data/components/brick-teaser-reels.json +0 -9
- package/dist/data/components/brick-teaser.json +0 -9
- package/dist/data/components/brick-template.json +0 -9
- package/dist/data/components/brick-textarea.json +0 -7
- package/dist/data/components/brick-themes.json +0 -6
- package/dist/data/components/brick-toast.json +0 -9
- package/dist/data/components/brick-toggle.json +0 -7
- package/dist/data/components/brick-tokens.json +0 -8
- package/dist/data/components/brick-tooltip.json +0 -7
|
@@ -0,0 +1,241 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: brick-tab
|
|
3
|
+
version: 0.1.14
|
|
4
|
+
selector: brick-tab
|
|
5
|
+
category: Navigation
|
|
6
|
+
tags: [tab, tabs, tablist, navigation, accessibility, aria, icon, avatar]
|
|
7
|
+
use_cases: [tabbed-navigation, content-organization, settings-panels, category-switching]
|
|
8
|
+
related: [brick-tabs, brick-icon, brick-tokens]
|
|
9
|
+
---
|
|
10
|
+
|
|
11
|
+
# Brick Tab
|
|
12
|
+
|
|
13
|
+
An individual tab button component that works within brick-tabs to provide accessible tabbed navigation with support for labels, icons, and avatars.
|
|
14
|
+
|
|
15
|
+
## Key Capabilities
|
|
16
|
+
|
|
17
|
+
- Individual tab button within a tablist
|
|
18
|
+
- Optional icon support via brick-icon
|
|
19
|
+
- Optional avatar image(s) display
|
|
20
|
+
- Icon-only mode with required ARIA label
|
|
21
|
+
- Proper ARIA attributes for accessibility
|
|
22
|
+
- Keyboard navigation support (handled by brick-tabs)
|
|
23
|
+
- Must be used within brick-tabs and brick-tablist components
|
|
24
|
+
- Server-side rendering support
|
|
25
|
+
|
|
26
|
+
## Props/Attributes
|
|
27
|
+
|
|
28
|
+
| Attribute | Type | Default | Required | Description |
|
|
29
|
+
| ------------------ | ------ | ------- | -------- | -------------------------------------------------------------- |
|
|
30
|
+
| `data-label` | string | - | no* | Tab button label text |
|
|
31
|
+
| `data-button-id` | string | - | yes | Unique ID for the tab button element |
|
|
32
|
+
| `data-panel-id` | string | - | yes | ID of the associated tabpanel element |
|
|
33
|
+
| `data-icon-id` | string | - | no | Icon ID from brick-icon to display |
|
|
34
|
+
| `data-avatar-urls` | string | - | no | Comma-separated URLs for avatar images |
|
|
35
|
+
| `data-aria-label` | string | - | no** | ARIA label for accessibility (required for icon-only tabs) |
|
|
36
|
+
|
|
37
|
+
*Either `data-label` or `data-icon-id` must be provided
|
|
38
|
+
**Required when `data-label` is not provided (icon-only mode)
|
|
39
|
+
|
|
40
|
+
## Examples
|
|
41
|
+
|
|
42
|
+
### Basic Tab
|
|
43
|
+
|
|
44
|
+
```html
|
|
45
|
+
<brick-tabs>
|
|
46
|
+
<brick-tablist>
|
|
47
|
+
<brick-tab
|
|
48
|
+
data-label="Tab 1"
|
|
49
|
+
data-button-id="tab-1"
|
|
50
|
+
data-panel-id="tab1-panel"
|
|
51
|
+
></brick-tab>
|
|
52
|
+
</brick-tablist>
|
|
53
|
+
|
|
54
|
+
<brick-tabpanel id="tab1-panel" data-labelledby="tab-1">
|
|
55
|
+
<p>Tab 1 content</p>
|
|
56
|
+
</brick-tabpanel>
|
|
57
|
+
</brick-tabs>
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
### Tab with Icon
|
|
61
|
+
|
|
62
|
+
```html
|
|
63
|
+
<brick-tab
|
|
64
|
+
data-label="Volume"
|
|
65
|
+
data-button-id="tab-2"
|
|
66
|
+
data-panel-id="tab2-panel"
|
|
67
|
+
data-icon-id="volume-on"
|
|
68
|
+
></brick-tab>
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
### Icon-Only Tab
|
|
72
|
+
|
|
73
|
+
```html
|
|
74
|
+
<brick-tab
|
|
75
|
+
data-button-id="tab-3"
|
|
76
|
+
data-panel-id="tab3-panel"
|
|
77
|
+
data-icon-id="plusall"
|
|
78
|
+
data-aria-label="Pluss alt abonnement"
|
|
79
|
+
></brick-tab>
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
### Tab with Avatar
|
|
83
|
+
|
|
84
|
+
```html
|
|
85
|
+
<brick-tab
|
|
86
|
+
data-label="Min avis"
|
|
87
|
+
data-button-id="tab-4"
|
|
88
|
+
data-panel-id="tab4-panel"
|
|
89
|
+
data-avatar-urls="https://r.acdn.no/local/v3/publications/www.rastavanger.no/gfx/square.svg"
|
|
90
|
+
></brick-tab>
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
### Tab with Multiple Avatars
|
|
94
|
+
|
|
95
|
+
```html
|
|
96
|
+
<brick-tab
|
|
97
|
+
data-label="Mine aviser"
|
|
98
|
+
data-button-id="tab-5"
|
|
99
|
+
data-panel-id="tab5-panel"
|
|
100
|
+
data-avatar-urls="https://r.acdn.no/local/v3/publications/www.dt.no/gfx/square.svg, https://r.acdn.no/local/v3/publications/www.rastavanger.no/gfx/square.svg, https://r.acdn.no/local/v3/publications/www.ao.no/gfx/square.svg"
|
|
101
|
+
></brick-tab>
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
## Complete Example with brick-tabs
|
|
105
|
+
|
|
106
|
+
```html
|
|
107
|
+
<brick-tabs data-aria-label="Main navigation">
|
|
108
|
+
<brick-tablist>
|
|
109
|
+
<brick-tab
|
|
110
|
+
data-label="For meg"
|
|
111
|
+
data-button-id="tab-1"
|
|
112
|
+
data-panel-id="tab1-panel"
|
|
113
|
+
data-avatar-urls="https://r.acdn.no/local/v3/publications/www.rastavanger.no/gfx/square.svg"
|
|
114
|
+
></brick-tab>
|
|
115
|
+
|
|
116
|
+
<brick-tab
|
|
117
|
+
data-label="Andre aviser"
|
|
118
|
+
data-button-id="tab-2"
|
|
119
|
+
data-panel-id="tab2-panel"
|
|
120
|
+
data-icon-id="volume-on"
|
|
121
|
+
></brick-tab>
|
|
122
|
+
|
|
123
|
+
<brick-tab
|
|
124
|
+
data-label="Dine aviser"
|
|
125
|
+
data-button-id="tab-3"
|
|
126
|
+
data-panel-id="tab3-panel"
|
|
127
|
+
></brick-tab>
|
|
128
|
+
</brick-tablist>
|
|
129
|
+
|
|
130
|
+
<brick-tabpanel id="tab1-panel" data-labelledby="tab-1">
|
|
131
|
+
<p>Content for tab 1</p>
|
|
132
|
+
</brick-tabpanel>
|
|
133
|
+
|
|
134
|
+
<brick-tabpanel id="tab2-panel" data-labelledby="tab-2">
|
|
135
|
+
<p>Content for tab 2</p>
|
|
136
|
+
</brick-tabpanel>
|
|
137
|
+
|
|
138
|
+
<brick-tabpanel id="tab3-panel" data-labelledby="tab-3">
|
|
139
|
+
<p>Content for tab 3</p>
|
|
140
|
+
</brick-tabpanel>
|
|
141
|
+
</brick-tabs>
|
|
142
|
+
```
|
|
143
|
+
|
|
144
|
+
## Server-Side Rendering
|
|
145
|
+
|
|
146
|
+
```javascript
|
|
147
|
+
import { renderBrickTab } from '@amedia/brick-tab/template';
|
|
148
|
+
|
|
149
|
+
const tabHTML = renderBrickTab({
|
|
150
|
+
dataLabel: 'Tab 1',
|
|
151
|
+
dataButtonId: 'tab-1',
|
|
152
|
+
dataPanelId: 'tab1-panel',
|
|
153
|
+
dataIconId: 'volume-on',
|
|
154
|
+
});
|
|
155
|
+
```
|
|
156
|
+
|
|
157
|
+
## Accessibility
|
|
158
|
+
|
|
159
|
+
- Properly implements ARIA tab pattern
|
|
160
|
+
- Tab buttons have `role="tab"`
|
|
161
|
+
- `aria-controls` attribute points to associated panel
|
|
162
|
+
- `aria-selected` managed by brick-tabs parent
|
|
163
|
+
- Icon-only tabs require `data-aria-label` for screen readers
|
|
164
|
+
- Keyboard navigation (Left/Right arrows, Home/End) handled by brick-tabs
|
|
165
|
+
- Focus management handled by brick-tabs parent
|
|
166
|
+
|
|
167
|
+
## Common Patterns
|
|
168
|
+
|
|
169
|
+
### Publication Tabs with Avatars
|
|
170
|
+
|
|
171
|
+
```html
|
|
172
|
+
<brick-tabs>
|
|
173
|
+
<brick-tablist>
|
|
174
|
+
<brick-tab
|
|
175
|
+
data-label="Rogalands Avis"
|
|
176
|
+
data-button-id="tab-ra"
|
|
177
|
+
data-panel-id="panel-ra"
|
|
178
|
+
data-avatar-urls="https://r.acdn.no/local/v3/publications/www.rastavanger.no/gfx/square.svg"
|
|
179
|
+
></brick-tab>
|
|
180
|
+
</brick-tablist>
|
|
181
|
+
|
|
182
|
+
<brick-tabpanel id="panel-ra" data-labelledby="tab-ra">
|
|
183
|
+
<!-- Publication content -->
|
|
184
|
+
</brick-tabpanel>
|
|
185
|
+
</brick-tabs>
|
|
186
|
+
```
|
|
187
|
+
|
|
188
|
+
### Settings Tabs with Icons
|
|
189
|
+
|
|
190
|
+
```html
|
|
191
|
+
<brick-tabs>
|
|
192
|
+
<brick-tablist>
|
|
193
|
+
<brick-tab
|
|
194
|
+
data-label="Account"
|
|
195
|
+
data-icon-id="user"
|
|
196
|
+
data-button-id="tab-account"
|
|
197
|
+
data-panel-id="panel-account"
|
|
198
|
+
></brick-tab>
|
|
199
|
+
|
|
200
|
+
<brick-tab
|
|
201
|
+
data-label="Notifications"
|
|
202
|
+
data-icon-id="bell"
|
|
203
|
+
data-button-id="tab-notifications"
|
|
204
|
+
data-panel-id="panel-notifications"
|
|
205
|
+
></brick-tab>
|
|
206
|
+
</brick-tablist>
|
|
207
|
+
|
|
208
|
+
<brick-tabpanel id="panel-account" data-labelledby="tab-account">
|
|
209
|
+
<!-- Account settings -->
|
|
210
|
+
</brick-tabpanel>
|
|
211
|
+
|
|
212
|
+
<brick-tabpanel id="panel-notifications" data-labelledby="tab-notifications">
|
|
213
|
+
<!-- Notification settings -->
|
|
214
|
+
</brick-tabpanel>
|
|
215
|
+
</brick-tabs>
|
|
216
|
+
```
|
|
217
|
+
|
|
218
|
+
## Technical Details
|
|
219
|
+
|
|
220
|
+
- **Custom Element**: `brick-tab`
|
|
221
|
+
- **Base Class**: BrickElement
|
|
222
|
+
- **Dependencies**:
|
|
223
|
+
- @amedia/brick-template (base class)
|
|
224
|
+
- @amedia/brick-tokens (design tokens)
|
|
225
|
+
- **Parent Component**: Must be used within `brick-tabs` and `brick-tablist`
|
|
226
|
+
- **Renders as**: `<button role="tab">`
|
|
227
|
+
- **SSR Compatible**: Yes, with template function
|
|
228
|
+
|
|
229
|
+
## Important Notes
|
|
230
|
+
|
|
231
|
+
- brick-tab must always be used within brick-tabs and brick-tablist components
|
|
232
|
+
- The `data-button-id` must be unique within the page
|
|
233
|
+
- The `data-panel-id` must match the `id` attribute of the associated brick-tabpanel
|
|
234
|
+
- Icon-only tabs (no `data-label`) require `data-aria-label` for accessibility
|
|
235
|
+
- Avatar URLs in `data-avatar-urls` should be comma-separated for multiple avatars
|
|
236
|
+
- Keyboard navigation and focus management are handled by the parent brick-tabs component
|
|
237
|
+
- The component does not function properly when tested in isolation (requires brick-tabs parent)
|
|
238
|
+
|
|
239
|
+
## Version
|
|
240
|
+
|
|
241
|
+
Current version: 0.1.14
|
|
@@ -0,0 +1,420 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: brick-tabs
|
|
3
|
+
version: 0.1.15
|
|
4
|
+
selector: brick-tabs
|
|
5
|
+
category: Navigation
|
|
6
|
+
tags: [tabs, tablist, tabpanel, navigation, accessibility, aria, container]
|
|
7
|
+
use_cases: [tabbed-navigation, content-organization, settings-panels, category-switching, multi-section-content]
|
|
8
|
+
related: [brick-tab, brick-icon, brick-tokens]
|
|
9
|
+
---
|
|
10
|
+
|
|
11
|
+
# Brick Tabs
|
|
12
|
+
|
|
13
|
+
A container component that implements the ARIA tabs pattern, managing tablist, individual tabs, and tabpanels with full keyboard navigation and accessibility support.
|
|
14
|
+
|
|
15
|
+
## Key Capabilities
|
|
16
|
+
|
|
17
|
+
- Complete ARIA tabs pattern implementation
|
|
18
|
+
- Automatic keyboard navigation (Arrow keys, Home, End)
|
|
19
|
+
- Automatic focus management
|
|
20
|
+
- Pre-select specific tab via attribute
|
|
21
|
+
- Optional border styling
|
|
22
|
+
- Configurable tab wrapping behavior
|
|
23
|
+
- Configurable tab width (full or auto)
|
|
24
|
+
- Manages state for child brick-tab components
|
|
25
|
+
- Full accessibility with ARIA labels
|
|
26
|
+
- Server-side rendering support
|
|
27
|
+
|
|
28
|
+
## Props/Attributes
|
|
29
|
+
|
|
30
|
+
| Attribute | Type | Default | Required | Description |
|
|
31
|
+
| ---------------------- | ------------------------ | ----------- | -------- | --------------------------------------------------------- |
|
|
32
|
+
| `data-aria-label` | string | - | yes | ARIA label for the tablist (e.g., "Main navigation") |
|
|
33
|
+
| `data-selected-panel` | string | First panel | no | ID of panel to show on initial render |
|
|
34
|
+
| `data-border` | string | - | no | Set to "true" to add border styling |
|
|
35
|
+
| `data-wrap` | `"wrap" \| "no-wrap"` | `"no-wrap"` | no | Control tab wrapping behavior |
|
|
36
|
+
| `data-width` | `"full" \| "auto"` | `"auto"` | no | Tab button width (full = 100%, auto = content-based) |
|
|
37
|
+
|
|
38
|
+
## Examples
|
|
39
|
+
|
|
40
|
+
### Basic Tabs
|
|
41
|
+
|
|
42
|
+
```html
|
|
43
|
+
<brick-tabs data-aria-label="Content sections">
|
|
44
|
+
<brick-tablist>
|
|
45
|
+
<brick-tab
|
|
46
|
+
data-label="For meg"
|
|
47
|
+
data-button-id="tab-1"
|
|
48
|
+
data-panel-id="tab1-panel"
|
|
49
|
+
></brick-tab>
|
|
50
|
+
|
|
51
|
+
<brick-tab
|
|
52
|
+
data-label="Andre aviser"
|
|
53
|
+
data-button-id="tab-2"
|
|
54
|
+
data-panel-id="tab2-panel"
|
|
55
|
+
></brick-tab>
|
|
56
|
+
</brick-tablist>
|
|
57
|
+
|
|
58
|
+
<brick-tabpanel id="tab1-panel" data-labelledby="tab-1">
|
|
59
|
+
<p>Content for first tab</p>
|
|
60
|
+
</brick-tabpanel>
|
|
61
|
+
|
|
62
|
+
<brick-tabpanel id="tab2-panel" data-labelledby="tab-2">
|
|
63
|
+
<p>Content for second tab</p>
|
|
64
|
+
</brick-tabpanel>
|
|
65
|
+
</brick-tabs>
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
### Pre-selected Tab
|
|
69
|
+
|
|
70
|
+
```html
|
|
71
|
+
<brick-tabs
|
|
72
|
+
data-aria-label="Navigation"
|
|
73
|
+
data-selected-panel="tab2-panel"
|
|
74
|
+
>
|
|
75
|
+
<brick-tablist>
|
|
76
|
+
<brick-tab
|
|
77
|
+
data-label="Tab 1"
|
|
78
|
+
data-button-id="tab-1"
|
|
79
|
+
data-panel-id="tab1-panel"
|
|
80
|
+
></brick-tab>
|
|
81
|
+
|
|
82
|
+
<brick-tab
|
|
83
|
+
data-label="Tab 2"
|
|
84
|
+
data-button-id="tab-2"
|
|
85
|
+
data-panel-id="tab2-panel"
|
|
86
|
+
></brick-tab>
|
|
87
|
+
</brick-tablist>
|
|
88
|
+
|
|
89
|
+
<brick-tabpanel id="tab1-panel" data-labelledby="tab-1">
|
|
90
|
+
<p>Tab 1 content</p>
|
|
91
|
+
</brick-tabpanel>
|
|
92
|
+
|
|
93
|
+
<brick-tabpanel id="tab2-panel" data-labelledby="tab-2">
|
|
94
|
+
<p>Tab 2 content (initially visible)</p>
|
|
95
|
+
</brick-tabpanel>
|
|
96
|
+
</brick-tabs>
|
|
97
|
+
```
|
|
98
|
+
|
|
99
|
+
### With Border
|
|
100
|
+
|
|
101
|
+
```html
|
|
102
|
+
<brick-tabs
|
|
103
|
+
data-aria-label="Settings"
|
|
104
|
+
data-border="true"
|
|
105
|
+
>
|
|
106
|
+
<brick-tablist>
|
|
107
|
+
<brick-tab
|
|
108
|
+
data-label="Account"
|
|
109
|
+
data-button-id="tab-1"
|
|
110
|
+
data-panel-id="panel-1"
|
|
111
|
+
></brick-tab>
|
|
112
|
+
|
|
113
|
+
<brick-tab
|
|
114
|
+
data-label="Privacy"
|
|
115
|
+
data-button-id="tab-2"
|
|
116
|
+
data-panel-id="panel-2"
|
|
117
|
+
></brick-tab>
|
|
118
|
+
</brick-tablist>
|
|
119
|
+
|
|
120
|
+
<brick-tabpanel id="panel-1" data-labelledby="tab-1">
|
|
121
|
+
<!-- Account settings -->
|
|
122
|
+
</brick-tabpanel>
|
|
123
|
+
|
|
124
|
+
<brick-tabpanel id="panel-2" data-labelledby="tab-2">
|
|
125
|
+
<!-- Privacy settings -->
|
|
126
|
+
</brick-tabpanel>
|
|
127
|
+
</brick-tabs>
|
|
128
|
+
```
|
|
129
|
+
|
|
130
|
+
### Wrapping Tabs with Full Width
|
|
131
|
+
|
|
132
|
+
```html
|
|
133
|
+
<brick-tabs
|
|
134
|
+
data-aria-label="Categories"
|
|
135
|
+
data-wrap="wrap"
|
|
136
|
+
data-width="full"
|
|
137
|
+
>
|
|
138
|
+
<brick-tablist>
|
|
139
|
+
<brick-tab
|
|
140
|
+
data-label="Category 1"
|
|
141
|
+
data-button-id="cat-1"
|
|
142
|
+
data-panel-id="panel-1"
|
|
143
|
+
></brick-tab>
|
|
144
|
+
|
|
145
|
+
<brick-tab
|
|
146
|
+
data-label="Category 2"
|
|
147
|
+
data-button-id="cat-2"
|
|
148
|
+
data-panel-id="panel-2"
|
|
149
|
+
></brick-tab>
|
|
150
|
+
|
|
151
|
+
<brick-tab
|
|
152
|
+
data-label="Category 3"
|
|
153
|
+
data-button-id="cat-3"
|
|
154
|
+
data-panel-id="panel-3"
|
|
155
|
+
></brick-tab>
|
|
156
|
+
|
|
157
|
+
<brick-tab
|
|
158
|
+
data-label="Category 4"
|
|
159
|
+
data-button-id="cat-4"
|
|
160
|
+
data-panel-id="panel-4"
|
|
161
|
+
></brick-tab>
|
|
162
|
+
</brick-tablist>
|
|
163
|
+
|
|
164
|
+
<brick-tabpanel id="panel-1" data-labelledby="cat-1">
|
|
165
|
+
<p>Category 1 content</p>
|
|
166
|
+
</brick-tabpanel>
|
|
167
|
+
|
|
168
|
+
<brick-tabpanel id="panel-2" data-labelledby="cat-2">
|
|
169
|
+
<p>Category 2 content</p>
|
|
170
|
+
</brick-tabpanel>
|
|
171
|
+
|
|
172
|
+
<brick-tabpanel id="panel-3" data-labelledby="cat-3">
|
|
173
|
+
<p>Category 3 content</p>
|
|
174
|
+
</brick-tabpanel>
|
|
175
|
+
|
|
176
|
+
<brick-tabpanel id="panel-4" data-labelledby="cat-4">
|
|
177
|
+
<p>Category 4 content</p>
|
|
178
|
+
</brick-tabpanel>
|
|
179
|
+
</brick-tabs>
|
|
180
|
+
```
|
|
181
|
+
|
|
182
|
+
### Tabs with Icons and Avatars
|
|
183
|
+
|
|
184
|
+
```html
|
|
185
|
+
<brick-tabs data-aria-label="Publications">
|
|
186
|
+
<brick-tablist>
|
|
187
|
+
<brick-tab
|
|
188
|
+
data-label="For meg"
|
|
189
|
+
data-button-id="tab-1"
|
|
190
|
+
data-panel-id="panel-1"
|
|
191
|
+
data-avatar-urls="https://r.acdn.no/local/v3/publications/www.rastavanger.no/gfx/square.svg"
|
|
192
|
+
></brick-tab>
|
|
193
|
+
|
|
194
|
+
<brick-tab
|
|
195
|
+
data-label="Andre aviser"
|
|
196
|
+
data-button-id="tab-2"
|
|
197
|
+
data-panel-id="panel-2"
|
|
198
|
+
data-icon-id="volume-on"
|
|
199
|
+
></brick-tab>
|
|
200
|
+
|
|
201
|
+
<brick-tab
|
|
202
|
+
data-label="Dine aviser"
|
|
203
|
+
data-button-id="tab-3"
|
|
204
|
+
data-panel-id="panel-3"
|
|
205
|
+
></brick-tab>
|
|
206
|
+
</brick-tablist>
|
|
207
|
+
|
|
208
|
+
<brick-tabpanel id="panel-1" data-labelledby="tab-1">
|
|
209
|
+
<p>Personal content</p>
|
|
210
|
+
</brick-tabpanel>
|
|
211
|
+
|
|
212
|
+
<brick-tabpanel id="panel-2" data-labelledby="tab-2">
|
|
213
|
+
<p>Other publications</p>
|
|
214
|
+
</brick-tabpanel>
|
|
215
|
+
|
|
216
|
+
<brick-tabpanel id="panel-3" data-labelledby="tab-3">
|
|
217
|
+
<p>Your publications</p>
|
|
218
|
+
</brick-tabpanel>
|
|
219
|
+
</brick-tabs>
|
|
220
|
+
```
|
|
221
|
+
|
|
222
|
+
## Programmatic Usage
|
|
223
|
+
|
|
224
|
+
### Switch Tabs Programmatically
|
|
225
|
+
|
|
226
|
+
```javascript
|
|
227
|
+
const tabs = document.querySelector('brick-tabs');
|
|
228
|
+
|
|
229
|
+
// Switch to specific panel
|
|
230
|
+
tabs.dataSelectedPanel = 'tab2-panel';
|
|
231
|
+
```
|
|
232
|
+
|
|
233
|
+
### Listen for Tab Changes
|
|
234
|
+
|
|
235
|
+
```javascript
|
|
236
|
+
const tabs = document.querySelector('brick-tabs');
|
|
237
|
+
|
|
238
|
+
tabs.addEventListener('brick-tabs:change', (event) => {
|
|
239
|
+
console.log('Active panel:', event.detail.panelId);
|
|
240
|
+
});
|
|
241
|
+
```
|
|
242
|
+
|
|
243
|
+
## Server-Side Rendering
|
|
244
|
+
|
|
245
|
+
```javascript
|
|
246
|
+
import { renderBrickTabs } from '@amedia/brick-tabs/template';
|
|
247
|
+
|
|
248
|
+
const html = renderBrickTabs({
|
|
249
|
+
dataAriaLabel: 'Main navigation',
|
|
250
|
+
dataSelectedPanel: 'tab1-panel',
|
|
251
|
+
dataBorder: 'true',
|
|
252
|
+
dataWrap: 'wrap',
|
|
253
|
+
dataWidth: 'full',
|
|
254
|
+
});
|
|
255
|
+
```
|
|
256
|
+
|
|
257
|
+
## Keyboard Navigation
|
|
258
|
+
|
|
259
|
+
The component automatically handles keyboard navigation:
|
|
260
|
+
|
|
261
|
+
- **Left Arrow**: Move to previous tab
|
|
262
|
+
- **Right Arrow**: Move to next tab
|
|
263
|
+
- **Home**: Move to first tab
|
|
264
|
+
- **End**: Move to last tab
|
|
265
|
+
- **Tab**: Move focus into active tabpanel content
|
|
266
|
+
|
|
267
|
+
## Accessibility
|
|
268
|
+
|
|
269
|
+
- Implements W3C ARIA Authoring Practices tabs pattern
|
|
270
|
+
- Tablist has `role="tablist"`
|
|
271
|
+
- Each tab has `role="tab"`, `aria-controls`, and `aria-selected`
|
|
272
|
+
- Each tabpanel has `role="tabpanel"` and `aria-labelledby`
|
|
273
|
+
- Keyboard navigation fully supported
|
|
274
|
+
- Focus management automatically handled
|
|
275
|
+
- Only active tabpanel visible to screen readers
|
|
276
|
+
- Required `data-aria-label` for tablist semantic labeling
|
|
277
|
+
|
|
278
|
+
## Common Patterns
|
|
279
|
+
|
|
280
|
+
### Settings Tabs
|
|
281
|
+
|
|
282
|
+
```html
|
|
283
|
+
<brick-tabs data-aria-label="User settings" data-border="true">
|
|
284
|
+
<brick-tablist>
|
|
285
|
+
<brick-tab
|
|
286
|
+
data-label="Profile"
|
|
287
|
+
data-button-id="profile-tab"
|
|
288
|
+
data-panel-id="profile-panel"
|
|
289
|
+
data-icon-id="user"
|
|
290
|
+
></brick-tab>
|
|
291
|
+
|
|
292
|
+
<brick-tab
|
|
293
|
+
data-label="Notifications"
|
|
294
|
+
data-button-id="notifications-tab"
|
|
295
|
+
data-panel-id="notifications-panel"
|
|
296
|
+
data-icon-id="bell"
|
|
297
|
+
></brick-tab>
|
|
298
|
+
|
|
299
|
+
<brick-tab
|
|
300
|
+
data-label="Security"
|
|
301
|
+
data-button-id="security-tab"
|
|
302
|
+
data-panel-id="security-panel"
|
|
303
|
+
data-icon-id="lock"
|
|
304
|
+
></brick-tab>
|
|
305
|
+
</brick-tablist>
|
|
306
|
+
|
|
307
|
+
<brick-tabpanel id="profile-panel" data-labelledby="profile-tab">
|
|
308
|
+
<!-- Profile settings form -->
|
|
309
|
+
</brick-tabpanel>
|
|
310
|
+
|
|
311
|
+
<brick-tabpanel id="notifications-panel" data-labelledby="notifications-tab">
|
|
312
|
+
<!-- Notification preferences -->
|
|
313
|
+
</brick-tabpanel>
|
|
314
|
+
|
|
315
|
+
<brick-tabpanel id="security-panel" data-labelledby="security-tab">
|
|
316
|
+
<!-- Security settings -->
|
|
317
|
+
</brick-tabpanel>
|
|
318
|
+
</brick-tabs>
|
|
319
|
+
```
|
|
320
|
+
|
|
321
|
+
### Content Categories
|
|
322
|
+
|
|
323
|
+
```html
|
|
324
|
+
<brick-tabs data-aria-label="Article categories" data-width="full">
|
|
325
|
+
<brick-tablist>
|
|
326
|
+
<brick-tab
|
|
327
|
+
data-label="Latest"
|
|
328
|
+
data-button-id="latest-tab"
|
|
329
|
+
data-panel-id="latest-panel"
|
|
330
|
+
></brick-tab>
|
|
331
|
+
|
|
332
|
+
<brick-tab
|
|
333
|
+
data-label="Sports"
|
|
334
|
+
data-button-id="sports-tab"
|
|
335
|
+
data-panel-id="sports-panel"
|
|
336
|
+
></brick-tab>
|
|
337
|
+
|
|
338
|
+
<brick-tab
|
|
339
|
+
data-label="Business"
|
|
340
|
+
data-button-id="business-tab"
|
|
341
|
+
data-panel-id="business-panel"
|
|
342
|
+
></brick-tab>
|
|
343
|
+
</brick-tablist>
|
|
344
|
+
|
|
345
|
+
<brick-tabpanel id="latest-panel" data-labelledby="latest-tab">
|
|
346
|
+
<!-- Latest articles -->
|
|
347
|
+
</brick-tabpanel>
|
|
348
|
+
|
|
349
|
+
<brick-tabpanel id="sports-panel" data-labelledby="sports-tab">
|
|
350
|
+
<!-- Sports articles -->
|
|
351
|
+
</brick-tabpanel>
|
|
352
|
+
|
|
353
|
+
<brick-tabpanel id="business-panel" data-labelledby="business-tab">
|
|
354
|
+
<!-- Business articles -->
|
|
355
|
+
</brick-tabpanel>
|
|
356
|
+
</brick-tabs>
|
|
357
|
+
```
|
|
358
|
+
|
|
359
|
+
## Framework Integration
|
|
360
|
+
|
|
361
|
+
### Svelte
|
|
362
|
+
|
|
363
|
+
```svelte
|
|
364
|
+
<script>
|
|
365
|
+
let selectedPanel = 'tab1-panel';
|
|
366
|
+
</script>
|
|
367
|
+
|
|
368
|
+
<brick-tabs
|
|
369
|
+
data-aria-label="Navigation"
|
|
370
|
+
data-selected-panel={selectedPanel}
|
|
371
|
+
>
|
|
372
|
+
<brick-tablist>
|
|
373
|
+
<brick-tab
|
|
374
|
+
data-label="Tab 1"
|
|
375
|
+
data-button-id="tab-1"
|
|
376
|
+
data-panel-id="tab1-panel"
|
|
377
|
+
/>
|
|
378
|
+
<brick-tab
|
|
379
|
+
data-label="Tab 2"
|
|
380
|
+
data-button-id="tab-2"
|
|
381
|
+
data-panel-id="tab2-panel"
|
|
382
|
+
/>
|
|
383
|
+
</brick-tablist>
|
|
384
|
+
|
|
385
|
+
<brick-tabpanel id="tab1-panel" data-labelledby="tab-1">
|
|
386
|
+
<p>Tab 1 content</p>
|
|
387
|
+
</brick-tabpanel>
|
|
388
|
+
|
|
389
|
+
<brick-tabpanel id="tab2-panel" data-labelledby="tab-2">
|
|
390
|
+
<p>Tab 2 content</p>
|
|
391
|
+
</brick-tabpanel>
|
|
392
|
+
</brick-tabs>
|
|
393
|
+
```
|
|
394
|
+
|
|
395
|
+
## Technical Details
|
|
396
|
+
|
|
397
|
+
- **Custom Element**: `brick-tabs`
|
|
398
|
+
- **Base Class**: BrickElement
|
|
399
|
+
- **Dependencies**:
|
|
400
|
+
- @amedia/brick-tab (tab buttons)
|
|
401
|
+
- @amedia/brick-template (base class)
|
|
402
|
+
- @amedia/brick-tokens (design tokens)
|
|
403
|
+
- **Child Components**: Requires brick-tablist, brick-tab, and brick-tabpanel
|
|
404
|
+
- **Renders as**: Container div managing tablist and tabpanels
|
|
405
|
+
- **SSR Compatible**: Yes, with template function
|
|
406
|
+
|
|
407
|
+
## Important Notes
|
|
408
|
+
|
|
409
|
+
- Must contain brick-tablist with brick-tab children and brick-tabpanel siblings
|
|
410
|
+
- Each brick-tab's `data-panel-id` must match a brick-tabpanel's `id` attribute
|
|
411
|
+
- Each brick-tabpanel's `data-labelledby` must match a brick-tab's `data-button-id`
|
|
412
|
+
- The `data-aria-label` is required for proper accessibility
|
|
413
|
+
- First tab/panel is selected by default unless `data-selected-panel` is specified
|
|
414
|
+
- Tab IDs must be unique within the page
|
|
415
|
+
- Keyboard navigation is automatic and cannot be disabled
|
|
416
|
+
- Only one tabpanel is visible at a time (others are hidden with `display: none`)
|
|
417
|
+
|
|
418
|
+
## Version
|
|
419
|
+
|
|
420
|
+
Current version: 0.1.15
|