blocks-dusted 0.1.12 → 0.1.13

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 (148) hide show
  1. package/package.json +1 -1
  2. package/src/installers/patchRenderBlocks.js +1 -1
  3. package/src/registry/validateTemplateManifest.js +2 -1
  4. package/templates/blocks/BannerDD790432/Component.tsx +63 -0
  5. package/templates/blocks/BannerDD790432/config.ts +54 -0
  6. package/templates/blocks/BannerDD790432/manifest.json +80 -0
  7. package/templates/blocks/Button47/Component.tsx +124 -0
  8. package/templates/blocks/Button47/config.ts +75 -0
  9. package/templates/blocks/Button47/link.ts +22 -0
  10. package/templates/blocks/Button47/manifest.json +105 -0
  11. package/templates/blocks/Button47/styles.module.scss +75 -0
  12. package/templates/blocks/DD-Accordion/Component.tsx +55 -36
  13. package/templates/blocks/DD-Accordion/config.ts +71 -59
  14. package/templates/blocks/DD-AnimText/Component.tsx +50 -32
  15. package/templates/blocks/DD-AnimText/config.ts +296 -295
  16. package/templates/blocks/DD-AsideNav/Component.tsx +323 -319
  17. package/templates/blocks/DD-Banner/Component.tsx +54 -51
  18. package/templates/blocks/DD-BookCall/Component.tsx +535 -535
  19. package/templates/blocks/DD-ButtonPop/Component.tsx +118 -117
  20. package/templates/blocks/DD-Card/Component.tsx +4 -4
  21. package/templates/blocks/DD-CardTemplate01/Component.tsx +139 -140
  22. package/templates/blocks/DD-CardsWithVariantV3/Component.tsx +472 -0
  23. package/templates/blocks/DD-CardsWithVariantV3/ElectricBorder/index.tsx +203 -0
  24. package/templates/blocks/DD-CardsWithVariantV3/ElectricBorder/styles.ts +87 -0
  25. package/templates/blocks/DD-CardsWithVariantV3/ElectricBorder/useInjectStyle.ts +39 -0
  26. package/templates/blocks/DD-CardsWithVariantV3/config.ts +326 -0
  27. package/templates/blocks/DD-CardsWithVariantV3/manifest.json +110 -0
  28. package/templates/blocks/DD-Carousel-A/Component.tsx +251 -249
  29. package/templates/blocks/DD-Carousel-B/Component.tsx +405 -403
  30. package/templates/blocks/DD-ComparisonTable/Component.tsx +255 -256
  31. package/templates/blocks/DD-Contact/Component.tsx +433 -435
  32. package/templates/blocks/DD-Counter/Component.tsx +11 -6
  33. package/templates/blocks/DD-DeliCard/Component.tsx +303 -0
  34. package/templates/blocks/DD-DeliCard/config.ts +186 -0
  35. package/templates/blocks/DD-DeliCard/manifest.json +94 -0
  36. package/templates/blocks/DD-FeatCat/Component.tsx +302 -302
  37. package/templates/blocks/DD-FeatProd/CircularGallery.tsx +1179 -0
  38. package/templates/blocks/DD-FeatProd/Component.tsx +484 -0
  39. package/templates/blocks/DD-FeatProd/config.ts +173 -0
  40. package/templates/blocks/DD-FeatProd/manifest.json +93 -0
  41. package/templates/blocks/DD-FeatServ/Component.tsx +607 -0
  42. package/templates/blocks/DD-FeatServ/config.ts +213 -0
  43. package/templates/blocks/DD-FeatServ/manifest.json +113 -0
  44. package/templates/blocks/DD-FeatStrip/Component.tsx +584 -585
  45. package/templates/blocks/DD-FluidBtn/ButtonsEyeCatching.tsx +627 -628
  46. package/templates/blocks/DD-FluidBtn/Component.tsx +46 -43
  47. package/templates/blocks/DD-GooeyInfo/Component.tsx +150 -149
  48. package/templates/blocks/DD-GooeyInfo/config.ts +136 -135
  49. package/templates/blocks/DD-Hero/Component.tsx +296 -297
  50. package/templates/blocks/DD-HeroPlas/Component.tsx +50 -0
  51. package/templates/blocks/DD-HeroPlas/ThreeScene.tsx +109 -0
  52. package/templates/blocks/DD-HeroPlas/config.ts +33 -0
  53. package/templates/blocks/DD-HeroPlas/manifest.json +88 -0
  54. package/templates/blocks/DD-HorizontalScroll/Component.tsx +937 -936
  55. package/templates/blocks/DD-Icon/Component.tsx +46 -81
  56. package/templates/blocks/DD-IconButton/Component.tsx +13 -20
  57. package/templates/blocks/DD-IdTag/Component.tsx +22 -21
  58. package/templates/blocks/DD-LineAnim/Component.tsx +42 -36
  59. package/templates/blocks/DD-LogoMarq/Component.tsx +38 -48
  60. package/templates/blocks/DD-Lottie/Component.tsx +11 -3
  61. package/templates/blocks/DD-MasonaryMedia/Component.tsx +544 -545
  62. package/templates/blocks/DD-MasonaryMedia/config.ts +389 -389
  63. package/templates/blocks/DD-Masonry/Component.tsx +654 -644
  64. package/templates/blocks/DD-Masonry/config.ts +475 -475
  65. package/templates/blocks/DD-MaterialSwatches/Component.tsx +85 -0
  66. package/templates/blocks/DD-MaterialSwatches/config.ts +232 -0
  67. package/templates/blocks/DD-MaterialSwatches/manifest.json +84 -0
  68. package/templates/blocks/DD-MaterialSwatches/material.ts +107 -0
  69. package/templates/blocks/DD-NineCanvas/Component.tsx +129 -0
  70. package/templates/blocks/DD-NineCanvas/RenderBlocks.tsx +244 -0
  71. package/templates/blocks/DD-NineCanvas/allowedCanvasBlocks.ts +6 -0
  72. package/templates/blocks/DD-NineCanvas/blockComponents.tsx +8 -0
  73. package/templates/blocks/DD-NineCanvas/canvas/CanvasGrid.tsx +316 -0
  74. package/templates/blocks/DD-NineCanvas/canvas/RadialNav.tsx +432 -0
  75. package/templates/blocks/DD-NineCanvas/canvas/canvas-panels.css +889 -0
  76. package/templates/blocks/DD-NineCanvas/canvas/icons/custom-icons.tsx +364 -0
  77. package/templates/blocks/DD-NineCanvas/config.ts +61 -0
  78. package/templates/blocks/DD-NineCanvas/manifest.json +165 -0
  79. package/templates/blocks/DD-NineCanvas/styles.scss +152 -0
  80. package/templates/blocks/DD-NineCanvas/tooltip/get-strict-context.tsx +26 -0
  81. package/templates/blocks/DD-NineCanvas/tooltip/primitives.tsx +178 -0
  82. package/templates/blocks/DD-NineCanvas/tooltip/tooltip.tsx +71 -0
  83. package/templates/blocks/DD-NineCanvas/tooltip/use-controlled-state.tsx +33 -0
  84. package/templates/blocks/DD-NineCanvas/utilities/FadeOnScroll.tsx +68 -0
  85. package/templates/blocks/DD-NineCanvas/utilities/ParallaxWrapper.tsx +157 -0
  86. package/templates/blocks/DD-NineCanvas/utilities/renderCustomCSS.ts +5 -0
  87. package/templates/blocks/DD-NineCanvas/utilities/webglCleanup.ts +27 -0
  88. package/templates/blocks/DD-PayloadAIAssistant/Component.tsx +78 -0
  89. package/templates/blocks/DD-PayloadAIAssistant/DustedBot.tsx +590 -0
  90. package/templates/blocks/DD-PayloadAIAssistant/config.ts +37 -0
  91. package/templates/blocks/DD-PayloadAIAssistant/demo.css +125 -0
  92. package/templates/blocks/DD-PayloadAIAssistant/manifest.json +93 -0
  93. package/templates/blocks/DD-PayloadAIAssistant/source-defaults.ts +17 -0
  94. package/templates/blocks/DD-PayloadAIAssistant/styles.ts +306 -0
  95. package/templates/blocks/DD-Pricing/Component.tsx +2 -3
  96. package/templates/blocks/DD-Pricing/config.ts +215 -215
  97. package/templates/blocks/DD-Process/Component.tsx +2 -2
  98. package/templates/blocks/DD-ProjHeader/Component.tsx +93 -91
  99. package/templates/blocks/DD-ProjSlider/Component.tsx +1 -1
  100. package/templates/blocks/DD-Section/Component.tsx +265 -266
  101. package/templates/blocks/DD-Separator/Component.tsx +66 -66
  102. package/templates/blocks/DD-Services/Component.tsx +176 -176
  103. package/templates/blocks/DD-ShowcaseGrid/Component.tsx +306 -307
  104. package/templates/blocks/DD-Slider-A/Component.tsx +2 -2
  105. package/templates/blocks/DD-StackCards/Component.tsx +172 -171
  106. package/templates/blocks/DD-Team/Component.tsx +247 -247
  107. package/templates/blocks/DD-TeamCards/Component.tsx +251 -251
  108. package/templates/blocks/DD-TechStack/Component.tsx +173 -174
  109. package/templates/blocks/DD-TestMarq/Component.tsx +158 -132
  110. package/templates/blocks/DD-Testim/Component.tsx +247 -247
  111. package/templates/blocks/DD-Testim2/Component.tsx +265 -256
  112. package/templates/blocks/DD-Testimonials/Component.tsx +139 -139
  113. package/templates/blocks/DD-Thanks/Component.tsx +1 -1
  114. package/templates/blocks/DD-Work/Component.tsx +318 -318
  115. package/templates/blocks/DD-Work-B/Component.tsx +294 -294
  116. package/templates/blocks/DDHG-CTASection2/Component.tsx +183 -184
  117. package/templates/blocks/DDHG-HighlightArc/Component.tsx +6 -3
  118. package/templates/blocks/DDHG-LogoMarquee/Component.tsx +45 -8
  119. package/templates/blocks/DDHG-NavCodeGrid/Component.tsx +1 -3
  120. package/templates/blocks/DDHG-ServiceDetails/ServiceDetailCard.tsx +9 -22
  121. package/templates/blocks/DDHG-ServiceHero/Component.tsx +10 -10
  122. package/templates/blocks/DDHG-TeamCards/Component.tsx +6 -35
  123. package/templates/blocks/Form/Checkbox/index.tsx +45 -0
  124. package/templates/blocks/Form/Component.tsx +163 -0
  125. package/templates/blocks/Form/Country/index.tsx +65 -0
  126. package/templates/blocks/Form/Country/options.ts +982 -0
  127. package/templates/blocks/Form/Email/index.tsx +38 -0
  128. package/templates/blocks/Form/Error/index.tsx +15 -0
  129. package/templates/blocks/Form/Message/index.tsx +13 -0
  130. package/templates/blocks/Form/Number/index.tsx +36 -0
  131. package/templates/blocks/Form/Select/index.tsx +63 -0
  132. package/templates/blocks/Form/State/index.tsx +64 -0
  133. package/templates/blocks/Form/State/options.ts +52 -0
  134. package/templates/blocks/Form/Text/index.tsx +32 -0
  135. package/templates/blocks/Form/Textarea/index.tsx +40 -0
  136. package/templates/blocks/Form/Width/index.tsx +13 -0
  137. package/templates/blocks/Form/config.ts +51 -0
  138. package/templates/blocks/Form/fields.tsx +21 -0
  139. package/templates/blocks/Form/manifest.json +168 -0
  140. package/templates/blocks/MediaBlock/Component.tsx +67 -0
  141. package/templates/blocks/MediaBlock/config.ts +14 -0
  142. package/templates/blocks/MediaBlock/manifest.json +92 -0
  143. package/templates/blocks/TransitionsDustedShowcase/Component.tsx +9 -0
  144. package/templates/blocks/TransitionsDustedShowcase/config.ts +13 -0
  145. package/templates/blocks/TransitionsDustedShowcase/manifest.json +80 -0
  146. package/templates/blocks/rawHtml/Component.tsx +25 -0
  147. package/templates/blocks/rawHtml/config.ts +56 -0
  148. package/templates/blocks/rawHtml/manifest.json +80 -0
