dune-react 0.0.37 → 0.0.38

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.
@@ -1,6 +1,6 @@
1
1
  "use client";
2
2
  import { jsxs, jsx, Fragment } from "react/jsx-runtime";
3
- import { useState, useEffect, useRef } from "react";
3
+ import { useState, useEffect } from "react";
4
4
  import { Carousel, CarouselContent, CarouselItem, CarouselPrevious, CarouselNext } from "../../../shadcn/carousel.js";
5
5
  import { CompoundMedia } from "../../../puck-base/media.js";
6
6
  import { cn } from "../../../../utils/css-utils.js";
@@ -29,36 +29,10 @@ const ImageCarousel = (props) => {
29
29
  const [current, setCurrent] = useState(0);
30
30
  useEffect(() => {
31
31
  if (!api) return;
32
- const onSelect = () => {
32
+ setCurrent(api.selectedScrollSnap() + 1);
33
+ api.on("select", () => {
33
34
  setCurrent(api.selectedScrollSnap() + 1);
34
- };
35
- const onSettle = () => {
36
- const idx = api.selectedScrollSnap();
37
- const container = api.containerNode();
38
- if (container && idx > 0) {
39
- const slideNodes = api.slideNodes();
40
- const viewportNode = container.parentElement;
41
- if (viewportNode && slideNodes[idx]) {
42
- const viewportLeft = viewportNode.getBoundingClientRect().left;
43
- const slideLeft = slideNodes[idx].getBoundingClientRect().left;
44
- const offset = slideLeft - viewportLeft;
45
- if (Math.abs(offset) > 2) {
46
- const currentTransform = new DOMMatrix(getComputedStyle(container).transform);
47
- container.style.transform = "translate3d(" + (currentTransform.m41 - offset) + "px, 0px, 0px)";
48
- }
49
- }
50
- }
51
- };
52
- onSelect();
53
- api.on("select", onSelect);
54
- api.on("settle", onSettle);
55
- return () => {
56
- api.off("select", onSelect);
57
- api.off("settle", onSettle);
58
- api.off("select", onSelect);
59
- api.off("reInit", onReInit);
60
- api.off("settle", onSettle);
61
- };
35
+ });
62
36
  }, [api]);
63
37
  const getBasisClass = () => {
64
38
  switch (slidesPerView) {
@@ -101,7 +75,7 @@ const ImageCarousel = (props) => {
101
75
  Carousel,
102
76
  {
103
77
  setApi,
104
- opts: { loop: true, align: "start" },
78
+ opts: { align: "start" },
105
79
  className: cn({
106
80
  "overflow-hidden": slideOverflow === "hidden",
107
81
  "relative flex-1 min-h-0 [&>[data-slot=carousel-content]]:h-full": isFullscreen
@@ -9,55 +9,233 @@ import { RxChevronDown } from "../../../../node_modules/.pnpm/react-icons@5.6.0_
9
9
  import { cn } from "../../../../utils/css-utils.js";
10
10
  import { SectionWrapper } from "../../../puck-core/section-wrapper.js";
11
11
  import { CompoundSocialLinks } from "../../../puck-base/social-links.js";
12
+ import { actionDefaults } from "../../../puck-core/core/props/interactive.js";
12
13
  const StandardNavbar = (props) => {
13
- const { logo, navLinks, buttons, socialLinks, styles } = { ...StandardNavbarDefaults, ...props };
14
- const { className: sectionClassName, style: sectionStyle, css } = styles ?? {};
14
+ const { logo, navLinks, buttons, socialLinks, styles } = {
15
+ ...StandardNavbarDefaults,
16
+ ...props
17
+ };
18
+ const {
19
+ className: sectionClassName,
20
+ style: sectionStyle,
21
+ css
22
+ } = styles ?? {};
15
23
  const [isMobileMenuOpen, setIsMobileMenuOpen] = useState(false);
16
24
  const isMobile = useMediaQuery("(max-width: 991px)");
17
- return /* @__PURE__ */ jsx(SectionWrapper, { className: cn("z-[999] flex w-full items-center border-b border-border-primary bg-background-primary lg:min-h-18 lg:px-[5%]", sectionClassName), style: sectionStyle, css, children: /* @__PURE__ */ jsxs("div", { className: "size-full lg:flex lg:items-center lg:justify-between", children: [
18
- /* @__PURE__ */ jsxs("div", { className: "flex min-h-16 items-center justify-between px-[5%] md:min-h-18 lg:min-h-full lg:px-0", children: [
19
- /* @__PURE__ */ jsx("a", { href: logo == null ? void 0 : logo.url, children: /* @__PURE__ */ jsx(CompoundMedia, { src: logo == null ? void 0 : logo.src, alt: logo == null ? void 0 : logo.alt, className: "h-9 w-auto" }) }),
20
- /* @__PURE__ */ jsxs("button", { className: "-mr-2 flex size-12 flex-col items-center justify-center lg:hidden", onClick: () => setIsMobileMenuOpen((prev) => !prev), children: [
21
- /* @__PURE__ */ jsx(motion.span, { className: "my-[3px] h-0.5 w-6 bg-black", animate: isMobileMenuOpen ? ["open", "rotatePhase"] : "closed", variants: topLineVariants }),
22
- /* @__PURE__ */ jsx(motion.span, { className: "my-[3px] h-0.5 w-6 bg-black", animate: isMobileMenuOpen ? "open" : "closed", variants: middleLineVariants }),
23
- /* @__PURE__ */ jsx(motion.span, { className: "my-[3px] h-0.5 w-6 bg-black", animate: isMobileMenuOpen ? ["open", "rotatePhase"] : "closed", variants: bottomLineVariants })
24
- ] })
25
- ] }),
26
- /* @__PURE__ */ jsxs(motion.div, { variants: { open: { height: "var(--height-open, 100dvh)" }, close: { height: "var(--height-closed, 0)" } }, initial: "close", exit: "close", animate: isMobileMenuOpen ? "open" : "close", transition: { duration: 0.4 }, className: "overflow-hidden px-[5%] lg:flex lg:items-center lg:px-0 lg:[--height-closed:auto] lg:[--height-open:auto]", children: [
27
- navLinks == null ? void 0 : navLinks.map(
28
- (navLink, index) => navLink.subMenuLinks && navLink.subMenuLinks.length > 0 ? /* @__PURE__ */ jsx(SubMenu, { navLink, isMobile }, index) : /* @__PURE__ */ jsx("a", { href: navLink.url, className: "block py-3 text-md first:pt-7 lg:px-4 lg:py-2 lg:text-base first:lg:pt-2", children: navLink.title }, index)
25
+ return /* @__PURE__ */ jsx(
26
+ SectionWrapper,
27
+ {
28
+ className: cn(
29
+ "z-[999] flex w-full items-center border-b border-border-primary bg-background-primary lg:min-h-18 lg:px-[5%]",
30
+ sectionClassName
29
31
  ),
30
- /* @__PURE__ */ jsxs("div", { className: "mt-6 flex flex-col items-center gap-4 lg:ml-4 lg:mt-0 lg:flex-row", children: [
31
- buttons == null ? void 0 : buttons.map((button, index) => /* @__PURE__ */ jsx(Button, { variant: button.variant, size: button.size, className: "w-full", children: button.label }, index)),
32
- (styles == null ? void 0 : styles.showSocialLinks) === "true" && /* @__PURE__ */ jsx(CompoundSocialLinks, { links: socialLinks ?? [], iconClassName: "size-5", className: "gap-2" })
32
+ style: sectionStyle,
33
+ css,
34
+ children: /* @__PURE__ */ jsxs("div", { className: "size-full lg:flex lg:items-center lg:justify-between", children: [
35
+ /* @__PURE__ */ jsxs("div", { className: "flex min-h-16 items-center justify-between px-[5%] md:min-h-18 lg:min-h-full lg:px-0", children: [
36
+ /* @__PURE__ */ jsx("a", { href: logo == null ? void 0 : logo.url, children: /* @__PURE__ */ jsx(
37
+ CompoundMedia,
38
+ {
39
+ src: logo == null ? void 0 : logo.src,
40
+ alt: logo == null ? void 0 : logo.alt,
41
+ className: "h-9 w-auto"
42
+ }
43
+ ) }),
44
+ /* @__PURE__ */ jsxs(
45
+ "button",
46
+ {
47
+ className: "-mr-2 flex size-12 flex-col items-center justify-center lg:hidden",
48
+ onClick: () => setIsMobileMenuOpen((prev) => !prev),
49
+ children: [
50
+ /* @__PURE__ */ jsx(
51
+ motion.span,
52
+ {
53
+ className: "my-[3px] h-0.5 w-6 bg-black",
54
+ animate: isMobileMenuOpen ? ["open", "rotatePhase"] : "closed",
55
+ variants: topLineVariants
56
+ }
57
+ ),
58
+ /* @__PURE__ */ jsx(
59
+ motion.span,
60
+ {
61
+ className: "my-[3px] h-0.5 w-6 bg-black",
62
+ animate: isMobileMenuOpen ? "open" : "closed",
63
+ variants: middleLineVariants
64
+ }
65
+ ),
66
+ /* @__PURE__ */ jsx(
67
+ motion.span,
68
+ {
69
+ className: "my-[3px] h-0.5 w-6 bg-black",
70
+ animate: isMobileMenuOpen ? ["open", "rotatePhase"] : "closed",
71
+ variants: bottomLineVariants
72
+ }
73
+ )
74
+ ]
75
+ }
76
+ )
77
+ ] }),
78
+ /* @__PURE__ */ jsxs(
79
+ motion.div,
80
+ {
81
+ variants: {
82
+ open: { height: "var(--height-open, 100dvh)" },
83
+ close: { height: "var(--height-closed, 0)" }
84
+ },
85
+ initial: "close",
86
+ exit: "close",
87
+ animate: isMobileMenuOpen ? "open" : "close",
88
+ transition: { duration: 0.4 },
89
+ className: "overflow-hidden px-[5%] lg:flex lg:items-center lg:px-0 lg:[--height-closed:auto] lg:[--height-open:auto]",
90
+ children: [
91
+ navLinks == null ? void 0 : navLinks.map(
92
+ (navLink, index) => navLink.subMenuLinks && navLink.subMenuLinks.length > 0 ? /* @__PURE__ */ jsx(SubMenu, { navLink, isMobile }, index) : /* @__PURE__ */ jsx(
93
+ "a",
94
+ {
95
+ href: navLink.url,
96
+ className: "block py-3 text-md first:pt-7 lg:px-4 lg:py-2 lg:text-base first:lg:pt-2",
97
+ children: navLink.title
98
+ },
99
+ index
100
+ )
101
+ ),
102
+ /* @__PURE__ */ jsxs("div", { className: "mt-6 flex flex-col items-center gap-4 lg:ml-4 lg:mt-0 lg:flex-row", children: [
103
+ buttons == null ? void 0 : buttons.map((button, index) => /* @__PURE__ */ jsx(
104
+ Button,
105
+ {
106
+ variant: button.variant,
107
+ size: button.size,
108
+ className: "w-full",
109
+ children: button.label
110
+ },
111
+ index
112
+ )),
113
+ (styles == null ? void 0 : styles.showSocialLinks) === "true" && /* @__PURE__ */ jsx(
114
+ CompoundSocialLinks,
115
+ {
116
+ links: socialLinks ?? [],
117
+ iconClassName: "size-5",
118
+ className: "gap-2"
119
+ }
120
+ )
121
+ ] })
122
+ ]
123
+ }
124
+ )
33
125
  ] })
34
- ] })
35
- ] }) });
126
+ }
127
+ );
36
128
  };
37
- const SubMenu = ({ navLink, isMobile }) => {
129
+ const SubMenu = ({
130
+ navLink,
131
+ isMobile
132
+ }) => {
38
133
  var _a;
39
134
  const [isDropdownOpen, setIsDropdownOpen] = useState(false);
40
- return /* @__PURE__ */ jsxs("div", { onMouseEnter: () => !isMobile && setIsDropdownOpen(true), onMouseLeave: () => !isMobile && setIsDropdownOpen(false), children: [
41
- /* @__PURE__ */ jsxs("button", { className: "flex w-full items-center justify-between gap-2 py-3 text-left text-md lg:flex-none lg:justify-start lg:px-4 lg:py-2 lg:text-base", onClick: () => setIsDropdownOpen((prev) => !prev), children: [
42
- /* @__PURE__ */ jsx("span", { children: navLink.title }),
43
- /* @__PURE__ */ jsx(motion.span, { variants: { rotated: { rotate: 180 }, initial: { rotate: 0 } }, animate: isDropdownOpen ? "rotated" : "initial", transition: { duration: 0.3 }, children: /* @__PURE__ */ jsx(RxChevronDown, {}) })
44
- ] }),
45
- isDropdownOpen && /* @__PURE__ */ jsx(AnimatePresence, { children: /* @__PURE__ */ jsx(motion.nav, { variants: { open: { visibility: "visible", opacity: "var(--opacity-open, 100%)", y: 0 }, close: { visibility: "hidden", opacity: "var(--opacity-close, 0)", y: "var(--y-close, 0%)" } }, animate: isDropdownOpen ? "open" : "close", initial: "close", exit: "close", transition: { duration: 0.2 }, className: "bg-background-primary lg:absolute lg:z-50 lg:border lg:border-border-primary lg:p-2 lg:[--y-close:25%]", children: (_a = navLink.subMenuLinks) == null ? void 0 : _a.map((link, index) => /* @__PURE__ */ jsx("a", { href: link.url, className: "block py-3 pl-[5%] text-md lg:px-4 lg:py-2 lg:text-base", children: link.title }, index)) }) })
46
- ] });
135
+ return /* @__PURE__ */ jsxs(
136
+ "div",
137
+ {
138
+ onMouseEnter: () => !isMobile && setIsDropdownOpen(true),
139
+ onMouseLeave: () => !isMobile && setIsDropdownOpen(false),
140
+ children: [
141
+ /* @__PURE__ */ jsxs(
142
+ "button",
143
+ {
144
+ className: "flex w-full items-center justify-between gap-2 py-3 text-left text-md lg:flex-none lg:justify-start lg:px-4 lg:py-2 lg:text-base",
145
+ onClick: () => setIsDropdownOpen((prev) => !prev),
146
+ children: [
147
+ /* @__PURE__ */ jsx("span", { children: navLink.title }),
148
+ /* @__PURE__ */ jsx(
149
+ motion.span,
150
+ {
151
+ variants: { rotated: { rotate: 180 }, initial: { rotate: 0 } },
152
+ animate: isDropdownOpen ? "rotated" : "initial",
153
+ transition: { duration: 0.3 },
154
+ children: /* @__PURE__ */ jsx(RxChevronDown, {})
155
+ }
156
+ )
157
+ ]
158
+ }
159
+ ),
160
+ isDropdownOpen && /* @__PURE__ */ jsx(AnimatePresence, { children: /* @__PURE__ */ jsx(
161
+ motion.nav,
162
+ {
163
+ variants: {
164
+ open: {
165
+ visibility: "visible",
166
+ opacity: "var(--opacity-open, 100%)",
167
+ y: 0
168
+ },
169
+ close: {
170
+ visibility: "hidden",
171
+ opacity: "var(--opacity-close, 0)",
172
+ y: "var(--y-close, 0%)"
173
+ }
174
+ },
175
+ animate: isDropdownOpen ? "open" : "close",
176
+ initial: "close",
177
+ exit: "close",
178
+ transition: { duration: 0.2 },
179
+ className: "bg-background-primary lg:absolute lg:z-50 lg:border lg:border-border-primary lg:p-2 lg:[--y-close:25%]",
180
+ children: (_a = navLink.subMenuLinks) == null ? void 0 : _a.map((link, index) => /* @__PURE__ */ jsx(
181
+ "a",
182
+ {
183
+ href: link.url,
184
+ className: "block py-3 pl-[5%] text-md lg:px-4 lg:py-2 lg:text-base",
185
+ children: link.title
186
+ },
187
+ index
188
+ ))
189
+ }
190
+ ) })
191
+ ]
192
+ }
193
+ );
194
+ };
195
+ const topLineVariants = {
196
+ open: { translateY: 8, transition: { delay: 0.1 } },
197
+ rotatePhase: { rotate: -45, transition: { delay: 0.2 } },
198
+ closed: { translateY: 0, rotate: 0, transition: { duration: 0.2 } }
199
+ };
200
+ const middleLineVariants = {
201
+ open: { width: 0, transition: { duration: 0.1 } },
202
+ closed: { width: "1.5rem", transition: { delay: 0.3, duration: 0.2 } }
203
+ };
204
+ const bottomLineVariants = {
205
+ open: { translateY: -8, transition: { delay: 0.1 } },
206
+ rotatePhase: { rotate: 45, transition: { delay: 0.2 } },
207
+ closed: { translateY: 0, rotate: 0, transition: { duration: 0.2 } }
47
208
  };
48
- const topLineVariants = { open: { translateY: 8, transition: { delay: 0.1 } }, rotatePhase: { rotate: -45, transition: { delay: 0.2 } }, closed: { translateY: 0, rotate: 0, transition: { duration: 0.2 } } };
49
- const middleLineVariants = { open: { width: 0, transition: { duration: 0.1 } }, closed: { width: "1.5rem", transition: { delay: 0.3, duration: 0.2 } } };
50
- const bottomLineVariants = { open: { translateY: -8, transition: { delay: 0.1 } }, rotatePhase: { rotate: 45, transition: { delay: 0.2 } }, closed: { translateY: 0, rotate: 0, transition: { duration: 0.2 } } };
51
209
  const StandardNavbarDefaults = {
52
210
  __metadata: { type: "header" },
53
- logo: { url: "#", src: "https://file.springbrand.ai/web_assets/template-logo.svg", alt: "Logo image" },
211
+ logo: {
212
+ url: "#",
213
+ src: "https://file.springbrand.ai/web_assets/template-logo.svg",
214
+ alt: "Logo image"
215
+ },
54
216
  navLinks: [
55
217
  { title: "Link One", url: "#" },
56
218
  { title: "Link Two", url: "#" },
57
219
  { title: "Link Three", url: "#" },
58
- { title: "Link Four", url: "#", subMenuLinks: [{ title: "Link Five", url: "#" }, { title: "Link Six", url: "#" }, { title: "Link Seven", url: "#" }] }
220
+ {
221
+ title: "Link Four",
222
+ url: "#",
223
+ subMenuLinks: [
224
+ { title: "Link Five", url: "#" },
225
+ { title: "Link Six", url: "#" },
226
+ { title: "Link Seven", url: "#" }
227
+ ]
228
+ }
229
+ ],
230
+ buttons: [
231
+ {
232
+ label: "Button",
233
+ action: actionDefaults,
234
+ variant: "secondary",
235
+ size: "sm"
236
+ },
237
+ { label: "Button", action: actionDefaults, size: "sm" }
59
238
  ],
60
- buttons: [{ label: "Button", variant: "secondary", size: "sm" }, { label: "Button", size: "sm" }],
61
239
  socialLinks: [],
62
240
  styles: { dropdownType: "simple" }
63
241
  };
@@ -2,6 +2,7 @@ import { buttonsField, badgeField } from "./interactive.js";
2
2
  import { actionDefaults, actionField, buttonDefaults, buttonField, iconField, resolveActionUrl } from "./interactive.js";
3
3
  import { descriptionField, headingField, featuresField } from "./content.js";
4
4
  import { cardField, cardsField } from "./content.js";
5
+ import { getPlaceholderMediaUrl, media16x9Placeholder, media1x1Placeholder, media9x16Placeholder, mediaField, mediasField } from "./media.js";
5
6
  const contentFields = {
6
7
  heading: headingField,
7
8
  description: descriptionField,
@@ -28,7 +29,13 @@ export {
28
29
  contentFieldsWithFeatures,
29
30
  descriptionField,
30
31
  featuresField,
32
+ getPlaceholderMediaUrl,
31
33
  headingField,
32
34
  iconField,
35
+ media16x9Placeholder,
36
+ media1x1Placeholder,
37
+ media9x16Placeholder,
38
+ mediaField,
39
+ mediasField,
33
40
  resolveActionUrl
34
41
  };
@@ -35,9 +35,15 @@ const customSchemaRegistry = /* @__PURE__ */ new Map([
35
35
  ["MediaUploadField", mediaUploadSchema],
36
36
  ["LocationField", locationSchema]
37
37
  ]);
38
+ const labelToRegistryKey = {
39
+ action: "ActionField",
40
+ Media: "MediaUploadField",
41
+ Location: "LocationField",
42
+ "Map Location": "LocationField"
43
+ };
38
44
  function resolveCustomField(field) {
39
45
  const render = field.render;
40
- const name = render == null ? void 0 : render.name;
46
+ const name = (render == null ? void 0 : render.name) ?? (field.label ? labelToRegistryKey[field.label] : "IconPickerField");
41
47
  if (name && customSchemaRegistry.has(name)) {
42
48
  return customSchemaRegistry.get(name);
43
49
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "dune-react",
3
- "version": "0.0.37",
3
+ "version": "0.0.38",
4
4
  "license": "MIT",
5
5
  "type": "module",
6
6
  "scripts": {