@magic-spells/tab-group 0.1.0

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/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2025 Magic Spells (Cory Schulz)
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,298 @@
1
+ # ✨ Tab Group
2
+
3
+ ![License: MIT](https://img.shields.io/badge/License-MIT-blue.svg)
4
+ ![Version](https://img.shields.io/badge/version-0.1.0-brightgreen)
5
+
6
+ A lightweight, accessible tab interface web component with keyboard navigation and rich customization options.
7
+
8
+ 🔍 **[Live Demo](https://magic-spells.github.io/tab-group/demo/)** - See it in action!
9
+
10
+ ## 🚀 Features
11
+
12
+ - **Fully Accessible** - Built following WAI-ARIA Tab pattern guidelines
13
+ - **Custom Events** - Listen for tab changes with detailed event data
14
+ - **Keyboard Navigation** - Complete keyboard support for accessibility
15
+ - **Auto Consistency** - Ensures tab buttons and panels stay in sync
16
+ - **Theme Support** - Extensive CSS variable customization
17
+ - **Zero Dependencies** - Lightweight and standalone
18
+ - **Easy Integration** - Works with any framework or vanilla JS
19
+
20
+ ## 📦 Installation
21
+
22
+ ```bash
23
+ # npm
24
+ npm install @magic-spells/tab-group
25
+
26
+ # yarn
27
+ yarn add @magic-spells/tab-group
28
+
29
+ # pnpm
30
+ pnpm add @magic-spells/tab-group
31
+ ```
32
+
33
+ ## 🔧 Usage
34
+
35
+ ### Basic Implementation
36
+
37
+ ```html
38
+ <!-- Import the component -->
39
+ <script type="module">
40
+ import '@magic-spells/tab-group';
41
+ </script>
42
+
43
+ <!-- Use the component -->
44
+ <tab-group>
45
+ <tab-list>
46
+ <tab-button>First Tab</tab-button>
47
+ <tab-button>Second Tab</tab-button>
48
+ <tab-button>Third Tab</tab-button>
49
+ </tab-list>
50
+
51
+ <tab-panel>
52
+ <h3>First Tab Content</h3>
53
+ <p>This is the content for the first tab.</p>
54
+ </tab-panel>
55
+
56
+ <tab-panel>
57
+ <h3>Second Tab Content</h3>
58
+ <p>This is the content for the second tab.</p>
59
+ </tab-panel>
60
+
61
+ <tab-panel>
62
+ <h3>Third Tab Content</h3>
63
+ <p>This is the content for the third tab.</p>
64
+ </tab-panel>
65
+ </tab-group>
66
+ ```
67
+
68
+ ### Listening for Tab Changes
69
+
70
+ ```javascript
71
+ document
72
+ .querySelector('tab-group')
73
+ .addEventListener('tabchange', (event) => {
74
+ console.log('Tab changed!');
75
+
76
+ // Access detailed event data
77
+ const {
78
+ previousIndex, // Index of previous tab
79
+ currentIndex, // Index of current tab
80
+ previousTab, // Previous tab element
81
+ currentTab, // Current tab element
82
+ previousPanel, // Previous panel element
83
+ currentPanel, // Current panel element
84
+ } = event.detail;
85
+
86
+ // Do something with the data
87
+ console.log(
88
+ `Changed from tab ${previousIndex} to tab ${currentIndex}`
89
+ );
90
+ });
91
+ ```
92
+
93
+ ## 🎨 Styling
94
+
95
+ ### CSS Variables
96
+
97
+ The Tab Group component can be extensively customized using CSS variables:
98
+
99
+ ```css
100
+ tab-group {
101
+ /* Base colors */
102
+ --color-background: #ffffff;
103
+ --color-text: #333333;
104
+ --color-border: #dddddd;
105
+ --color-border-hover: #bbbbbb;
106
+ --color-primary: #3366ff;
107
+ --color-hover: #f0f5ff;
108
+ --color-focus: #b3cbff;
109
+
110
+ /* Panel styling */
111
+ --panel-background: white;
112
+ --panel-border: 1px solid var(--color-border);
113
+ --panel-padding: 1rem;
114
+ --panel-radius: 0 0 0.5rem 0.5rem;
115
+ --panel-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
116
+
117
+ /* Tab list styling */
118
+ --tab-list-gap: 0.25rem;
119
+ --tab-list-padding: 0.5rem 0.5rem 0;
120
+ --tab-list-background: transparent;
121
+ --tab-list-border-bottom: 1px solid var(--color-border);
122
+ --tab-list-radius: 0.5rem 0.5rem 0 0;
123
+
124
+ /* Tab button styling */
125
+ --tab-button-radius: 0.25rem 0.25rem 0 0;
126
+ --tab-active-background: white;
127
+ --tab-active-color: var(--color-primary);
128
+ --tab-active-font-weight: 500;
129
+ --tab-active-shadow: none;
130
+ --tab-active-transform: translateY(0);
131
+
132
+ /* Tab indicator styling */
133
+ --tab-indicator-height: 2px;
134
+ --tab-indicator-color: var(--color-primary);
135
+ --tab-indicator-left: 0;
136
+ --tab-indicator-right: 0;
137
+ }
138
+ ```
139
+
140
+ ### SCSS Integration
141
+
142
+ This package provides multiple ways to integrate with your SCSS workflow:
143
+
144
+ ```scss
145
+ // Option 1: Use the main entry point (recommended)
146
+ @use "@magic-spells/tab-group/scss" with (
147
+ $color-primary: #3366ff,
148
+ $border-radius: 0.5rem
149
+ );
150
+
151
+ // Option 2: Import individual files
152
+ @use "@magic-spells/tab-group/scss/variables" with (
153
+ $color-primary: #3366ff,
154
+ $border-radius: 0.5rem
155
+ );
156
+ @use "@magic-spells/tab-group/scss/tab-group";
157
+
158
+ // Option 3: Direct paths (if needed)
159
+ @use "node_modules/@magic-spells/tab-group/dist/tab-group.scss";
160
+ @use "node_modules/@magic-spells/tab-group/dist/scss/tab-group";
161
+ ```
162
+
163
+ #### Available SCSS Variables
164
+
165
+ You can customize the appearance by overriding these SCSS variables:
166
+
167
+ ```scss
168
+ // Colors
169
+ $color-background: #ffffff !default;
170
+ $color-text: #333333 !default;
171
+ $color-border: #dddddd !default;
172
+ $color-border-hover: #bbbbbb !default;
173
+ $color-border-dark: #999999 !default;
174
+ $color-primary: #3366ff !default;
175
+ $color-hover: #f0f5ff !default;
176
+ $color-focus: #b3cbff !default;
177
+
178
+ // Border radius
179
+ $border-radius: 0.5rem !default;
180
+
181
+ // Box shadow
182
+ $box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1) !default;
183
+
184
+ // Tab list
185
+ $tab-list-gap: 0.25rem !default;
186
+ $tab-list-padding: 0.5rem 0.5rem 0 !default;
187
+ $tab-list-background: transparent !default;
188
+ $tab-list-border-bottom: 1px solid $color-border !default;
189
+ $tab-list-radius: $border-radius $border-radius 0 0 !default;
190
+
191
+ // Tab button
192
+ $tab-button-radius: 0.25rem 0.25rem 0 0 !default;
193
+ $tab-active-background: white !default;
194
+ $tab-active-color: $color-primary !default;
195
+ $tab-active-font-weight: 500 !default;
196
+ $tab-active-shadow: none !default;
197
+ $tab-active-transform: translateY(0) !default;
198
+
199
+ // Tab indicator
200
+ $tab-indicator-height: 2px !default;
201
+ $tab-indicator-color: $color-primary !default;
202
+ $tab-indicator-left: 0 !default;
203
+ $tab-indicator-right: 0 !default;
204
+
205
+ // Panel
206
+ $panel-background: white !default;
207
+ $panel-border: 1px solid $color-border !default;
208
+ $panel-padding: 1rem !default;
209
+ $panel-radius: 0 0 $border-radius $border-radius !default;
210
+ $panel-shadow: $box-shadow !default;
211
+ ```
212
+
213
+ ## 🌈 Theme Examples
214
+
215
+ ### Dark Theme
216
+
217
+ ```css
218
+ tab-group {
219
+ --color-background: #2d3748;
220
+ --color-text: #e2e8f0;
221
+ --color-border: #4a5568;
222
+ --color-border-hover: #718096;
223
+ --color-primary: #4299e1;
224
+ --color-hover: #1a202c;
225
+ --color-focus: #2c5282;
226
+ --panel-background: #1e293b;
227
+ --panel-border: 1px solid #4a5568;
228
+ --panel-shadow: 0 4px 6px rgba(0, 0, 0, 0.3);
229
+ --tab-active-color: #63b3ed;
230
+ --tab-indicator-color: #63b3ed;
231
+ }
232
+ ```
233
+
234
+ ### Rounded Pills Theme
235
+
236
+ ```css
237
+ tab-group {
238
+ --border-radius: 0.5rem;
239
+ --color-primary: #9f7aea;
240
+ --color-focus: #e9d8fd;
241
+ --tab-button-radius: 999px;
242
+ --tab-list-padding: 0.75rem 0.5rem 0;
243
+ --tab-list-gap: 0.5rem;
244
+ --panel-radius: 1rem;
245
+ --panel-shadow: 0 4px 12px rgba(159, 122, 234, 0.15);
246
+ --panel-border: 1px solid #e9d8fd;
247
+ --panel-padding: 1.5rem;
248
+ --tab-active-background: #9f7aea;
249
+ --tab-active-color: white;
250
+ --tab-active-font-weight: 500;
251
+ --tab-active-transform: translateY(-3px);
252
+ --tab-active-shadow: 0 4px 8px rgba(159, 122, 234, 0.3);
253
+ --tab-indicator-height: 0;
254
+ }
255
+ ```
256
+
257
+ ## ⌨️ Accessibility
258
+
259
+ The Tab Group component follows the [WAI-ARIA Tabs Pattern](https://www.w3.org/WAI/ARIA/apg/patterns/tabs/) with:
260
+
261
+ - Proper ARIA roles, states, and properties
262
+ - Keyboard navigation:
263
+ - `Tab` to focus the active tab button
264
+ - `←` / `↑` to move to the previous tab
265
+ - `→` / `↓` to move to the next tab
266
+ - `Home` to move to the first tab
267
+ - `End` to move to the last tab
268
+
269
+ ## 🛠️ API Reference
270
+
271
+ ### Components
272
+
273
+ | Element | Description |
274
+ | -------------- | -------------------------------------- |
275
+ | `<tab-group>` | Container for the entire tab interface |
276
+ | `<tab-list>` | Container for tab buttons |
277
+ | `<tab-button>` | Individual tab trigger |
278
+ | `<tab-panel>` | Content container for each tab |
279
+
280
+ ### Events
281
+
282
+ | Event | Detail | Description |
283
+ | ----------- | --------------------------------------------------------------------------------------- | --------------------------------- |
284
+ | `tabchange` | `{ previousIndex, currentIndex, previousTab, currentTab, previousPanel, currentPanel }` | Fired when the active tab changes |
285
+
286
+ ## 🌟 Examples
287
+
288
+ Check out more examples in the [demo directory](https://github.com/magic-spells/tab-group/tree/main/demo).
289
+
290
+ ## 📄 License
291
+
292
+ This project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details.
293
+
294
+ ---
295
+
296
+ <p align="center">
297
+ Made with ✨ by <a href="https://github.com/cory-schulz">Cory Schulz</a>
298
+ </p>
@@ -0,0 +1,125 @@
1
+ // Tab Group base styles
2
+ tab-group {
3
+ display: block;
4
+ width: 100%;
5
+ font-family: var(--font-family);
6
+ font-size: var(--font-size-base);
7
+ line-height: var(--line-height);
8
+ color: var(--color-text);
9
+ }
10
+
11
+ // Tab List styles
12
+ tab-list {
13
+ display: flex;
14
+ border-bottom: var(
15
+ --tab-list-border-bottom,
16
+ 1px solid var(--color-border)
17
+ );
18
+ margin-bottom: var(--spacing-md);
19
+ overflow-x: auto;
20
+ overflow-y: hidden;
21
+ padding: var(--tab-list-padding, 0.5rem 0.25rem 0);
22
+ gap: var(--tab-list-gap, 0.25rem);
23
+ justify-content: var(--tab-list-justify, flex-start);
24
+ background-color: var(--tab-list-background, transparent);
25
+ background-image: var(--tab-list-background-image, none);
26
+ border-radius: var(--tab-list-radius, 0);
27
+ }
28
+
29
+ // Tab Button styles
30
+ tab-button {
31
+ display: block;
32
+ padding: var(--spacing-sm) var(--spacing-md);
33
+ margin: var(--spacing-xs);
34
+ border: 1px solid transparent;
35
+ border-bottom: none;
36
+ background-color: var(--color-background);
37
+ color: var(--color-text);
38
+ cursor: pointer;
39
+ border-radius: var(
40
+ --tab-button-radius,
41
+ var(--border-radius) var(--border-radius) 0 0
42
+ );
43
+ white-space: nowrap;
44
+ user-select: none;
45
+ transition: all var(--transition-duration);
46
+ margin-bottom: -1px;
47
+ position: relative;
48
+ font-size: var(--font-size-base);
49
+ font-weight: var(--tab-button-font-weight, normal);
50
+ text-align: center;
51
+ min-width: 100px;
52
+
53
+ &:hover {
54
+ background-color: var(--color-hover);
55
+ }
56
+
57
+ &:focus {
58
+ outline: none;
59
+ box-shadow: var(
60
+ --tab-button-focus-shadow,
61
+ 0 0 0 2px var(--color-primary)
62
+ );
63
+ }
64
+
65
+ &[aria-selected='true'] {
66
+ background-color: var(
67
+ --tab-active-background,
68
+ var(--color-background)
69
+ );
70
+ border-color: var(--color-border);
71
+ border-bottom: 1px solid var(--color-background);
72
+ font-weight: var(--tab-active-font-weight, 600);
73
+ color: var(--tab-active-color, var(--color-primary));
74
+ box-shadow: var(--tab-active-shadow, none);
75
+ transform: var(--tab-active-transform, none);
76
+
77
+ &::after {
78
+ content: '';
79
+ position: absolute;
80
+ bottom: 0;
81
+ left: var(--tab-indicator-left, 0);
82
+ right: var(--tab-indicator-right, 0);
83
+ height: var(--tab-indicator-height, 2px);
84
+ background-color: var(
85
+ --tab-indicator-color,
86
+ var(--color-primary)
87
+ );
88
+ border-radius: var(--tab-indicator-radius, 0);
89
+ }
90
+ }
91
+ }
92
+
93
+ // Tab Panel styles
94
+ tab-panel {
95
+ display: block;
96
+ padding: var(--panel-padding, var(--spacing-md));
97
+ background-color: var(--panel-background, var(--color-background));
98
+ border-radius: var(
99
+ --panel-radius,
100
+ 0 0 var(--border-radius) var(--border-radius)
101
+ );
102
+ border: var(--panel-border, none);
103
+ border-top: var(--panel-border-top, none);
104
+ box-shadow: var(--panel-shadow, none);
105
+ transition: var(--panel-transition, all 0.3s ease);
106
+ margin: var(--panel-margin, 0);
107
+ min-height: var(--panel-min-height, 150px);
108
+
109
+ // When hidden (using the hidden attribute)
110
+ &[hidden] {
111
+ display: none;
112
+ }
113
+ }
114
+
115
+ // Responsive adjustments
116
+ @media (max-width: 768px) {
117
+ tab-list {
118
+ flex-wrap: wrap;
119
+ }
120
+
121
+ tab-button {
122
+ flex: 1 0 auto;
123
+ text-align: center;
124
+ }
125
+ }
File without changes