@@ -1,321 +1,325 @@
1
- 'use client'
2
-
3
- import * as React from 'react'
4
- import { useEffect, useMemo, useRef, useState } from 'react'
5
- import { createPortal } from 'react-dom'
6
- import { motion } from 'framer-motion'
7
- import { ArrowDownWideNarrow } from 'lucide-react'
8
- import { extractCustomCSS } from '@/utilities/renderCustomCSS'
9
-
10
- const Divider: React.FC = () => (
11
- <span className="block h-px w-4 shrink-0 bg-white/55 dark:bg-white/55" />
12
- )
13
-
14
- const FadeEdges: React.FC = () => (
15
- <div className="sticky top-0 z-[100]">
16
- <div
17
- aria-hidden="true"
18
- className="pointer-events-none absolute -left-1 -top-1 h-24 w-screen bg-gradient-to-b from-[var(--color-muted,transparent)] to-transparent blur-[6px]"
19
- />
20
- <div
21
- aria-hidden="true"
22
- className="pointer-events-none absolute -bottom-1 -left-1 h-24 w-screen bg-gradient-to-t from-[var(--color-muted,transparent)] to-transparent"
23
- />
24
- </div>
25
- )
26
-
27
- const rowVariants = {
28
- hidden: { opacity: 0, y: 10 },
29
- show: {
30
- opacity: 1,
31
- y: 0,
32
- transition: {
33
- type: 'spring' as const,
34
- stiffness: 200,
35
- damping: 20,
36
- staggerChildren: 0.1
37
- }
38
- }
39
- } as const
40
-
1
+ 'use client'
2
+
3
+ import * as React from 'react'
4
+ import { useEffect, useMemo, useRef, useState } from 'react'
5
+ import { createPortal } from 'react-dom'
6
+ import { motion } from 'framer-motion'
7
+ import { ArrowDownWideNarrow } from 'lucide-react'
8
+ import { extractCustomCSS } from '@/utilities/renderCustomCSS'
9
+
10
+ const Divider: React.FC = () => (
11
+ <span className="block h-px w-4 shrink-0 bg-stone-300 dark:bg-white/55" />
12
+ )
13
+
14
+ // const FadeEdges: React.FC = () => (
15
+ // <div className="sticky top-0 z-100">
16
+ // <div
17
+ // aria-hidden="true"
18
+ // className="pointer-events-none absolute -left-1 -top-1 h-24 w-screen bg-linear-to-b from-(--color-muted,transparent) to-transparent blur-[6px]"
19
+ // />
20
+ // <div
21
+ // aria-hidden="true"
22
+ // className="pointer-events-none absolute -bottom-1 -left-1 h-24 w-screen bg-linear-to-t from-(--color-muted,transparent) to-transparent"
23
+ // />
24
+ // </div>
25
+ // )
26
+
27
+ const rowVariants = {
28
+ hidden: { opacity: 0, y: 10 },
29
+ show: {
30
+ opacity: 1,
31
+ y: 0,
32
+ transition: {
33
+ type: 'spring' as const,
34
+ stiffness: 200,
35
+ damping: 20,
36
+ staggerChildren: 0.1,
37
+ },
38
+ },
39
+ } as const
40
+
41
41
  const childBarVariants = (w = 55) => ({
42
- rest: { width: 36, backgroundColor: 'rgba(255,255,255,0.65)' },
43
- hover: { width: w, backgroundColor: 'var(--accent)' }
42
+ rest: { width: 36, backgroundColor: 'var(--aside-nav-line)' },
43
+ hover: { width: w, backgroundColor: '#87da07' },
44
44
  })
