ml-ui-lib 1.0.27 → 1.0.29

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.
@@ -15,6 +15,7 @@
15
15
  align-items: center;
16
16
  max-width: 1200px;
17
17
  margin: 0 auto;
18
+ padding: 1rem;
18
19
  }
19
20
 
20
21
  .navbar-logo img {
@@ -26,7 +27,6 @@
26
27
  ------------------------- */
27
28
  .nav-items {
28
29
  display: flex;
29
- overflow: none;
30
30
  gap: 1.5rem;
31
31
  }
32
32
 
@@ -38,19 +38,37 @@
38
38
  cursor: pointer;
39
39
  }
40
40
 
41
- /* Dropdown menu */
41
+ /* Desktop dropdown bubble */
42
+ .navbar-dropdown-content {
43
+ display: flex;
44
+ flex-direction: column;
45
+ position: relative;
46
+ top: 15px;
47
+ padding: 12px 45px 12px 20px;
48
+ background: #fff;
49
+ border-radius: 22px;
50
+ box-shadow: 0 10px 25px rgba(0, 0, 0, 0.15);
51
+ }
52
+
53
+ .navbar-dropdown-content::before {
54
+ content: "";
55
+ position: absolute;
56
+ top: -8px;
57
+ right: 30px;
58
+ width: 15px;
59
+ height: 15px;
60
+ background: #fff;
61
+ transform: rotate(45deg);
62
+ box-shadow: -4px 2px 8px rgba(0, 0, 0, 0.05);
63
+ }
64
+
42
65
  .navbar-dropdown {
43
- /* hidden by default */
44
- display: none;
45
- padding: 20px 25px 10px 10px;
46
66
  position: absolute;
47
67
  top: 20px;
48
- left: -25px;
49
- background: #fff;
50
- min-width: 180px;
51
- /* box-shadow: 0 8px 20px rgba(0, 0, 0, 0.15); */
68
+ left: -35px;
69
+ display: none;
70
+ z-index: 10;
52
71
  flex-direction: column;
53
- z-index: 999;
54
72
  }
55
73
 
56
74
  .navbar-dropdown-link {
@@ -64,12 +82,12 @@
64
82
  background: #f2f2f2;
65
83
  }
66
84
 
67
- /* Show dropdown on hover (desktop) */
85
+ /* Desktop hover */
68
86
  .navbar-item.has-dropdown:hover .navbar-dropdown {
69
87
  display: flex;
70
88
  }
71
89
 
72
- /* Add linear caret for items with dropdown */
90
+ /* Caret arrow */
73
91
  .navbar-item.has-dropdown>.navbar-link::after {
74
92
  content: ">";
75
93
  display: inline-block;
@@ -80,6 +98,10 @@
80
98
  transform: rotate(90deg);
81
99
  }
82
100
 
101
+ .separator {
102
+ display: block !important;
103
+ }
104
+
83
105
  /* -------------------------
84
106
  Navbar Links
85
107
  ------------------------- */
@@ -95,28 +117,15 @@
95
117
  font-weight: 400;
96
118
  font-size: 17px;
97
119
  transition: color 0.2s;
98
- display: inline-block;
99
- /* allows width & height */
100
- width: auto;
101
- /* default for desktop */
102
120
  }
103
121
 
104
- /* Style for parent items with sublinks (desktop) */
105
122
  .navbar-link.parent-link {
106
123
  cursor: default;
107
- /* show pointer as normal arrow, not hand */
108
124
  color: #333 !important;
109
- /* normal text color */
110
- /* font-weight: 500; */
111
- /* optional: slightly bolder */
112
125
  }
113
126
 
114
- /* Prevent hover effect for parent items */
115
127
  .navbar-link.parent-link:hover {
116
- color: #333;
117
- /* do not turn red */
118
128
  background: none;
119
- /* no background change */
120
129
  }
121
130
 
