@levo-so/blocks 0.1.102 → 0.1.104

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.
Files changed (30) hide show
  1. package/package.json +23 -23
  2. package/src/blocks/blogs/blog-post-1.tsx +16 -7
  3. package/src/blocks/cards/cards-21.tsx +6 -6
  4. package/src/blocks/carousel/carousel-1.tsx +2 -2
  5. package/src/blocks/ecommerce/ecommerce-1.schema.ts +477 -0
  6. package/src/blocks/ecommerce/ecommerce-1.tsx +243 -0
  7. package/src/blocks/ecommerce/ecommerce-2.schema.ts +268 -0
  8. package/src/blocks/ecommerce/ecommerce-2.tsx +238 -0
  9. package/src/blocks/ecommerce/ecommerce-3.schema.ts +56 -0
  10. package/src/blocks/ecommerce/ecommerce-3.tsx +72 -0
  11. package/src/blocks/ecommerce/ecommerce-4.schema.ts +461 -0
  12. package/src/blocks/ecommerce/ecommerce-4.tsx +249 -0
  13. package/src/blocks/ecommerce/ecommerce-5.schema.ts +230 -0
  14. package/src/blocks/ecommerce/ecommerce-5.tsx +146 -0
  15. package/src/blocks/index.ts +12 -2
  16. package/src/blocks/logos/logos-2.schema.ts +223 -0
  17. package/src/blocks/logos/logos-2.tsx +55 -0
  18. package/src/blocks/navbar/navbar-3.schema.ts +6 -0
  19. package/src/blocks/navbar/navbar-3.tsx +3 -2
  20. package/src/blocks/navbar/navbar-4.schema.ts +6 -0
  21. package/src/blocks/navbar/navbar-4.tsx +1 -6
  22. package/src/blocks/products/products-listing-3.schema.ts +2 -4
  23. package/src/blocks/products/products-listing-3.tsx +86 -84
  24. package/src/blocks/services/service-2.tsx +0 -3
  25. package/src/blocks/services/service-3.schema.ts +22 -0
  26. package/src/blocks/services/service-3.tsx +12 -4
  27. package/src/schemas/blocks.ts +13 -3
  28. package/src/schemas/categories.ts +6 -0
  29. package/src/blocks/navbar/navbar-2.schema.ts +0 -1255
  30. package/src/blocks/navbar/navbar-2.tsx +0 -381
