@levo-so/blocks 0.1.60 → 0.1.62

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 (230) hide show
  1. package/package.json +13 -14
  2. package/src/blocks/about-us/about-us-1.schema.ts +15 -30
  3. package/src/blocks/about-us/about-us-1.tsx +2 -4
  4. package/src/blocks/about-us/about-us-2.schema.ts +24 -48
  5. package/src/blocks/about-us/about-us-2.tsx +7 -13
  6. package/src/blocks/blogs/blog-listing-1.schema.ts +7 -14
  7. package/src/blocks/blogs/blog-listing-1.tsx +10 -21
  8. package/src/blocks/blogs/blog-listing-2.schema.ts +17 -34
  9. package/src/blocks/blogs/blog-listing-2.tsx +4 -12
  10. package/src/blocks/blogs/blog-listing-3.schema.ts +32 -64
  11. package/src/blocks/blogs/blog-listing-3.tsx +4 -12
  12. package/src/blocks/blogs/blog-post-1.schema.ts +9 -18
  13. package/src/blocks/blogs/blog-post-1.tsx +3 -14
  14. package/src/blocks/calendar/calendar-1.schema.ts +95 -6
  15. package/src/blocks/calendar/calendar-1.tsx +33 -29
  16. package/src/blocks/cards/cards-10.schema.ts +62 -124
  17. package/src/blocks/cards/cards-10.tsx +9 -14
  18. package/src/blocks/cards/cards-11.schema.ts +69 -138
  19. package/src/blocks/cards/cards-11.tsx +5 -11
  20. package/src/blocks/cards/cards-12.schema.ts +7 -14
  21. package/src/blocks/cards/cards-12.tsx +4 -10
  22. package/src/blocks/cards/cards-13.schema.ts +40 -80
  23. package/src/blocks/cards/cards-13.tsx +4 -6
  24. package/src/blocks/cards/cards-14.schema.ts +7 -14
  25. package/src/blocks/cards/cards-14.tsx +5 -11
  26. package/src/blocks/cards/cards-15.schema.ts +7 -14
  27. package/src/blocks/cards/cards-15.tsx +2 -4
  28. package/src/blocks/cards/cards-2.schema.ts +7 -14
  29. package/src/blocks/cards/cards-2.tsx +2 -15
  30. package/src/blocks/cards/cards-3.schema.ts +7 -14
  31. package/src/blocks/cards/cards-3.tsx +7 -13
  32. package/src/blocks/cards/cards-4.schema.ts +13 -26
  33. package/src/blocks/cards/cards-4.tsx +9 -15
  34. package/src/blocks/cards/cards-5.schema.ts +17 -34
  35. package/src/blocks/cards/cards-5.tsx +1 -9
  36. package/src/blocks/cards/cards-6.schema.ts +52 -104
  37. package/src/blocks/cards/cards-6.tsx +12 -20
  38. package/src/blocks/cards/cards-7.schema.ts +48 -96
  39. package/src/blocks/cards/cards-7.tsx +8 -27
  40. package/src/blocks/cards/cards-8.schema.ts +9 -20
  41. package/src/blocks/cards/cards-8.tsx +5 -11
  42. package/src/blocks/cards/cards-9.schema.ts +41 -82
  43. package/src/blocks/cards/cards-9.tsx +14 -22
  44. package/src/blocks/carousel/carousel-1.schema.ts +64 -128
  45. package/src/blocks/carousel/carousel-1.tsx +6 -8
  46. package/src/blocks/carousel/carousel-2.schema.ts +26 -52
  47. package/src/blocks/carousel/carousel-2.tsx +11 -23
  48. package/src/blocks/community/community-1.schema.ts +78 -32
  49. package/src/blocks/community/community-1.tsx +417 -550
  50. package/src/blocks/community/community-post-1.schema.ts +21 -30
  51. package/src/blocks/community/community-post-1.tsx +334 -84
  52. package/src/blocks/contact-us/contact-us-1.schema.ts +8 -16
  53. package/src/blocks/contact-us/contact-us-1.tsx +2 -12
  54. package/src/blocks/contact-us/contact-us-2.tsx +20 -31
  55. package/src/blocks/content/content-1.schema.ts +21 -42
  56. package/src/blocks/content/content-1.tsx +10 -17
  57. package/src/blocks/content/content-2.schema.ts +29 -58
  58. package/src/blocks/content/content-2.tsx +4 -4
  59. package/src/blocks/content/content-3.tsx +13 -29
  60. package/src/blocks/content/content-4.schema.ts +23 -46
  61. package/src/blocks/content/content-4.tsx +8 -17
  62. package/src/blocks/content/content-5.schema.ts +29 -24
  63. package/src/blocks/content/content-5.tsx +13 -27
  64. package/src/blocks/content/content-6.schema.ts +46 -94
  65. package/src/blocks/content/content-6.tsx +14 -31
  66. package/src/blocks/content/content-7.schema.ts +35 -72
  67. package/src/blocks/content/content-7.tsx +15 -31
  68. package/src/blocks/content/content-8.schema.ts +1 -6
  69. package/src/blocks/content/content-8.tsx +3 -3
  70. package/src/blocks/content/content-9.tsx +26 -41
  71. package/src/blocks/cta/cta-1.schema.ts +10 -20
  72. package/src/blocks/cta/cta-2.schema.ts +14 -28
  73. package/src/blocks/cta/cta-2.tsx +2 -6
  74. package/src/blocks/cta/cta-3.schema.ts +24 -50
  75. package/src/blocks/cta/cta-3.tsx +2 -6
  76. package/src/blocks/embed/embed-1.tsx +1 -9
  77. package/src/blocks/event/ClientOnly.tsx +1 -4
  78. package/src/blocks/event/event-details.schema.ts +16 -32
  79. package/src/blocks/event/event-details.tsx +8 -23
  80. package/src/blocks/event/event-listing-2.schema.ts +19 -38
  81. package/src/blocks/event/event-listing-2.tsx +12 -23
  82. package/src/blocks/event/event-listing-3.schema.ts +10 -20
  83. package/src/blocks/event/event-listing-3.tsx +9 -15
  84. package/src/blocks/event/event-listing-4.schema.ts +40 -80
  85. package/src/blocks/event/event-listing-4.tsx +5 -13
  86. package/src/blocks/event/event-listing.schema.ts +12 -24
  87. package/src/blocks/event/event-listing.tsx +9 -15
  88. package/src/blocks/faq/faq-1.schema.ts +8 -16
  89. package/src/blocks/faq/faq-1.tsx +19 -30
  90. package/src/blocks/faq/faq-2.schema.ts +8 -16
  91. package/src/blocks/faq/faq-2.tsx +11 -10
  92. package/src/blocks/faq/faq-3.schema.ts +9 -18
  93. package/src/blocks/faq/faq-3.tsx +11 -19
  94. package/src/blocks/features/features-1/features-1.tsx +2 -4
  95. package/src/blocks/features/features-1/variants/default.ts +4 -8
  96. package/src/blocks/features/features-1/variants/index.ts +1 -1
  97. package/src/blocks/features/features-2.schema.ts +32 -64
  98. package/src/blocks/features/features-2.tsx +8 -10
  99. package/src/blocks/features/features-3.schema.ts +32 -64
  100. package/src/blocks/features/features-3.tsx +7 -16
  101. package/src/blocks/features/features-4.schema.ts +16 -32
  102. package/src/blocks/features/features-4.tsx +3 -7
  103. package/src/blocks/features/features-5.schema.ts +1 -2
  104. package/src/blocks/features/features-5.tsx +6 -17
  105. package/src/blocks/features/features-6.schema.ts +32 -64
  106. package/src/blocks/features/features-6.tsx +16 -36
  107. package/src/blocks/filter-listing/filter-listing-1.tsx +12 -36
  108. package/src/blocks/floating-buttons/floating-button-1.schema.ts +5 -10
  109. package/src/blocks/floating-buttons/floating-button-1.tsx +3 -9
  110. package/src/blocks/footer/footer-1.schema.ts +8 -16
  111. package/src/blocks/footer/footer-1.tsx +15 -30
  112. package/src/blocks/footer/footer-2.schema.ts +8 -16
  113. package/src/blocks/footer/footer-2.tsx +17 -28
  114. package/src/blocks/footer/footer-3.schema.ts +1 -2
  115. package/src/blocks/footer/footer-3.tsx +9 -25
  116. package/src/blocks/footer/footer-4.schema.ts +8 -16
  117. package/src/blocks/footer/footer-4.tsx +35 -54
  118. package/src/blocks/footer/footer-5.schema.ts +10 -24
  119. package/src/blocks/footer/footer-5.tsx +14 -29
  120. package/src/blocks/footer/footer-6.schema.ts +10 -25
  121. package/src/blocks/footer/footer-6.tsx +29 -44
  122. package/src/blocks/form/form-1.schema.ts +144 -0
  123. package/src/blocks/form/form-1.tsx +33 -0
  124. package/src/blocks/hero/hero-1.schema.ts +45 -90
  125. package/src/blocks/hero/hero-1.tsx +4 -4
  126. package/src/blocks/hero/hero-10.schema.ts +1 -2
  127. package/src/blocks/hero/hero-10.tsx +4 -4
  128. package/src/blocks/hero/hero-11.schema.ts +18 -14
  129. package/src/blocks/hero/hero-11.tsx +4 -9
  130. package/src/blocks/hero/hero-12.schema.ts +18 -36
  131. package/src/blocks/hero/hero-12.tsx +3 -6
  132. package/src/blocks/hero/hero-13.schema.ts +8 -16
  133. package/src/blocks/hero/hero-13.tsx +1 -1
  134. package/src/blocks/hero/hero-2.schema.ts +3 -6
  135. package/src/blocks/hero/hero-2.tsx +3 -21
  136. package/src/blocks/hero/hero-3.schema.ts +28 -56
  137. package/src/blocks/hero/hero-3.tsx +6 -15
  138. package/src/blocks/hero/hero-4.schema.ts +22 -44
  139. package/src/blocks/hero/hero-4.tsx +16 -27
  140. package/src/blocks/hero/hero-5.schema.ts +21 -42
  141. package/src/blocks/hero/hero-5.tsx +15 -18
  142. package/src/blocks/hero/hero-6.schema.ts +35 -70
  143. package/src/blocks/hero/hero-6.tsx +6 -6
  144. package/src/blocks/hero/hero-7.schema.ts +24 -48
  145. package/src/blocks/hero/hero-7.tsx +2 -3
  146. package/src/blocks/hero/hero-8.schema.ts +24 -50
  147. package/src/blocks/hero/hero-8.tsx +5 -19
  148. package/src/blocks/hero/hero-9.schema.ts +8 -16
  149. package/src/blocks/hero/hero-9.tsx +3 -3
  150. package/src/blocks/index.ts +8 -11
  151. package/src/blocks/jobs/jobs-1.schema.ts +990 -0
  152. package/src/blocks/jobs/jobs-1.tsx +145 -0
  153. package/src/blocks/logos/logos-1.schema.ts +53 -113
  154. package/src/blocks/logos/logos-1.tsx +7 -7
  155. package/src/blocks/navbar/navbar-1.schema.ts +15 -28
  156. package/src/blocks/navbar/navbar-1.tsx +24 -60
  157. package/src/blocks/navbar/navbar-2.schema.ts +14 -28
  158. package/src/blocks/navbar/navbar-2.tsx +26 -56
  159. package/src/blocks/navbar/navbar-3.schema.ts +11 -22
  160. package/src/blocks/navbar/navbar-3.tsx +33 -82
  161. package/src/blocks/navbar/navbar-4.schema.ts +14343 -0
  162. package/src/blocks/navbar/navbar-4.tsx +546 -0
  163. package/src/blocks/polling/polling-1.schema.ts +1 -2
  164. package/src/blocks/polling/polling-1.tsx +24 -39
  165. package/src/blocks/pricing/pricing-1.schema.ts +13 -26
  166. package/src/blocks/pricing/pricing-1.tsx +20 -44
  167. package/src/blocks/products/products-listing-1.schema.ts +32 -64
  168. package/src/blocks/products/products-listing-1.tsx +6 -12
  169. package/src/blocks/products/products-listing-2.schema.ts +26 -54
  170. package/src/blocks/products/products-listing-2.tsx +8 -17
  171. package/src/blocks/products/products-listing-3.schema.ts +25 -52
  172. package/src/blocks/products/products-listing-3.tsx +87 -93
  173. package/src/blocks/profile/profile-1.schema.ts +7 -14
  174. package/src/blocks/profile/profile-1.tsx +2 -8
  175. package/src/blocks/profile/profile-2.schema.ts +9 -18
  176. package/src/blocks/profile/profile-2.tsx +4 -6
  177. package/src/blocks/profile/profile-3.schema.ts +21 -42
  178. package/src/blocks/profile/profile-3.tsx +18 -40
  179. package/src/blocks/{blogs/blog-post-2.schema.ts → profile/profile-4.schema.ts} +75 -97
  180. package/src/blocks/{blogs/blog-post-2.tsx → profile/profile-4.tsx} +32 -61
  181. package/src/blocks/{blogs/blog-post-3.schema.ts → profile/profile-5.schema.ts} +6 -6
  182. package/src/blocks/{blogs/blog-post-3.tsx → profile/profile-5.tsx} +6 -11
  183. package/src/blocks/services/service-1.schema.ts +20 -40
  184. package/src/blocks/services/service-1.tsx +45 -71
  185. package/src/blocks/services/service-2.schema.ts +8 -16
  186. package/src/blocks/services/service-2.tsx +4 -6
  187. package/src/blocks/services/service-3.schema.ts +12 -24
  188. package/src/blocks/services/service-3.tsx +4 -6
  189. package/src/blocks/stats/stats-1.tsx +3 -14
  190. package/src/blocks/stats/stats-2.tsx +3 -14
  191. package/src/blocks/stats/variants/index.ts +1 -1
  192. package/src/blocks/tabs/tab-1.schema.ts +4 -8
  193. package/src/blocks/tabs/tab-1.tsx +47 -64
  194. package/src/blocks/tabs/tab-2.schema.ts +13 -26
  195. package/src/blocks/tabs/tab-2.tsx +14 -15
  196. package/src/blocks/team/team-1.schema.ts +28 -56
  197. package/src/blocks/team/team-1.tsx +7 -21
  198. package/src/blocks/team/team-2.schema.ts +104 -208
  199. package/src/blocks/team/team-2.tsx +15 -33
  200. package/src/blocks/team/team-3.schema.ts +24 -48
  201. package/src/blocks/team/team-3.tsx +8 -14
  202. package/src/blocks/team/team-4.schema.ts +25 -50
  203. package/src/blocks/team/team-4.tsx +15 -24
  204. package/src/blocks/team/team-5.schema.ts +14 -28
  205. package/src/blocks/team/team-5.tsx +1 -1
  206. package/src/blocks/termsAndPrivacy/terms-and-conditions-1.tsx +3 -5
  207. package/src/blocks/testimonial/testimonial-1.schema.ts +1 -2
  208. package/src/blocks/testimonial/testimonial-1.tsx +10 -19
  209. package/src/blocks/testimonial/testimonial-2.schema.ts +16 -32
  210. package/src/blocks/testimonial/testimonial-2.tsx +17 -36
  211. package/src/blocks/testimonial/testimonial-3.schema.ts +8 -16
  212. package/src/blocks/testimonial/testimonial-3.tsx +13 -26
  213. package/src/blocks/testimonial/testimonial-4.schema.ts +94 -188
  214. package/src/blocks/testimonial/testimonial-4.tsx +12 -33
  215. package/src/blocks/testimonial/testimonial-5/variants/default.ts +24 -48
  216. package/src/blocks/testimonial/testimonial-5/variants/index.ts +1 -1
  217. package/src/blocks/testimonial/testimonial-5/variants/testimonialWithLogo.ts +4 -8
  218. package/src/blocks/testimonial/testimonial-5/variants/testimonialWithRatings.ts +24 -48
  219. package/src/blocks/testimonial/testimonial-5.schema.ts +2 -6
  220. package/src/blocks/testimonial/testimonial-5.tsx +15 -25
  221. package/src/blocks/testimonial/testimonial-6.schema.ts +26 -52
  222. package/src/blocks/testimonial/testimonial-6.tsx +9 -25
  223. package/src/blocks/testimonial/testimonial-7.tsx +15 -26
  224. package/src/blocks/timeline/timeline-1.schema.ts +34 -68
  225. package/src/blocks/timeline/timeline-1.tsx +2 -6
  226. package/src/blocks/users/edit-profile.tsx +10 -22
  227. package/src/constants/index.ts +3 -6
  228. package/src/index.ts +1 -1
  229. package/src/schemas/blocks.ts +14 -8
  230. package/src/schemas/categories.ts +14 -2
