@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 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
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@qobo/banner",
3
- "version": "1.0.7",
3
+ "version": "1.0.9",
4
4
  "description": "Shared Qobo banner component for all generated projects",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
@@ -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
- <div aria-hidden="true" style={{ height: `${BANNER_HEIGHT}px`, width: '100%' }} />
73
- <div
74
- 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"
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
- padding: '12px 16px',
85
- textAlign: 'center',
86
- fontSize: '0.95rem',
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
- Made with{' '}
98
- <span
99
- style={{
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
@@ -1 +1,2 @@
1
1
  export { QoboBanner, default } from './QoboBanner.jsx';
2
+ export { BannerProvider, useBannerVisibility } from './BannerContext.jsx';