diff --git a/app/components/Button.tsx b/app/components/Button.tsx index b5ade938..bcc4d201 100644 --- a/app/components/Button.tsx +++ b/app/components/Button.tsx @@ -40,7 +40,10 @@ let variants = cva( export interface ButtonProps extends VariantProps, - Omit, "children">, + Omit< + HTMLAttributes, + "children" | "type" + >, Partial { as?: keyof HTMLElementTagNameMap; className?: string; diff --git a/app/components/Icons.tsx b/app/components/Icons.tsx index 2d414be1..0fbac817 100644 --- a/app/components/Icons.tsx +++ b/app/components/Icons.tsx @@ -1,5 +1,3 @@ -import clsx from "clsx"; - type IconProps = JSX.IntrinsicElements["svg"]; // Using icons from https://phosphoricons.com/ @@ -64,37 +62,92 @@ export function IconTag(props: IconProps) { ); } -export function IconCaret(props: IconProps) { - let { className, direction = "right", ...rest } = props; - let rotate; +export function IconCaretLeft(props: IconProps) { + return ( + + + + ); +} + +export function IconCaretRight(props: IconProps) { + return ( + + + + ); +} + +export function IconCaretDown(props: IconProps) { + return ( + + + + ); +} + +export function IconCaretUp(props: IconProps) { + return ( + + + + ); +} - switch (direction) { - case "down": - rotate = "rotate-0"; - break; - case "up": - rotate = "rotate-180"; - break; - case "right": - rotate = "-rotate-90"; - break; - case "left": - rotate = "rotate-90"; - break; - default: - rotate = "rotate-0"; - } +export function IconArrowLeft(props: IconProps) { return ( + + + ); +} + +export function IconArrowRight(props: IconProps) { + return ( + - + ); } diff --git a/app/components/OverlayAndBackground.tsx b/app/components/OverlayAndBackground.tsx new file mode 100644 index 00000000..8f5f0c31 --- /dev/null +++ b/app/components/OverlayAndBackground.tsx @@ -0,0 +1,33 @@ +import type { BackgroundImageProps } from "./BackgroundImage"; +import { BackgroundImage } from "./BackgroundImage"; +import type { OverlayProps } from "./Overlay"; +import { Overlay } from "./Overlay"; + +export interface OverlayAndBackgroundProps + extends BackgroundImageProps, + OverlayProps {} + +export function OverlayAndBackground(props: OverlayAndBackgroundProps) { + let { + backgroundImage, + backgroundFit, + backgroundPosition, + enableOverlay, + overlayColor, + overlayOpacity, + } = props; + return ( + <> + + + + ); +} diff --git a/app/components/Section.tsx b/app/components/Section.tsx index 7ac5f9ab..100953dd 100644 --- a/app/components/Section.tsx +++ b/app/components/Section.tsx @@ -8,9 +8,10 @@ import type { HTMLAttributes } from "react"; import React, { forwardRef } from "react"; import { cn } from "~/lib/cn"; import type { BackgroundImageProps } from "./BackgroundImage"; -import { BackgroundImage, backgroundInputs } from "./BackgroundImage"; +import { backgroundInputs } from "./BackgroundImage"; import type { OverlayProps } from "./Overlay"; -import { Overlay, overlayInputs } from "./Overlay"; +import { overlayInputs } from "./Overlay"; +import { OverlayAndBackground } from "./OverlayAndBackground"; export type BackgroundProps = BackgroundImageProps & { backgroundFor: "section" | "content"; @@ -132,31 +133,6 @@ export let Section = forwardRef((props, ref) => { ); }); -function OverlayAndBackground(props: SectionProps) { - let { - backgroundImage, - backgroundFit, - backgroundPosition, - enableOverlay, - overlayColor, - overlayOpacity, - } = props; - return ( - <> - - - - ); -} - export let layoutInputs: InspectorGroup["inputs"] = [ { type: "select", diff --git a/app/lib/utils.ts b/app/lib/utils.ts index 383df813..b57c125b 100644 --- a/app/lib/utils.ts +++ b/app/lib/utils.ts @@ -2,6 +2,7 @@ import { useLocation } from "@remix-run/react"; import type { FulfillmentStatus } from "@shopify/hydrogen/customer-account-api-types"; import type { MoneyV2 } from "@shopify/hydrogen/storefront-api-types"; import type { WeaverseImage } from "@weaverse/hydrogen"; +import type { LinkHTMLAttributes } from "react"; import type { ChildMenuItemFragment, MenuFragment, @@ -347,3 +348,17 @@ export function getImageAspectRatio( } return aspRt; } + +export function loadCSS(attrs: LinkHTMLAttributes) { + return new Promise((resolve, reject) => { + let found = document.querySelector(`link[href="${attrs.href}"]`); + if (found) { + return resolve(true); + } + let link = document.createElement("link"); + Object.assign(link, attrs); + link.addEventListener("load", () => resolve(true)); + link.onerror = reject; + document.head.appendChild(link); + }); +} diff --git a/app/modules/Drawer.tsx b/app/modules/Drawer.tsx index cc9183f1..cf164ac0 100644 --- a/app/modules/Drawer.tsx +++ b/app/modules/Drawer.tsx @@ -1,10 +1,9 @@ -import { Fragment, useState } from "react"; import { Dialog, Transition } from "@headlessui/react"; - -import { Heading, IconClose } from "~/modules"; -import { cn } from "~/lib/cn"; import clsx from "clsx"; -import { IconCaret } from "~/components/Icons"; +import { Fragment, useState } from "react"; +import { IconCaretLeft } from "~/components/Icons"; +import { cn } from "~/lib/cn"; +import { Heading, IconClose } from "~/modules"; /** * Drawer component that opens on user click. @@ -101,9 +100,8 @@ export function Drawer({ onClick={onClose} data-test="close-cart" > - diff --git a/app/modules/Input.tsx b/app/modules/Input.tsx index c7531451..cbb755b6 100644 --- a/app/modules/Input.tsx +++ b/app/modules/Input.tsx @@ -20,18 +20,21 @@ const variants = { }; export const Input = forwardRef( - ({ - className = "", - type, - variant = "default", - prefixElement, - prefix, - suffix, - onFocus, - onBlur, - onClear, - ...rest - }: InputProps) => { + ( + { + className = "", + type, + variant = "default", + prefixElement, + prefix, + suffix, + onFocus, + onBlur, + onClear, + ...rest + }, + ref, + ) => { let [focused, setFocused] = useState(false); let commonClasses = clsx( "w-full rounded-sm border px-3 py-2.5", @@ -52,6 +55,7 @@ export const Input = forwardRef( let rawInput = ( {item.title} - + {open ? ( + + ) : ( + + )} @@ -101,8 +102,7 @@ function MultiMenu(props: MultiMenuProps) { onClick={openMenu} > {title}{" "} - - + {content} @@ -134,7 +134,11 @@ function ImageMenu({ {imageItems.map((item, id) => (
- +
{item.title}
diff --git a/app/modules/product-form/product-media.tsx b/app/modules/product-form/product-media.tsx index 0ab94037..f5ead282 100644 --- a/app/modules/product-form/product-media.tsx +++ b/app/modules/product-form/product-media.tsx @@ -1,8 +1,7 @@ import { Image } from "@shopify/hydrogen"; import clsx from "clsx"; -import { useKeenSlider } from "keen-slider/react.es"; +import { useKeenSlider } from "keen-slider/react"; import { useEffect, useState } from "react"; - import type { MediaFragment } from "storefrontapi.generated"; interface ProductMediaProps { diff --git a/app/sections/columns-with-images/column.tsx b/app/sections/columns-with-images/column.tsx index 3e50912a..ee49fb23 100644 --- a/app/sections/columns-with-images/column.tsx +++ b/app/sections/columns-with-images/column.tsx @@ -10,7 +10,9 @@ import { forwardRef } from "react"; import type { ButtonProps } from "~/components/Button"; import Button, { buttonContentInputs } from "~/components/Button"; -interface ColumnWithImageItemProps extends ButtonProps, HydrogenComponentProps { +interface ColumnWithImageItemProps + extends Pick, + HydrogenComponentProps { imageSrc: WeaverseImage; heading: string; content: string; @@ -134,6 +136,6 @@ export let schema: HydrogenComponentSchema = { }, ], presets: { - imageSrc: IMAGES_PLACEHOLDERS.image, + imageSrc: IMAGES_PLACEHOLDERS.product_1, }, }; diff --git a/app/sections/hero-image.tsx b/app/sections/hero-image.tsx index f63c5200..7881cf9b 100644 --- a/app/sections/hero-image.tsx +++ b/app/sections/hero-image.tsx @@ -107,7 +107,7 @@ export let schema: HydrogenComponentSchema = { presets: { height: "large", contentPosition: "bottom left", - backgroundImage: IMAGES_PLACEHOLDERS.backgroundImage, + backgroundImage: IMAGES_PLACEHOLDERS.banner_1, backgroundFit: "cover", enableOverlay: true, overlayOpacity: 35, diff --git a/app/sections/slideshow/arrows.tsx b/app/sections/slideshow/arrows.tsx new file mode 100644 index 00000000..0e9e0a3a --- /dev/null +++ b/app/sections/slideshow/arrows.tsx @@ -0,0 +1,132 @@ +import type { VariantProps } from "class-variance-authority"; +import { cva } from "class-variance-authority"; +import clsx from "clsx"; +import { useState } from "react"; +import { useSwiper } from "swiper/react"; +import { + IconArrowLeft, + IconArrowRight, + IconCaretLeft, + IconCaretRight, +} from "~/components/Icons"; + +let variants = cva( + [ + "hidden md:block", + "absolute top-1/2 -translate-y-1/2 z-1", + "p-2 text-center cursor-pointer", + "border border-transparent", + "transition-all duration-200", + ], + { + variants: { + arrowsColor: { + light: "text-gray-900 bg-white hover:bg-gray-100", + dark: "text-gray-100 bg-gray-900 hover:bg-gray-800", + }, + arrowsShape: { + square: "", + rounded: "rounded-md", + circle: "rounded-full", + }, + disabled: { + true: "opacity-75 cursor-not-allowed", + false: "", + }, + showArrowsOnHover: { true: "", false: "" }, + side: { left: "", right: "" }, + }, + compoundVariants: [ + { + showArrowsOnHover: true, + side: "left", + className: "-left-12 group-hover:left-6", + }, + { + showArrowsOnHover: false, + side: "left", + className: "left-6", + }, + { + showArrowsOnHover: true, + side: "right", + className: "-right-12 group-hover:right-6", + }, + { + showArrowsOnHover: false, + side: "right", + className: "right-6", + }, + ], + }, +); + +export interface SlideshowArrowsProps extends VariantProps { + arrowsIcon: "caret" | "arrow"; + iconSize: number; + showArrowsOnHover: boolean; +} + +export function Arrows(props: SlideshowArrowsProps) { + let { arrowsIcon, iconSize, arrowsColor, showArrowsOnHover, arrowsShape } = + props; + let [canNext, setCanNext] = useState(true); + let [canPrev, setCanPrev] = useState(true); + let swiper = useSwiper(); + + if (!swiper.params.loop) { + swiper.on("init", ({ activeIndex, slides }) => { + setCanNext(activeIndex < slides.length - 1); + setCanPrev(activeIndex > 0); + }); + swiper.on("activeIndexChange", ({ activeIndex, slides }) => { + setCanNext(activeIndex < slides.length - 1); + setCanPrev(activeIndex > 0); + }); + } + + return ( + <> + + + + ); +} diff --git a/app/sections/slideshow/dots.tsx b/app/sections/slideshow/dots.tsx new file mode 100644 index 00000000..3b7056f2 --- /dev/null +++ b/app/sections/slideshow/dots.tsx @@ -0,0 +1,39 @@ +import type { VariantProps } from "class-variance-authority"; +import { cva } from "class-variance-authority"; +import clsx from "clsx"; + +export interface SlideshowDotsProps extends VariantProps { + className?: string; +} + +let variants = cva( + [ + "slideshow-dots", + "absolute z-1 flex justify-center items-center px-2.5 gap-4", + ], + { + variants: { + dotsPosition: { + top: "left-0 right-0 top-10", + bottom: "left-0 right-0 bottom-10", + left: "top-0 bottom-0 flex-col left-5", + right: "top-0 bottom-0 flex-col right-5", + }, + dotsColor: { + light: "[&_.dot]:bg-white [&_.active]:!outline-white", + dark: "[&_.dot]:bg-black [&_.active]:!outline-black", + }, + }, + defaultVariants: { + dotsPosition: "bottom", + dotsColor: "light", + }, + }, +); + +export function Dots(props: SlideshowDotsProps) { + let { className, dotsPosition, dotsColor } = props; + return ( +
+ ); +} diff --git a/app/sections/slideshow/index.tsx b/app/sections/slideshow/index.tsx index 68f2c6e4..8f7acab7 100644 --- a/app/sections/slideshow/index.tsx +++ b/app/sections/slideshow/index.tsx @@ -1,119 +1,358 @@ -import type { - HydrogenComponentProps, - HydrogenComponentSchema, +import { + IMAGES_PLACEHOLDERS, + type HydrogenComponentProps, + type HydrogenComponentSchema, } from "@weaverse/hydrogen"; +import type { VariantProps } from "class-variance-authority"; +import { cva } from "class-variance-authority"; import clsx from "clsx"; -import { useKeenSlider } from "keen-slider/react.es"; -import type { CSSProperties } from "react"; -import { forwardRef, useCallback, useEffect, useState } from "react"; +import { forwardRef } from "react"; +import { Autoplay, EffectFade, Navigation, Pagination } from "swiper/modules"; +import { Swiper, SwiperSlide } from "swiper/react"; +import type { SlideshowArrowsProps } from "./arrows"; +import { Arrows } from "./arrows"; +import type { SlideshowDotsProps } from "./dots"; +import { Dots } from "./dots"; -interface SlideShowProps extends HydrogenComponentProps { - sectionHeight: number; -} - -let SlideShow = forwardRef((props, ref) => { - let { sectionHeight, children, ...rest } = props; - const [activeIndex, setActiveIndex] = useState(0); - const [sliderRef, instanceRef] = useKeenSlider({ - loop: true, - slideChanged(slider) { - let pos = slider.track.details.rel; - setActiveIndex(pos); +let variants = cva("group", { + variants: { + height: { + small: "h-[40vh] lg:h-[50vh]", + medium: "h-[50vh] lg:h-[60vh]", + large: "h-[70vh] lg:h-[80vh]", + full: "h-screen-no-nav", }, - }); - - let moveToIdx = useCallback( - (idx: number) => { - setActiveIndex(idx); - if (instanceRef.current) { - instanceRef.current.moveToIdx(idx); - } - }, - [instanceRef], - ); - - let handleClickNavigation = (idx: number) => { - moveToIdx(idx); - }; - - let renderNavigation = () => { - if (children && children?.length > 1) { - return children?.map((child, index) => ( - handleClickNavigation(index)} - role="listitem" - /> - )); - } - return null; - }; + }, + defaultVariants: { + height: "large", + }, +}); - useEffect(() => { - if (instanceRef) { - instanceRef.current?.update(); - } - }, [children, instanceRef]); +export interface SlideshowProps + extends VariantProps, + SlideshowArrowsProps, + SlideshowDotsProps, + HydrogenComponentProps { + showArrows: boolean; + showDots: boolean; + dotsPosition: "top" | "bottom" | "left" | "right"; + dotsColor: "light" | "dark"; + loop: boolean; + autoRotate: boolean; + changeSlidesEvery: number; +} - let sectionStyle: CSSProperties = { - "--section-height": `${sectionHeight}px`, - } as CSSProperties; +let Slideshow = forwardRef((props, ref) => { + let { + height, + showArrows, + arrowsIcon, + iconSize, + showArrowsOnHover, + arrowsColor, + arrowsShape, + showDots = true, + dotsPosition, + dotsColor, + loop, + autoRotate, + changeSlidesEvery, + children = [], + ...rest + } = props; return ( -
-
- {children?.map((child, index) => ( -
- {child} -
+
+ + {children.map((child, idx) => ( + {child} ))} -
-
- {renderNavigation()} -
+ {showArrows && } + {showDots && } +
); }); -export default SlideShow; +export default Slideshow; export let schema: HydrogenComponentSchema = { - type: "slide-show", - title: "Slide show", - toolbar: ["general-settings", ["duplicate", "delete"]], + title: "Slideshow", + type: "slideshow", + childTypes: ["slideshow-slide"], inspector: [ { - group: "SLideshow", + group: "Slideshow", inputs: [ { - type: "range", - name: "sectionHeight", + type: "select", + name: "height", label: "Section height", - defaultValue: 500, configs: { - min: 400, - max: 700, - step: 10, - unit: "px", + options: [ + { value: "small", label: "Small" }, + { value: "medium", label: "Medium" }, + { value: "large", label: "Large" }, + { value: "full", label: "Fullscreen" }, + ], + }, + defaultValue: "large", + }, + { + type: "switch", + label: "Loop", + name: "loop", + defaultValue: true, + }, + { + type: "switch", + label: "Auto-rotate slides", + name: "autoRotate", + defaultValue: true, + }, + { + type: "range", + label: "Change slides every", + name: "changeSlidesEvery", + configs: { + min: 3, + max: 9, + step: 1, + unit: "s", }, + defaultValue: 5, + condition: "autoRotate.eq.true", + helpText: "Auto-rotate is disabled inside Weaverse Studio.", + }, + ], + }, + { + group: "Navigation & Controls", + inputs: [ + { + type: "heading", + label: "Arrows", + }, + { + type: "switch", + label: "Show arrows", + name: "showArrows", + defaultValue: false, + }, + { + type: "select", + label: "Arrow icon", + name: "arrowsIcon", + configs: { + options: [ + { value: "caret", label: "Caret" }, + { value: "arrow", label: "Arrow" }, + ], + }, + defaultValue: "arrow", + condition: "showArrows.eq.true", + }, + { + type: "range", + label: "Icon size", + name: "iconSize", + configs: { + min: 16, + max: 40, + step: 2, + }, + defaultValue: 20, + condition: "showArrows.eq.true", + }, + { + type: "switch", + label: "Show arrows on hover", + name: "showArrowsOnHover", + defaultValue: true, + condition: "showArrows.eq.true", + }, + { + type: "select", + label: "Arrows color", + name: "arrowsColor", + configs: { + options: [ + { value: "light", label: "Light" }, + { value: "dark", label: "Dark" }, + ], + }, + defaultValue: "light", + condition: "showArrows.eq.true", + }, + { + type: "toggle-group", + label: "Arrows shape", + name: "arrowsShape", + configs: { + options: [ + { value: "rounded", label: "Rounded", icon: "squircle" }, + { value: "circle", label: "Circle", icon: "circle" }, + { value: "square", label: "Square", icon: "square" }, + ], + }, + defaultValue: "rounded", + condition: "showArrows.eq.true", + }, + + { + type: "heading", + label: "Dots", + }, + { + type: "switch", + label: "Show dots", + name: "showDots", + defaultValue: true, + }, + { + type: "select", + label: "Dots position", + name: "dotsPosition", + configs: { + options: [ + { value: "top", label: "Top" }, + { value: "bottom", label: "Bottom" }, + { value: "left", label: "Left" }, + { value: "right", label: "Right" }, + ], + }, + defaultValue: "bottom", + condition: "showDots.eq.true", + }, + { + type: "select", + label: "Dots color", + name: "dotsColor", + configs: { + options: [ + { value: "light", label: "Light" }, + { value: "dark", label: "Dark" }, + ], + }, + defaultValue: "light", + condition: "showDots.eq.true", }, ], }, ], - childTypes: ["slide-show--item"], presets: { children: [ { - type: "slide-show--item", + type: "slideshow-slide", + verticalPadding: "large", + contentPosition: "center center", + backgroundImage: IMAGES_PLACEHOLDERS.banner_1, + backgroundFit: "cover", + enableOverlay: true, + overlayOpacity: 50, + children: [ + { + type: "subheading", + content: "Limited time offer", + color: "#fff", + }, + { + type: "heading", + content: "Spring / Summer 2024 Sale", + color: "#fff", + size: "scale", + minSize: 16, + maxSize: 56, + }, + { + type: "paragraph", + content: + "It's hard to be nice if you don't feel comfortable. All the ready-to-wear and accessories you need for your next summer vacation is now up to 50% off.", + color: "#fff", + }, + { + type: "button", + content: "Shop collection", + variant: "primary", + buttonStyle: "custom", + backgroundColor: "#00000000", + textColor: "#fff", + borderColor: "#fff", + backgroundColorHover: "#fff", + textColorHover: "#000", + borderColorHover: "#fff", + }, + ], + }, + { + type: "slideshow-slide", + verticalPadding: "large", + contentPosition: "bottom left", + backgroundImage: IMAGES_PLACEHOLDERS.banner_2, + backgroundFit: "cover", + enableOverlay: true, + overlayOpacity: 50, + children: [ + { + type: "subheading", + content: "Exclusive offer", + color: "#fff", + }, + { + type: "heading", + content: "Autumn / Winter 2024 Sale", + color: "#fff", + size: "scale", + minSize: 16, + maxSize: 56, + }, + { + type: "paragraph", + content: + "Stay warm and stylish with our winter collection. All the ready-to-wear and accessories you need for your next winter vacation is now up to 60% off.", + color: "#fff", + }, + { + type: "button", + content: "Shop collection", + buttonStyle: "custom", + backgroundColor: "#00000000", + textColor: "#fff", + borderColor: "#fff", + backgroundColorHover: "#fff", + textColorHover: "#000", + borderColorHover: "#fff", + }, + ], }, ], }, diff --git a/app/sections/slideshow/slide.tsx b/app/sections/slideshow/slide.tsx index 36ae1cdf..7a53cd53 100644 --- a/app/sections/slideshow/slide.tsx +++ b/app/sections/slideshow/slide.tsx @@ -1,145 +1,174 @@ -import type { - HydrogenComponentProps, - HydrogenComponentSchema, - WeaverseImage, +import { + IMAGES_PLACEHOLDERS, + type HydrogenComponentProps, + type HydrogenComponentSchema, } from "@weaverse/hydrogen"; -import type { CSSProperties } from "react"; +import type { VariantProps } from "class-variance-authority"; +import { cva } from "class-variance-authority"; import { forwardRef } from "react"; -import { Image } from "@shopify/hydrogen"; -import clsx from "clsx"; +import { backgroundInputs } from "~/components/BackgroundImage"; +import { overlayInputs } from "~/components/Overlay"; +import type { OverlayAndBackgroundProps } from "~/components/OverlayAndBackground"; +import { OverlayAndBackground } from "~/components/OverlayAndBackground"; +import { layoutInputs } from "~/components/Section"; -import { IconImageBlank } from "~/modules"; +let variants = cva("w-full h-full flex flex-col [&_.paragraph]:mx-[unset]", { + variants: { + width: { + full: "", + stretch: "px-3 md:px-10 lg:px-16", + fixed: "max-w-[var(--page-width,1280px)] mx-auto px-3 md:px-10 lg:px-16", + }, + verticalPadding: { + none: "", + small: "py-4 md:py-6 lg:py-8", + medium: "py-8 md:py-12 lg:py-16", + large: "py-12 md:py-24 lg:py-32", + }, + gap: { + 0: "", + 4: "space-y-1", + 8: "space-y-2", + 12: "space-y-3", + 16: "space-y-4", + 20: "space-y-5", + 24: "space-y-3 lg:space-y-6", + 28: "space-y-3.5 lg:space-y-7", + 32: "space-y-4 lg:space-y-8", + 36: "space-y-4 lg:space-y-9", + 40: "space-y-5 lg:space-y-10", + 44: "space-y-5 lg:space-y-11", + 48: "space-y-6 lg:space-y-12", + 52: "space-y-6 lg:space-y-[52px]", + 56: "space-y-7 lg:space-y-14", + 60: "space-y-7 lg:space-y-[60px]", + }, + contentPosition: { + "top left": "justify-start items-start [&_.paragraph]:[text-align:left]", + "top center": + "justify-start items-center [&_.paragraph]:[text-align:center]", + "top right": "justify-start items-end [&_.paragraph]:[text-align:right]", + "center left": + "justify-center items-start [&_.paragraph]:[text-align:left]", + "center center": + "justify-center items-center [&_.paragraph]:[text-align:center]", + "center right": + "justify-center items-end [&_.paragraph]:[text-align:right]", + "bottom left": "justify-end items-start [&_.paragraph]:[text-align:left]", + "bottom center": + "justify-end items-center [&_.paragraph]:[text-align:center]", + "bottom right": "justify-end items-end [&_.paragraph]:[text-align:right]", + }, + }, + defaultVariants: { + contentPosition: "bottom left", + }, +}); -interface CountDownProps extends HydrogenComponentProps { - backgroundImage: WeaverseImage; - overlayColor: string; - overlayOpacity: number; - contentPosition: string; +export interface SlideProps + extends VariantProps, + HydrogenComponentProps, + OverlayAndBackgroundProps { + backgroundColor: string; } -let SlideShowItem = forwardRef((props, ref) => { +let Slide = forwardRef((props, ref) => { let { + contentPosition, + width, + gap, + verticalPadding, + backgroundColor, backgroundImage, - overlayColor, + enableOverlay, overlayOpacity, - contentPosition, + overlayColor, + backgroundFit, + backgroundPosition, children, ...rest } = props; - let positionClass: { [key: string]: string } = { - "top left": "items-start justify-start", - "top right": "items-start justify-end", - "top center": "items-start justify-center", - "center left": "items-center justify-start", - "center center": "items-center justify-center", - "center right": "items-center justify-end", - "bottom left": "items-end justify-start", - "bottom center": "items-end justify-center", - "bottom right": "items-end justify-end", - }; - - let slideStyle: CSSProperties = { - "--overlay-color": overlayColor, - "--overlay-opacity": `${overlayOpacity}%`, - } as CSSProperties; - return ( -
-
- {backgroundImage ? ( - - ) : ( -
- -
- )} - {backgroundImage && ( -
- )} -
-
+
+ +
{children}
); }); -export default SlideShowItem; +export default Slide; export let schema: HydrogenComponentSchema = { - type: "slide-show--item", title: "Slide", - toolbar: ["general-settings", ["duplicate", "delete"]], + type: "slideshow-slide", + childTypes: ["subheading", "heading", "paragraph", "button"], inspector: [ { group: "Slide", inputs: [ - { - type: "image", - name: "backgroundImage", - label: "Background image", - }, { type: "position", - name: "contentPosition", label: "Content position", + name: "contentPosition", defaultValue: "center center", }, - { - type: "color", - name: "overlayColor", - label: "Overlay color", - }, - { - type: "range", - name: "overlayOpacity", - label: "Overlay opacity", - defaultValue: 50, - configs: { - min: 10, - max: 100, - step: 10, - unit: "%", - }, - }, + ...layoutInputs.filter( + (inp) => inp.name !== "divider" && inp.name !== "borderRadius", + ), ], }, + { + group: "Background", + inputs: backgroundInputs.filter((inp) => + ["backgroundImage", "backgroundFit", "backgroundPosition"].includes( + inp.name, + ), + ), + }, + { group: "Overlay", inputs: overlayInputs }, ], - childTypes: ["subheading", "heading", "paragraph", "button"], presets: { + verticalPadding: "large", + contentPosition: "bottom left", + backgroundImage: IMAGES_PLACEHOLDERS.banner_1, + backgroundFit: "cover", + enableOverlay: true, + overlayOpacity: 50, children: [ { type: "subheading", content: "Subheading", + color: "#fff", }, { type: "heading", - content: "Slide Heading", + content: "Slide with text overlay", + color: "#fff", + size: "scale", + minSize: 16, + maxSize: 56, }, { type: "paragraph", content: - "Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown.", + "Use this text to share information about your brand with your customers. Describe a product, share announcements, or welcome customers to your store.", + color: "#fff", }, { type: "button", - content: "Button section", + content: "Shop all", + buttonStyle: "custom", + backgroundColor: "#00000000", + textColor: "#fff", + borderColor: "#fff", + backgroundColorHover: "#fff", + textColorHover: "#000", + borderColorHover: "#fff", }, ], }, diff --git a/app/sections/user-profiles/index.tsx b/app/sections/user-profiles/index.tsx index 513e84e0..b7d98df9 100644 --- a/app/sections/user-profiles/index.tsx +++ b/app/sections/user-profiles/index.tsx @@ -55,11 +55,13 @@ interface UserProfilesProps extends HydrogenComponentProps { type: string; }; itemsPerRow: number; + gap: number; } const UserProfiles = forwardRef( (props, ref) => { - let { loaderData, metaObjectData, itemsPerRow, className, ...rest } = props; + let { loaderData, metaObjectData, itemsPerRow, gap, className, ...rest } = + props; if (!metaObjectData) { return (
( ); } return ( -
+
{loaderData?.userProfiles.map((user: any) => { @@ -108,7 +106,6 @@ export let schema: HydrogenComponentSchema = { label: "Select metaobject definition", type: "metaobject", name: "metaObjectData", - shouldRevalidate: true, }, { label: "Items per row", @@ -120,6 +117,17 @@ export let schema: HydrogenComponentSchema = { }, defaultValue: 3, }, + { + label: "Gap between items", + name: "gap", + type: "range", + configs: { + min: 0, + step: 2, + max: 100, + }, + defaultValue: 4, + }, ], }, ], diff --git a/app/styles/app.css b/app/styles/app.css index 6c430a06..bed1f4af 100644 --- a/app/styles/app.css +++ b/app/styles/app.css @@ -1,4 +1,8 @@ @import "keen-slider/keen-slider.min.css"; +@import "swiper/css"; +@import "swiper/css/navigation"; +@import "swiper/css/effect-fade"; + @tailwind base; @tailwind components; @tailwind utilities; diff --git a/app/weaverse/components.ts b/app/weaverse/components.ts index 1b6c2349..9d97c316 100644 --- a/app/weaverse/components.ts +++ b/app/weaverse/components.ts @@ -1,7 +1,7 @@ import type { HydrogenComponent } from "@weaverse/hydrogen"; import { sharedComponents } from "~/components"; import * as Judgeme from "~/modules/product-form/judgeme-review"; -import * as SlideShowItem from "~/sections/slideshow/slide"; +import * as SlideShowSlide from "~/sections/slideshow/slide"; import * as SlideShow from "~/sections/slideshow"; import * as AliReview from "~/sections/ali-reviews"; import * as AliReviewList from "~/sections/ali-reviews/review-list"; @@ -98,7 +98,7 @@ export let components: HydrogenComponent[] = [ Judgeme, MetaDemo, SlideShow, - SlideShowItem, + SlideShowSlide, ProductList, ContactForm, Spacer, diff --git a/package-lock.json b/package-lock.json index 0f5d8011..ccb68643 100644 --- a/package-lock.json +++ b/package-lock.json @@ -18,7 +18,7 @@ "@shopify/cli-hydrogen": "^8.1.1", "@shopify/hydrogen": "^2024.4.7", "@shopify/remix-oxygen": "^2.0.4", - "@weaverse/hydrogen": "3.1.14", + "@weaverse/hydrogen": "3.1.16", "class-variance-authority": "0.7.0", "clsx": "2.1.1", "cross-env": "7.0.3", @@ -34,6 +34,7 @@ "react-player": "2.16.0", "react-use": "17.5.0", "schema-dts": "1.1.2", + "swiper": "^11.1.4", "tailwind-merge": "2.3.0", "tiny-invariant": "1.3.3", "typographic-base": "1.0.4" @@ -3298,7 +3299,6 @@ "version": "1.12.1", "resolved": "https://registry.npmjs.org/@google/model-viewer/-/model-viewer-1.12.1.tgz", "integrity": "sha512-GOf/By81rbxSmwWRVxBtlY5b3050msJ+BDWqonPj7M0/I7rNS/vVNjbLxTofbGjZObS3n0ELHj8TZ47UtkZbtg==", - "license": "Apache-2.0", "dependencies": { "lit": "^2.2.3", "three": "^0.139.2" @@ -4493,14 +4493,12 @@ "node_modules/@lit-labs/ssr-dom-shim": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/@lit-labs/ssr-dom-shim/-/ssr-dom-shim-1.2.0.tgz", - "integrity": "sha512-yWJKmpGE6lUURKAaIltoPIE/wrbY3TEkqQt+X0m+7fQNnAv0keydnYvbiJFP1PnMhizmIWRWOG5KLhYyc/xl+g==", - "license": "BSD-3-Clause" + "integrity": "sha512-yWJKmpGE6lUURKAaIltoPIE/wrbY3TEkqQt+X0m+7fQNnAv0keydnYvbiJFP1PnMhizmIWRWOG5KLhYyc/xl+g==" }, "node_modules/@lit/reactive-element": { "version": "1.6.3", "resolved": "https://registry.npmjs.org/@lit/reactive-element/-/reactive-element-1.6.3.tgz", "integrity": "sha512-QuTgnG52Poic7uM1AN5yJ09QMe0O28e10XzSvWDz02TJiiKee4stsiownEIadWm8nYzyDAyT+gKzUoZmiWQtsQ==", - "license": "BSD-3-Clause", "dependencies": { "@lit-labs/ssr-dom-shim": "^1.0.0" } @@ -4850,6 +4848,7 @@ "jackspeak": "^3.1.2", "minimatch": "^9.0.4", "minipass": "^7.1.2", + "package-json-from-dist": "^1.0.0", "path-scurry": "^1.11.1" }, "bin": { @@ -4903,14 +4902,14 @@ "cli-progress": "^3.12.0", "color": "^4.2.3", "debug": "^4.3.4", - "ejs": "^3.1.10", + "ejs": "^3.1.9", "get-package-type": "^0.1.0", "globby": "^11.1.0", "hyperlinker": "^1.0.0", "indent-string": "^4.0.0", "is-wsl": "^2.2.0", "js-yaml": "^3.14.1", - "minimatch": "^9.0.4", + "minimatch": "^9.0.3", "natural-orderby": "^2.0.3", "object-treeify": "^1.1.33", "password-prompt": "^1.1.3", @@ -6191,9 +6190,9 @@ } }, "node_modules/@remix-run/dev/node_modules/ws": { - "version": "7.5.9", - "resolved": "https://registry.npmjs.org/ws/-/ws-7.5.9.tgz", - "integrity": "sha512-F+P9Jil7UiSKSkppIiD94dN07AwvFixvLIj1Og1Rl9GGMuNipJnV9JzjD6XuqmAeiswGvUmNLjr5cFuXwNS77Q==", + "version": "7.5.10", + "resolved": "https://registry.npmjs.org/ws/-/ws-7.5.10.tgz", + "integrity": "sha512-+dbF1tHwZpXcbOJdVOkzLDxZP1ailvSxM6ZweXTegylPny803bFhA+vqBYw4s31NSAk4S2Qz+AKXK9a4wkdjcQ==", "devOptional": true, "license": "MIT", "engines": { @@ -6787,7 +6786,7 @@ "dependencies": { "@bugsnag/js": "7.21.0", "@iarna/toml": "2.2.5", - "@oclif/core": "3.26.5", + "@oclif/core": "3.23.0", "@opentelemetry/api": "1.6.0", "@opentelemetry/core": "1.17.1", "@opentelemetry/exporter-metrics-otlp-http": "0.43.0", @@ -6846,6 +6845,151 @@ "node": ">=18.12.0" } }, + "node_modules/@shopify/cli-kit/node_modules/@oclif/core": { + "version": "3.23.0", + "resolved": "https://registry.npmjs.org/@oclif/core/-/core-3.23.0.tgz", + "integrity": "sha512-giQ/8Ft8yXWg4IyPVtynPb7ihoQsa3A/1Q53UIJIhh+8k+EedE3lJ01yn6sq6Ha35IGqsG1WhkeHzlJIuldEaw==", + "dependencies": { + "@types/cli-progress": "^3.11.5", + "ansi-escapes": "^4.3.2", + "ansi-styles": "^4.3.0", + "cardinal": "^2.1.1", + "chalk": "^4.1.2", + "clean-stack": "^3.0.1", + "cli-progress": "^3.12.0", + "color": "^4.2.3", + "debug": "^4.3.4", + "ejs": "^3.1.9", + "get-package-type": "^0.1.0", + "globby": "^11.1.0", + "hyperlinker": "^1.0.0", + "indent-string": "^4.0.0", + "is-wsl": "^2.2.0", + "js-yaml": "^3.14.1", + "minimatch": "^9.0.3", + "natural-orderby": "^2.0.3", + "object-treeify": "^1.1.33", + "password-prompt": "^1.1.3", + "slice-ansi": "^4.0.0", + "string-width": "^4.2.3", + "strip-ansi": "^6.0.1", + "supports-color": "^8.1.1", + "supports-hyperlinks": "^2.2.0", + "widest-line": "^3.1.0", + "wordwrap": "^1.0.0", + "wrap-ansi": "^7.0.0" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@shopify/cli-kit/node_modules/@oclif/core/node_modules/ansi-escapes": { + "version": "4.3.2", + "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.2.tgz", + "integrity": "sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ==", + "dependencies": { + "type-fest": "^0.21.3" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@shopify/cli-kit/node_modules/@oclif/core/node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "engines": { + "node": ">=8" + } + }, + "node_modules/@shopify/cli-kit/node_modules/@oclif/core/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/@shopify/cli-kit/node_modules/@oclif/core/node_modules/chalk/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/@shopify/cli-kit/node_modules/@oclif/core/node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/@shopify/cli-kit/node_modules/@oclif/core/node_modules/supports-color": { + "version": "8.1.1", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", + "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/supports-color?sponsor=1" + } + }, + "node_modules/@shopify/cli-kit/node_modules/@oclif/core/node_modules/supports-hyperlinks": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/supports-hyperlinks/-/supports-hyperlinks-2.3.0.tgz", + "integrity": "sha512-RpsAZlpWcDwOPQA22aCH4J0t7L8JmAvsCxfOSEwm7cQs3LshN36QaTkwd70DnBOXDWGssw2eUoc8CaRWT0XunA==", + "dependencies": { + "has-flag": "^4.0.0", + "supports-color": "^7.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/@shopify/cli-kit/node_modules/@oclif/core/node_modules/supports-hyperlinks/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/@shopify/cli-kit/node_modules/@oclif/core/node_modules/type-fest": { + "version": "0.21.3", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.21.3.tgz", + "integrity": "sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/@shopify/cli-kit/node_modules/ansi-escapes": { "version": "6.2.0", "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-6.2.0.tgz", @@ -6873,6 +7017,14 @@ "url": "https://github.com/chalk/ansi-regex?sponsor=1" } }, + "node_modules/@shopify/cli-kit/node_modules/argparse": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", + "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", + "dependencies": { + "sprintf-js": "~1.0.2" + } + }, "node_modules/@shopify/cli-kit/node_modules/chalk": { "version": "5.3.0", "resolved": "https://registry.npmjs.org/chalk/-/chalk-5.3.0.tgz", @@ -7002,6 +7154,18 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/@shopify/cli-kit/node_modules/js-yaml": { + "version": "3.14.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz", + "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==", + "dependencies": { + "argparse": "^1.0.7", + "esprima": "^4.0.0" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, "node_modules/@shopify/cli-kit/node_modules/lru-cache": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", @@ -7793,8 +7957,7 @@ "node_modules/@stitches/core": { "version": "1.2.8", "resolved": "https://registry.npmjs.org/@stitches/core/-/core-1.2.8.tgz", - "integrity": "sha512-Gfkvwk9o9kE9r9XNBmJRfV8zONvXThnm1tcuojL04Uy5uRyqg93DC83lDebl0rocZCfKSjUv+fWYtMQmEDJldg==", - "license": "MIT" + "integrity": "sha512-Gfkvwk9o9kE9r9XNBmJRfV8zONvXThnm1tcuojL04Uy5uRyqg93DC83lDebl0rocZCfKSjUv+fWYtMQmEDJldg==" }, "node_modules/@swc/helpers": { "version": "0.5.11", @@ -8176,8 +8339,7 @@ "node_modules/@types/trusted-types": { "version": "2.0.7", "resolved": "https://registry.npmjs.org/@types/trusted-types/-/trusted-types-2.0.7.tgz", - "integrity": "sha512-ScaPdn1dQczgbl0QFTeTOmVHFULt394XJgOQNoyVhZ6r2vLnMLJfBPd53SB52T/3G36VI1/g2MZaX0cwDuXsfw==", - "license": "MIT" + "integrity": "sha512-ScaPdn1dQczgbl0QFTeTOmVHFULt394XJgOQNoyVhZ6r2vLnMLJfBPd53SB52T/3G36VI1/g2MZaX0cwDuXsfw==" }, "node_modules/@types/unist": { "version": "2.0.10", @@ -8461,9 +8623,9 @@ } }, "node_modules/@vanilla-extract/css": { - "version": "1.15.2", - "resolved": "https://registry.npmjs.org/@vanilla-extract/css/-/css-1.15.2.tgz", - "integrity": "sha512-Bi61iCAtojCuqvV+FYaF5i69vBjuMQJpHPdpgKYyQvx+e2Hp79V0ELglyYOdcyg9Wh0k0MFwgCDipVd7EloTXQ==", + "version": "1.15.3", + "resolved": "https://registry.npmjs.org/@vanilla-extract/css/-/css-1.15.3.tgz", + "integrity": "sha512-mxoskDAxdQAspbkmQRxBvolUi1u1jnyy9WZGm+GeH8V2wwhEvndzl1QoK7w8JfA0WFevTxbev5d+i+xACZlPhA==", "devOptional": true, "license": "MIT", "dependencies": { @@ -8569,10 +8731,9 @@ "license": "MIT" }, "node_modules/@weaverse/core": { - "version": "3.1.14", - "resolved": "https://registry.npmjs.org/@weaverse/core/-/core-3.1.14.tgz", - "integrity": "sha512-G+MnfDouT8Q/6CMPJmZ3KacrpHarF3FS0QKLFkq5X0jKPFw8s2SHLvA6ZDCB6nN4GuNOgMvjST8vJMZfReYf0g==", - "license": "MIT", + "version": "3.1.16", + "resolved": "https://registry.npmjs.org/@weaverse/core/-/core-3.1.16.tgz", + "integrity": "sha512-bvkSdO+hnBQWkJADAauCIOU2lBArDE94HKlY7zKsGjy+fk+TevlK9dW6JkVMgnzPzcMnm5mgVyu6MJ0fraCeFw==", "dependencies": { "@stitches/core": "^1.2.8" }, @@ -8581,12 +8742,11 @@ } }, "node_modules/@weaverse/hydrogen": { - "version": "3.1.14", - "resolved": "https://registry.npmjs.org/@weaverse/hydrogen/-/hydrogen-3.1.14.tgz", - "integrity": "sha512-bMISL+/D0qkCVCfDNPQG3Vz7ThzkXE9xUd8ChtBLlO7A06fN6rkunAEu1ekrGop1t5mU6tFMycovovhU4yTbhA==", - "license": "MIT", + "version": "3.1.16", + "resolved": "https://registry.npmjs.org/@weaverse/hydrogen/-/hydrogen-3.1.16.tgz", + "integrity": "sha512-+IPEZRS3kIuFeeOeuDALJ3aPdbciqqJWMnZFkF2kmPFwUZpmyUdmnilWTkICVGQGz7psHpG+KFAoHzfbLvxOJw==", "dependencies": { - "@weaverse/react": "3.1.14", + "@weaverse/react": "3.1.16", "react-error-boundary": "^4.0.13" }, "engines": { @@ -8600,12 +8760,11 @@ } }, "node_modules/@weaverse/react": { - "version": "3.1.14", - "resolved": "https://registry.npmjs.org/@weaverse/react/-/react-3.1.14.tgz", - "integrity": "sha512-uHiHXx9w4QTDDs+kJxYQjjVyfMrLbJRc0e2/EJoF1ZtrY05xdDVfv6Vr0x2j91ZslCb+teYOxKlcU/b+qXU0sg==", - "license": "MIT", + "version": "3.1.16", + "resolved": "https://registry.npmjs.org/@weaverse/react/-/react-3.1.16.tgz", + "integrity": "sha512-GyRWX2/CHpuFF9jliY+3AX8Ju5EuRjzlheSZOpo22frH+6cTqtyt8LHRkvnfkPwI8YAaKEddaQTr5R6LrmQ+ew==", "dependencies": { - "@weaverse/core": "3.1.14", + "@weaverse/core": "3.1.16", "clsx": "^2.1.1" }, "engines": { @@ -8669,14 +8828,12 @@ "node_modules/@xstate/fsm": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/@xstate/fsm/-/fsm-2.1.0.tgz", - "integrity": "sha512-oJlc0iD0qZvAM7If/KlyJyqUt7wVI8ocpsnlWzAPl97evguPbd+oJbRM9R4A1vYJffYH96+Bx44nLDE6qS8jQg==", - "license": "MIT" + "integrity": "sha512-oJlc0iD0qZvAM7If/KlyJyqUt7wVI8ocpsnlWzAPl97evguPbd+oJbRM9R4A1vYJffYH96+Bx44nLDE6qS8jQg==" }, "node_modules/@xstate/react": { "version": "3.2.2", "resolved": "https://registry.npmjs.org/@xstate/react/-/react-3.2.2.tgz", "integrity": "sha512-feghXWLedyq8JeL13yda3XnHPZKwYDN5HPBLykpLeuNpr9178tQd2/3d0NrH6gSd0sG5mLuLeuD+ck830fgzLQ==", - "license": "MIT", "dependencies": { "use-isomorphic-layout-effect": "^1.1.2", "use-sync-external-store": "^1.0.0" @@ -8731,9 +8888,9 @@ } }, "node_modules/acorn": { - "version": "8.11.3", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.11.3.tgz", - "integrity": "sha512-Y9rRfJG5jcKOE0CLisYbojUjIrIEE7AGMzA/Sm4BslANhbS+cDMpgBdcPT91oJ7OuJ9hYJBx59RjbhxVnrF8Xg==", + "version": "8.12.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.12.0.tgz", + "integrity": "sha512-RTvkC4w+KNXrM39/lWCUaG0IbRkWdCv7W/IOW9oU6SawyxulvkQy5HQPVTKxEjczcUvapcrw3cFx/60VN/NRNw==", "devOptional": true, "license": "MIT", "bin": { @@ -8754,9 +8911,9 @@ } }, "node_modules/acorn-walk": { - "version": "8.3.2", - "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.3.2.tgz", - "integrity": "sha512-cjkyv4OtNCIeqhHrfS81QWXoCBPExR/J62oyEqepVw8WaQeSqpW2uhuLPh1m9eWhDuOo/jUXVTlifvesOWp/4A==", + "version": "8.3.3", + "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.3.3.tgz", + "integrity": "sha512-MxXdReSRhGO7VlFe1bRG/oI7/mdLV9B9JJT0N8vZOhF7gFRR5l3M8W9G8JxmKV+JC5mGqJ0QvqfSOLsCPa4nUw==", "devOptional": true, "license": "MIT", "engines": { @@ -9321,9 +9478,9 @@ } }, "node_modules/axe-core": { - "version": "4.7.0", - "resolved": "https://registry.npmjs.org/axe-core/-/axe-core-4.7.0.tgz", - "integrity": "sha512-M0JtH+hlOL5pLQwHOLNYZaXuhqmvS8oExsqB1SBYgA4Dk7u/xx+YdGHXaK5pyUfed5mYXdlYiphWq3G8cRi5JQ==", + "version": "4.9.1", + "resolved": "https://registry.npmjs.org/axe-core/-/axe-core-4.9.1.tgz", + "integrity": "sha512-QbUdXJVTpvUTHU7871ppZkdOLBeGUKBQWHkHrvN2V9IQWGMt61zf3B45BtzjxEJzYuj0JBjBZP/hmYS/R9pmAw==", "dev": true, "license": "MPL-2.0", "engines": { @@ -9331,13 +9488,13 @@ } }, "node_modules/axobject-query": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/axobject-query/-/axobject-query-3.2.1.tgz", - "integrity": "sha512-jsyHu61e6N4Vbz/v18DHwWYKK0bSWLqn47eeDSKPB7m8tqMHF9YJ+mhIk2lVteyZrY8tnSj/jHOv4YiTCuCJgg==", + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/axobject-query/-/axobject-query-3.1.1.tgz", + "integrity": "sha512-goKlv8DZrK9hUh975fnHzhNIO4jUnFCfv/dszV5VwUGDFjI6vQ2VwoyjYjYNEbBE8AH87TduWP5uyDR1D+Iteg==", "dev": true, "license": "Apache-2.0", "dependencies": { - "dequal": "^2.0.3" + "deep-equal": "^2.0.5" } }, "node_modules/babel-plugin-syntax-trailing-function-commas": { @@ -9701,6 +9858,7 @@ "jackspeak": "^3.1.2", "minimatch": "^9.0.4", "minipass": "^7.1.2", + "package-json-from-dist": "^1.0.0", "path-scurry": "^1.11.1" }, "bin": { @@ -12242,28 +12400,28 @@ } }, "node_modules/eslint-plugin-jsx-a11y": { - "version": "6.8.0", - "resolved": "https://registry.npmjs.org/eslint-plugin-jsx-a11y/-/eslint-plugin-jsx-a11y-6.8.0.tgz", - "integrity": "sha512-Hdh937BS3KdwwbBaKd5+PLCOmYY6U4f2h9Z2ktwtNKvIdIEu137rjYbcb9ApSbVJfWxANNuiKTD/9tOKjK9qOA==", + "version": "6.9.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-jsx-a11y/-/eslint-plugin-jsx-a11y-6.9.0.tgz", + "integrity": "sha512-nOFOCaJG2pYqORjK19lqPqxMO/JpvdCZdPtNdxY3kvom3jTvkAbOvQvD8wuD0G8BYR0IGAGYDlzqWJOh/ybn2g==", "dev": true, "license": "MIT", "dependencies": { - "@babel/runtime": "^7.23.2", - "aria-query": "^5.3.0", - "array-includes": "^3.1.7", + "aria-query": "~5.1.3", + "array-includes": "^3.1.8", "array.prototype.flatmap": "^1.3.2", "ast-types-flow": "^0.0.8", - "axe-core": "=4.7.0", - "axobject-query": "^3.2.1", + "axe-core": "^4.9.1", + "axobject-query": "~3.1.1", "damerau-levenshtein": "^1.0.8", "emoji-regex": "^9.2.2", - "es-iterator-helpers": "^1.0.15", - "hasown": "^2.0.0", + "es-iterator-helpers": "^1.0.19", + "hasown": "^2.0.2", "jsx-ast-utils": "^3.3.5", "language-tags": "^1.0.9", "minimatch": "^3.1.2", - "object.entries": "^1.1.7", - "object.fromentries": "^2.0.7" + "object.fromentries": "^2.0.8", + "safe-regex-test": "^1.0.3", + "string.prototype.includes": "^2.0.0" }, "engines": { "node": ">=4.0" @@ -12352,9 +12510,9 @@ } }, "node_modules/eslint-plugin-react": { - "version": "7.34.2", - "resolved": "https://registry.npmjs.org/eslint-plugin-react/-/eslint-plugin-react-7.34.2.tgz", - "integrity": "sha512-2HCmrU+/JNigDN6tg55cRDKCQWicYAPB38JGSFDQt95jDm8rrvSUo7YPkOIm5l6ts1j1zCvysNcasvfTMQzUOw==", + "version": "7.34.3", + "resolved": "https://registry.npmjs.org/eslint-plugin-react/-/eslint-plugin-react-7.34.3.tgz", + "integrity": "sha512-aoW4MV891jkUulwDApQbPYTVZmeuSyFrudpbTAQuj5Fv8VL+o6df2xIGpw8B0hPjAaih1/Fb0om9grCdyFYemA==", "dev": true, "license": "MIT", "dependencies": { @@ -12362,7 +12520,7 @@ "array.prototype.findlast": "^1.2.5", "array.prototype.flatmap": "^1.3.2", "array.prototype.toreversed": "^1.1.2", - "array.prototype.tosorted": "^1.1.3", + "array.prototype.tosorted": "^1.1.4", "doctrine": "^2.1.0", "es-iterator-helpers": "^1.0.19", "estraverse": "^5.3.0", @@ -15094,7 +15252,10 @@ "devOptional": true, "license": "MIT", "dependencies": { - "hasown": "^2.0.0" + "hasown": "^2.0.2" + }, + "engines": { + "node": ">= 0.4" }, "funding": { "url": "https://github.com/sponsors/ljharb" @@ -15586,7 +15747,6 @@ "version": "5.1.9", "resolved": "https://registry.npmjs.org/isbot/-/isbot-5.1.9.tgz", "integrity": "sha512-NITFjA2Jpcv1qWCpzqZQoW/66H3xXbF+n4yJIXr/gIn/wgaSKOPXTTczswiKMYx+BVymG9lm30ZGPtFWqAD4hA==", - "license": "Unlicense", "engines": { "node": ">=18" } @@ -16090,7 +16250,6 @@ "version": "2.8.0", "resolved": "https://registry.npmjs.org/lit/-/lit-2.8.0.tgz", "integrity": "sha512-4Sc3OFX9QHOJaHbmTMk28SYgVxLN3ePDjg7hofEft2zWlehFL3LiAuapWc4U/kYwMYJSh2hTCPZ6/LIC7ii0MA==", - "license": "BSD-3-Clause", "dependencies": { "@lit/reactive-element": "^1.6.0", "lit-element": "^3.3.0", @@ -16101,7 +16260,6 @@ "version": "3.3.3", "resolved": "https://registry.npmjs.org/lit-element/-/lit-element-3.3.3.tgz", "integrity": "sha512-XbeRxmTHubXENkV4h8RIPyr8lXc+Ff28rkcQzw3G6up2xg5E8Zu1IgOWIwBLEQsu3cOVFqdYwiVi0hv0SlpqUA==", - "license": "BSD-3-Clause", "dependencies": { "@lit-labs/ssr-dom-shim": "^1.1.0", "@lit/reactive-element": "^1.3.0", @@ -16112,7 +16270,6 @@ "version": "2.8.0", "resolved": "https://registry.npmjs.org/lit-html/-/lit-html-2.8.0.tgz", "integrity": "sha512-o9t+MQM3P4y7M7yNzqAyjp7z+mQGa4NS4CxiyLqFPyFWyc4O+nodLrkrxSaCTrla6M5YOLaT3RpbbqjszB5g3Q==", - "license": "BSD-3-Clause", "dependencies": { "@types/trusted-types": "^2.0.2" } @@ -18260,9 +18417,9 @@ } }, "node_modules/object-inspect": { - "version": "1.13.1", - "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.1.tgz", - "integrity": "sha512-5qoj1RUiKOMsCCNLV1CBiPYE10sziTsnmNxkAI/rZhiD63CF7IqdFGC/XzjWjpSgLf0LxXX3bDFIh0E18f6UhQ==", + "version": "1.13.2", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.2.tgz", + "integrity": "sha512-IRZSRuzJiynemAXPYtPe5BoI/RESNYR7TYm50MC5Mqbd3Jmw5y790sErYw3V6SryFJD64b74qQQs9wn5Bg/k3g==", "devOptional": true, "license": "MIT", "funding": { @@ -18692,6 +18849,12 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/package-json-from-dist": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/package-json-from-dist/-/package-json-from-dist-1.0.0.tgz", + "integrity": "sha512-dATvCeZN/8wQsGywez1mzHtTlP22H8OEfPrVMLNr4/eGa+ijtLn/6M5f0dY8UKNrC2O9UCU6SSoG3qRKnt7STw==", + "devOptional": true + }, "node_modules/package-json/node_modules/semver": { "version": "7.6.2", "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.2.tgz", @@ -21014,7 +21177,6 @@ "version": "2.0.2", "resolved": "https://registry.npmjs.org/regexparam/-/regexparam-2.0.2.tgz", "integrity": "sha512-A1PeDEYMrkLrfyOwv2jwihXbo9qxdGD3atBYQA9JJgreAx8/7rC6IUkWOw2NQlOxLp2wL0ifQbh1HuidDfYA6w==", - "license": "MIT", "engines": { "node": ">=8" } @@ -21362,9 +21524,9 @@ } }, "node_modules/rimraf/node_modules/glob": { - "version": "10.4.1", - "resolved": "https://registry.npmjs.org/glob/-/glob-10.4.1.tgz", - "integrity": "sha512-2jelhlq3E4ho74ZyVLN03oKdAZVUa6UDZzFLVH1H7dnoax+y9qyaq8zBkfDIggjniU19z0wU18y16jMB2eyVIw==", + "version": "10.4.2", + "resolved": "https://registry.npmjs.org/glob/-/glob-10.4.2.tgz", + "integrity": "sha512-GwMlUF6PkPo3Gk21UxkCohOv0PLcIXVtKyLlpEI28R/cO/4eNOdmLk3CMW1wROV/WR/EsZOWAfBbBOqYvs88/w==", "dev": true, "license": "ISC", "dependencies": { @@ -21372,6 +21534,7 @@ "jackspeak": "^3.1.2", "minimatch": "^9.0.4", "minipass": "^7.1.2", + "package-json-from-dist": "^1.0.0", "path-scurry": "^1.11.1" }, "bin": { @@ -22209,6 +22372,16 @@ "node": ">=8" } }, + "node_modules/string.prototype.includes": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/string.prototype.includes/-/string.prototype.includes-2.0.0.tgz", + "integrity": "sha512-E34CkBgyeqNDcrbU76cDjL5JLcVrtSdYq0MEh/B10r17pRP4ciHLwTgnuLV8Ay6cgEMLkcBkFCKyFZ43YldYzg==", + "dev": true, + "dependencies": { + "define-properties": "^1.1.3", + "es-abstract": "^1.17.5" + } + }, "node_modules/string.prototype.matchall": { "version": "4.0.11", "resolved": "https://registry.npmjs.org/string.prototype.matchall/-/string.prototype.matchall-4.0.11.tgz", @@ -22426,9 +22599,9 @@ } }, "node_modules/sucrase/node_modules/glob": { - "version": "10.4.1", - "resolved": "https://registry.npmjs.org/glob/-/glob-10.4.1.tgz", - "integrity": "sha512-2jelhlq3E4ho74ZyVLN03oKdAZVUa6UDZzFLVH1H7dnoax+y9qyaq8zBkfDIggjniU19z0wU18y16jMB2eyVIw==", + "version": "10.4.2", + "resolved": "https://registry.npmjs.org/glob/-/glob-10.4.2.tgz", + "integrity": "sha512-GwMlUF6PkPo3Gk21UxkCohOv0PLcIXVtKyLlpEI28R/cO/4eNOdmLk3CMW1wROV/WR/EsZOWAfBbBOqYvs88/w==", "dev": true, "license": "ISC", "dependencies": { @@ -22436,6 +22609,7 @@ "jackspeak": "^3.1.2", "minimatch": "^9.0.4", "minipass": "^7.1.2", + "package-json-from-dist": "^1.0.0", "path-scurry": "^1.11.1" }, "bin": { @@ -22510,6 +22684,24 @@ "tslib": "^2.0.3" } }, + "node_modules/swiper": { + "version": "11.1.4", + "resolved": "https://registry.npmjs.org/swiper/-/swiper-11.1.4.tgz", + "integrity": "sha512-1n7kbYJB2dFEpUHRFszq7gys/ofIBrMNibwTiMvPHwneKND/t9kImnHt6CfGPScMHgI+dWMbGTycCKGMoOO1KA==", + "funding": [ + { + "type": "patreon", + "url": "https://www.patreon.com/swiperjs" + }, + { + "type": "open_collective", + "url": "http://opencollective.com/swiper" + } + ], + "engines": { + "node": ">= 4.7.0" + } + }, "node_modules/tabbable": { "version": "6.2.0", "resolved": "https://registry.npmjs.org/tabbable/-/tabbable-6.2.0.tgz", @@ -22860,8 +23052,7 @@ "node_modules/three": { "version": "0.139.2", "resolved": "https://registry.npmjs.org/three/-/three-0.139.2.tgz", - "integrity": "sha512-gV7q7QY8rogu7HLFZR9cWnOQAUedUhu2WXAnpr2kdXZP9YDKsG/0ychwQvWkZN5PlNw9mv5MoCTin6zNTXoONg==", - "license": "MIT" + "integrity": "sha512-gV7q7QY8rogu7HLFZR9cWnOQAUedUhu2WXAnpr2kdXZP9YDKsG/0ychwQvWkZN5PlNw9mv5MoCTin6zNTXoONg==" }, "node_modules/throttle-debounce": { "version": "3.0.1", @@ -23509,9 +23700,9 @@ } }, "node_modules/undici": { - "version": "6.18.2", - "resolved": "https://registry.npmjs.org/undici/-/undici-6.18.2.tgz", - "integrity": "sha512-o/MQLTwRm9IVhOqhZ0NQ9oXax1ygPjw6Vs+Vq/4QRjbOAC3B1GCHy7TYxxbExKlb7bzDRzt9vBWU6BDz0RFfYg==", + "version": "6.19.2", + "resolved": "https://registry.npmjs.org/undici/-/undici-6.19.2.tgz", + "integrity": "sha512-JfjKqIauur3Q6biAtHJ564e3bWa8VvT+7cSiOJHFbX4Erv6CLGDpg8z+Fmg/1OI/47RA+GI2QZaF48SSaLvyBA==", "devOptional": true, "license": "MIT", "engines": { @@ -23831,7 +24022,6 @@ "version": "1.1.2", "resolved": "https://registry.npmjs.org/use-isomorphic-layout-effect/-/use-isomorphic-layout-effect-1.1.2.tgz", "integrity": "sha512-49L8yCO3iGT/ZF9QttjwLF/ZD9Iwto5LnH5LmEdk/6cFmXddqi2ulF0edxTwjj+7mqvpVVGQWvbXZdn32wRSHA==", - "license": "MIT", "peerDependencies": { "react": "^16.8.0 || ^17.0.0 || ^18.0.0" }, @@ -23858,7 +24048,6 @@ "version": "1.2.2", "resolved": "https://registry.npmjs.org/use-sync-external-store/-/use-sync-external-store-1.2.2.tgz", "integrity": "sha512-PElTlVMwpblvbNqQ82d2n6RjStvdSoNe9FG28kNfz3WiXilJm4DdNkEzRhCZuIDwY8U08WVihhGR5iRqAwfDiw==", - "license": "MIT", "peerDependencies": { "react": "^16.8.0 || ^17.0.0 || ^18.0.0" } @@ -24709,7 +24898,6 @@ "version": "0.7.3", "resolved": "https://registry.npmjs.org/worktop/-/worktop-0.7.3.tgz", "integrity": "sha512-WBHP1hk8pLP7ahAw13fugDWcO0SUAOiCD6DHT/bfLWoCIA/PL9u7GKdudT2nGZ8EGR1APbGCAI6ZzKG1+X+PnQ==", - "license": "MIT", "dependencies": { "regexparam": "^2.0.0" }, diff --git a/package.json b/package.json index 05071b99..20776555 100644 --- a/package.json +++ b/package.json @@ -31,7 +31,7 @@ "@shopify/cli-hydrogen": "^8.1.1", "@shopify/hydrogen": "^2024.4.7", "@shopify/remix-oxygen": "^2.0.4", - "@weaverse/hydrogen": "3.1.14", + "@weaverse/hydrogen": "3.1.16", "class-variance-authority": "0.7.0", "clsx": "2.1.1", "cross-env": "7.0.3", @@ -47,6 +47,7 @@ "react-player": "2.16.0", "react-use": "17.5.0", "schema-dts": "1.1.2", + "swiper": "^11.1.4", "tailwind-merge": "2.3.0", "tiny-invariant": "1.3.3", "typographic-base": "1.0.4" diff --git a/tailwind.config.js b/tailwind.config.js index 6f623b5f..c1ce989f 100644 --- a/tailwind.config.js +++ b/tailwind.config.js @@ -22,6 +22,9 @@ export default { sale: "rgb(var(--color-sale) / )", // sale background color bar: "rgb(var(--color-border) / )", // border color }, + outlineOffset: { + 3: "3px", + }, screens: { sm: "32em", md: "48em", @@ -85,6 +88,9 @@ export default { border: "inset 0px 0px 0px 1px rgb(var(--color-border) / 0.08)", header: "inset 0px -1px 0px 0px rgba(21, 21, 21, 0.05)", }, + zIndex: { + 1: "1", + } }, }, plugins: [ diff --git a/vite.config.ts b/vite.config.ts index d3551a71..e748403b 100644 --- a/vite.config.ts +++ b/vite.config.ts @@ -20,12 +20,13 @@ export default defineConfig({ ], build: { // Allow a strict Content-Security-Policy - // withtout inlining assets as base64: + // without inlining assets as base64: assetsInlineLimit: 0, }, ssr: { optimizeDeps: { include: [ + "keen-slider/react", // removing this soon "typographic-trademark", "typographic-single-spaces", "typographic-registered-trademark",