@@ -0,0 +1,546 @@
1
+ import { cn } from "@levo-so/react";
2
+ import type { ILevoBlockBaseProps } from "@levo-so/studio";
3
+ import {
4
+ Box,
5
+ Button,
6
+ Container,
7
+ Icon,
8
+ Image,
9
+ PopoverContent,
10
+ PopoverRoot,
11
+ PopoverTrigger,
12
+ Section,
13
+ Typography,
14
+ UserMenu,
15
+ } from "@levo-so/studio";
16
+ import { ChevronDown, ChevronRight, Menu, X } from "lucide-react";
17
+ import React, { useEffect, useState } from "react";
18
+
19
+ import type { INavbar3Content } from "./navbar-3.schema";
20
+
21
+ const NestedDropdownItem: React.FC<{
22
+ subItem: any;
23
+ parentIndex: number;
24
+ subIndex: number;
25
+ }> = ({ subItem, parentIndex, subIndex }) => {
26
+ const [isNestedDropdownOpen, setIsNestedDropdownOpen] = useState<boolean>(false);
27
+ const nestedSubItems = subItem?.["sub-sub-items"] as Array<any>;
28
+ const hasNestedItems =
29
+ nestedSubItems && Array.isArray(nestedSubItems) && nestedSubItems.length > 0;
30
+
31
+ if (!hasNestedItems) {
32
+ return (
33
+ <Box
34
+ elementKey={`desktop-nav-menu.${parentIndex}.sub-items.${subIndex}.sub-item-link`}
35
+ data-levo_group_item
36
+ className="flex items-center gap-3"
37
+ >
38
+ {subItem?.["sub-item-icon"] && (
39
+ <Box
40
+ elementKey={`desktop-nav-menu.${parentIndex}.sub-items.${subIndex}.sub-item-icon-container`}
41
+ className=""
42
+ >
43
+ <Icon
44
+ elementKey={`desktop-nav-menu.${parentIndex}.sub-items.${subIndex}.sub-item-icon`}
45
+ />
46
+ </Box>
47
+ )}
48
+ <Box
49
+ elementKey={`desktop-nav-menu.${parentIndex}.sub-items.${subIndex}.sub-item-text-container`}
50
+ className=""
51
+ >
52
+ <Typography
53
+ elementKey={`desktop-nav-menu.${parentIndex}.sub-items.${subIndex}.sub-item-title`}
54
+ />
55
+ <Typography
56
+ elementKey={`desktop-nav-menu.${parentIndex}.sub-items.${subIndex}.sub-item-description`}
57
+ />
58
+ </Box>
59
+ </Box>
60
+ );
61
+ }
62
+
63
+ return (
64
+ <PopoverRoot open={isNestedDropdownOpen} onOpenChange={setIsNestedDropdownOpen}>
65
+ <PopoverTrigger
66
+ elementKey={`desktop-nav-menu.${parentIndex}.sub-items.${subIndex}.sub-item-link`}
67
+ onMouseEnter={() => setIsNestedDropdownOpen(true)}
68
+ data-levo_group_item
69
+ className="group flex items-center justify-between px-4 py-2 focus:outline-none"
70
+ >
71
+ <div className="flex items-center gap-3">
72
+ {subItem?.["sub-item-icon"] && (
73
+ <Box
74
+ elementKey={`desktop-nav-menu.${parentIndex}.sub-items.${subIndex}.sub-item-icon-container`}
75
+ className=""
76
+ >
77
+ <Icon
78
+ elementKey={`desktop-nav-menu.${parentIndex}.sub-items.${subIndex}.sub-item-icon`}
79
+ />
80
+ </Box>
81
+ )}
82
+ <Box
83
+ elementKey={`desktop-nav-menu.${parentIndex}.sub-items.${subIndex}.sub-item-text-container`}
84
+ className=""
85
+ >
86
+ <Typography
87
+ elementKey={`desktop-nav-menu.${parentIndex}.sub-items.${subIndex}.sub-item-title`}
88
+ />
89
+ <Typography
90
+ elementKey={`desktop-nav-menu.${parentIndex}.sub-items.${subIndex}.sub-item-description`}
91
+ />
92
+ </Box>
93
+ </div>
94
+ <div className="ml-auto group-hover:text-text-1">
95
+ <ChevronRight
96
+ aria-hidden="true"
97
+ style={{
98
+ position: "relative",
99
+ top: "1px",
100
+ height: "14px",
101
+ width: "14px",
102
+ transitionProperty:
103
+ "color, background-color, border-color, text-decoration-color, fill, stroke, opacity, box-shadow, transform, filter, backdrop-filter",
104
+ transitionTimingFunction: "cubic-bezier(0.4, 0, 0.2, 1)",
105
+ transitionDuration: "300ms",
106
+ color: "var(--color-text-1)",
107
+ }}
108
+ />
109
+ </div>
110
+ </PopoverTrigger>
111
+ <PopoverContent
112
+ elementKey={`desktop-nav-menu.${parentIndex}.sub-items.${subIndex}.sub-sub-items`}
113
+ onMouseLeave={() => setIsNestedDropdownOpen(false)}
114
+ inPortal={true}
115
+ className="!bg-white z-[60] min-w-16 rounded-md border border-gray-200 shadow-lg focus:outline-none"
116
+ style={{
117
+ backgroundColor: "white !important",
118
+ background: "white",
119
+ outline: "none",
120
+ boxShadow: "0 10px 15px -3px rgba(0, 0, 0, 0.1), 0 4px 6px -2px rgba(0, 0, 0, 0.05)",
121
+ minWidth: "8rem",
122
+ width: "fit-content",
123
+ }}
124
+ side="right"
125
+ align="start"
126
+ >
127
+ {nestedSubItems?.map((_: any, nestedIdx: number) => (
128
+ <Box
129
+ elementKey={`desktop-nav-menu.${parentIndex}.sub-items.${subIndex}.sub-sub-items.${nestedIdx}.nested-sub-item-container`}
130
+ key={`nestedSubItem_${parentIndex}_${subIndex}_${nestedIdx}`}
131
+ data-levo_group_item
132
+ className="-mx-2 cursor-pointer whitespace-nowrap rounded px-2 py-2 hover:bg-gray-50 focus:outline-none"
133
+ >
134
+ <Typography
135
+ elementKey={`desktop-nav-menu.${parentIndex}.sub-items.${subIndex}.sub-sub-items.${nestedIdx}.nested-sub-item-title`}
136
+ />
137
+ <Typography
138
+ elementKey={`desktop-nav-menu.${parentIndex}.sub-items.${subIndex}.sub-sub-items.${nestedIdx}.nested-sub-item-description`}
139
+ />
140
+ </Box>
141
+ ))}
142
+ </PopoverContent>
143
+ </PopoverRoot>
144
+ );
145
+ };
146
+
147
+ const DropdownNavigationItem: React.FC<{
148
+ navItem: any;
149
+ index: number;
150
+ }> = ({ navItem, index }) => {
151
+ const [isDropdownPopoverOpen, setIsDropdownPopoverOpen] = useState<boolean>(false);
152
+
153
+ const subItems = navItem?.["sub-items"] as Array<any>;
154
+
155
+ return (
156
+ <PopoverRoot
157
+ open={isDropdownPopoverOpen}
158
+ onOpenChange={(open) => setIsDropdownPopoverOpen(open)}
159
+ defaultOpen
160
+ >
161
+ <PopoverTrigger
162
+ elementKey={`desktop-nav-menu.${index}.nav-item-dropdown-trigger`}
163
+ onMouseEnter={() => setIsDropdownPopoverOpen(true)}
164
+ data-levo_group_item
165
+ className="focus:outline-none"
166
+ >
167
+ <Typography elementKey={`desktop-nav-menu.${index}.nav-item-dropdown-trigger-title`} />
168
+ <ChevronDown
169
+ aria-hidden="true"
170
+ style={{
171
+ position: "relative",
172
+
173
+ height: "14px",
174
+ width: "14px",
175
+ transitionProperty:
176
+ "color, background-color, border-color, text-decoration-color, fill, stroke, opacity, box-shadow, transform, filter, backdrop-filter",
177
+ transitionTimingFunction: "cubic-bezier(0.4, 0, 0.2, 1)",
178
+ transitionDuration: "300ms",
179
+ rotate: isDropdownPopoverOpen ? "180deg" : "0deg",
180
+ color: "var(--color-text-1)",
181
+ }}
182
+ />
183
+ </PopoverTrigger>
184
+ <PopoverContent
185
+ elementKey={`desktop-nav-menu.${index}.sub-items_levoGroup`}
186
+ data-levo_group
187
+ onMouseLeave={() => setIsDropdownPopoverOpen(false)}
188
+ inPortal={false}
189
+ className="focus:outline-none"
190
+ side="bottom"
191
+ align="start"
192
+ >
193
+ {subItems && Array?.isArray(subItems)
194
+ ? subItems?.map((subItem: any, idx: number) => (
195
+ <NestedDropdownItem
196
+ key={`subItem_${index}_${idx}`}
197
+ subItem={subItem}
198
+ parentIndex={index}
199
+ subIndex={idx}
200
+ />
201
+ ))
202
+ : null}
203
+ </PopoverContent>
204
+ </PopoverRoot>
205
+ );
206
+ };
207
+
208
+ const DesktopNavItem: React.FC<{
209
+ navItem: any;
210
+ index: number;
211
+ }> = ({ index, navItem }) => {
212
+ const navSubItems = navItem?.["sub-items"] ?? [];
213
+ const isNavItemDropdown = navSubItems && Array.isArray(navSubItems) && navSubItems?.length > 0;
214
+
215
+ console.log({
216
+ navItem,
217
+ });
218
+
219
+ return (
220
+ <>
221
+ {isNavItemDropdown && <DropdownNavigationItem navItem={navItem} index={index} />}
222
+ {!isNavItemDropdown && (
223
+ <Typography data-levo_groupItem elementKey={`desktop-nav-menu.${index}.nav-item-title`} />
224
+ )}
225
+ </>
226
+ );
227
+ };
228
+
229
+ const DesktopNavigationMenu: React.FC<{
230
+ navItems: any;
231
+ }> = ({ navItems }) => {
232
+ return (
233
+ <Box elementKey="desktop-nav-menu_levoGroup" data-levo_group>
234
+ {navItems?.map((item: any, index: number) => {
235
+ return <DesktopNavItem navItem={item} index={index} key={`desktop-nav-menu.${index}`} />;
236
+ })}
237
+ </Box>
238
+ );
239
+ };
240
+
241
+ const NestedDropdownItemMobile: React.FC<any> = ({ subItem, parentIndex, subIndex }) => {
242
+ const [isNestedDropdownOpen, setIsNestedDropdownOpen] = useState<boolean>(false);
243
+
244
+ const nestedSubItems = subItem?.["sub-sub-items"] as Array<any>;
245
+
246
+ return (
247
+ <>
248
+ <Box
249
+ elementKey={`mobile-nav-menu.${parentIndex}.sub-items.${subIndex}.nested-dropdown-trigger`}
250
+ onClick={() => setIsNestedDropdownOpen((prev) => !prev)}
251
+ data-levo_group_item
252
+ className="flex w-full items-center focus:outline-none"
253
+ >
254
+ <Box
255
+ elementKey={`mobile-nav-menu.${parentIndex}.sub-items.${subIndex}.sub-item-text-container`}
256
+ >
257
+ <Typography
258
+ elementKey={`mobile-nav-menu.${parentIndex}.sub-items.${subIndex}.sub-item-title`}
259
+ />
260
+
261
+ <Typography
262
+ elementKey={`mobile-nav-menu.${parentIndex}.sub-items.${subIndex}.sub-item-description`}
263
+ />
264
+ </Box>
265
+
266
+ <ChevronDown
267
+ aria-hidden="true"
268
+ className="flex-shrink-0"
269
+ style={{
270
+ height: "16px",
271
+ width: "16px",
272
+ transition: "transform 300ms cubic-bezier(0.4, 0, 0.2, 1)",
273
+ transform: isNestedDropdownOpen ? "rotate(180deg)" : "rotate(0deg)",
274
+ color: "black",
275
+ }}
276
+ />
277
+ </Box>
278
+
279
+ {isNestedDropdownOpen && Array.isArray(nestedSubItems) && (
280
+ <Box
281
+ elementKey={`mobile-nav-menu.${parentIndex}.sub-items.${subIndex}.nested-dropdown-trigger`}
282
+ className="mt-4 flex w-full flex-col gap-y-2 pl-4 focus:outline-none"
283
+ >
284
+ {nestedSubItems.map((nestedSubItem, nestedIdx) => (
285
+ <Box
286
+ key={`nestedSubItem_${parentIndex}_${subIndex}_${nestedIdx}`}
287
+ elementKey={`mobile-nav-menu.${parentIndex}.sub-items.${subIndex}.sub-sub-items.${nestedIdx}.nested-sub-item-container`}
288
+ className={cn("focus:outline-none")}
289
+ data-levo_group_item
290
+ >
291
+ <Typography
292
+ elementKey={`mobile-nav-menu.${parentIndex}.sub-items.${subIndex}.sub-sub-items.${nestedIdx}.nested-sub-item-title`}
293
+ />
294
+
295
+ <Typography
296
+ elementKey={`mobile-nav-menu.${parentIndex}.sub-items.${subIndex}.sub-sub-items.${nestedIdx}.nested-sub-item-description`}
297
+ />
298
+ </Box>
299
+ ))}
300
+ </Box>
301
+ )}
302
+ </>
303
+ );
304
+ };
305
+
306
+ const DropdownNavigationItemMobile: React.FC<{
307
+ navItem: any;
308
+ index: number;
309
+ setIsOpen: (value: boolean) => void;
310
+ }> = ({ navItem, index, setIsOpen }) => {
311
+ const [isDropdownOpen, setIsDropdownOpen] = useState<boolean>(false);
312
+
313
+ const subItems = navItem?.["sub-items"] as Array<any>;
314
+ const hasSubItems = subItems && Array.isArray(subItems) && subItems.length > 0;
315
+ const hasSubSubItems = hasSubItems;
316
+
317
+ return (
318
+ <Box elementKey={`mobile-nav-menu.${index}.nav-item-dropdown-container`}>
319
+ <Box
320
+ elementKey={`mobile-nav-menu.${index}.nav-item-dropdown-trigger`}
321
+ onClick={() => setIsDropdownOpen((prev) => !prev)}
322
+ className="flex items-center justify-between focus:outline-none"
323
+ >
324
+ <Typography elementKey={`mobile-nav-menu.${index}.nav-item-dropdown-trigger-title`} />
325
+ {hasSubSubItems && (
326
+ <ChevronDown
327
+ aria-hidden="true"
328
+ style={{
329
+ position: "relative",
330
+ top: "2px",
331
+ height: "16px",
332
+ width: "16px",
333
+ transitionProperty:
334
+ "color, background-color, border-color, text-decoration-color, fill, stroke, opacity, box-shadow, transform, filter, backdrop-filter",
335
+ transitionTimingFunction: "cubic-bezier(0.4, 0, 0.2, 1)",
336
+ transitionDuration: "300ms",
337
+ rotate: isDropdownOpen ? "180deg" : "0deg",
338
+ color: "var(--color-text-1)",
339
+ }}
340
+ />
341
+ )}
342
+ </Box>
343
+ {isDropdownOpen && hasSubItems && (
344
+ <Box elementKey={`mobile-nav-menu.${index}.sub-items_levoGroup`} data-levo_group>
345
+ {subItems?.map((subItem: any, idx: number) => {
346
+ const nestedSubItems = subItem?.["sub-sub-items"] as Array<any>;
347
+ const hasNestedItems =
348
+ nestedSubItems && Array.isArray(nestedSubItems) && nestedSubItems.length > 0;
349
+
350
+ return (
351
+ <Box
352
+ key={`subItem_${index}_${idx}`}
353
+ elementKey={`mobile-nav-menu.${index}.sub-items.${idx}.sub-item-link`}
354
+ data-levo_group_item
355
+ className={cn("")}
356
+ >
357
+ {hasNestedItems ? (
358
+ <NestedDropdownItemMobile
359
+ subItem={subItem}
360
+ parentIndex={index}
361
+ subIndex={idx}
362
+ setIsOpen={setIsOpen}
363
+ />
364
+ ) : (
365
+ <Box
366
+ elementKey={`mobile-nav-menu.${index}.sub-items.${idx}.sub-item-text-container`}
367
+ >
368
+ <Typography
369
+ elementKey={`mobile-nav-menu.${index}.sub-items.${idx}.sub-item-title`}
370
+ />
371
+ <Typography
372
+ elementKey={`mobile-nav-menu.${index}.sub-items.${idx}.sub-item-description`}
373
+ />
374
+ </Box>
375
+ )}
376
+ </Box>
377
+ );
378
+ })}
379
+ </Box>
380
+ )}
381
+ </Box>
382
+ );
383
+ };
384
+
385
+ const MobileNavItem: React.FC<{
386
+ navItem: any;
387
+ index: number;
388
+ setIsOpen: (value: boolean) => void;
389
+ }> = ({ navItem, index, setIsOpen }) => {
390
+ const navSubItems = navItem?.["sub-items"] ?? [];
391
+ const isNavItemDropdown = navSubItems && Array.isArray(navSubItems) && navSubItems?.length > 0;
392
+
393
+ return (
394
+ <React.Fragment>
395
+ {isNavItemDropdown && (
396
+ <DropdownNavigationItemMobile navItem={navItem} setIsOpen={setIsOpen} index={index} />
397
+ )}
398
+ {!isNavItemDropdown && (
399
+ <Box
400
+ data-levo_group_item
401
+ elementKey={`mobile-nav-menu.${index}.nav-item-title-container`}
402
+ onClick={() => setIsOpen(false)}
403
+ >
404
+ <Typography elementKey={`mobile-nav-menu.${index}.nav-item-title`} />
405
+ </Box>
406
+ )}
407
+ </React.Fragment>
408
+ );
409
+ };
410
+
411
+ const MobileNavigationSheet: React.FC<{
412
+ navItems: any;
413
+ content: any;
414
+ isOpen: boolean;
415
+ setIsOpen: (value: boolean) => void;
416
+ }> = ({ navItems, content, isOpen, setIsOpen }) => {
417
+ return (
418
+ <React.Fragment>
419
+ <Button
420
+ elementKey="mobile-nav-menu-button"
421
+ aria-label="Open navigation"
422
+ onClick={() => setIsOpen(!isOpen)}
423
+ >
424
+ {isOpen ? <X size={32} /> : <Menu size={32} />}
425
+ </Button>
426
+ {isOpen && (
427
+ <Box elementKey="mobile-nav-menu-wrapper">
428
+ <Box elementKey="mobile-nav-menu_levoGroup" data-levo_group>
429
+ {Array.isArray(navItems)
430
+ ? navItems?.map((item, index) => {
431
+ return (
432
+ <MobileNavItem
433
+ navItem={item}
434
+ key={`${item?.["nav-item-title"]}_${index}`}
435
+ setIsOpen={setIsOpen}
436
+ index={index}
437
+ />
438
+ );
439
+ })
440
+ : null}
441
+ </Box>
442
+ {content?.["mobile-cta-group"]?.length > 0 && (
443
+ <Box elementKey="mobile-cta-group_levoGroup" data-levo_group>
444
+ {content?.["mobile-cta-group"]?.map((_: any, index: number) => (
445
+ <Button
446
+ key={`mobile-cta-group.${index}.cta`}
447
+ elementKey={`mobile-cta-group.${index}.cta`}
448
+ data-levo_group_item
449
+ className="mb-2 w-full"
450
+ >
451
+ {content?.["mobile-cta-group"]?.[index]?.cta}
452
+ </Button>
453
+ ))}
454
+ </Box>
455
+ )}
456
+ <Box elementKey="socials-mobile_levoGroup" data-levo_group>
457
+ {content?.["socials-mobile"]?.map((_: any, index: number) => (
458
+ <Icon
459
+ key={`socials-mobile.${index}.social`}
460
+ elementKey={`socials-mobile.${index}.social`}
461
+ data-levo_group_item
462
+ />
463
+ ))}
464
+ </Box>
465
+ </Box>
466
+ )}
467
+ </React.Fragment>
468
+ );
469
+ };
470
+
471
+ const Navbar4: React.FC<ILevoBlockBaseProps<INavbar3Content>> = ({ content }) => {
472
+ const [isScrolled, setIsScrolled] = useState(false);
473
+ const [isOpen, setIsOpen] = useState(false);
474
+
475
+ useEffect(() => {
476
+ const handleScroll = () => {
477
+ if (window.scrollY === 0 && isScrolled) {
478
+ setIsScrolled(false);
479
+ } else if (window.scrollY >= 40 && !isScrolled) {
480
+ setIsScrolled(true);
481
+ }
482
+ };
483
+
484
+ document.addEventListener("scroll", handleScroll);
485
+
486
+ return () => {
487
+ document.removeEventListener("scroll", handleScroll);
488
+ };
489
+ }, [isScrolled]);
490
+
491
+ const desktopNavLinks = content?.["desktop-nav-menu"];
492
+ const mobileNavLinks = content?.["mobile-nav-menu"];
493
+
494
+ return (
495
+ <>
496
+ {isOpen && (
497
+ <Box
498
+ elementKey="mobile-background-overlay"
499
+ onClick={() => setIsOpen(false)}
500
+ className="fixed top-0 right-0 bottom-0 left-0 z-20 bg-black/20"
501
+ />
502
+ )}
503
+ <Section elementKey="layout" className={cn(isScrolled ? "top-2" : "top-8")}>
504
+ <Container elementKey="nav-container">
505
+ <Image elementKey="nav-logo" alt="Logo" />
506
+ <Box elementKey="nav-content">
507
+ <Box elementKey="nav-content-top">
508
+ <Box elementKey="socials_levoGroup" data-levo_group>
509
+ {content?.socials?.map((_: any, index: number) => (
510
+ <Icon
511
+ key={`socials.${index}.social`}
512
+ elementKey={`socials.${index}.social`}
513
+ data-levo_group_item
514
+ />
515
+ ))}
516
+ </Box>
517
+ <Box elementKey="desktop-cta-group_levoGroup" data-levo_group>
518
+ {content?.["desktop-cta-group"]?.map((_: any, index: number) => (
519
+ <Button
520
+ key={`desktop-cta-group.${index}.cta`}
521
+ elementKey={`desktop-cta-group.${index}.cta`}
522
+ data-levo_group_item
523
+ />
524
+ ))}
525
+ </Box>
526
+ </Box>
527
+ <Box elementKey="nav-content-bottom">
528
+ {desktopNavLinks &&
529
+ Array?.isArray(desktopNavLinks) &&
530
+ desktopNavLinks?.length > 0 && <DesktopNavigationMenu navItems={desktopNavLinks} />}
531
+ </Box>
532
+ </Box>
533
+
534
+ <MobileNavigationSheet
535
+ navItems={mobileNavLinks || []}
536
+ content={content}
537
+ isOpen={isOpen}
538
+ setIsOpen={setIsOpen}
539
+ />
540
+ </Container>
541
+ </Section>
542
+ </>
543
+ );
544
+ };
545
+
546
+ export default Navbar4;
@@ -5,8 +5,7 @@ const DEFAULT_CONTENT = {
5
5
  container: null,
6
6
  header: null,
7
7
  title: "Polls",
8
- description:
9
- "Our polls help you to get the insights you need to make informed decisions.",
8
+ description: "Our polls help you to get the insights you need to make informed decisions.",
10
9
  polls: null,
11
10
  loading_container: null,
12
11
  };