@@ -1,381 +0,0 @@
1
- "use client";
2
-
3
- import { cn } from "@levo-so/react";
4
- import type { ILevoBlockBaseProps } from "@levo-so/studio";
5
- import {
6
- Box,
7
- Button,
8
- Container,
9
- GlobalSearch,
10
- Icon,
11
- Image,
12
- PopoverContent,
13
- PopoverRoot,
14
- PopoverTrigger,
15
- Section,
16
- Typography,
17
- } from "@levo-so/studio";
18
- import { ChevronDown, Menu, X } from "lucide-react";
19
- import React, { useEffect, useState } from "react";
20
-
21
- import type { INavbar1Content } from "./navbar-1.schema";
22
-
23
- const DropdownNavigationItem: React.FC<{
24
- navItem: any;
25
- index: number;
26
- prefixKey: string;
27
- }> = ({ navItem, index, prefixKey }) => {
28
- const [isDropdownPopoverOpen, setIsDropdownPopoverOpen] = useState<boolean>(false);
29
-
30
- const subItems = navItem?.["sub-items"] as Array<any>;
31
-
32
- return (
33
- <PopoverRoot
34
- open={isDropdownPopoverOpen}
35
- onOpenChange={(open) => setIsDropdownPopoverOpen(open)}
36
- >
37
- <PopoverTrigger
38
- elementKey={`${prefixKey}.${index}.nav-item-dropdown-trigger`}
39
- onMouseEnter={() => setIsDropdownPopoverOpen(true)}
40
- data-levo_group_item
41
- >
42
- <Typography elementKey={`${prefixKey}.${index}.nav-item-dropdown-trigger-title`} />
43
- <ChevronDown
44
- aria-hidden="true"
45
- style={{
46
- position: "relative",
47
- top: "1px",
48
- height: "14px",
49
- width: "14px",
50
- transitionProperty:
51
- "color, background-color, border-color, text-decoration-color, fill, stroke, opacity, box-shadow, transform, filter, backdrop-filter",
52
- transitionTimingFunction: "cubic-bezier(0.4, 0, 0.2, 1)",
53
- transitionDuration: "300ms",
54
- rotate: isDropdownPopoverOpen ? "180deg" : "0deg",
55
- color: "var(--color-text-1)",
56
- }}
57
- />
58
- </PopoverTrigger>
59
- <PopoverContent
60
- elementKey={`${prefixKey}.${index}.sub-items_levoGroup`}
61
- data-levo_group
62
- onMouseLeave={() => setIsDropdownPopoverOpen(false)}
63
- inPortal={false}
64
- >
65
- {subItems && Array?.isArray(subItems)
66
- ? subItems?.map((subItem: any, idx: number) => (
67
- <Box
68
- elementKey={`left-desktop-nav-menu.${index}.sub-items.${idx}.sub-item-link`}
69
- key={`subItem_${index}_${idx}`}
70
- data-levo_group_item
71
- className={cn("group hover:bg-opacity-50", "")}
72
- >
73
- {subItem?.["sub-item-icon"] && (
74
- <Box
75
- elementKey={`left-desktop-nav-menu.${index}.sub-items.${idx}.sub-item-icon-container`}
76
- className="group-hover:bg-slate-200 group-hover:bg-opacity-80"
77
- >
78
- <Icon
79
- elementKey={`left-desktop-nav-menu.${index}.sub-items.${idx}.sub-item-icon`}
80
- />
81
- </Box>
82
- )}
83
- <Box
84
- elementKey={`left-desktop-nav-menu.${index}.sub-items.${idx}.sub-item-text-container`}
85
- >
86
- <Typography
87
- elementKey={`left-desktop-nav-menu.${index}.sub-items.${idx}.sub-item-title`}
88
- />
89
- <Typography
90
- elementKey={`left-desktop-nav-menu.${index}.sub-items.${idx}.sub-item-description`}
91
- />
92
- </Box>
93
- </Box>
94
- ))
95
- : null}
96
- </PopoverContent>
97
- </PopoverRoot>
98
- );
99
- };
100
-
101
- const DesktopNavItem: React.FC<{
102
- navItem: any;
103
- index: number;
104
- prefixKey: string;
105
- }> = ({ index, navItem, prefixKey }) => {
106
- const navSubItems = navItem?.["sub-items"] ?? [];
107
- const isNavItemDropdown = navSubItems && Array.isArray(navSubItems) && navSubItems?.length > 0;
108
-
109
- return (
110
- <>
111
- {isNavItemDropdown && (
112
- <DropdownNavigationItem navItem={navItem} index={index} prefixKey={prefixKey} />
113
- )}
114
- {!isNavItemDropdown && (
115
- <Typography data-levo_group_item elementKey={`${prefixKey}.${index}.nav-item-title`} />
116
- )}
117
- </>
118
- );
119
- };
120
-
121
- const DesktopNavigationMenu: React.FC<{
122
- navItems: any;
123
- prefixKey: string;
124
- }> = ({ navItems, prefixKey }) => {
125
- return (
126
- <Box elementKey={`${prefixKey}_levoGroup`} data-levo_group>
127
- {navItems?.map((item: any, index: number) => {
128
- return (
129
- <DesktopNavItem
130
- navItem={item}
131
- index={index}
132
- key={`${prefixKey}.${index}`}
133
- prefixKey={prefixKey}
134
- />
135
- );
136
- })}
137
- </Box>
138
- );
139
- };
140
-
141
- const DropdownNavigationItemMobile: React.FC<{
142
- navItem: any;
143
- index: number;
144
- setIsOpen: (value: boolean) => void;
145
- }> = ({ navItem, index, setIsOpen }) => {
146
- const [isDropdownOpen, setIsDropdownOpen] = useState<boolean>(false);
147
-
148
- const subItems = navItem?.["sub-items"] as Array<any>;
149
-
150
- return (
151
- <Box elementKey={`mobile-nav-menu.${index}.nav-item-dropdown-container`}>
152
- <Box
153
- elementKey={`mobile-nav-menu.${index}.nav-item-dropdown-trigger`}
154
- onClick={() => setIsDropdownOpen((prev) => !prev)}
155
- >
156
- <Typography elementKey={`mobile-nav-menu.${index}.nav-item-dropdown-trigger-title`} />
157
- <ChevronDown
158
- aria-hidden="true"
159
- style={{
160
- position: "relative",
161
- top: "2px",
162
- height: "16px",
163
- width: "16px",
164
- transitionProperty:
165
- "color, background-color, border-color, text-decoration-color, fill, stroke, opacity, box-shadow, transform, filter, backdrop-filter",
166
- transitionTimingFunction: "cubic-bezier(0.4, 0, 0.2, 1)",
167
- transitionDuration: "300ms",
168
- rotate: isDropdownOpen ? "180deg" : "0deg",
169
- color: "var(--color-text-1)",
170
- }}
171
- />
172
- </Box>
173
- {isDropdownOpen && (
174
- <Box elementKey={`mobile-nav-menu.${index}.sub-items_levoGroup`} data-levo_group>
175
- {subItems && Array?.isArray(subItems)
176
- ? subItems?.map((subItem: any, idx: number) => {
177
- return (
178
- <Box
179
- key={`subItem_${index}`}
180
- elementKey={`mobile-nav-menu.${index}.sub-items.${idx}.sub-item-link`}
181
- className={cn("group hover:bg-slate-100 hover:bg-opacity-50")}
182
- data-levo_group_item
183
- >
184
- {subItem?.["sub-item-icon"] && (
185
- <Box
186
- elementKey={`mobile-nav-menu.${index}.sub-items.${idx}.sub-item-icon-container`}
187
- className="bg-opacity-60 group-hover:bg-slate-200 group-hover:bg-opacity-80"
188
- >
189
- <Icon
190
- elementKey={`mobile-nav-menu.${index}.sub-items.${idx}.sub-item-icon`}
191
- />
192
- </Box>
193
- )}
194
- <Box
195
- elementKey={`mobile-nav-menu.${index}.sub-items.${idx}.sub-item-text-container`}
196
- >
197
- {subItem?.["sub-item-title"] && (
198
- <Box
199
- elementKey={`mobile-nav-menu.${index}.sub-items.${idx}.sub-item-title-container`}
200
- onClick={() => setIsOpen(false)}
201
- >
202
- <Typography
203
- elementKey={`mobile-nav-menu.${index}.sub-items.${idx}.sub-item-title`}
204
- />
205
- </Box>
206
- )}
207
- <Typography
208
- elementKey={`mobile-nav-menu.${index}.sub-items.${idx}.sub-item-description`}
209
- />
210
- </Box>
211
- </Box>
212
- );
213
- })
214
- : null}
215
- </Box>
216
- )}
217
- </Box>
218
- );
219
- };
220
-
221
- const MobileNavItem: React.FC<{
222
- navItem: any;
223
- index: number;
224
- setIsOpen: (value: boolean) => void;
225
- }> = ({ navItem, index, setIsOpen }) => {
226
- const navSubItems = navItem?.["sub-items"] ?? [];
227
- const isNavItemDropdown = navSubItems && Array.isArray(navSubItems) && navSubItems?.length > 0;
228
-
229
- return (
230
- <React.Fragment>
231
- {isNavItemDropdown && (
232
- <DropdownNavigationItemMobile navItem={navItem} setIsOpen={setIsOpen} index={index} />
233
- )}
234
- {!isNavItemDropdown && (
235
- <Box
236
- data-levo_group_item
237
- elementKey={`mobile-nav-menu.${index}.nav-item-title-container`}
238
- onClick={() => setIsOpen(false)}
239
- >
240
- <Typography elementKey={`mobile-nav-menu.${index}.nav-item-title`} />
241
- </Box>
242
- )}
243
- </React.Fragment>
244
- );
245
- };
246
-
247
- const MobileNavigationSheet: React.FC<{
248
- navItems: any;
249
- content: any;
250
- isOpen: boolean;
251
- setIsOpen: (value: boolean) => void;
252
- }> = ({ navItems, content, isOpen, setIsOpen }) => {
253
- return (
254
- <React.Fragment>
255
- <Box elementKey="mobile-nav-container">
256
- <Box elementKey="mobile-search-container">
257
- <GlobalSearch variant="icon" />
258
- </Box>
259
- <Button
260
- elementKey="mobile-nav-menu-button"
261
- aria-label="Open navigation"
262
- onClick={() => setIsOpen(!isOpen)}
263
- >
264
- {isOpen ? <X size={24} /> : <Menu size={24} />}
265
- </Button>
266
- </Box>
267
- {isOpen && (
268
- <Box elementKey="mobile-nav-menu-wrapper">
269
- <Box elementKey="mobile-nav-menu_levoGroup" data-levo_group>
270
- {Array.isArray(navItems)
271
- ? navItems?.map((item, index) => {
272
- return (
273
- <MobileNavItem
274
- navItem={item}
275
- key={`${item?.["nav-item-title"]}_${index}`}
276
- setIsOpen={setIsOpen}
277
- index={index}
278
- />
279
- );
280
- })
281
- : null}
282
- </Box>
283
- {content?.["mobile-cta-group"]?.length > 0 && (
284
- <Box elementKey="mobile-cta-group_levoGroup" data-levo_group>
285
- {content?.["mobile-cta-group"]?.map((_: any, index: number) => (
286
- <Button
287
- key={`mobile-cta-group.${index}.cta`}
288
- elementKey={`mobile-cta-group.${index}.cta`}
289
- data-levo_group_item
290
- />
291
- ))}
292
- </Box>
293
- )}
294
- </Box>
295
- )}
296
- </React.Fragment>
297
- );
298
- };
299
-
300
- const Navbar2: React.FC<ILevoBlockBaseProps<INavbar1Content>> = ({ content }) => {
301
- const [isScrolled, setIsScrolled] = useState(false);
302
- const [isOpen, setIsOpen] = useState(false);
303
-
304
- useEffect(() => {
305
- const handleScroll = () => {
306
- if (window.scrollY === 0 && isScrolled) {
307
- setIsScrolled(false);
308
- } else if (window.scrollY >= 40 && !isScrolled) {
309
- setIsScrolled(true);
310
- }
311
- };
312
-
313
- document.addEventListener("scroll", handleScroll);
314
-
315
- return () => {
316
- document.removeEventListener("scroll", handleScroll);
317
- };
318
- }, [isScrolled]);
319
-
320
- const leftDesktopNavLinks = content?.["left-desktop-nav-menu"];
321
- const rightDesktopNavLinks = content?.["right-desktop-nav-menu"];
322
- const mobileNavLinks = content?.["mobile-nav-menu"];
323
-
324
- return (
325
- <>
326
- {isOpen && (
327
- <Box
328
- elementKey="mobile-background-overlay"
329
- onClick={() => setIsOpen(false)}
330
- className="fixed top-0 right-0 bottom-0 left-0 z-20 bg-black/20"
331
- />
332
- )}
333
- <Section elementKey="layout" className={cn(isScrolled ? "top-2" : "top-8")}>
334
- <Container elementKey="nav-container">
335
- {leftDesktopNavLinks &&
336
- Array?.isArray(leftDesktopNavLinks) &&
337
- leftDesktopNavLinks?.length > 0 && (
338
- <DesktopNavigationMenu
339
- navItems={leftDesktopNavLinks}
340
- prefixKey="left-desktop-nav-menu"
341
- />
342
- )}
343
- <Image elementKey="nav-logo" alt="Logo" />
344
- <Box elementKey="right-container">
345
- {rightDesktopNavLinks &&
346
- Array?.isArray(rightDesktopNavLinks) &&
347
- rightDesktopNavLinks?.length > 0 && (
348
- <DesktopNavigationMenu
349
- navItems={rightDesktopNavLinks}
350
- prefixKey="right-desktop-nav-menu"
351
- />
352
- )}
353
- {content?.["desktop-cta-group"]?.length > 0 && (
354
- <Box elementKey="desktop-cta-group_levoGroup" data-levo_group>
355
- <Box elementKey="desktop-search-container">
356
- <GlobalSearch variant="icon" />
357
- </Box>
358
- {content?.["desktop-cta-group"]?.map((_: any, index: number) => (
359
- <Button
360
- key={`desktop-cta-group.${index}.cta`}
361
- elementKey={`desktop-cta-group.${index}.cta`}
362
- data-levo_group_item
363
- />
364
- ))}
365
- </Box>
366
- )}
367
- </Box>
368
-
369
- <MobileNavigationSheet
370
- navItems={mobileNavLinks || []}
371
- content={content}
372
- isOpen={isOpen}
373
- setIsOpen={setIsOpen}
374
- />
375
- </Container>
376
- </Section>
377
- </>
378
- );
379
- };
380
-
381
- export default Navbar2;