@rhavenside/baseline-ui 1.0.0 → 1.0.2

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.
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../src/js/components/modal.js", "../src/js/components/dropdown.js", "../src/js/components/tooltip.js", "../src/js/components/tabs.js", "../src/js/components/alert.js", "../src/js/baseline.js"],
4
+ "sourcesContent": ["// ============================================================================\n// Modal Component JavaScript\n// ============================================================================\n\nexport function initModal(modalElement) {\n if (!modalElement) return;\n\n const backdrop = modalElement.querySelector('.bl-modal-backdrop') || document.createElement('div');\n if (!backdrop.classList.contains('bl-modal-backdrop')) {\n backdrop.className = 'bl-modal-backdrop';\n modalElement.insertBefore(backdrop, modalElement.firstChild);\n }\n\n // Open modal buttons\n const modalId = modalElement.id;\n if (modalId) {\n const openButtons = document.querySelectorAll(`[data-modal-open=\"${modalId}\"]`);\n openButtons.forEach(btn => {\n btn.addEventListener('click', () => {\n openModal(modalId);\n });\n });\n }\n\n // Close modal buttons\n const closeButtons = modalElement.querySelectorAll('.bl-modal-close, [data-modal-close]');\n closeButtons.forEach(btn => {\n btn.addEventListener('click', () => {\n closeModal(modalId);\n });\n });\n\n // Close on backdrop click\n backdrop.addEventListener('click', (e) => {\n if (e.target === backdrop) {\n closeModal(modalId);\n }\n });\n\n // Close on ESC key\n const escHandler = (e) => {\n if (e.key === 'Escape' && modalElement.style.display === 'block') {\n closeModal(modalId);\n }\n };\n document.addEventListener('keydown', escHandler);\n \n // Store handler for cleanup if needed\n modalElement._escHandler = escHandler;\n}\n\nexport function openModal(modalId) {\n const modal = document.getElementById(modalId);\n if (modal) {\n modal.style.display = 'block';\n document.body.style.overflow = 'hidden';\n }\n}\n\nexport function closeModal(modalId) {\n const modal = document.getElementById(modalId);\n if (modal) {\n modal.style.display = 'none';\n document.body.style.overflow = '';\n }\n}\n\n", "// ============================================================================\n// Dropdown Component JavaScript\n// ============================================================================\n\nexport function initDropdown(dropdownElement) {\n if (!dropdownElement) return;\n\n const toggle = dropdownElement.querySelector('.bl-dropdown-toggle');\n const menu = dropdownElement.querySelector('.bl-dropdown-menu');\n\n if (!toggle || !menu) return;\n\n toggle.addEventListener('click', (e) => {\n e.preventDefault();\n e.stopPropagation();\n\n // Close all other dropdowns\n document.querySelectorAll('.bl-dropdown-menu.bl-show').forEach(otherMenu => {\n if (otherMenu !== menu) {\n otherMenu.classList.remove('bl-show');\n }\n });\n\n // Toggle current dropdown\n menu.classList.toggle('bl-show');\n });\n\n // Close on outside click\n const outsideClickHandler = (e) => {\n if (!dropdownElement.contains(e.target)) {\n menu.classList.remove('bl-show');\n }\n };\n \n document.addEventListener('click', outsideClickHandler);\n \n // Store handler for cleanup if needed\n dropdownElement._outsideClickHandler = outsideClickHandler;\n}\n\n", "// ============================================================================\n// Tooltip Component JavaScript\n// ============================================================================\n\nexport function initTooltip(tooltipElement) {\n if (!tooltipElement) return;\n\n const trigger = tooltipElement.querySelector('.bl-tooltip-trigger');\n const content = tooltipElement.querySelector('.bl-tooltip-content');\n\n if (!trigger || !content) return;\n\n trigger.addEventListener('mouseenter', () => {\n content.classList.add('bl-show');\n });\n\n trigger.addEventListener('mouseleave', () => {\n content.classList.remove('bl-show');\n });\n}\n\n", "// ============================================================================\n// Tabs Component JavaScript\n// ============================================================================\n\nexport function initTabs(tabsContainer) {\n if (!tabsContainer) return;\n\n const tabLinks = tabsContainer.querySelectorAll('.bl-nav-link[data-tab-target]');\n const tabGroup = tabsContainer.getAttribute('data-tab-group');\n\n tabLinks.forEach(link => {\n link.addEventListener('click', (e) => {\n e.preventDefault();\n\n // Remove active from all tabs in group\n if (tabGroup) {\n document.querySelectorAll(`[data-tab-group=\"${tabGroup}\"] .bl-nav-link`).forEach(l => {\n l.classList.remove('bl-active');\n });\n } else {\n tabsContainer.querySelectorAll('.bl-nav-link').forEach(l => {\n l.classList.remove('bl-active');\n });\n }\n\n // Add active to clicked tab\n link.classList.add('bl-active');\n\n // Show/hide tab content\n const targetId = link.getAttribute('data-tab-target');\n if (targetId) {\n // Find all tab contents - search in parent container or document\n const container = tabsContainer.closest('.docs-example-preview') || \n tabsContainer.parentElement || \n document;\n \n container.querySelectorAll('[data-tab-content]').forEach(content => {\n content.style.display = 'none';\n });\n\n const targetContent = document.getElementById(targetId);\n if (targetContent) {\n targetContent.style.display = 'block';\n }\n }\n });\n });\n}\n\n", "// ============================================================================\n// Alert Component JavaScript\n// ============================================================================\n\nexport function initAlert(alertElement) {\n if (!alertElement) return;\n\n const closeBtn = alertElement.querySelector('.bl-alert-close');\n if (!closeBtn) return;\n\n closeBtn.addEventListener('click', () => {\n dismissAlert(alertElement);\n });\n}\n\nexport function dismissAlert(alertElement) {\n if (!alertElement) return;\n \n alertElement.style.transition = 'opacity 0.3s ease-out';\n alertElement.style.opacity = '0';\n setTimeout(() => {\n alertElement.remove();\n }, 300);\n}\n\n", "// ============================================================================\n// Baseline UI JavaScript\n// Main Entry Point\n// ============================================================================\n\nimport { initModal, openModal, closeModal } from './components/modal.js';\nimport { initDropdown } from './components/dropdown.js';\nimport { initTooltip } from './components/tooltip.js';\nimport { initTabs } from './components/tabs.js';\nimport { initAlert, dismissAlert } from './components/alert.js';\n\n// Export all functions for manual use\nexport {\n initModal,\n openModal,\n closeModal,\n initDropdown,\n initTooltip,\n initTabs,\n initAlert,\n dismissAlert\n};\n\n// Auto-initialize on DOM ready\nfunction autoInit() {\n // Initialize all modals\n document.querySelectorAll('.bl-modal').forEach(modal => {\n initModal(modal);\n });\n\n // Initialize all dropdowns\n document.querySelectorAll('.bl-dropdown').forEach(dropdown => {\n initDropdown(dropdown);\n });\n\n // Initialize all tooltips\n document.querySelectorAll('.bl-tooltip').forEach(tooltip => {\n initTooltip(tooltip);\n });\n\n // Initialize all tabs\n document.querySelectorAll('.bl-nav-tabs').forEach(tabs => {\n initTabs(tabs);\n });\n\n // Initialize all dismissible alerts\n document.querySelectorAll('.bl-alert-dismissible').forEach(alert => {\n initAlert(alert);\n });\n}\n\n// Initialize when DOM is ready\nif (document.readyState === 'loading') {\n document.addEventListener('DOMContentLoaded', autoInit);\n} else {\n autoInit();\n}\n\n"],
5
+ "mappings": "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",
6
+ "names": ["initModal", "modalElement", "backdrop", "modalId", "btn", "openModal", "closeModal", "e", "escHandler", "modal", "initDropdown", "dropdownElement", "toggle", "menu", "e", "otherMenu", "outsideClickHandler", "initTooltip", "tooltipElement", "trigger", "content", "initTabs", "tabsContainer", "tabLinks", "tabGroup", "link", "e", "l", "targetId", "content", "targetContent", "initAlert", "alertElement", "closeBtn", "dismissAlert", "autoInit", "modal", "initModal", "dropdown", "initDropdown", "tooltip", "initTooltip", "tabs", "initTabs", "alert", "initAlert"]
7
+ }
package/package.json CHANGED
@@ -1,11 +1,12 @@
1
1
  {
2
2
  "name": "@rhavenside/baseline-ui",
3
- "version": "1.0.0",
3
+ "version": "1.0.2",
4
4
  "type": "module",
5
5
  "description": "A technical glass design framework with SCSS source and compiled CSS - minimalist, rectangular forms with milky glass effects",
6
6
  "main": "dist/baseline.css",
7
7
  "style": "dist/baseline.css",
8
8
  "sass": "src/baseline.scss",
9
+ "js": "dist/baseline.js",
9
10
  "files": [
10
11
  "dist",
11
12
  "src",
@@ -13,11 +14,18 @@
13
14
  "CHANGELOG.md",
14
15
  "LICENSE"
15
16
  ],
17
+ "exports": {
18
+ ".": {
19
+ "style": "./dist/baseline.css",
20
+ "sass": "./src/baseline.scss",
21
+ "js": "./dist/baseline.js",
22
+ "default": "./dist/baseline.css"
23
+ }
24
+ },
16
25
  "scripts": {
17
26
  "build": "node build.js",
18
27
  "watch": "node build.js --watch",
19
- "docs:dev": "storybook dev -p 6006",
20
- "docs:build": "storybook build",
28
+ "docs": "open docs/index.html",
21
29
  "prepublishOnly": "npm run build"
22
30
  },
23
31
  "keywords": [
@@ -33,7 +41,8 @@
33
41
  "glassmorphism",
34
42
  "technical-design",
35
43
  "minimalist",
36
- "glass-effect"
44
+ "glass-effect",
45
+ "javascript"
37
46
  ],
38
47
  "author": "",
39
48
  "license": "MIT",
@@ -46,14 +55,7 @@
46
55
  },