@@ -1,16 +1,16 @@
1
+ import { cn, errorToast, Spinner, successToast, useLevo } from "@levo-so/react";
1
2
  import {
2
- type ILevoBlockBaseProps,
3
- Heading,
4
- Typography,
3
+ Box,
5
4
  Container,
5
+ Heading,
6
+ type ILevoBlockBaseProps,
6
7
  Section,
7
- Box,
8
- useBlockContext,
8
+ Typography,
9
9
  useAuth,
10
+ useBlockContext,
10
11
  } from "@levo-so/studio";
11
- import { useCallback, useEffect, useMemo, useState } from "react";
12
- import { cn, errorToast, Spinner, successToast, useLevo } from "@levo-so/react";
13
12
  import { CircleCheckBig, LoaderCircle } from "lucide-react";
13
+ import { useCallback, useEffect, useMemo, useState } from "react";
14
14
 
15
15
  import type { IPolling1Content } from "./polling-1.schema";
16
16
 
@@ -168,11 +168,7 @@ const PollOption: React.FC<{
168
168
  const isCurrentOptionSelected = selectedOption === option._id;
169
169
 
170
170
  const percentage = useMemo(() => {
171
- if (
172
- Number.isFinite(totalVotes) &&
173
- Number.isFinite(option?.count) &&
174
- totalVotes > 0
175
- ) {
171
+ if (Number.isFinite(totalVotes) && Number.isFinite(option?.count) && totalVotes > 0) {
176
172
  return ((option.count / totalVotes) * 100)?.toFixed(0);
177
173
  }
178
174
  return null;
@@ -208,11 +204,7 @@ const PollOption: React.FC<{
208
204
  status: boolean;
209
205
  }>();
210
206
 
211
- if (
212
- response?.status &&
213
- response?.content?.data &&
214
- response?.content?.data?.voted
215
- ) {
207
+ if (response?.status && response?.content?.data && response?.content?.data?.voted) {
216
208
  successToast(response?.content?.data?.message);
217
209
  fetchPolls?.();
218
210
  }
@@ -247,22 +239,19 @@ const PollOption: React.FC<{
247
239
  </Heading>
248
240
 
249
241
  {(isUserOnOption || isCurrentOptionSelected) && isVoting === false && (
250
- <CircleCheckBig className="text-brand size-5" />
242
+ <CircleCheckBig className="size-5 text-brand" />
251
243
  )}
252
244
  </div>
253
245
  <div className="flex items-center justify-between gap-x-2">
254
246
  <div
255
- className={cn(
256
- "relative h-2 w-full rounded",
257
- isVoting && "animate-pulse",
258
- )}
247
+ className={cn("relative h-2 w-full rounded", isVoting && "animate-pulse")}
259
248
  style={{
260
249
  maxWidth: "95%",
261
250
  backgroundColor: "oklch(0.9416 0.0121 259.8229)",
262
251
  }}
263
252
  >
264
253
  <div
265
- className="bg-brand absolute top-0 right-0 left-0 h-2 rounded transition-all ease-out"
254
+ className="absolute top-0 right-0 left-0 h-2 rounded bg-brand transition-all ease-out"
266
255
  style={{
267
256
  width,
268
257
  transformOrigin: "left center",
@@ -273,7 +262,7 @@ const PollOption: React.FC<{
273
262
  <div>
274
263
  {isVoting ? (
275
264
  <LoaderCircle
276
- className={cn("text-brand size-6 animate-spin font-bold")}
265
+ className={cn("size-6 animate-spin font-bold text-brand")}
277
266
  style={{
278
267
  height: "25.59px",
279
268
  }}
@@ -377,9 +366,7 @@ const Poll: React.FC<{
377
366
  );
378
367
  };
379
368
 
380
- const Polling1: React.FC<ILevoBlockBaseProps<IPolling1Content>> = ({
381
- content,
382
- }) => {
369
+ const Polling1: React.FC<ILevoBlockBaseProps<IPolling1Content>> = ({ content }) => {
383
370
  const levoClient = useLevo();
384
371
  const { isBuilder } = useBlockContext();
385
372
 
@@ -422,18 +409,16 @@ const Polling1: React.FC<ILevoBlockBaseProps<IPolling1Content>> = ({
422
409
  <Box elementKey="polls">
423
410
  {isBuilder ? (
424
411
  <>
425
- {POLLS_RESPONSE_SAMPLE?.content?.data?.map(
426
- (item: any, index: number) => {
427
- return (
428
- <Poll
429
- poll={item}
430
- isLoading={isLoading}
431
- key={`polls.${index}`}
432
- fetchPolls={fetchPolls}
433
- />
434
- );
435
- },
436
- )}
412
+ {POLLS_RESPONSE_SAMPLE?.content?.data?.map((item: any, index: number) => {
413
+ return (
414
+ <Poll
415
+ poll={item}
416
+ isLoading={isLoading}
417
+ key={`polls.${index}`}
418
+ fetchPolls={fetchPolls}
419
+ />
420
+ );
421
+ })}
437
422
  </>
438
423
  ) : (
439
424
  <>