122
131
  .navbar-links a:hover {
@@ -168,88 +177,76 @@
168
177
  /* -------------------------
169
178
  Responsive
170
179
  ------------------------- */
171
- @media (min-width: 1000px) {
172
- .navbar-container {
173
- padding: 1rem 5rem;
174
- }
175
- }
176
-
177
- @media (min-width: 993px) {
180
+ @media (max-width: 992px) {
178
181
  .navbar-container {
179
- padding: 1rem 0;
182
+ margin: 0 20px;
183
+ padding: 1rem 1.5rem;
184
+ justify-content: space-between;
180
185
  }
181
- }
182
186
 
183
- @media (max-width: 500px) {
184
- .navbar-container {
185
- margin: 0 !important;
186
- }
187
- }
188
-
189
- .mobile-login-btn {
190
- display: none;
191
- }
192
-
193
- /* -------------------------
194
- Mobile Menu
195
- ------------------------- */
196
- @media (max-width: 992px) {
197
- /* .navbar-item.has-dropdown>.navbar-link::after {
198
- display: none;
199
- } */
200
-
201
- .separator {
187
+ .navbar-item.has-dropdown:hover .navbar-dropdown {
202
188
  display: none;
203
189
  }
204
190
 
205
- .mobile-login-btn {
206
- display: block;
191
+ .burger {
192
+ display: flex;
193
+ z-index: 10000;
207
194
  }
208
195
 
196
+ .separator,
209
197
  .login-btn {
210
198
  display: none !important;
211
199
  }
212
200
 
213
- .burger {
214
- display: flex;
215
- z-index: 10000;
216
- }
217
-
218
- .navbar-container {
219
- margin: 0 20px;
220
- padding: 1rem 1.5rem;
221
- justify-content: space-between;
201
+ .mobile-login-btn {
202
+ display: block;
203
+ position: fixed;
204
+ bottom: 0;
205
+ /* left: 0; */
206
+ width: 400px;
207
+ padding: 1.3rem;
208
+ border: none;
209
+ color: #333;
210
+ font-size: 1.1rem;
211
+ font-weight: 600;
212
+ z-index: 99;
222
213
  }
223
214
 
224
- .nav-items {
225
- gap: 0px;
226
- flex-direction: column;
227
- overflow: auto;
215
+ .navbar-dropdown-content {
216
+ padding: 0px !important;
228
217
  }
229
218
 
230
219
  .navbar-links {
231
220
  position: fixed;
232
221
  top: 0;
233
222
  right: -100%;
234
- height: 100vh;
235
223
  width: 400px;
224
+ height: 100vh;
236
225
  background: #fff;
237
226
  flex-direction: column;
238
227
  padding: 65px 0px 70px;
239
228
  transition: right 0.3s ease-in-out;
240
229
  box-shadow: -4px 0 12px rgba(0, 0, 0, 0.1);
241
230
  z-index: 9999;
231
+ overflow-y: auto;
242
232
  }
243
233
 
244
234
  .navbar-links.open {
245
235
  right: 0;
246
236
  }
247
237
 
238
+ .nav-items {
239
+ flex-direction: column;
240
+ gap: 0;
241
+ overflow: visible;
242
+ }
243
+
248
244
  .navbar-links a {
249
245
  display: block;
250
246
  width: 100%;
251
247
  padding: 1rem 50px;
252
248
  font-size: 1.2rem;
249
+ color: #333;
253
250
  }
254
251
 
255
252
  .navbar-links a:hover {
@@ -257,48 +254,78 @@
257
254
  color: #fff;
258
255
  }
259
256
 
260
- .navbar-links a.active:hover {
261
- color: #fff;
257
+ /* -------------------------
258
+ Mobile accordion
259
+ ------------------------- */
260
+ .navbar-item.has-dropdown {
261
+ display: flex;
262
+ flex-direction: column;
263
+ width: 100%;
264
+ }
265
+
266
+ /* arrow */
267
+ .navbar-item.has-dropdown .navbar-link::after {
268
+ content: "▸";
269
+ margin-left: auto;
270
+ transition: transform 0.3s ease;
271
+ float: right;
272
+ }
273
+
274
+ .navbar-item.has-dropdown.open .navbar-link::after {
275
+ transform: rotate(90deg);
262
276
  }
263
277
 
264
- /* Mobile dropdown inside sliding menu */
278
+ /* remove absolute, make dropdown push content */
265
279
  .navbar-dropdown {
266
- position: static;
267
- display: flex !important;
280
+ display: none;
268
281
  flex-direction: column;
269
- background: transparent;
282
+ width: 100%;
283
+ /* margin-top: 0.3rem; */
284
+ }
285
+
286
+ /* show when open */
287
+ .navbar-item.has-dropdown.open .navbar-dropdown {
288
+ position: static;
289
+ display: flex;
290
+ }
291
+
292
+ .navbar-item.has-dropdown.open .navbar-dropdown a {
293
+ padding-left: 70px;
294
+ }
295
+
296
+ .navbar-dropdown-content {
297
+ padding: 0.5rem 1rem;
298
+ /* margin: 0.2rem 0; */
299
+ top: 0px;
300
+ border-radius: 8px;
301
+ background: #fff;
270
302
  box-shadow: none;
271
- padding: 0px;
303
+ }
304
+
305
+ .navbar-dropdown-content::before,
306
+ .navbar-dropdown-content::after {
307
+ display: none;
272
308
  }
273
309
 
274
310
  .navbar-dropdown-link {
275
- padding-left: 50px;
311
+ padding: 0.7rem 1rem;
312
+ font-size: 1rem;
276
313
  color: #333;
314
+ white-space: normal;
277
315
  }
278
316
 
279
317
  .has-dropdown .navbar-dropdown-link {
280
- padding: 1rem 70px;
281
- }
282
-
283
- /* MOBILE LOGIN FIXED AT BOTTOM */
284
- .mobile-login-btn {
285
- position: absolute;
286
- bottom: 0;
287
- left: 0;
288
- width: 100%;
289
- padding: 1.3rem;
290
- border: none;
291
- color: #333;
292
- font-size: 1.1rem;
293
- font-weight: 600;
318
+ padding-left: 1.5rem;
294
319
  }
295
320
  }
296
321
 
322
+
297
323
  /* -------------------------
298
- Login Button
324
+ Login & Panels
299
325
  ------------------------- */
300
326
  .login-btn {
301
- color: #333;
327
+ color: #e00000;
328
+ font-weight: 700;
302
329
  border: none;
303
330
  border-radius: 6px;
304
331
  cursor: pointer;
@@ -314,11 +341,6 @@
314
341
  font-weight: 500;
315
342
  }
316
343
 
317
- .navbar-login-panel .spb-header {
318
- padding: 0 !important;
319
- border-bottom: none !important;
320
- }
321
-
322
344
  .navbar-panel-content {
323
345
  padding: 20px;
324
346
  }
@@ -353,7 +375,6 @@
353
375
  width: 280px;
354
376
  height: 80px;
355
377
  background: url(https://mlhuillier.com/img/revamp/ml-logo-2.svg) center/contain no-repeat;
356
- opacity: 1;
357
378
  pointer-events: none;
358
379
  z-index: 1;
359
380
  }
@@ -366,6 +387,10 @@
366
387
  .navbar-links {
367
388
  width: 100%;
368
389
  }
390
+
391
+ .mobile-login-btn {
392
+ width: 100%;
393
+ }
369
394
  }
370
395
 
371
396
  /* Right-side group */
@@ -3,7 +3,7 @@ import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-run
3
3
  import { useState, useEffect } from 'react';
4
4
  import './Navbar.css';
5
5
  import { SlidingPanel } from '../SlidingPanel/SlidingPanel';
6
- export const Navbar = ({ siteUrl, items, logoSrc = '', logoAlt = 'M Lhuillier Logo', logoWidth = 220, logoHeight = 40, className = '', login = false, logedinData = null, loginContent, otherContent, onClose, }) => {
6
+ export const Navbar = ({ siteUrl, items, logoSrc = '', logoAlt = 'Logo', logoWidth = 220, logoHeight = 40, className = '', login = false, logedinData = null, loginContent, otherContent, onClose, }) => {
7
7
  const [menuOpen, setMenuOpen] = useState(false);
8
8
  const [showLogin, setShowLogin] = useState(false);
9
9
  const [isClosing, setIsClosing] = useState(false);
@@ -21,13 +21,10 @@ export const Navbar = ({ siteUrl, items, logoSrc = '', logoAlt = 'M Lhuillier Lo
21
21
  if (!menuOpen)
22
22
  setOpenDropdown(null);
23
23
  }, [menuOpen]);
24
- const toggleMenu = () => setMenuOpen((prev) => !prev);
24
+ const toggleMenu = () => setMenuOpen(prev => !prev);
25
25
  const toggleLogin = () => {
26
26
  setMenuOpen(false);
27
- setShowLogin((prev) => !prev);
28
- };
29
- const toggleDropdown = (name) => {
30
- setOpenDropdown(prev => (prev === name ? null : name));
27
+ setShowLogin(prev => !prev);
31
28
  };
32
29
  const handleInternalClose = () => {
33
30
  setIsClosing(true);
@@ -39,14 +36,8 @@ export const Navbar = ({ siteUrl, items, logoSrc = '', logoAlt = 'M Lhuillier Lo
39
36
  }, 350);
40
37
  };
41
38
  useEffect(() => {
42
- if (menuOpen) {
43
- document.body.style.overflow = 'hidden';
44
- document.body.style.touchAction = 'none';
45
- }
46
- else {
47
- document.body.style.overflow = '';
48
- document.body.style.touchAction = '';
49
- }
39
+ document.body.style.overflow = menuOpen ? 'hidden' : '';
40
+ document.body.style.touchAction = menuOpen ? 'none' : '';
50
41
  return () => {
51
42
  document.body.style.overflow = '';
52
43
  document.body.style.touchAction = '';
@@ -54,30 +45,21 @@ export const Navbar = ({ siteUrl, items, logoSrc = '', logoAlt = 'M Lhuillier Lo
54
45
  }, [menuOpen]);
55
46
  return (_jsxs(_Fragment, { children: [_jsx("nav", { className: `navbar ${className}`, children: _jsxs("div", { className: "navbar-container", children: [_jsx("div", { className: "navbar-logo", children: _jsx("a", { href: siteUrl, className: "navbar-brand", children: _jsx("img", { src: logoSrc, alt: logoAlt, width: logoWidth, height: logoHeight, style: { cursor: 'pointer', display: 'block' } }) }) }), _jsxs("div", { style: { display: 'flex', flexDirection: 'row', gap: '10px', alignItems: 'center' }, children: [_jsxs("div", { className: `navbar-links ${menuOpen ? 'open' : ''}`, children: [_jsx("div", { className: "nav-items", children: items.map(item => {
56
47
  const hasSubLinks = item.subLinks && item.subLinks.length > 0;
57
- const linkPath = new URL(item.link, 'https://dummybase').pathname;
48
+ const linkPath = new URL(item.link || '#', 'https://dummybase').pathname;
58
49
  const isActive = currentPath === linkPath;
59
50
  const isDropdownOpen = openDropdown === item.name;
60
- return (_jsxs("div", { className: `navbar-item ${hasSubLinks ? 'has-dropdown' : ''} ${isDropdownOpen ? 'open' : ''}`, children: [_jsx("a", { href: hasSubLinks && !isMobile ? '#' : item.link, target: item.target || '_self', className: `navbar-link ${isActive ? 'active' : ''} ${hasSubLinks && !isMobile ? 'parent-link' : ''}`, onClick: (e) => {
61
- if (hasSubLinks) {
62
- if (isMobile) {
63
- e.preventDefault();
64
- toggleDropdown(item.name);
65
- }
66
- else {
67
- e.preventDefault(); // prevent desktop click
68
- }
51
+ return (_jsxs("div", { className: `navbar-item ${hasSubLinks ? 'has-dropdown' : ''} ${isDropdownOpen ? 'open' : ''}`, children: [_jsx("a", { href: hasSubLinks ? '#' : item.link, target: item.target || '_self', className: `navbar-link ${isActive ? 'active' : ''} ${hasSubLinks ? 'parent-link' : ''}`, onClick: (e) => {
52
+ if (hasSubLinks && isMobile) {
53
+ e.preventDefault();
54
+ setOpenDropdown(prev => (prev === item.name ? null : item.name));
69
55
  }
70
56
  else {
71
57
  setMenuOpen(false);
72
58
  }
73
- }, children: item.name }), hasSubLinks && (_jsx("div", { className: "navbar-dropdown", style: {
74
- display: isMobile
75
- ? isDropdownOpen ? 'flex' : 'none'
76
- : undefined,
77
- }, children: item.subLinks.map(sub => (_jsx("a", { href: sub.link, target: sub.target || '_self', className: "navbar-dropdown-link", onClick: () => {
78
- setMenuOpen(false);
79
- setOpenDropdown(null);
80
- }, children: sub.name }, sub.name))) }))] }, item.name));
81
- }) }), isMobile && login && !logedinData && (_jsx("button", { className: "mobile-login-btn", onClick: toggleLogin, children: "Login" }))] }), _jsx("div", { className: 'separator', style: { color: '#aaaaaa', fontSize: '27px', padding: '0 15px' }, children: " | " }), _jsxs("div", { className: "navbar-right", children: [_jsxs("button", { className: `burger ${menuOpen ? 'active' : ''}`, onClick: toggleMenu, "aria-label": "Toggle menu", children: [_jsx("span", {}), _jsx("span", {}), _jsx("span", {})] }), !isMobile && login && !logedinData && (_jsx("span", { style: { color: '#e00000', fontWeight: '700' }, className: "login-btn", onClick: toggleLogin, children: "Login" }))] })] })] }) }), login && !logedinData && (_jsx(_Fragment, { children: !isMobile ? (showLogin && (_jsxs(_Fragment, { children: [_jsx("div", { className: "overlay-side-content", children: otherContent }), _jsx("div", { className: "navbar-login-panel", children: _jsxs(SlidingPanel, { isOpen: showLogin && !isClosing, width: "400px", height: "100%", position: "right", closeOnOverlayClick: false, onClose: handleInternalClose, children: [_jsx("div", { className: "navbar-panel-header" }), _jsx("div", { className: "navbar-panel-content", children: loginContent })] }) })] }))) : (_jsx("div", { className: "navbar-login-panel", children: _jsxs(SlidingPanel, { isOpen: showLogin, height: "70%", position: "bottom", onClose: handleInternalClose, children: [_jsx("div", { className: "navbar-panel-header" }), _jsx("div", { className: "navbar-panel-content", children: loginContent })] }) })) }))] }));
59
+ }, children: item.name }), hasSubLinks && (_jsx("div", { className: "navbar-dropdown", children: _jsx("div", { className: "navbar-dropdown-content", children: item.subLinks.map(sub => (_jsx("a", { href: sub.link, target: sub.target || '_self', className: "navbar-dropdown-link", onClick: () => {
60
+ setMenuOpen(false);
61
+ setOpenDropdown(null);
62
+ }, children: sub.name }, sub.name))) }) }))] }, item.name));
63
+ }) }), isMobile && login && !logedinData && (_jsx("div", { className: 'navbar-item', style: { background: '#ffffff' }, children: _jsx("button", { className: "mobile-login-btn", onClick: toggleLogin, children: "Login" }) }))] }), _jsx("div", { className: 'separator', style: { color: '#aaaaaa', fontSize: '27px', padding: '0 15px' }, children: " | " }), _jsxs("div", { className: "navbar-right", children: [_jsxs("button", { className: `burger ${menuOpen ? 'active' : ''}`, onClick: toggleMenu, children: [_jsx("span", {}), _jsx("span", {}), _jsx("span", {})] }), !isMobile && login && !logedinData && (_jsx("span", { className: "login-btn", onClick: toggleLogin, children: "Login" }))] })] })] }) }), login && !logedinData && (_jsx(_Fragment, { children: !isMobile ? (showLogin && (_jsxs(_Fragment, { children: [_jsx("div", { className: "overlay-side-content", children: otherContent }), _jsx("div", { className: "navbar-login-panel", children: _jsxs(SlidingPanel, { isOpen: showLogin && !isClosing, width: "400px", height: "100%", position: "right", closeOnOverlayClick: false, onClose: handleInternalClose, children: [_jsx("div", { className: "navbar-panel-header" }), _jsx("div", { className: "navbar-panel-content", children: loginContent })] }) })] }))) : (_jsx("div", { className: "navbar-login-panel", children: _jsxs(SlidingPanel, { isOpen: showLogin, height: "70%", position: "bottom", onClose: handleInternalClose, children: [_jsx("div", { className: "navbar-panel-header" }), _jsx("div", { className: "navbar-panel-content", children: loginContent })] }) })) }))] }));
82
64
  };
83
65
  export default Navbar;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ml-ui-lib",
3
- "version": "1.0.27",
3
+ "version": "1.0.29",
4
4
  "main": "dist/index.js",
5
5
  "module": "dist/index.esm.js",
6
6
  "types": "dist/index.d.ts",