47
56
  "homepage": "https://github.com/e7a-0-e7a/baseline#readme",
48
57
  "devDependencies": {
49
- "@storybook/addon-essentials": "^7.6.21",
50
- "@storybook/addon-interactions": "^7.6.21",
51
- "@storybook/addon-links": "^7.6.21",
52
- "@storybook/blocks": "^7.6.21",
53
- "@storybook/html": "^7.6.21",
54
- "@storybook/html-webpack5": "^7.6.21",
55
- "@storybook/test": "^7.6.21",
56
58
  "sass": "^1.69.0",
57
- "storybook": "^7.6.21"
59
+ "esbuild": "^0.19.0"
58
60
  }
59
61
  }
@@ -17,8 +17,12 @@
17
17
  position: relative;
18
18
 
19
19
  // Optional: Vertical accent line at edge
20
- &.bl-card-accent {
21
- border-left: 2px solid var(--color-accent);
20
+ &.bl-card-accent-left {
21
+ border-left: 4px solid var(--color-accent);
22
+ }
23
+
24
+ &.bl-card-accent-right {
25
+ border-right: 4px solid var(--color-accent);
22
26
  }
23
27
  }
24
28
 
@@ -60,18 +64,10 @@
60
64
  // Card Variants
61
65
  .bl-card-primary {
62
66
  border-color: var(--color-accent);
63
-
64
- &.bl-card-accent {
65
- border-left-color: var(--color-accent);
66
- }
67
67
  }