45
-
46
- const childTextVariants = {
47
- rest: { opacity: 1, color: 'inherit', filter: 'brightness(1.1)' },
48
- hover: { opacity: 1, color: 'var(--accent)' }
49
- }
50
-
51
- const ParentRow: React.FC<{ label: string; index: number }> = ({ label, index }) => (
52
- <motion.div
53
- initial="hidden"
54
- animate="show"
55
- variants={rowVariants}
56
- custom={index}
57
- className="relative color-alt will-change-[transform,opacity]"
58
- transition={{
59
- delay: index * 0.025,
60
- type: 'spring',
61
- stiffness: 200,
62
- damping: 20
63
- }}
64
- >
65
- <div className="group relative flex h-px items-center gap-3 py-2">
66
- <span className="inline-block h-px w-9 shrink-0 bg-white/65 text-sm opacity-100 dark:bg-white/65" />
67
- <span className="color-text whitespace-nowrap text-md font-semibold uppercase opacity-100">
68
- {label}
69
- </span>
70
- </div>
71
- </motion.div>
72
- )
73
-
74
- const ChildRow: React.FC<{
75
- targetSection?: string
76
- label: string
77
- index: number
78
- wideOnHover?: number
79
- scrollOffset?: number
80
- }> = ({ targetSection, label, index, wideOnHover = 55, scrollOffset = -100 }) => {
81
- const handleScrollTo = (e: React.MouseEvent) => {
82
- e.preventDefault()
83
-
84
- if (!targetSection) return
85
-
86
- const el = document.getElementById(targetSection)
87
-
88
- if (!el) {
89
- console.warn(`Target element with id "${targetSection}" not found`)
90
- return
91
- }
92
-
93
- const elementTop = el.getBoundingClientRect().top + window.pageYOffset
94
- const targetTop = elementTop + scrollOffset
95
-
96
- window.scrollTo({ top: targetTop, behavior: 'smooth' })
97
- }
98
-
99
- return (
100
- <motion.div
101
- initial="hidden"
102
- animate="show"
103
- variants={rowVariants}
104
- custom={index}
105
- transition={{
106
- delay: index * 0.025,
107
- type: 'spring',
108
- stiffness: 200,
109
- damping: 20
110
- }}
111
- >
112
- <motion.button
113
- onClick={handleScrollTo}
114
- initial="rest"
115
- whileHover="hover"
116
- animate="rest"
117
- disabled={!targetSection}
118
- className="group relative flex h-px cursor-pointer items-center gap-4 border-0 bg-transparent py-0 text-left text-sm opacity-50 hover:opacity-100 will-change-[transform,opacity] after:absolute after:left-0 after:top-1/2 after:size-full after:-translate-y-1/2 after:p-[12px] disabled:cursor-not-allowed disabled:opacity-50 disabled:[&_*]:opacity-30 focus-visible:rounded focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-[var(--dd-accent,#9803e2)]"
119
- >
120
- <motion.span
121
- className="inline-block h-px shrink-0 text-sm opacity-100 will-change-[width,background-color]"
122
- variants={childBarVariants(wideOnHover)}
123
- transition={{ type: 'spring', stiffness: 500, damping: 35 }}
124
- />
125
-
126
- <motion.span
127
- className="whitespace-nowrap text-sm !font-medium text-stone-400 transition-all ease-out will-change-[color,opacity] group-hover:!font-semibold group-hover:text-[var(--dd-accent,#9803e2)]"
128
- variants={childTextVariants}
129
- transition={{ type: 'spring', stiffness: 500, damping: 35 }}
130
- >
131
- {label}
132
- </motion.span>
133
- </motion.button>
134
- </motion.div>
135
- )
136
- }
137
-
138
- interface AsideScrollLinksProps {
139
- parentSections?: Array<{
140
- sectionId?: string
141
- label: string
142
- children?: Array<{
143
- linkId?: string
144
- label: string
145
- targetSection?: string
146
- scrollOffset?: number
147
- wideOnHover?: number
148
- }>
149
- }>
150
- position?: 'left' | 'right'
151
- zIndex?: number
152
- offsetFromEdge?: number
153
- className?: string
154
- blockName?: string
155
- enableCustomCSS?: boolean
156
- customCSS?: any[]
157
- }
158
-
159
- function AsideNav({
160
- parentSections = [
161
- {
162
- label: 'Out of the box',
163
- children: [{ label: 'Aside PageLinks', targetSection: 's1' }]
164
- }
165
- ],
166
- position = 'left',
167
- offsetFromEdge = 8,
168
- enableCustomCSS = false,
169
- customCSS = []
170
- }: AsideScrollLinksProps) {
171
- const [mounted, setMounted] = useState(false)
172
- const styleIdRef = useRef(`aside-nav-css-${Math.random().toString(36).slice(2)}`)
173
-
174
- const extractedCSS = enableCustomCSS && customCSS?.length > 0 ? extractCustomCSS(customCSS) : ''
175
-
176
- useEffect(() => {
177
- setMounted(true)
178
- }, [])
179
-
180
- useEffect(() => {
181
- if (!extractedCSS) return
182
-
183
- const styleId = styleIdRef.current
184
- const existingStyle = document.getElementById(styleId)
185
-
186
- if (existingStyle) {
187
- existingStyle.textContent = extractedCSS
188
- } else {
189
- const style = document.createElement('style')
190
- style.id = styleId
191
- style.textContent = extractedCSS
192
- document.head.appendChild(style)
193
- }
194
-
195
- return () => {
196
- document.getElementById(styleId)?.remove()
197
- }
198
- }, [extractedCSS])
199
-
200
- const items = useMemo(() => {
201
- const flat: Array<{
202
- type: 'parent' | 'child'
203
- label: string
204
- targetSection?: string
205
- scrollOffset?: number
206
- wideOnHover?: number
207
- }> = []
208
-
209
- parentSections.forEach((p) => {
210
- flat.push({ type: 'parent', label: p.label })
211
-
212
- p.children?.forEach((c) =>
213
- flat.push({
214
- type: 'child',
215
- label: c.label,
216
- targetSection: c.targetSection,
217
- scrollOffset: c.scrollOffset,
218
- wideOnHover: c.wideOnHover
219
- })
220
- )
221
- })
222
-
223
- return flat
224
- }, [parentSections])
225
-
226
- const positionClass = position === 'left' ? 'left-2' : 'right-2'
227
-
228
- const asideContent = (
229
- <aside
230
- className={[
231
- 'aside-scroll-block group fixed top-16 z-[200] flex items-start overflow-hidden opacity-100 shadow-lg transition-[width,height,max-width,max-height,border-radius,padding] duration-300 delay-50 hover:delay-0 focus-within:delay-0',
232
- 'h-[2.3rem] w-[2.3rem] max-w-[12rem] max-h-[30vh] p-px',
233
- 'rounded-2xl backdrop-blur-[10px]',
234
- 'bg-[var(--border)] border-[2px] border-ridge border-[#edededf0] shadow-[inset_0_0_20px_0px_rgb(255_255_255_/_80%)]',
235
- 'dark:bg-[var(--background)] dark:border-[rgba(245,245,245,0.5)] dark:shadow-[inset_0_0_20px_#ffffff70]',
236
- 'hover:h-auto hover:w-[calc(100%+1rem)] hover:max-w-[15rem] hover:max-h-[40vh] hover:rounded-2xl hover:p-1 hover:duration-200 focus-within:h-auto focus-within:w-[calc(100%+1rem)] focus-within:max-w-[15rem] focus-within:max-h-[40vh] focus-within:rounded-2xl focus-within:p-1',
237
- positionClass
238
- ].join(' ')}
239
- style={{
240
- opacity: 1,
241
- transform: 'none',
242
- [position]: `${offsetFromEdge}px`
243
- }}
244
- >
245
- <div
246
- data-lenis-prevent
247
- className={[
248
- 'aside-inner-box relative flex h-full w-full overflow-hidden p-1 text-[14px] tracking-tight backdrop-blur-md transition-all duration-300',
249
- 'rounded-2xl bg-[rgba(5,5,5,0.5)] border border-[rgba(152,3,226,0.1)]',
250
- 'dark:bg-[rgba(22,20,34,0.9)] dark:border-[rgba(152,3,226,0.15)]',
251
- 'group-hover:rounded-xl group-hover:p-0.5 group-focus-within:rounded-xl group-focus-within:p-0.5'
252
- ].join(' ')}
253
- >
254
- <div className="w-full overflow-hidden">
255
- <ArrowDownWideNarrow className="icon-arrow-down-wide-narrow color-alt sticky left-0 top-1 z-[100] h-auto w-6 shrink-0 p-1" />
256
-
257
- <FadeEdges />
258
-
259
- <nav
260
- data-lenis-prevent
261
- className="aside-nav-list pointer-events-none relative m-0 flex h-fit max-h-[40vh] w-full flex-col gap-2 overflow-x-clip overflow-y-auto px-0 pb-24 pt-2 text-stone-200 opacity-0 transition-opacity duration-150 group-hover:pointer-events-auto group-hover:opacity-100 group-focus-within:pointer-events-auto group-focus-within:opacity-100 [-ms-overflow-style:none] [scrollbar-width:none] [&::-webkit-scrollbar]:hidden [&::-webkit-scrollbar]:h-0 [&::-webkit-scrollbar]:w-0 dark:text-stone-200"
262
- >
263
- {items.map((it, i) => {
264
- if (it.type === 'parent') {
265
- return (
266
- <React.Fragment key={`p-${i}`}>
267
- <ParentRow label={it.label} index={i} />
268
- <Divider />
269
- <Divider />
270
- </React.Fragment>
271
- )
272
- }
273
-
274
- return (
275
- <React.Fragment key={`c-${i}`}>
276
- <ChildRow
277
- targetSection={it.targetSection}
278
- label={it.label}
279
- index={i}
280
- wideOnHover={it.wideOnHover ?? 55}
281
- scrollOffset={it.scrollOffset ?? -100}
282
- />
283
- <Divider />
284
- <Divider />
285
- <Divider />
286
- </React.Fragment>
287
- )
288
- })}
289
- </nav>
290
- </div>
291
- </div>
292
-
293
- <style jsx global>{`
294
- .aside-nav-list {
295
- -ms-overflow-style: none !important;
296
- scrollbar-width: none !important;
297
- overscroll-behavior: contain;
298
- }
299
-
300
- .aside-nav-list::-webkit-scrollbar,
301
- .aside-nav-list *::-webkit-scrollbar {
302
- display: none !important;
303
- width: 0 !important;
304
- height: 0 !important;
305
- background: transparent !important;
306
- }
307
-
308
- .aside-scroll-block {
309
- border-style: ridge;
310
- }
311
- `}</style>
312
- </aside>
313
- )
314
-
315
- if (!mounted || typeof window === 'undefined') return null
316
-
317
- return createPortal(asideContent, document.body)
318
- }
319
-
320
- export { AsideNav as DDAsideNav }
321
- export default AsideNav
45
+
46
+ const childTextVariants = {
47
+ rest: { opacity: 1, color: 'inherit', filter: 'brightness(1.1)' },
48
+ hover: { opacity: 1, color: '#9803e2' },
49
+ }
50
+
51
+ const ParentRow: React.FC<{ label: string; index: number }> = ({ label, index }) => (
52
+ <motion.div
53
+ initial="hidden"
54
+ animate="show"
55
+ variants={rowVariants}
56
+ custom={index}
57
+ className="relative color-alt will-change-[transform,opacity]"
58
+ transition={{
59
+ delay: index * 0.025,
60
+ type: 'spring',
61
+ stiffness: 200,
62
+ damping: 20,
63
+ }}
64
+ >
65
+ <div className="group relative flex h-px items-center gap-3 py-2">
66
+ <span className="inline-block h-px w-9 shrink-0 bg-stone-500 text-sm opacity-100 dark:bg-white/65" />
67
+ <span className="whitespace-nowrap text-md font-semibold uppercase text-stone-800 opacity-100 dark:text-stone-200">
68
+ {label}
69
+ </span>
70
+ </div>
71
+ </motion.div>
72
+ )
73
+
74
+ const ChildRow: React.FC<{
75
+ targetSection?: string
76
+ label: string
77
+ index: number
78
+ wideOnHover?: number
79
+ scrollOffset?: number
80
+ }> = ({ targetSection, label, index, wideOnHover = 55, scrollOffset = -100 }) => {
81
+ const handleScrollTo = (e: React.MouseEvent) => {
82
+ e.preventDefault()
83
+
84
+ if (!targetSection) return
85
+
86
+ const el = document.getElementById(targetSection)
87
+
88
+ if (!el) {
89
+ console.warn(`Target element with id "${targetSection}" not found`)
90
+ return
91
+ }
92
+
93
+ const elementTop = el.getBoundingClientRect().top + window.pageYOffset
94
+ const targetTop = elementTop + scrollOffset
95
+
96
+ window.scrollTo({ top: targetTop, behavior: 'smooth' })
97
+ }
98
+
99
+ return (
100
+ <motion.div
101
+ initial="hidden"
102
+ animate="show"
103
+ variants={rowVariants}
104
+ custom={index}
105
+ transition={{
106
+ delay: index * 0.025,
107
+ type: 'spring',
108
+ stiffness: 200,
109
+ damping: 20,
110
+ }}
111
+ >
112
+ <motion.button
113
+ onClick={handleScrollTo}
114
+ initial="rest"
115
+ whileHover="hover"
116
+ animate="rest"
117
+ disabled={!targetSection}
118
+ className="group/aside-row relative flex h-px cursor-pointer items-center gap-4 border-0 bg-transparent py-0 text-left text-sm opacity-50 hover:opacity-100 will-change-[transform,opacity] after:absolute after:left-0 after:top-1/2 after:size-full after:-translate-y-1/2 after:p-3 disabled:cursor-not-allowed disabled:opacity-50 disabled:**:opacity-30 focus-visible:rounded focus-visible:outline focus-visible:outline-offset-2 focus-visible:outline-[#9803e2]!"
119
+ >
120
+ <motion.span
121
+ className="inline-block h-px shrink-0 text-sm opacity-100 will-change-[width,background-color]"
122
+ variants={childBarVariants(wideOnHover)}
123
+ transition={{ type: 'spring', stiffness: 500, damping: 35 }}
124
+ />
125
+
126
+ <motion.span
127
+ className="whitespace-nowrap text-sm font-medium! text-stone-600 transition-all ease-out will-change-[color,opacity] group-hover/aside-row:font-semibold! group-hover/aside-row:text-[#9803e2]! hover:text-[#9803e2]! active:text-[#9803e2]! dark:text-stone-400"
128
+ variants={childTextVariants}
129
+ transition={{ type: 'spring', stiffness: 500, damping: 35 }}
130
+ >
131
+ {label}
132
+ </motion.span>
133
+ </motion.button>
134
+ </motion.div>
135
+ )
136
+ }
137
+
138
+ interface AsideScrollLinksProps {
139
+ parentSections?: Array<{
140
+ sectionId?: string
141
+ label: string
142
+ children?: Array<{
143
+ linkId?: string
144
+ label: string
145
+ targetSection?: string
146
+ scrollOffset?: number
147
+ wideOnHover?: number
148
+ }>
149
+ }>
150
+ position?: 'left' | 'right'
151
+ zIndex?: number
152
+ offsetFromEdge?: number
153
+ className?: string
154
+ blockName?: string
155
+ enableCustomCSS?: boolean
156
+ customCSS?: any[]
157
+ }
158
+
159
+ function AsideNav({
160
+ parentSections = [
161
+ {
162
+ label: 'Out of the box',
163
+ children: [{ label: 'Aside PageLinks', targetSection: 's1' }],
164
+ },
165
+ ],
166
+ position = 'left',
167
+ offsetFromEdge = 8,
168
+ enableCustomCSS = false,
169
+ customCSS = [],
170
+ }: AsideScrollLinksProps) {
171
+ const [mounted, setMounted] = useState(false)
172
+ const styleIdRef = useRef(`aside-nav-css-${Math.random().toString(36).slice(2)}`)
173
+
174
+ const extractedCSS = enableCustomCSS && customCSS?.length > 0 ? extractCustomCSS(customCSS) : ''
175
+
176
+ useEffect(() => {
177
+ setMounted(true)
178
+ }, [])
179
+
180
+ useEffect(() => {
181
+ if (!extractedCSS) return
182
+
183
+ const styleId = styleIdRef.current
184
+ const existingStyle = document.getElementById(styleId)
185
+
186
+ if (existingStyle) {
187
+ existingStyle.textContent = extractedCSS
188
+ } else {
189
+ const style = document.createElement('style')
190
+ style.id = styleId
191
+ style.textContent = extractedCSS
192
+ document.head.appendChild(style)
193
+ }
194
+
195
+ return () => {
196
+ document.getElementById(styleId)?.remove()
197
+ }
198
+ }, [extractedCSS])
199
+
200
+ const items = useMemo(() => {
201
+ const flat: Array<{
202
+ type: 'parent' | 'child'
203
+ label: string
204
+ targetSection?: string
205
+ scrollOffset?: number
206
+ wideOnHover?: number
207
+ }> = []
208
+
209
+ parentSections.forEach((p) => {
210
+ flat.push({ type: 'parent', label: p.label })
211
+
212
+ p.children?.forEach((c) =>
213
+ flat.push({
214
+ type: 'child',
215
+ label: c.label,
216
+ targetSection: c.targetSection,
217
+ scrollOffset: c.scrollOffset,
218
+ wideOnHover: c.wideOnHover,
219
+ }),
220
+ )
221
+ })
222
+
223
+ return flat
224
+ }, [parentSections])
225
+
226
+ const positionClass = position === 'left' ? 'left-2' : 'right-2'
227
+
228
+ const asideContent = (
229
+ <aside
230
+ className={[
231
+ 'aside-scroll-block group fixed top-16 z-200 flex items-start overflow-hidden opacity-100 shadow-lg transition-[width,height,max-width,max-height,border-radius,padding] duration-300 delay-50 hover:delay-0 focus-within:delay-0',
232
+ 'h-[2.3rem] w-[2.3rem] max-w-48 max-h-[30vh] p-px',
233
+ 'rounded-2xl backdrop-blur-[10px]',
234
+ 'border border-solid border-stone-300 shadow-[inset_0_0_18px_0px_rgb(120_113_108/18%)] dark:border-ridge dark:border-stone-800 dark:bg-background dark:shadow-[inset_0_0_20px_#ffffff70]',
235
+ 'hover:h-auto hover:w-[calc(100%+1rem)] hover:max-w-60 hover:max-h-[40vh] hover:rounded-2xl hover:p-1 hover:duration-200 focus-within:h-auto focus-within:w-[calc(100%+1rem)] focus-within:max-w-60 focus-within:max-h-[40vh] focus-within:rounded-2xl focus-within:p-1',
236
+ positionClass,
237
+ ].join(' ')}
238
+ style={{
239
+ opacity: 1,
240
+ transform: 'none',
241
+ [position]: `${offsetFromEdge}px`,
242
+ }}
243
+ >
244
+ <div
245
+ data-lenis-prevent
246
+ className={[
247
+ 'aside-inner-box relative flex h-full w-full overflow-hidden p-1 text-[14px] tracking-tight backdrop-blur-md transition-all duration-300',
248
+ 'rounded-2xl border border-stone-300 bg-stone-100/95 shadow-2xl dark:bg-[rgba(5,5,5,0.5)]',
249
+ 'dark:border-[rgba(152,3,226,0.15)] dark:bg-[rgba(22,20,34,0.9)]',
250
+ 'group-hover:rounded-xl group-hover:p-0.5 group-focus-within:rounded-xl group-focus-within:p-0',
251
+ ].join(' ')}
252
+ >
253
+ <div className="w-full overflow-hidden">
254
+ <ArrowDownWideNarrow className="icon-arrow-down-wide-narrow color-alt sticky left-0 top-0 z-100 h-auto w-6 shrink-0 p-1" />
255
+
256
+ {/* <FadeEdges /> */}
257
+
258
+ <nav
259
+ data-lenis-prevent
260
+ className="aside-nav-list pointer-events-none relative m-0 flex h-fit max-h-[40vh] w-full flex-col gap-2 overflow-x-clip overflow-y-auto px-0 pb-24 pt-2 text-stone-800 opacity-0 transition-opacity duration-150 group-hover:pointer-events-auto group-hover:opacity-100 group-focus-within:pointer-events-auto group-focus-within:opacity-100 [-ms-overflow-style:none] scrollbar-none [&::-webkit-scrollbar]:hidden [&::-webkit-scrollbar]:h-0 [&::-webkit-scrollbar]:w-0 dark:text-stone-200"
261
+ >
262
+ {items.map((it, i) => {
263
+ if (it.type === 'parent') {
264
+ return (
265
+ <React.Fragment key={`p-${i}`}>
266
+ <ParentRow label={it.label} index={i} />
267
+ <Divider />
268
+ <Divider />
269
+ </React.Fragment>
270
+ )
271
+ }
272
+
273
+ return (
274
+ <React.Fragment key={`c-${i}`}>
275
+ <ChildRow
276
+ targetSection={it.targetSection}
277
+ label={it.label}
278
+ index={i}
279
+ wideOnHover={it.wideOnHover ?? 55}
280
+ scrollOffset={it.scrollOffset ?? -100}
281
+ />
282
+ <Divider />
283
+ <Divider />
284
+ <Divider />
285
+ </React.Fragment>
286
+ )
287
+ })}
288
+ </nav>
289
+ </div>
290
+ </div>
291
+
292
+ <style jsx global>{`
293
+ .aside-nav-list {
294
+ -ms-overflow-style: none !important;
295
+ scrollbar-width: none !important;
296
+ overscroll-behavior: contain;
297
+ }
298
+
299
+ .aside-nav-list::-webkit-scrollbar,
300
+ .aside-nav-list *::-webkit-scrollbar {
301
+ display: none !important;
302
+ width: 0 !important;
303
+ height: 0 !important;
304
+ background: transparent !important;
305
+ }
306
+
307
+ .aside-scroll-block {
308
+ --aside-nav-line: rgb(120 113 108);
309
+ border-style: ridge;
310
+ }
311
+
312
+ .dark .aside-scroll-block {
313
+ --aside-nav-line: rgba(255, 255, 255, 0.65);
314
+ }
315
+ `}</style>
316
+ </aside>
317
+ )
318
+
319
+ if (!mounted || typeof window === 'undefined') return null
320
+
321
+ return createPortal(asideContent, document.body)
322
+ }
323
+
324
+ export { AsideNav as DDAsideNav }
325
+ export default AsideNav