blocks-dusted 0.1.11 → 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 (161) hide show
  1. package/package.json +5 -2
  2. package/src/cli.js +39 -3
  3. package/src/commands/shop.js +59 -0
  4. package/src/commands/warehouse.js +73 -0
  5. package/src/installers/patchRenderBlocks.js +1 -1
  6. package/src/registry/validateTemplateManifest.js +2 -1
  7. package/templates/blocks/BannerDD790432/Component.tsx +63 -0
  8. package/templates/blocks/BannerDD790432/config.ts +54 -0
  9. package/templates/blocks/BannerDD790432/manifest.json +80 -0
  10. package/templates/blocks/Button47/Component.tsx +124 -0
  11. package/templates/blocks/Button47/config.ts +75 -0
  12. package/templates/blocks/Button47/link.ts +22 -0
  13. package/templates/blocks/Button47/manifest.json +105 -0
  14. package/templates/blocks/Button47/styles.module.scss +75 -0
  15. package/templates/blocks/DD-Accordion/Component.tsx +55 -36
  16. package/templates/blocks/DD-Accordion/config.ts +71 -59
  17. package/templates/blocks/DD-AnimText/Component.tsx +50 -32
  18. package/templates/blocks/DD-AnimText/config.ts +296 -295
  19. package/templates/blocks/DD-AsideNav/Component.tsx +323 -319
  20. package/templates/blocks/DD-Banner/Component.tsx +54 -51
  21. package/templates/blocks/DD-BookCall/Component.tsx +10 -9
  22. package/templates/blocks/DD-ButtonPop/Component.tsx +118 -117
  23. package/templates/blocks/DD-Card/Component.tsx +4 -4
  24. package/templates/blocks/DD-CardTemplate01/Component.tsx +5 -5
  25. package/templates/blocks/DD-CardsWithVariantV3/Component.tsx +472 -0
  26. package/templates/blocks/DD-CardsWithVariantV3/ElectricBorder/index.tsx +203 -0
  27. package/templates/blocks/DD-CardsWithVariantV3/ElectricBorder/styles.ts +87 -0
  28. package/templates/blocks/DD-CardsWithVariantV3/ElectricBorder/useInjectStyle.ts +39 -0
  29. package/templates/blocks/DD-CardsWithVariantV3/config.ts +326 -0
  30. package/templates/blocks/DD-CardsWithVariantV3/manifest.json +110 -0
  31. package/templates/blocks/DD-Carousel-A/Component.tsx +251 -249
  32. package/templates/blocks/DD-Carousel-B/Component.tsx +405 -403
  33. package/templates/blocks/DD-Chip/Component.tsx +14 -14
  34. package/templates/blocks/DD-ComparisonTable/Component.tsx +255 -256
  35. package/templates/blocks/DD-Contact/Component.tsx +433 -434
  36. package/templates/blocks/DD-Counter/Component.tsx +18 -13
  37. package/templates/blocks/DD-DeliCard/Component.tsx +303 -0
  38. package/templates/blocks/DD-DeliCard/config.ts +186 -0
  39. package/templates/blocks/DD-DeliCard/manifest.json +94 -0
  40. package/templates/blocks/DD-FeatCat/Component.tsx +302 -302
  41. package/templates/blocks/DD-FeatProd/CircularGallery.tsx +1179 -0
  42. package/templates/blocks/DD-FeatProd/Component.tsx +484 -0
  43. package/templates/blocks/DD-FeatProd/config.ts +173 -0
  44. package/templates/blocks/DD-FeatProd/manifest.json +93 -0
  45. package/templates/blocks/DD-FeatServ/Component.tsx +607 -0
  46. package/templates/blocks/DD-FeatServ/config.ts +213 -0
  47. package/templates/blocks/DD-FeatServ/manifest.json +113 -0
  48. package/templates/blocks/DD-FeatStrip/Component.tsx +584 -585
  49. package/templates/blocks/DD-FluidBtn/ButtonsEyeCatching.tsx +627 -628
  50. package/templates/blocks/DD-FluidBtn/Component.tsx +46 -43
  51. package/templates/blocks/DD-GooeyInfo/Component.tsx +150 -149
  52. package/templates/blocks/DD-GooeyInfo/config.ts +136 -135
  53. package/templates/blocks/DD-Hero/Component.tsx +16 -40
  54. package/templates/blocks/DD-HeroPlas/Component.tsx +50 -0
  55. package/templates/blocks/DD-HeroPlas/ThreeScene.tsx +109 -0
  56. package/templates/blocks/DD-HeroPlas/config.ts +33 -0
  57. package/templates/blocks/DD-HeroPlas/manifest.json +88 -0
  58. package/templates/blocks/DD-HorizontalScroll/Component.tsx +4 -5
  59. package/templates/blocks/DD-Icon/Component.tsx +46 -81
  60. package/templates/blocks/DD-IconButton/Component.tsx +13 -20
  61. package/templates/blocks/DD-IdTag/Component.tsx +22 -21
  62. package/templates/blocks/DD-IframeMedia/Component.tsx +14 -10
  63. package/templates/blocks/DD-LineAnim/Component.tsx +42 -36
  64. package/templates/blocks/DD-LogoMarq/Component.tsx +38 -48
  65. package/templates/blocks/DD-Lottie/Component.tsx +11 -3
  66. package/templates/blocks/DD-MasonaryMedia/Component.tsx +544 -547
  67. package/templates/blocks/DD-MasonaryMedia/config.ts +389 -389
  68. package/templates/blocks/DD-Masonry/Component.tsx +654 -644
  69. package/templates/blocks/DD-Masonry/config.ts +475 -475
  70. package/templates/blocks/DD-MaterialSwatches/Component.tsx +85 -0
  71. package/templates/blocks/DD-MaterialSwatches/config.ts +232 -0
  72. package/templates/blocks/DD-MaterialSwatches/manifest.json +84 -0
  73. package/templates/blocks/DD-MaterialSwatches/material.ts +107 -0
  74. package/templates/blocks/DD-NineCanvas/Component.tsx +129 -0
  75. package/templates/blocks/DD-NineCanvas/RenderBlocks.tsx +244 -0
  76. package/templates/blocks/DD-NineCanvas/allowedCanvasBlocks.ts +6 -0
  77. package/templates/blocks/DD-NineCanvas/blockComponents.tsx +8 -0
  78. package/templates/blocks/DD-NineCanvas/canvas/CanvasGrid.tsx +316 -0
  79. package/templates/blocks/DD-NineCanvas/canvas/RadialNav.tsx +432 -0
  80. package/templates/blocks/DD-NineCanvas/canvas/canvas-panels.css +889 -0
  81. package/templates/blocks/DD-NineCanvas/canvas/icons/custom-icons.tsx +364 -0
  82. package/templates/blocks/DD-NineCanvas/config.ts +61 -0
  83. package/templates/blocks/DD-NineCanvas/manifest.json +165 -0
  84. package/templates/blocks/DD-NineCanvas/styles.scss +152 -0
  85. package/templates/blocks/DD-NineCanvas/tooltip/get-strict-context.tsx +26 -0
  86. package/templates/blocks/DD-NineCanvas/tooltip/primitives.tsx +178 -0
  87. package/templates/blocks/DD-NineCanvas/tooltip/tooltip.tsx +71 -0
  88. package/templates/blocks/DD-NineCanvas/tooltip/use-controlled-state.tsx +33 -0
  89. package/templates/blocks/DD-NineCanvas/utilities/FadeOnScroll.tsx +68 -0
  90. package/templates/blocks/DD-NineCanvas/utilities/ParallaxWrapper.tsx +157 -0
  91. package/templates/blocks/DD-NineCanvas/utilities/renderCustomCSS.ts +5 -0
  92. package/templates/blocks/DD-NineCanvas/utilities/webglCleanup.ts +27 -0
  93. package/templates/blocks/DD-PayloadAIAssistant/Component.tsx +78 -0
  94. package/templates/blocks/DD-PayloadAIAssistant/DustedBot.tsx +590 -0
  95. package/templates/blocks/DD-PayloadAIAssistant/config.ts +37 -0
  96. package/templates/blocks/DD-PayloadAIAssistant/demo.css +125 -0
  97. package/templates/blocks/DD-PayloadAIAssistant/manifest.json +93 -0
  98. package/templates/blocks/DD-PayloadAIAssistant/source-defaults.ts +17 -0
  99. package/templates/blocks/DD-PayloadAIAssistant/styles.ts +306 -0
  100. package/templates/blocks/DD-Pricing/Component.tsx +368 -372
  101. package/templates/blocks/DD-Pricing/config.ts +215 -215
  102. package/templates/blocks/DD-Process/Component.tsx +147 -149
  103. package/templates/blocks/DD-Progress/Component.tsx +156 -141
  104. package/templates/blocks/DD-ProjHeader/Component.tsx +93 -91
  105. package/templates/blocks/DD-ProjSlider/Component.tsx +1 -1
  106. package/templates/blocks/DD-ProjSlider/config.ts +2 -2
  107. package/templates/blocks/DD-Section/Component.tsx +265 -266
  108. package/templates/blocks/DD-Separator/Component.tsx +66 -66
  109. package/templates/blocks/DD-Services/Component.tsx +176 -176
  110. package/templates/blocks/DD-ShowcaseGrid/Component.tsx +306 -307
  111. package/templates/blocks/DD-Slider-A/Component.tsx +237 -237
  112. package/templates/blocks/DD-StackCards/Component.tsx +474 -473
  113. package/templates/blocks/DD-Team/Component.tsx +247 -247
  114. package/templates/blocks/DD-TeamCards/Component.tsx +251 -251
  115. package/templates/blocks/DD-TechStack/Component.tsx +161 -168
  116. package/templates/blocks/DD-TestMarq/Component.tsx +158 -132
  117. package/templates/blocks/DD-Testim/Component.tsx +247 -247
  118. package/templates/blocks/DD-Testim2/Component.tsx +265 -256
  119. package/templates/blocks/DD-Testimonials/Component.tsx +139 -147
  120. package/templates/blocks/DD-TextMarq/Component.tsx +157 -157
  121. package/templates/blocks/DD-Thanks/Component.tsx +501 -500
  122. package/templates/blocks/DD-Work/Component.tsx +315 -315
  123. package/templates/blocks/DD-Work-B/Component.tsx +294 -294
  124. package/templates/blocks/DDHG-CTASection2/Component.tsx +183 -184
  125. package/templates/blocks/DDHG-HighlightArc/Component.tsx +246 -243
  126. package/templates/blocks/DDHG-LogoMarquee/Component.tsx +180 -93
  127. package/templates/blocks/DDHG-LogoMarquee/config.ts +154 -66
  128. package/templates/blocks/DDHG-NavCodeGrid/Component.tsx +225 -213
  129. package/templates/blocks/DDHG-ProcessSec/Component.tsx +38 -39
  130. package/templates/blocks/DDHG-ServiceDetails/Component.tsx +11 -11
  131. package/templates/blocks/DDHG-ServiceDetails/ServiceDetailCard.tsx +30 -47
  132. package/templates/blocks/DDHG-ServiceHero/Component.tsx +10 -10
  133. package/templates/blocks/DDHG-ServiceOverview/Component.tsx +23 -23
  134. package/templates/blocks/DDHG-StatsFAQ/Component.tsx +40 -40
  135. package/templates/blocks/DDHG-TeamCards/Component.tsx +140 -131
  136. package/templates/blocks/Form/Checkbox/index.tsx +45 -0
  137. package/templates/blocks/Form/Component.tsx +163 -0
  138. package/templates/blocks/Form/Country/index.tsx +65 -0
  139. package/templates/blocks/Form/Country/options.ts +982 -0
  140. package/templates/blocks/Form/Email/index.tsx +38 -0
  141. package/templates/blocks/Form/Error/index.tsx +15 -0
  142. package/templates/blocks/Form/Message/index.tsx +13 -0
  143. package/templates/blocks/Form/Number/index.tsx +36 -0
  144. package/templates/blocks/Form/Select/index.tsx +63 -0
  145. package/templates/blocks/Form/State/index.tsx +64 -0
  146. package/templates/blocks/Form/State/options.ts +52 -0
  147. package/templates/blocks/Form/Text/index.tsx +32 -0
  148. package/templates/blocks/Form/Textarea/index.tsx +40 -0
  149. package/templates/blocks/Form/Width/index.tsx +13 -0
  150. package/templates/blocks/Form/config.ts +51 -0
  151. package/templates/blocks/Form/fields.tsx +21 -0
  152. package/templates/blocks/Form/manifest.json +168 -0
  153. package/templates/blocks/MediaBlock/Component.tsx +67 -0
  154. package/templates/blocks/MediaBlock/config.ts +14 -0
  155. package/templates/blocks/MediaBlock/manifest.json +92 -0
  156. package/templates/blocks/TransitionsDustedShowcase/Component.tsx +9 -0
  157. package/templates/blocks/TransitionsDustedShowcase/config.ts +13 -0
  158. package/templates/blocks/TransitionsDustedShowcase/manifest.json +80 -0
  159. package/templates/blocks/rawHtml/Component.tsx +25 -0
  160. package/templates/blocks/rawHtml/config.ts +56 -0
  161. 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