68
68
 
69
69
  .bl-card-secondary {
70
70
  border-color: var(--glass-border-heavy);
71
-
72
- &.bl-card-accent {
73
- border-left-color: var(--color-secondary);
74
- }
75
71
  }
76
72
 
77
73
  // Card with Shadow
@@ -26,7 +26,7 @@
26
26
  position: absolute;
27
27
  top: 100%;
28
28
  left: 0;
29
- z-index: var(--z-index-dropdown);
29
+ z-index: 99999 !important; // Immer ganz oben
30
30
  display: none;
31
31
  min-width: 10rem;
32
32
  padding: var(--spacing-xs) 0;
@@ -41,6 +41,9 @@
41
41
  border: 1px solid var(--glass-border-medium);
42
42
  border-radius: var(--tech-border-radius-md);
43
43
  overflow: hidden;
44
+ overflow-y: auto;
45
+ max-height: 300px;
46
+ box-shadow: var(--glass-shadow-lg);
44
47
 
45
48
  &.bl-show {
46
49
  display: block;
@@ -73,40 +73,191 @@
73
73
  }
74
74
  }
75
75
 
76
- // Select (Mechanical Switch, Angular Arrow)
76
+ // Select (wird automatisch zu Dropdown umgewandelt)
77
77
  .bl-select {
78
+ // Wird durch JavaScript in .bl-select-dropdown umgewandelt
79
+ // Fallback-Styling für den Fall, dass JS nicht lädt
78
80
  display: block;
79
81
  width: 100%;
80
82
  padding: var(--form-input-padding-y) var(--form-input-padding-x);
81
- padding-right: calc(var(--form-input-padding-x) + 1.5rem); // Space for arrow
83
+ padding-right: calc(var(--form-input-padding-x) + 1.5rem);
82
84
  font-family: var(--font-family-base);
83
85
  font-size: var(--form-input-font-size);
84
86
  line-height: var(--form-input-line-height);
85
87
  color: var(--color-text);
86
- background: var(--glass-bg-light);
88
+ background: var(--glass-bg-medium);
87
89
  border: 1px solid var(--glass-border-medium);
88
- border-radius: var(--tech-border-radius-sm);
89
- backdrop-filter: blur(var(--glass-blur-md));
90
- -webkit-backdrop-filter: blur(var(--glass-blur-md));
90
+ border-radius: var(--tech-border-radius-md);
91
+ backdrop-filter: blur(var(--glass-blur-lg));
92
+ -webkit-backdrop-filter: blur(var(--glass-blur-lg));
91
93
  transition: var(--transition-base);
92
94
  cursor: pointer;
93
95
  appearance: none;
96
+ -webkit-appearance: none;
97
+ -moz-appearance: none;
94
98
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='8' height='8' viewBox='0 0 8 8'%3E%3Cpath fill='%23ffffff' d='M0 2l4 4 4-4z'/%3E%3C/svg%3E");
95
99
  background-repeat: no-repeat;
96
100
  background-position: right var(--form-input-padding-x) center;
97
101
  background-size: 0.75rem;
102
+ box-shadow: var(--glass-shadow-sm);
98
103
 
99
104
  &:focus {
100
105
  outline: none;
101
106
  border-width: 2px;
102
107
  border-color: var(--color-accent);
103
108
  background-color: var(--glass-bg-medium);
109
+ box-shadow: var(--glass-shadow-md), 0 0 0 1px var(--color-accent);
110
+ }
111
+
112
+ &:hover {
113
+ background-color: var(--glass-bg-heavy);
114
+ border-color: var(--glass-border-heavy);
104
115
  }
105
116
 
106
117
  &:disabled {
107
118
  opacity: var(--form-input-opacity-disabled);
108
119
  cursor: not-allowed;
109
120
  background-color: var(--glass-bg-dark);
121
+ box-shadow: none;
122
+ }
123
+
124
+ // Wenn Select in Dropdown umgewandelt wurde, verstecken
125
+ &.bl-select-converted {
126
+ display: none;
127
+ }
128
+ }
129
+
130
+ // Select Dropdown (automatisch generiert aus .bl-select)
131
+ .bl-select-dropdown {
132
+ position: relative;
133
+ display: block;
134
+ width: 100%;
135
+
136
+ .bl-select-toggle {
137
+ display: flex;
138
+ align-items: center;
139
+ justify-content: space-between;
140
+ width: 100%;
141
+ padding: var(--form-input-padding-y) var(--form-input-padding-x);
142
+ font-family: var(--font-family-base);
143
+ font-size: var(--form-input-font-size);
144
+ line-height: var(--form-input-line-height);
145
+ color: var(--color-text);
146
+ background: var(--glass-bg-medium);
147
+ border: 1px solid var(--glass-border-medium);
148
+ border-radius: var(--tech-border-radius-md);
149
+ backdrop-filter: blur(var(--glass-blur-lg));
150
+ -webkit-backdrop-filter: blur(var(--glass-blur-lg));
151
+ transition: var(--transition-base);
152
+ cursor: pointer;
153
+ box-shadow: var(--glass-shadow-sm);
154
+ text-align: left;
155
+ border: none; // Reset button border
156
+
157
+ &::after {
158
+ display: inline-block;
159
+ margin-left: var(--spacing-xs);
160
+ vertical-align: 0.255em;
161
+ content: "";
162
+ border-top: 0.3em solid var(--color-text);
163
+ border-right: 0.3em solid transparent;
164
+ border-bottom: 0;
165
+ border-left: 0.3em solid transparent;
166
+ flex-shrink: 0;
167
+ }
168
+
169
+ &:focus {
170
+ outline: none;
171
+ border-width: 2px;
172
+ border-color: var(--color-accent);
173
+ box-shadow: var(--glass-shadow-md), 0 0 0 1px var(--color-accent);
174
+ }
175
+
176
+ &:hover {
177
+ background-color: var(--glass-bg-heavy);
178
+ border-color: var(--glass-border-heavy);
179
+ }
180
+
181
+ &:disabled {
182
+ opacity: var(--form-input-opacity-disabled);
183
+ cursor: not-allowed;
184
+ background-color: var(--glass-bg-dark);
185
+ }
186
+ }
187
+
188
+ .bl-select-menu {
189
+ position: absolute;
190
+ top: 100%;
191
+ left: 0;
192
+ z-index: 999999 !important; // Immer ganz oben
193
+ display: none;
194
+ width: 100%;
195
+ min-width: 100%;
196
+ padding: var(--spacing-xs) 0;
197
+ margin: var(--spacing-xs) 0 0 0;
198
+ font-size: var(--font-size-base);
199
+ color: var(--color-text);
200
+ text-align: left;
201
+ list-style: none;
202
+ background: var(--glass-bg-medium);
203
+ backdrop-filter: blur(var(--glass-blur-lg));
204
+ -webkit-backdrop-filter: blur(var(--glass-blur-lg));
205
+ border: 1px solid var(--glass-border-medium);
206
+ border-radius: var(--tech-border-radius-md);
207
+ overflow: hidden;
208
+ overflow-y: auto;
209
+ max-height: 300px;
210
+ box-shadow: var(--glass-shadow-lg);
211
+
212
+ &.bl-show {
213
+ display: block;
214
+ }
215
+ }
216
+
217
+ .bl-select-item {
218
+ display: block;
219
+ width: 100%;
220
+ padding: var(--spacing-sm) var(--spacing-md);
221
+ clear: both;
222
+ font-weight: var(--font-weight-normal);
223
+ color: var(--color-text);
224
+ text-align: inherit;
225
+ text-decoration: none;
226
+ white-space: nowrap;
227
+ background-color: transparent;
228
+ border: 0;
229
+ cursor: pointer;
230
+ transition: var(--transition-base);
231
+
232
+ &:hover,
233
+ &:focus {
234
+ color: var(--color-text);
235
+ text-decoration: none;
236
+ background: var(--glass-bg-heavy);
237
+ }
238
+
239
+ &:active {
240
+ color: var(--color-text);
241
+ background: var(--glass-bg-heavy);
242
+ }
243
+
244
+ &.bl-selected {
245
+ background: var(--glass-bg-heavy);
246
+ color: var(--color-accent);
247
+
248
+ &::before {
249
+ content: "✓ ";
250
+ margin-right: var(--spacing-xs);
251
+ }
252
+ }
253
+
254
+ &.bl-disabled,
255
+ &:disabled {
256
+ color: var(--color-text-muted);
257
+ pointer-events: none;
258
+ background-color: transparent;
259
+ opacity: 0.6;
260
+ }
110
261
  }
111
262
  }
