@qobo/banner 1.0.7 → 1.0.9
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 +33 -0
- package/package.json +1 -1
- package/src/QoboBanner.jsx +60 -49
- package/src/index.js +1 -0
package/README.md
CHANGED
|
@@ -31,6 +31,39 @@ export default function App() {
|
|
|
31
31
|
- **Error resilient**: Defaults to visible if API fails
|
|
32
32
|
- **Layout shift prevention**: Initializes as visible before API response
|
|
33
33
|
- **Responsive**: Works on all screen sizes
|
|
34
|
+
- **Navbar positioning**: Sets CSS variable `--qobo-banner-height` (0px when hidden, 50px when visible) for sticky navbar positioning
|
|
35
|
+
- **Sticky banner**: Uses sticky positioning so navbar can stick below it
|
|
36
|
+
|
|
37
|
+
## Navbar Positioning
|
|
38
|
+
|
|
39
|
+
The banner automatically sets a CSS variable `--qobo-banner-height` on the document root that you can use for sticky navbar positioning:
|
|
40
|
+
|
|
41
|
+
- When banner is visible: `--qobo-banner-height` is `50px`
|
|
42
|
+
- When banner is hidden: `--qobo-banner-height` is `0px`
|
|
43
|
+
|
|
44
|
+
### Using with Tailwind CSS
|
|
45
|
+
|
|
46
|
+
For your navbar component, use the CSS variable in your sticky positioning:
|
|
47
|
+
|
|
48
|
+
```jsx
|
|
49
|
+
<nav className="sticky z-[60] bg-white border-b" style={{ top: 'var(--qobo-banner-height, 0px)' }}>
|
|
50
|
+
{/* Navbar content */}
|
|
51
|
+
</nav>
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
Or using Tailwind's arbitrary values (requires Tailwind 3.1+):
|
|
55
|
+
|
|
56
|
+
```jsx
|
|
57
|
+
<nav className="sticky z-[60] bg-white border-b" style={{ top: 'var(--qobo-banner-height)' }}>
|
|
58
|
+
{/* Navbar content */}
|
|
59
|
+
</nav>
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
This ensures:
|
|
63
|
+
- When `showBanner` is `true`: Navbar sticks below the banner (at 50px from top)
|
|
64
|
+
- When `showBanner` is `false`: Navbar sticks to the top (at 0px from top)
|
|
65
|
+
|
|
66
|
+
**Important**: The banner uses `z-index: 50` and sticky positioning. Your navbar should use a higher z-index (e.g., `z-60` or `z-[60]`) to stay visible when scrolling.
|
|
34
67
|
|
|
35
68
|
## Environment Variables
|
|
36
69
|
|
package/package.json
CHANGED
package/src/QoboBanner.jsx
CHANGED
|
@@ -12,6 +12,8 @@ import React, { useState, useEffect } from 'react';
|
|
|
12
12
|
* - Defaults to visible on error
|
|
13
13
|
* - Links to https://qobo.dev in a new tab
|
|
14
14
|
* - Has consistent styling across all projects
|
|
15
|
+
* - Sets CSS variable --qobo-banner-height for navbar positioning (0px when hidden, 50px when visible)
|
|
16
|
+
* - Banner uses sticky positioning so navbar can stick below it
|
|
15
17
|
*/
|
|
16
18
|
export function QoboBanner({ apiKey, apiBaseUrl }) {
|
|
17
19
|
const [isVisible, setIsVisible] = useState(false); // Start hidden until API responds
|
|
@@ -64,63 +66,72 @@ export function QoboBanner({ apiKey, apiBaseUrl }) {
|
|
|
64
66
|
fetchBannerVisibility();
|
|
65
67
|
}, [apiKey, apiBaseUrl]);
|
|
66
68
|
|
|
69
|
+
// Set CSS variable for banner height (always set, even when hidden)
|
|
70
|
+
// Navbars can use: top: var(--qobo-banner-height, 0px) for sticky positioning
|
|
71
|
+
useEffect(() => {
|
|
72
|
+
const bannerHeight = isVisible && !isLoading ? BANNER_HEIGHT : 0;
|
|
73
|
+
document.documentElement.style.setProperty('--qobo-banner-height', `${bannerHeight}px`);
|
|
74
|
+
|
|
75
|
+
return () => {
|
|
76
|
+
// Cleanup: reset to 0 when component unmounts
|
|
77
|
+
document.documentElement.style.setProperty('--qobo-banner-height', '0px');
|
|
78
|
+
};
|
|
79
|
+
}, [isVisible, isLoading, BANNER_HEIGHT]);
|
|
80
|
+
|
|
67
81
|
if (isLoading) return null;
|
|
68
82
|
if (!isVisible) return null;
|
|
69
83
|
|
|
70
84
|
return (
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
85
|
+
<div
|
|
86
|
+
className="w-full bg-gradient-to-r from-cyan-400 to-blue-500 text-white py-2 px-4 text-center text-sm font-medium shadow-md"
|
|
87
|
+
style={{
|
|
88
|
+
position: 'sticky',
|
|
89
|
+
top: 0,
|
|
90
|
+
left: 0,
|
|
91
|
+
right: 0,
|
|
92
|
+
zIndex: 50,
|
|
93
|
+
height: `${BANNER_HEIGHT}px`,
|
|
94
|
+
background: 'linear-gradient(90deg, #FF7A2F 0%, #46C6B9 100%)',
|
|
95
|
+
color: '#F1F5F9',
|
|
96
|
+
padding: '12px 16px',
|
|
97
|
+
textAlign: 'center',
|
|
98
|
+
fontSize: '0.95rem',
|
|
99
|
+
fontWeight: '600',
|
|
100
|
+
letterSpacing: '0.01em',
|
|
101
|
+
fontFamily: '"Inter", "Segoe UI", system-ui, -apple-system, sans-serif',
|
|
102
|
+
boxShadow: '0 2px 4px rgba(0, 0, 0, 0.1)',
|
|
103
|
+
transition: 'all 0.3s ease',
|
|
104
|
+
display: 'flex',
|
|
105
|
+
alignItems: 'center',
|
|
106
|
+
justifyContent: 'center',
|
|
107
|
+
}}
|
|
108
|
+
>
|
|
109
|
+
Made with{' '}
|
|
110
|
+
<span
|
|
111
|
+
style={{
|
|
112
|
+
color: '#FF1744',
|
|
113
|
+
display: 'inline-block',
|
|
114
|
+
margin: '0 0.35rem',
|
|
115
|
+
}}
|
|
116
|
+
>
|
|
117
|
+
❤️
|
|
118
|
+
</span>{' '}
|
|
119
|
+
by{' '}
|
|
120
|
+
<a
|
|
121
|
+
href="https://qobo.dev"
|
|
122
|
+
target="_blank"
|
|
123
|
+
rel="noopener noreferrer"
|
|
75
124
|
style={{
|
|
76
|
-
position: 'fixed',
|
|
77
|
-
top: 0,
|
|
78
|
-
left: 0,
|
|
79
|
-
right: 0,
|
|
80
|
-
zIndex: 9999,
|
|
81
|
-
height: `${BANNER_HEIGHT}px`,
|
|
82
|
-
background: 'linear-gradient(90deg, #FF7A2F 0%, #46C6B9 100%)',
|
|
83
125
|
color: '#F1F5F9',
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
fontWeight: '600',
|
|
88
|
-
letterSpacing: '0.01em',
|
|
89
|
-
fontFamily: '"Inter", "Segoe UI", system-ui, -apple-system, sans-serif',
|
|
90
|
-
boxShadow: '0 2px 4px rgba(0, 0, 0, 0.1)',
|
|
91
|
-
transition: 'all 0.3s ease',
|
|
92
|
-
display: 'flex',
|
|
93
|
-
alignItems: 'center',
|
|
94
|
-
justifyContent: 'center',
|
|
126
|
+
textDecoration: 'underline',
|
|
127
|
+
fontWeight: '700',
|
|
128
|
+
cursor: 'pointer',
|
|
95
129
|
}}
|
|
130
|
+
className="hover:text-cyan-100 transition-colors"
|
|
96
131
|
>
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
color: '#FF1744',
|
|
101
|
-
display: 'inline-block',
|
|
102
|
-
margin: '0 0.35rem',
|
|
103
|
-
}}
|
|
104
|
-
>
|
|
105
|
-
❤️
|
|
106
|
-
</span>{' '}
|
|
107
|
-
by{' '}
|
|
108
|
-
<a
|
|
109
|
-
href="https://qobo.dev"
|
|
110
|
-
target="_blank"
|
|
111
|
-
rel="noopener noreferrer"
|
|
112
|
-
style={{
|
|
113
|
-
color: '#F1F5F9',
|
|
114
|
-
textDecoration: 'underline',
|
|
115
|
-
fontWeight: '700',
|
|
116
|
-
cursor: 'pointer',
|
|
117
|
-
}}
|
|
118
|
-
className="hover:text-cyan-100 transition-colors"
|
|
119
|
-
>
|
|
120
|
-
qobo.dev
|
|
121
|
-
</a>
|
|
122
|
-
</div>
|
|
123
|
-
</>
|
|
132
|
+
qobo.dev
|
|
133
|
+
</a>
|
|
134
|
+
</div>
|
|
124
135
|
);
|
|
125
136
|
}
|
|
126
137
|
|
package/src/index.js
CHANGED