112
263
 
@@ -0,0 +1,58 @@
1
+ // ============================================================================
2
+ // Baseline UI JavaScript
3
+ // Main Entry Point
4
+ // ============================================================================
5
+
6
+ import { initModal, openModal, closeModal } from './components/modal.js';
7
+ import { initDropdown } from './components/dropdown.js';
8
+ import { initTooltip } from './components/tooltip.js';
9
+ import { initTabs } from './components/tabs.js';
10
+ import { initAlert, dismissAlert } from './components/alert.js';
11
+
12
+ // Export all functions for manual use
13
+ export {
14
+ initModal,
15
+ openModal,
16
+ closeModal,
17
+ initDropdown,
18
+ initTooltip,
19
+ initTabs,
20
+ initAlert,
21
+ dismissAlert
22
+ };
23
+
24
+ // Auto-initialize on DOM ready
25
+ function autoInit() {
26
+ // Initialize all modals
27
+ document.querySelectorAll('.bl-modal').forEach(modal => {
28
+ initModal(modal);
29
+ });
30
+
31
+ // Initialize all dropdowns
32
+ document.querySelectorAll('.bl-dropdown').forEach(dropdown => {
33
+ initDropdown(dropdown);
34
+ });
35
+
36
+ // Initialize all tooltips
37
+ document.querySelectorAll('.bl-tooltip').forEach(tooltip => {
38
+ initTooltip(tooltip);
39
+ });
40
+
41
+ // Initialize all tabs
42
+ document.querySelectorAll('.bl-nav-tabs').forEach(tabs => {
43
+ initTabs(tabs);
44
+ });
45
+
46
+ // Initialize all dismissible alerts
47
+ document.querySelectorAll('.bl-alert-dismissible').forEach(alert => {
48
+ initAlert(alert);
49
+ });
50
+ }
51
+
52
+ // Initialize when DOM is ready
53
+ if (document.readyState === 'loading') {
54
+ document.addEventListener('DOMContentLoaded', autoInit);
55
+ } else {
56
+ autoInit();
57
+ }
58
+
@@ -0,0 +1,25 @@
1
+ // ============================================================================
2
+ // Alert Component JavaScript
3
+ // ============================================================================
4
+
5
+ export function initAlert(alertElement) {
6
+ if (!alertElement) return;
7
+
8
+ const closeBtn = alertElement.querySelector('.bl-alert-close');
9
+ if (!closeBtn) return;
10
+
11
+ closeBtn.addEventListener('click', () => {
12
+ dismissAlert(alertElement);
13
+ });
14
+ }
15
+
16
+ export function dismissAlert(alertElement) {
17
+ if (!alertElement) return;
18
+
19
+ alertElement.style.transition = 'opacity 0.3s ease-out';
20
+ alertElement.style.opacity = '0';
21
+ setTimeout(() => {
22
+ alertElement.remove();
23
+ }, 300);
24
+ }
25
+
@@ -0,0 +1,40 @@
1
+ // ============================================================================
2
+ // Dropdown Component JavaScript
3
+ // ============================================================================
4
+
5
+ export function initDropdown(dropdownElement) {
6
+ if (!dropdownElement) return;
7
+
8
+ const toggle = dropdownElement.querySelector('.bl-dropdown-toggle');
9
+ const menu = dropdownElement.querySelector('.bl-dropdown-menu');
10
+
11
+ if (!toggle || !menu) return;
12
+
13
+ toggle.addEventListener('click', (e) => {
14
+ e.preventDefault();
15
+ e.stopPropagation();
16
+
17
+ // Close all other dropdowns
18
+ document.querySelectorAll('.bl-dropdown-menu.bl-show').forEach(otherMenu => {
19
+ if (otherMenu !== menu) {
20
+ otherMenu.classList.remove('bl-show');
21
+ }
22
+ });
23
+
24
+ // Toggle current dropdown
25
+ menu.classList.toggle('bl-show');
26
+ });
27
+
28
+ // Close on outside click
29
+ const outsideClickHandler = (e) => {
30
+ if (!dropdownElement.contains(e.target)) {
31
+ menu.classList.remove('bl-show');
32
+ }
33
+ };
34
+
35
+ document.addEventListener('click', outsideClickHandler);
36
+
37
+ // Store handler for cleanup if needed
38
+ dropdownElement._outsideClickHandler = outsideClickHandler;
39
+ }
40
+
@@ -0,0 +1,67 @@
1
+ // ============================================================================
2
+ // Modal Component JavaScript
3
+ // ============================================================================
4
+
5
+ export function initModal(modalElement) {
6
+ if (!modalElement) return;
7
+
8
+ const backdrop = modalElement.querySelector('.bl-modal-backdrop') || document.createElement('div');
9
+ if (!backdrop.classList.contains('bl-modal-backdrop')) {
10
+ backdrop.className = 'bl-modal-backdrop';
11
+ modalElement.insertBefore(backdrop, modalElement.firstChild);
12
+ }
13
+
14
+ // Open modal buttons
15
+ const modalId = modalElement.id;
16
+ if (modalId) {
17
+ const openButtons = document.querySelectorAll(`[data-modal-open="${modalId}"]`);
18
+ openButtons.forEach(btn => {
19
+ btn.addEventListener('click', () => {
20
+ openModal(modalId);
21
+ });
22
+ });
23
+ }
24
+
25
+ // Close modal buttons
26
+ const closeButtons = modalElement.querySelectorAll('.bl-modal-close, [data-modal-close]');
27
+ closeButtons.forEach(btn => {
28
+ btn.addEventListener('click', () => {
29
+ closeModal(modalId);
30
+ });
31
+ });
32
+
33
+ // Close on backdrop click
34
+ backdrop.addEventListener('click', (e) => {
35
+ if (e.target === backdrop) {
36
+ closeModal(modalId);
37
+ }
38
+ });
39
+
40
+ // Close on ESC key
41
+ const escHandler = (e) => {
42
+ if (e.key === 'Escape' && modalElement.style.display === 'block') {
43
+ closeModal(modalId);
44
+ }
45
+ };
46
+ document.addEventListener('keydown', escHandler);
47
+
48
+ // Store handler for cleanup if needed
49
+ modalElement._escHandler = escHandler;
50
+ }
51
+
52
+ export function openModal(modalId) {
53
+ const modal = document.getElementById(modalId);
54
+ if (modal) {
55
+ modal.style.display = 'block';
56
+ document.body.style.overflow = 'hidden';
57
+ }
58
+ }
59
+
60
+ export function closeModal(modalId) {
61
+ const modal = document.getElementById(modalId);
62
+ if (modal) {
63
+ modal.style.display = 'none';
64
+ document.body.style.overflow = '';
65
+ }
66
+ }
67
+
@@ -0,0 +1,49 @@
1
+ // ============================================================================
2
+ // Tabs Component JavaScript
3
+ // ============================================================================
4
+
5
+ export function initTabs(tabsContainer) {
6
+ if (!tabsContainer) return;
7
+
8
+ const tabLinks = tabsContainer.querySelectorAll('.bl-nav-link[data-tab-target]');
9
+ const tabGroup = tabsContainer.getAttribute('data-tab-group');
10
+
11
+ tabLinks.forEach(link => {
12
+ link.addEventListener('click', (e) => {
13
+ e.preventDefault();
14
+
15
+ // Remove active from all tabs in group
16
+ if (tabGroup) {
17
+ document.querySelectorAll(`[data-tab-group="${tabGroup}"] .bl-nav-link`).forEach(l => {
18
+ l.classList.remove('bl-active');
19
+ });
20
+ } else {
21
+ tabsContainer.querySelectorAll('.bl-nav-link').forEach(l => {
22
+ l.classList.remove('bl-active');
23
+ });
24
+ }
25
+
26
+ // Add active to clicked tab
27
+ link.classList.add('bl-active');
28
+
29
+ // Show/hide tab content
30
+ const targetId = link.getAttribute('data-tab-target');
31
+ if (targetId) {
32
+ // Find all tab contents - search in parent container or document
33
+ const container = tabsContainer.closest('.docs-example-preview') ||
34
+ tabsContainer.parentElement ||
35
+ document;
36
+
37
+ container.querySelectorAll('[data-tab-content]').forEach(content => {
38
+ content.style.display = 'none';
39
+ });
40
+
41
+ const targetContent = document.getElementById(targetId);
42
+ if (targetContent) {
43
+ targetContent.style.display = 'block';
44
+ }
45
+ }
46
+ });
47
+ });
48
+ }
49
+
@@ -0,0 +1,21 @@
1
+ // ============================================================================
2
+ // Tooltip Component JavaScript
3
+ // ============================================================================
4
+
5
+ export function initTooltip(tooltipElement) {
6
+ if (!tooltipElement) return;
7
+
8
+ const trigger = tooltipElement.querySelector('.bl-tooltip-trigger');
9
+ const content = tooltipElement.querySelector('.bl-tooltip-content');
10
+
11
+ if (!trigger || !content) return;
12
+
13
+ trigger.addEventListener('mouseenter', () => {
14
+ content.classList.add('bl-show');
15
+ });
16
+
17
+ trigger.addEventListener('mouseleave', () => {
18
+ content.classList.remove('bl-show');
19
+ });
20
+ }
21
+
@@ -4,7 +4,7 @@
4
4
 
5
5
  // Z-Index Layers
6
6
  $z-index-base: 0;
7
- $z-index-dropdown: 1000;
7
+ $z-index-dropdown: 9999; // Immer im Vordergrund
8
8
  $z-index-sticky: 1020;
9
9
  $z-index-fixed: 1030;
10
10
  $z-index-modal-backdrop: 1040;