@gfed-medusa/sf-lib-common 2.0.0 → 2.1.0
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.
- package/dist/components/breadcrumbs/index.d.ts.map +1 -1
- package/dist/components/breadcrumbs/index.js.map +1 -1
- package/dist/components/cart-mismatch-banner/index.d.ts +2 -2
- package/dist/components/cart-mismatch-banner/index.js +1 -1
- package/dist/components/delete-button/index.d.ts +2 -2
- package/dist/components/delete-button/index.js +1 -1
- package/dist/components/error-message/index.d.ts +2 -2
- package/dist/components/error-message/index.d.ts.map +1 -1
- package/dist/components/free-shipping-price-nudge/index.d.ts +2 -2
- package/dist/components/free-shipping-price-nudge/index.d.ts.map +1 -1
- package/dist/components/free-shipping-price-nudge/index.js +2 -2
- package/dist/components/free-shipping-price-nudge/index.js.map +1 -1
- package/dist/components/interactive-link/index.d.ts +2 -2
- package/dist/components/interactive-link/index.d.ts.map +1 -1
- package/dist/components/interactive-link/index.js +1 -1
- package/dist/components/line-item-options/index.d.ts +2 -2
- package/dist/components/line-item-price/index.d.ts +2 -2
- package/dist/components/localized-client-link/index.d.ts +2 -2
- package/dist/components/localized-client-link/index.d.ts.map +1 -1
- package/dist/components/localized-client-link/index.js +1 -5
- package/dist/components/localized-client-link/index.js.map +1 -1
- package/dist/components/modal/index.d.ts +2 -2
- package/dist/components/modal/index.d.ts.map +1 -1
- package/dist/components/modal/index.js +1 -1
- package/dist/components/preview-price/index.d.ts +2 -2
- package/dist/components/preview-price/index.d.ts.map +1 -1
- package/dist/components/product-card/index.d.ts +2 -2
- package/dist/components/product-card/index.d.ts.map +1 -1
- package/dist/components/product-card/index.js +2 -2
- package/dist/components/product-card/index.js.map +1 -1
- package/dist/components/product-preview/index.d.ts +2 -2
- package/dist/components/product-preview/index.js +1 -1
- package/dist/components/submit-button/index.d.ts +2 -2
- package/dist/components/submit-button/index.d.ts.map +1 -1
- package/dist/lib/context/apollo-context.d.ts +2 -2
- package/dist/lib/context/apollo-context.d.ts.map +1 -1
- package/dist/lib/context/modal-context.d.ts +2 -2
- package/dist/lib/context/modal-context.d.ts.map +1 -1
- package/dist/lib/data/cart.d.ts +7 -17
- package/dist/lib/data/cart.d.ts.map +1 -1
- package/dist/lib/data/cart.js +23 -46
- package/dist/lib/data/cart.js.map +1 -1
- package/dist/lib/data/context.d.ts +27 -0
- package/dist/lib/data/context.d.ts.map +1 -0
- package/dist/lib/data/context.js +18 -0
- package/dist/lib/data/context.js.map +1 -0
- package/dist/lib/data/cookies.d.ts +12 -10
- package/dist/lib/data/cookies.d.ts.map +1 -1
- package/dist/lib/data/cookies.js +25 -35
- package/dist/lib/data/cookies.js.map +1 -1
- package/dist/lib/data/customer.d.ts +3 -2
- package/dist/lib/data/customer.d.ts.map +1 -1
- package/dist/lib/data/customer.js +11 -10
- package/dist/lib/data/customer.js.map +1 -1
- package/dist/lib/data/next-context.d.ts +8 -0
- package/dist/lib/data/next-context.d.ts.map +1 -0
- package/dist/lib/data/next-context.js +65 -0
- package/dist/lib/data/next-context.js.map +1 -0
- package/dist/lib/data/orders.js +1 -1
- package/dist/lib/data/regions.d.ts +3 -2
- package/dist/lib/data/regions.d.ts.map +1 -1
- package/dist/lib/data/regions.js +5 -5
- package/dist/lib/data/regions.js.map +1 -1
- package/dist/lib/gql/fragments/customer.d.ts +3 -3
- package/dist/lib/gql/fragments/customer.d.ts.map +1 -1
- package/dist/lib/gql/fragments/product.d.ts +8 -8
- package/dist/lib/gql/mutations/cart.d.ts +4 -4
- package/dist/lib/gql/queries/cart.d.ts +2 -2
- package/dist/lib/gql/queries/collections.d.ts +2 -2
- package/dist/lib/gql/queries/customer.d.ts +2 -2
- package/dist/lib/gql/queries/footer.d.ts +2 -2
- package/dist/lib/gql/queries/product.d.ts +3 -3
- package/dist/lib/gql/queries/product.d.ts.map +1 -1
- package/dist/lib/utils/env.js +1 -1
- package/dist/lib/utils/env.js.map +1 -1
- package/package.json +1 -1
- package/dist/components/cart-button/index.d.ts +0 -7
- package/dist/components/cart-button/index.d.ts.map +0 -1
- package/dist/components/cart-button/index.js +0 -12
- package/dist/components/cart-button/index.js.map +0 -1
- package/dist/components/cart-dropdown/index.d.ts +0 -12
- package/dist/components/cart-dropdown/index.d.ts.map +0 -1
- package/dist/components/cart-dropdown/index.js +0 -196
- package/dist/components/cart-dropdown/index.js.map +0 -1
- package/dist/components/footer/index.d.ts +0 -7
- package/dist/components/footer/index.d.ts.map +0 -1
- package/dist/components/footer/index.js +0 -110
- package/dist/components/footer/index.js.map +0 -1
- package/dist/components/layout-country-select/index.d.ts +0 -16
- package/dist/components/layout-country-select/index.d.ts.map +0 -1
- package/dist/components/layout-country-select/index.js +0 -92
- package/dist/components/layout-country-select/index.js.map +0 -1
- package/dist/components/nav/index.d.ts +0 -7
- package/dist/components/nav/index.d.ts.map +0 -1
- package/dist/components/nav/index.js +0 -66
- package/dist/components/nav/index.js.map +0 -1
- package/dist/components/portable-text/index.d.ts +0 -13
- package/dist/components/portable-text/index.d.ts.map +0 -1
- package/dist/components/portable-text/index.js +0 -330
- package/dist/components/portable-text/index.js.map +0 -1
- package/dist/components/search-modal/index.d.ts +0 -12
- package/dist/components/search-modal/index.d.ts.map +0 -1
- package/dist/components/search-modal/index.js +0 -138
- package/dist/components/search-modal/index.js.map +0 -1
- package/dist/components/side-menu/index.d.ts +0 -12
- package/dist/components/side-menu/index.d.ts.map +0 -1
- package/dist/components/side-menu/index.js +0 -99
- package/dist/components/side-menu/index.js.map +0 -1
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","names":[],"sources":["../../../src/components/layout-country-select/index.tsx"],"sourcesContent":["'use client';\n\nimport { Fragment, useEffect, useMemo, useState } from 'react';\n\nimport { useParams, usePathname } from 'next/navigation';\n\nimport ReactCountryFlag from 'react-country-flag';\n\nimport {\n Listbox,\n ListboxButton,\n ListboxOption,\n ListboxOptions,\n Transition,\n} from '@headlessui/react';\n\nimport { updateRegion } from '@/lib/data/cart';\nimport { StateType } from '@/lib/hooks/use-toggle-state';\nimport { Region } from '@/types/graphql';\n\ntype CountryOption = {\n country: string;\n region: string;\n label: string;\n};\n\ntype CountrySelectProps = {\n toggleState: StateType;\n regions: Region[];\n};\n\nconst LayoutCountrySelect = ({ toggleState, regions }: CountrySelectProps) => {\n const [current, setCurrent] = useState<\n | { country: string | undefined; region: string; label: string | undefined }\n | undefined\n >(undefined);\n\n const { countryCode } = useParams();\n const currentPath = usePathname().split(`/${countryCode}`)[1] ?? 'gb';\n\n const { state, close } = toggleState;\n\n const options = useMemo(() => {\n return regions\n .map((r) => {\n return r.countries?.map((c) => ({\n country: c?.iso2 ?? undefined,\n region: r.id,\n label: c?.name ?? undefined,\n }));\n })\n .flat()\n .sort((a, b) => (a?.label ?? '').localeCompare(b?.label ?? ''));\n }, [regions]);\n\n useEffect(() => {\n if (countryCode) {\n const option = options?.find((o) => o?.country === countryCode);\n setCurrent(option);\n }\n }, [options, countryCode]);\n\n const handleChange = (option: CountryOption) => {\n updateRegion(option.country, currentPath);\n close();\n };\n\n return (\n <div>\n <Listbox\n as=\"span\"\n onChange={handleChange}\n defaultValue={\n countryCode\n ? options?.find(\n (o): o is CountryOption => o?.country === countryCode\n )\n : undefined\n }\n >\n <ListboxButton className=\"w-full py-1\">\n <div className=\"txt-compact-small flex items-start gap-x-2\">\n <span>Shipping to:</span>\n {current && (\n <span className=\"txt-compact-small flex items-center gap-x-2\">\n {/* @ts-ignore */}\n <ReactCountryFlag\n svg\n style={{\n width: '16px',\n height: '16px',\n }}\n countryCode={current.country ?? ''}\n />\n {current.label}\n </span>\n )}\n </div>\n </ListboxButton>\n <div className=\"relative flex w-full min-w-[320px]\">\n <Transition\n show={state}\n as={Fragment}\n leave=\"transition ease-in duration-150\"\n leaveFrom=\"opacity-100\"\n leaveTo=\"opacity-0\"\n >\n <ListboxOptions\n className=\"text-small-regular no-scrollbar rounded-rounded xsmall:left-auto xsmall:right-0 absolute -bottom-[calc(100%-36px)] left-0 z-[900] max-h-[442px] w-full overflow-y-scroll bg-white text-black uppercase drop-shadow-md\"\n static\n >\n {options?.map((o, index) => {\n return (\n <ListboxOption\n key={index}\n value={o}\n className=\"flex cursor-pointer items-center gap-x-2 px-3 py-2 hover:bg-gray-200\"\n >\n {/* @ts-ignore */}\n <ReactCountryFlag\n svg\n style={{\n width: '16px',\n height: '16px',\n }}\n countryCode={o?.country ?? ''}\n />{' '}\n {o?.label}\n </ListboxOption>\n );\n })}\n </ListboxOptions>\n </Transition>\n </div>\n </Listbox>\n </div>\n );\n};\n\nexport { LayoutCountrySelect };\n"],"mappings":";;;;;;;;;;AA+BA,MAAM,uBAAuB,EAAE,aAAa,cAAkC;CAC5E,MAAM,CAAC,SAAS,cAAc,SAG5B,OAAU;CAEZ,MAAM,EAAE,gBAAgB,WAAW;CACnC,MAAM,cAAc,aAAa,CAAC,MAAM,IAAI,cAAc,CAAC,MAAM;CAEjE,MAAM,EAAE,OAAO,UAAU;CAEzB,MAAM,UAAU,cAAc;AAC5B,SAAO,QACJ,KAAK,MAAM;AACV,UAAO,EAAE,WAAW,KAAK,OAAO;IAC9B,SAAS,GAAG,QAAQ;IACpB,QAAQ,EAAE;IACV,OAAO,GAAG,QAAQ;IACnB,EAAE;IACH,CACD,MAAM,CACN,MAAM,GAAG,OAAO,GAAG,SAAS,IAAI,cAAc,GAAG,SAAS,GAAG,CAAC;IAChE,CAAC,QAAQ,CAAC;AAEb,iBAAgB;AACd,MAAI,aAAa;GACf,MAAM,SAAS,SAAS,MAAM,MAAM,GAAG,YAAY,YAAY;AAC/D,cAAW,OAAO;;IAEnB,CAAC,SAAS,YAAY,CAAC;CAE1B,MAAM,gBAAgB,WAA0B;AAC9C,eAAa,OAAO,SAAS,YAAY;AACzC,SAAO;;AAGT,QACE,oBAAC,mBACC,qBAAC;EACC,IAAG;EACH,UAAU;EACV,cACE,cACI,SAAS,MACN,MAA0B,GAAG,YAAY,YAC3C,GACD;aAGN,oBAAC;GAAc,WAAU;aACvB,qBAAC;IAAI,WAAU;eACb,oBAAC,oBAAK,iBAAmB,EACxB,WACC,qBAAC;KAAK,WAAU;gBAEd,oBAAC;MACC;MACA,OAAO;OACL,OAAO;OACP,QAAQ;OACT;MACD,aAAa,QAAQ,WAAW;OAChC,EACD,QAAQ;MACJ;KAEL;IACQ,EAChB,oBAAC;GAAI,WAAU;aACb,oBAAC;IACC,MAAM;IACN,IAAI;IACJ,OAAM;IACN,WAAU;IACV,SAAQ;cAER,oBAAC;KACC,WAAU;KACV;eAEC,SAAS,KAAK,GAAG,UAAU;AAC1B,aACE,qBAAC;OAEC,OAAO;OACP,WAAU;;QAGV,oBAAC;SACC;SACA,OAAO;UACL,OAAO;UACP,QAAQ;UACT;SACD,aAAa,GAAG,WAAW;UAC3B;QAAC;QACF,GAAG;;SAbC,MAcS;OAElB;MACa;KACN;IACT;GACE,GACN"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","names":[],"sources":["../../../src/components/nav/index.tsx"],"sourcesContent":[],"mappings":";;;iBAUe,GAAA,CAAA,GAAG,QAAA,kBAAA,CAAA,GAAA,CAAA,OAAA"}
|
|
@@ -1,66 +0,0 @@
|
|
|
1
|
-
import { listRegions } from "../../lib/data/regions.js";
|
|
2
|
-
import { LocalizedClientLink } from "../localized-client-link/index.js";
|
|
3
|
-
import { CartButton } from "../cart-button/index.js";
|
|
4
|
-
import { SearchModal } from "../search-modal/index.js";
|
|
5
|
-
import { SideMenu } from "../side-menu/index.js";
|
|
6
|
-
import { Suspense } from "react";
|
|
7
|
-
import { jsx, jsxs } from "react/jsx-runtime";
|
|
8
|
-
|
|
9
|
-
//#region src/components/nav/index.tsx
|
|
10
|
-
async function Nav() {
|
|
11
|
-
return /* @__PURE__ */ jsx("div", {
|
|
12
|
-
className: "group sticky inset-x-0 top-0 z-50",
|
|
13
|
-
children: /* @__PURE__ */ jsx("header", {
|
|
14
|
-
className: "border-ui-border-base relative mx-auto h-16 border-b bg-white duration-200",
|
|
15
|
-
children: /* @__PURE__ */ jsxs("nav", {
|
|
16
|
-
className: "content-container text-small-regular txt-xsmall-plus text-ui-fg-subtle flex h-full w-full items-center justify-between",
|
|
17
|
-
children: [
|
|
18
|
-
/* @__PURE__ */ jsx("div", {
|
|
19
|
-
className: "flex h-full flex-1 basis-0 items-center",
|
|
20
|
-
children: /* @__PURE__ */ jsx("div", {
|
|
21
|
-
className: "h-full",
|
|
22
|
-
children: /* @__PURE__ */ jsx(SideMenu, { regions: await listRegions().then((regions) => regions).catch(() => null) })
|
|
23
|
-
})
|
|
24
|
-
}),
|
|
25
|
-
/* @__PURE__ */ jsx("div", {
|
|
26
|
-
className: "flex h-full items-center",
|
|
27
|
-
children: /* @__PURE__ */ jsx(LocalizedClientLink, {
|
|
28
|
-
href: "/",
|
|
29
|
-
className: "txt-compact-xlarge-plus hover:text-ui-fg-base uppercase",
|
|
30
|
-
"data-testid": "nav-store-link",
|
|
31
|
-
children: "Medusa Store"
|
|
32
|
-
})
|
|
33
|
-
}),
|
|
34
|
-
/* @__PURE__ */ jsxs("div", {
|
|
35
|
-
className: "flex h-full flex-1 basis-0 items-center justify-end gap-x-6",
|
|
36
|
-
children: [
|
|
37
|
-
/* @__PURE__ */ jsx(SearchModal, {}),
|
|
38
|
-
/* @__PURE__ */ jsx("div", {
|
|
39
|
-
className: "small:flex hidden h-full items-center gap-x-6",
|
|
40
|
-
children: /* @__PURE__ */ jsx(LocalizedClientLink, {
|
|
41
|
-
className: "hover:text-ui-fg-base",
|
|
42
|
-
href: "/account",
|
|
43
|
-
"data-testid": "nav-account-link",
|
|
44
|
-
children: "Account"
|
|
45
|
-
})
|
|
46
|
-
}),
|
|
47
|
-
/* @__PURE__ */ jsx(Suspense, {
|
|
48
|
-
fallback: /* @__PURE__ */ jsx(LocalizedClientLink, {
|
|
49
|
-
className: "hover:text-ui-fg-base flex gap-2",
|
|
50
|
-
href: "/cart",
|
|
51
|
-
"data-testid": "nav-cart-link",
|
|
52
|
-
children: "Cart (0)"
|
|
53
|
-
}),
|
|
54
|
-
children: /* @__PURE__ */ jsx(CartButton, {})
|
|
55
|
-
})
|
|
56
|
-
]
|
|
57
|
-
})
|
|
58
|
-
]
|
|
59
|
-
})
|
|
60
|
-
})
|
|
61
|
-
});
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
//#endregion
|
|
65
|
-
export { Nav };
|
|
66
|
-
//# sourceMappingURL=index.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","names":[],"sources":["../../../src/components/nav/index.tsx"],"sourcesContent":["import { Suspense } from 'react';\n\nimport { listRegions } from '@/lib/data/regions';\nimport { Region } from '@/types/graphql';\n\nimport { CartButton } from '../cart-button';\nimport { LocalizedClientLink } from '../localized-client-link';\nimport { SearchModal } from '../search-modal';\nimport { SideMenu } from '../side-menu';\n\nasync function Nav() {\n const regions = await listRegions()\n .then((regions: Region[]) => regions)\n .catch(() => null);\n\n return (\n <div className=\"group sticky inset-x-0 top-0 z-50\">\n <header className=\"border-ui-border-base relative mx-auto h-16 border-b bg-white duration-200\">\n <nav className=\"content-container text-small-regular txt-xsmall-plus text-ui-fg-subtle flex h-full w-full items-center justify-between\">\n <div className=\"flex h-full flex-1 basis-0 items-center\">\n <div className=\"h-full\">\n <SideMenu regions={regions} />\n </div>\n </div>\n\n <div className=\"flex h-full items-center\">\n <LocalizedClientLink\n href=\"/\"\n className=\"txt-compact-xlarge-plus hover:text-ui-fg-base uppercase\"\n data-testid=\"nav-store-link\"\n >\n Medusa Store\n </LocalizedClientLink>\n </div>\n\n <div className=\"flex h-full flex-1 basis-0 items-center justify-end gap-x-6\">\n <SearchModal />\n <div className=\"small:flex hidden h-full items-center gap-x-6\">\n <LocalizedClientLink\n className=\"hover:text-ui-fg-base\"\n href=\"/account\"\n data-testid=\"nav-account-link\"\n >\n Account\n </LocalizedClientLink>\n </div>\n <Suspense\n fallback={\n <LocalizedClientLink\n className=\"hover:text-ui-fg-base flex gap-2\"\n href=\"/cart\"\n data-testid=\"nav-cart-link\"\n >\n Cart (0)\n </LocalizedClientLink>\n }\n >\n <CartButton />\n </Suspense>\n </div>\n </nav>\n </header>\n </div>\n );\n}\n\nexport { Nav };\n"],"mappings":";;;;;;;;;AAUA,eAAe,MAAM;AAKnB,QACE,oBAAC;EAAI,WAAU;YACb,oBAAC;GAAO,WAAU;aAChB,qBAAC;IAAI,WAAU;;KACb,oBAAC;MAAI,WAAU;gBACb,oBAAC;OAAI,WAAU;iBACb,oBAAC,YAAS,SAVN,MAAM,aAAa,CAChC,MAAM,YAAsB,QAAQ,CACpC,YAAY,KAAK,GAQsB;QAC1B;OACF;KAEN,oBAAC;MAAI,WAAU;gBACb,oBAAC;OACC,MAAK;OACL,WAAU;OACV,eAAY;iBACb;QAEqB;OAClB;KAEN,qBAAC;MAAI,WAAU;;OACb,oBAAC,gBAAc;OACf,oBAAC;QAAI,WAAU;kBACb,oBAAC;SACC,WAAU;SACV,MAAK;SACL,eAAY;mBACb;UAEqB;SAClB;OACN,oBAAC;QACC,UACE,oBAAC;SACC,WAAU;SACV,MAAK;SACL,eAAY;mBACb;UAEqB;kBAGxB,oBAAC,eAAa;SACL;;OACP;;KACF;IACC;GACL"}
|
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
import { RichTextBlock } from "../../types/graphql.js";
|
|
2
|
-
import * as react_jsx_runtime8 from "react/jsx-runtime";
|
|
3
|
-
|
|
4
|
-
//#region src/components/portable-text/index.d.ts
|
|
5
|
-
type PortableTextProps = {
|
|
6
|
-
value: RichTextBlock[];
|
|
7
|
-
};
|
|
8
|
-
declare const PortableText: ({
|
|
9
|
-
value
|
|
10
|
-
}: PortableTextProps) => react_jsx_runtime8.JSX.Element | null;
|
|
11
|
-
//#endregion
|
|
12
|
-
export { PortableText };
|
|
13
|
-
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","names":[],"sources":["../../../src/components/portable-text/index.tsx"],"sourcesContent":[],"mappings":";;;;KAkCK,iBAAA;SACI;;AAHgB,cAMnB,YAJgB,EAAA,CAAA;EAAA;AACA,CAAb,EAGwB,iBAHX,EAAA,GAG4B,kBAAA,CAAA,GAAA,CAAA,OAAA,GAH5B,IAAA"}
|
|
@@ -1,330 +0,0 @@
|
|
|
1
|
-
import { Fragment } from "react";
|
|
2
|
-
import { jsx, jsxs } from "react/jsx-runtime";
|
|
3
|
-
import { Heading, Text } from "@medusajs/ui";
|
|
4
|
-
import { ArrowUpRightMini } from "@medusajs/icons";
|
|
5
|
-
import Image from "next/image";
|
|
6
|
-
import { PlaceholderImage } from "@gfed-medusa/sf-lib-ui/icons/placeholder-image";
|
|
7
|
-
import { Back } from "@gfed-medusa/sf-lib-ui/icons/back";
|
|
8
|
-
import { Bancontact } from "@gfed-medusa/sf-lib-ui/icons/bancontact";
|
|
9
|
-
import { ChevronDown } from "@gfed-medusa/sf-lib-ui/icons/chevron-down";
|
|
10
|
-
import { Eye } from "@gfed-medusa/sf-lib-ui/icons/eye";
|
|
11
|
-
import { EyeOff } from "@gfed-medusa/sf-lib-ui/icons/eye-off";
|
|
12
|
-
import { FastDelivery } from "@gfed-medusa/sf-lib-ui/icons/fast-delivery";
|
|
13
|
-
import { Ideal } from "@gfed-medusa/sf-lib-ui/icons/ideal";
|
|
14
|
-
import { MapPin } from "@gfed-medusa/sf-lib-ui/icons/map-pin";
|
|
15
|
-
import { Medusa } from "@gfed-medusa/sf-lib-ui/icons/medusa";
|
|
16
|
-
import { NextJs } from "@gfed-medusa/sf-lib-ui/icons/nextjs";
|
|
17
|
-
import { Package } from "@gfed-medusa/sf-lib-ui/icons/package";
|
|
18
|
-
import { PayPal } from "@gfed-medusa/sf-lib-ui/icons/paypal";
|
|
19
|
-
import { Refresh } from "@gfed-medusa/sf-lib-ui/icons/refresh";
|
|
20
|
-
import { Spinner as Spinner$1 } from "@gfed-medusa/sf-lib-ui/icons/spinner";
|
|
21
|
-
import { Trash as Trash$1 } from "@gfed-medusa/sf-lib-ui/icons/trash";
|
|
22
|
-
import { User } from "@gfed-medusa/sf-lib-ui/icons/user";
|
|
23
|
-
import { X } from "@gfed-medusa/sf-lib-ui/icons/x";
|
|
24
|
-
|
|
25
|
-
//#region src/components/portable-text/index.tsx
|
|
26
|
-
const PortableText = ({ value }) => {
|
|
27
|
-
if (!value || !Array.isArray(value)) return null;
|
|
28
|
-
const getBlockType = (block) => {
|
|
29
|
-
if (block.__typename) {
|
|
30
|
-
const typename = block.__typename.toLowerCase();
|
|
31
|
-
if (typename === "textblock") return "block";
|
|
32
|
-
return typename.replace("block", "");
|
|
33
|
-
}
|
|
34
|
-
return "unknown";
|
|
35
|
-
};
|
|
36
|
-
const renderSpan = (span, markDefs) => {
|
|
37
|
-
if (!span.text) return null;
|
|
38
|
-
let content = span.text;
|
|
39
|
-
const marks = span.marks || [];
|
|
40
|
-
marks.forEach((mark) => {
|
|
41
|
-
if (typeof mark === "string") switch (mark) {
|
|
42
|
-
case "strong":
|
|
43
|
-
content = /* @__PURE__ */ jsx("strong", { children: content });
|
|
44
|
-
break;
|
|
45
|
-
case "em":
|
|
46
|
-
content = /* @__PURE__ */ jsx("em", { children: content });
|
|
47
|
-
break;
|
|
48
|
-
case "code":
|
|
49
|
-
content = /* @__PURE__ */ jsx("code", {
|
|
50
|
-
className: "bg-ui-bg-subtle rounded px-1 py-0.5 font-mono text-sm",
|
|
51
|
-
children: content
|
|
52
|
-
});
|
|
53
|
-
break;
|
|
54
|
-
case "underline":
|
|
55
|
-
content = /* @__PURE__ */ jsx("u", { children: content });
|
|
56
|
-
break;
|
|
57
|
-
case "superscript":
|
|
58
|
-
content = /* @__PURE__ */ jsx("sup", { children: content });
|
|
59
|
-
break;
|
|
60
|
-
case "subscript":
|
|
61
|
-
content = /* @__PURE__ */ jsx("sub", { children: content });
|
|
62
|
-
break;
|
|
63
|
-
}
|
|
64
|
-
});
|
|
65
|
-
const getMarkByKey = (key) => {
|
|
66
|
-
return markDefs?.find((def) => def._key === key);
|
|
67
|
-
};
|
|
68
|
-
const linkMark = marks.find((mark) => {
|
|
69
|
-
if (typeof mark === "object") return mark;
|
|
70
|
-
if (typeof mark === "string") {
|
|
71
|
-
const markDef = getMarkByKey(mark);
|
|
72
|
-
return markDef && (markDef._type === "link" || markDef.__typename === "LinkMark");
|
|
73
|
-
}
|
|
74
|
-
return false;
|
|
75
|
-
});
|
|
76
|
-
const iconLinkMark = marks.find((mark) => {
|
|
77
|
-
if (typeof mark === "object") return mark;
|
|
78
|
-
if (typeof mark === "string") {
|
|
79
|
-
const markDef = getMarkByKey(mark);
|
|
80
|
-
return markDef && (markDef._type === "iconlink" || markDef.__typename === "IconLinkMark");
|
|
81
|
-
}
|
|
82
|
-
return false;
|
|
83
|
-
});
|
|
84
|
-
const resolvedIconLinkMark = typeof iconLinkMark === "string" ? (() => {
|
|
85
|
-
const mark = getMarkByKey(iconLinkMark);
|
|
86
|
-
return mark && (mark.__typename === "IconLinkMark" || mark._type === "iconlink") ? mark : void 0;
|
|
87
|
-
})() : iconLinkMark ? iconLinkMark : void 0;
|
|
88
|
-
const resolvedLinkMark = typeof linkMark === "string" ? getMarkByKey(linkMark) : linkMark;
|
|
89
|
-
if (resolvedIconLinkMark) return renderIconLink(resolvedIconLinkMark, content);
|
|
90
|
-
if (resolvedLinkMark) return /* @__PURE__ */ jsx("a", {
|
|
91
|
-
href: resolvedLinkMark.href,
|
|
92
|
-
target: resolvedLinkMark.target ?? "",
|
|
93
|
-
className: "text-ui-fg-interactive hover:underline",
|
|
94
|
-
children: content
|
|
95
|
-
});
|
|
96
|
-
return content;
|
|
97
|
-
};
|
|
98
|
-
const renderIconLink = (mark, children) => {
|
|
99
|
-
const renderIcon = () => {
|
|
100
|
-
switch (mark.iconType) {
|
|
101
|
-
case "class": return mark.iconClass ? /* @__PURE__ */ jsx("i", { className: mark.iconClass }) : null;
|
|
102
|
-
case "component": switch (mark.iconComponent) {
|
|
103
|
-
case "ArrowUpRightMini": return /* @__PURE__ */ jsx(ArrowUpRightMini, {
|
|
104
|
-
fill: mark.iconFill ?? "",
|
|
105
|
-
className: "h-4 w-4"
|
|
106
|
-
});
|
|
107
|
-
case "Back": return /* @__PURE__ */ jsx(Back, {
|
|
108
|
-
size: 16,
|
|
109
|
-
fill: mark.iconFill ?? ""
|
|
110
|
-
});
|
|
111
|
-
case "Bancontact": return /* @__PURE__ */ jsx(Bancontact, {
|
|
112
|
-
size: 16,
|
|
113
|
-
fill: mark.iconFill ?? ""
|
|
114
|
-
});
|
|
115
|
-
case "ChevronDown": return /* @__PURE__ */ jsx(ChevronDown, {
|
|
116
|
-
size: 16,
|
|
117
|
-
fill: mark.iconFill ?? ""
|
|
118
|
-
});
|
|
119
|
-
case "Eye": return /* @__PURE__ */ jsx(Eye, {
|
|
120
|
-
size: 16,
|
|
121
|
-
fill: mark.iconFill ?? ""
|
|
122
|
-
});
|
|
123
|
-
case "EyeOff": return /* @__PURE__ */ jsx(EyeOff, {
|
|
124
|
-
size: 16,
|
|
125
|
-
fill: mark.iconFill ?? ""
|
|
126
|
-
});
|
|
127
|
-
case "FastDelivery": return /* @__PURE__ */ jsx(FastDelivery, {
|
|
128
|
-
size: 16,
|
|
129
|
-
fill: mark.iconFill ?? ""
|
|
130
|
-
});
|
|
131
|
-
case "Ideal": return /* @__PURE__ */ jsx(Ideal, {
|
|
132
|
-
size: 16,
|
|
133
|
-
fill: mark.iconFill ?? ""
|
|
134
|
-
});
|
|
135
|
-
case "MapPin": return /* @__PURE__ */ jsx(MapPin, {
|
|
136
|
-
size: 16,
|
|
137
|
-
fill: mark.iconFill ?? ""
|
|
138
|
-
});
|
|
139
|
-
case "Medusa": return /* @__PURE__ */ jsx(Medusa, {
|
|
140
|
-
size: 16,
|
|
141
|
-
fill: mark.iconFill ?? ""
|
|
142
|
-
});
|
|
143
|
-
case "NextJs": return /* @__PURE__ */ jsx(NextJs, {
|
|
144
|
-
size: 16,
|
|
145
|
-
fill: mark.iconFill ?? ""
|
|
146
|
-
});
|
|
147
|
-
case "Package": return /* @__PURE__ */ jsx(Package, {
|
|
148
|
-
size: 16,
|
|
149
|
-
fill: mark.iconFill ?? ""
|
|
150
|
-
});
|
|
151
|
-
case "PayPal": return /* @__PURE__ */ jsx(PayPal, {});
|
|
152
|
-
case "PlaceholderImage": return /* @__PURE__ */ jsx(PlaceholderImage, {
|
|
153
|
-
size: 16,
|
|
154
|
-
fill: mark.iconFill ?? ""
|
|
155
|
-
});
|
|
156
|
-
case "Refresh": return /* @__PURE__ */ jsx(Refresh, {
|
|
157
|
-
size: 16,
|
|
158
|
-
fill: mark.iconFill ?? ""
|
|
159
|
-
});
|
|
160
|
-
case "Spinner": return /* @__PURE__ */ jsx(Spinner$1, {
|
|
161
|
-
size: 16,
|
|
162
|
-
fill: mark.iconFill ?? ""
|
|
163
|
-
});
|
|
164
|
-
case "Trash": return /* @__PURE__ */ jsx(Trash$1, {
|
|
165
|
-
size: 16,
|
|
166
|
-
fill: mark.iconFill ?? ""
|
|
167
|
-
});
|
|
168
|
-
case "User": return /* @__PURE__ */ jsx(User, {
|
|
169
|
-
size: 16,
|
|
170
|
-
fill: mark.iconFill ?? ""
|
|
171
|
-
});
|
|
172
|
-
case "X": return /* @__PURE__ */ jsx(X, {
|
|
173
|
-
size: 16,
|
|
174
|
-
fill: mark.iconFill ?? ""
|
|
175
|
-
});
|
|
176
|
-
default: return null;
|
|
177
|
-
}
|
|
178
|
-
case "sanity": return mark.iconImage?.asset?.url ? /* @__PURE__ */ jsx(Image, {
|
|
179
|
-
src: mark.iconImage.asset.url,
|
|
180
|
-
alt: mark.iconImage.alt || "Icon",
|
|
181
|
-
width: 16,
|
|
182
|
-
height: 16,
|
|
183
|
-
className: "h-4 w-4"
|
|
184
|
-
}) : null;
|
|
185
|
-
case "url": return mark.iconUrl ? /* @__PURE__ */ jsx(Image, {
|
|
186
|
-
src: mark.iconUrl,
|
|
187
|
-
alt: "Icon",
|
|
188
|
-
width: 16,
|
|
189
|
-
height: 16,
|
|
190
|
-
className: "h-4 w-4"
|
|
191
|
-
}) : null;
|
|
192
|
-
default: return null;
|
|
193
|
-
}
|
|
194
|
-
};
|
|
195
|
-
return /* @__PURE__ */ jsxs("a", {
|
|
196
|
-
href: mark.href,
|
|
197
|
-
target: mark.target ?? "",
|
|
198
|
-
className: "text-ui-fg-interactive inline-flex items-center gap-1 hover:underline",
|
|
199
|
-
children: [children, renderIcon()]
|
|
200
|
-
});
|
|
201
|
-
};
|
|
202
|
-
const renderTextBlock = (block) => {
|
|
203
|
-
const style = block.style || "normal";
|
|
204
|
-
const children = block.children || [];
|
|
205
|
-
const markDefs = block.markDefs || [];
|
|
206
|
-
const content = children.map((child, index) => /* @__PURE__ */ jsx(Fragment, { children: renderSpan(child, markDefs) }, child._key || index));
|
|
207
|
-
switch (style) {
|
|
208
|
-
case "h1": return /* @__PURE__ */ jsx("h1", {
|
|
209
|
-
className: "mt-8 mb-6 text-4xl font-bold",
|
|
210
|
-
children: content
|
|
211
|
-
});
|
|
212
|
-
case "h2": return /* @__PURE__ */ jsx(Heading, {
|
|
213
|
-
level: "h2",
|
|
214
|
-
className: "mt-6 mb-4 text-3xl font-semibold",
|
|
215
|
-
children: content
|
|
216
|
-
});
|
|
217
|
-
case "h3": return /* @__PURE__ */ jsx(Heading, {
|
|
218
|
-
level: "h3",
|
|
219
|
-
className: "mt-6 mb-4 text-2xl font-semibold",
|
|
220
|
-
children: content
|
|
221
|
-
});
|
|
222
|
-
case "h4": return /* @__PURE__ */ jsx("h4", {
|
|
223
|
-
className: "mt-4 mb-3 text-xl font-semibold",
|
|
224
|
-
children: content
|
|
225
|
-
});
|
|
226
|
-
case "h5": return /* @__PURE__ */ jsx("h5", {
|
|
227
|
-
className: "mt-4 mb-3 text-lg font-semibold",
|
|
228
|
-
children: content
|
|
229
|
-
});
|
|
230
|
-
case "h6": return /* @__PURE__ */ jsx("h6", {
|
|
231
|
-
className: "mt-4 mb-2 text-base font-semibold",
|
|
232
|
-
children: content
|
|
233
|
-
});
|
|
234
|
-
case "blockquote": return /* @__PURE__ */ jsx("blockquote", {
|
|
235
|
-
className: "border-ui-border-base my-4 border-l-4 py-2 pl-4 italic",
|
|
236
|
-
children: /* @__PURE__ */ jsx(Text, { children: content })
|
|
237
|
-
});
|
|
238
|
-
default: return /* @__PURE__ */ jsx(Text, {
|
|
239
|
-
className: "mb-4 leading-relaxed",
|
|
240
|
-
children: content
|
|
241
|
-
});
|
|
242
|
-
}
|
|
243
|
-
};
|
|
244
|
-
const renderImage = (image) => {
|
|
245
|
-
if (!image.asset?.url) return null;
|
|
246
|
-
return /* @__PURE__ */ jsx("div", {
|
|
247
|
-
className: "my-6",
|
|
248
|
-
children: /* @__PURE__ */ jsx(Image, {
|
|
249
|
-
src: image.asset.url,
|
|
250
|
-
alt: image.alt || "",
|
|
251
|
-
width: 800,
|
|
252
|
-
height: 400,
|
|
253
|
-
className: "h-auto w-full rounded-lg"
|
|
254
|
-
})
|
|
255
|
-
});
|
|
256
|
-
};
|
|
257
|
-
const renderFileBlock = (file) => {
|
|
258
|
-
if (!file.asset?.url) return null;
|
|
259
|
-
return /* @__PURE__ */ jsx("div", {
|
|
260
|
-
className: "my-6",
|
|
261
|
-
children: /* @__PURE__ */ jsxs("a", {
|
|
262
|
-
href: file.asset.url,
|
|
263
|
-
target: "_blank",
|
|
264
|
-
rel: "noopener noreferrer",
|
|
265
|
-
className: "border-ui-border-base text-ui-fg-interactive hover:bg-ui-bg-subtle inline-flex items-center gap-2 rounded-lg border p-4",
|
|
266
|
-
children: [
|
|
267
|
-
/* @__PURE__ */ jsx("span", { children: "📎" }),
|
|
268
|
-
/* @__PURE__ */ jsx("span", { children: file.asset.originalFilename || "Download file" }),
|
|
269
|
-
file.asset.size && /* @__PURE__ */ jsxs("span", {
|
|
270
|
-
className: "text-ui-fg-muted text-sm",
|
|
271
|
-
children: [
|
|
272
|
-
"(",
|
|
273
|
-
Math.round(file.asset.size / 1024),
|
|
274
|
-
" KB)"
|
|
275
|
-
]
|
|
276
|
-
})
|
|
277
|
-
]
|
|
278
|
-
})
|
|
279
|
-
});
|
|
280
|
-
};
|
|
281
|
-
const renderList = (items, listType) => {
|
|
282
|
-
return /* @__PURE__ */ jsx(listType === "bullet" ? "ul" : "ol", {
|
|
283
|
-
className: listType === "bullet" ? "list-disc pl-6 mb-4 space-y-1" : "list-decimal pl-6 mb-4 space-y-1",
|
|
284
|
-
children: items.map((item) => {
|
|
285
|
-
const markDefs = item.markDefs || [];
|
|
286
|
-
return /* @__PURE__ */ jsx("li", {
|
|
287
|
-
className: "leading-relaxed",
|
|
288
|
-
children: item.children?.map((child, childIndex) => /* @__PURE__ */ jsx(Fragment, { children: renderSpan(child, markDefs) }, child._key || childIndex))
|
|
289
|
-
}, item._key);
|
|
290
|
-
})
|
|
291
|
-
});
|
|
292
|
-
};
|
|
293
|
-
const renderBlock = (block) => {
|
|
294
|
-
const blockType = getBlockType(block);
|
|
295
|
-
if (blockType === "block" || blockType === "textblock" || blockType === "text") return renderTextBlock(block);
|
|
296
|
-
if (blockType === "image" || blockType === "imageblock") return renderImage(block);
|
|
297
|
-
if (blockType === "file" || blockType === "fileblock") return renderFileBlock(block);
|
|
298
|
-
return null;
|
|
299
|
-
};
|
|
300
|
-
const processedContent = [];
|
|
301
|
-
let currentListItems = [];
|
|
302
|
-
let currentListType = null;
|
|
303
|
-
value.forEach((block, index) => {
|
|
304
|
-
if (getBlockType(block) === "block" && block.listItem) {
|
|
305
|
-
const textBlock = block;
|
|
306
|
-
const listItem = textBlock.listItem || null;
|
|
307
|
-
if (currentListType !== listItem) {
|
|
308
|
-
if (currentListItems.length > 0 && currentListType) processedContent.push(/* @__PURE__ */ jsx(Fragment, { children: renderList(currentListItems, currentListType) }, `list-${index}`));
|
|
309
|
-
currentListItems = [textBlock];
|
|
310
|
-
currentListType = listItem;
|
|
311
|
-
} else currentListItems.push(textBlock);
|
|
312
|
-
} else {
|
|
313
|
-
if (currentListItems.length > 0 && currentListType) {
|
|
314
|
-
processedContent.push(/* @__PURE__ */ jsx(Fragment, { children: renderList(currentListItems, currentListType) }, `list-${index}`));
|
|
315
|
-
currentListItems = [];
|
|
316
|
-
currentListType = null;
|
|
317
|
-
}
|
|
318
|
-
processedContent.push(/* @__PURE__ */ jsx(Fragment, { children: renderBlock(block) }, block._key || index));
|
|
319
|
-
}
|
|
320
|
-
});
|
|
321
|
-
if (currentListItems.length > 0 && currentListType) processedContent.push(/* @__PURE__ */ jsx(Fragment, { children: renderList(currentListItems, currentListType) }, "final-list"));
|
|
322
|
-
return /* @__PURE__ */ jsx("div", {
|
|
323
|
-
className: "prose prose-ui max-w-none",
|
|
324
|
-
children: processedContent
|
|
325
|
-
});
|
|
326
|
-
};
|
|
327
|
-
|
|
328
|
-
//#endregion
|
|
329
|
-
export { PortableText };
|
|
330
|
-
//# sourceMappingURL=index.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","names":["content: ReactNode","resolvedIconLinkMark: IconLinkMark | undefined","Spinner","Trash","processedContent: ReactNode[]","currentListItems: TextBlock[]","currentListType: string | null"],"sources":["../../../src/components/portable-text/index.tsx"],"sourcesContent":["import { Fragment, ReactNode } from 'react';\n\nimport Image from 'next/image';\n\nimport { Back } from '@gfed-medusa/sf-lib-ui/icons/back';\nimport { Bancontact } from '@gfed-medusa/sf-lib-ui/icons/bancontact';\nimport { ChevronDown } from '@gfed-medusa/sf-lib-ui/icons/chevron-down';\nimport { Eye } from '@gfed-medusa/sf-lib-ui/icons/eye';\nimport { EyeOff } from '@gfed-medusa/sf-lib-ui/icons/eye-off';\nimport { FastDelivery } from '@gfed-medusa/sf-lib-ui/icons/fast-delivery';\nimport { Ideal } from '@gfed-medusa/sf-lib-ui/icons/ideal';\nimport { MapPin } from '@gfed-medusa/sf-lib-ui/icons/map-pin';\nimport { Medusa } from '@gfed-medusa/sf-lib-ui/icons/medusa';\nimport { NextJs } from '@gfed-medusa/sf-lib-ui/icons/nextjs';\nimport { Package } from '@gfed-medusa/sf-lib-ui/icons/package';\nimport { PayPal } from '@gfed-medusa/sf-lib-ui/icons/paypal';\nimport { PlaceholderImage } from '@gfed-medusa/sf-lib-ui/icons/placeholder-image';\nimport { Refresh } from '@gfed-medusa/sf-lib-ui/icons/refresh';\nimport { Spinner } from '@gfed-medusa/sf-lib-ui/icons/spinner';\nimport { Trash } from '@gfed-medusa/sf-lib-ui/icons/trash';\nimport { User } from '@gfed-medusa/sf-lib-ui/icons/user';\nimport { X } from '@gfed-medusa/sf-lib-ui/icons/x';\nimport { ArrowUpRightMini } from '@medusajs/icons';\nimport { Heading, Text } from '@medusajs/ui';\n\nimport {\n FileBlock,\n IconLinkMark,\n ImageBlock,\n RichTextBlock,\n Span,\n TextBlock,\n} from '@/types/graphql';\n\ntype PortableTextProps = {\n value: RichTextBlock[];\n};\n\nconst PortableText = ({ value }: PortableTextProps) => {\n if (!value || !Array.isArray(value)) {\n return null;\n }\n\n const getBlockType = (block: RichTextBlock): string => {\n if (block.__typename) {\n const typename = block.__typename.toLowerCase();\n if (typename === 'textblock') return 'block';\n return typename.replace('block', '');\n }\n return 'unknown';\n };\n\n const renderSpan = (\n span: Span,\n markDefs: TextBlock['markDefs']\n ): ReactNode => {\n if (!span.text) return null;\n\n let content: ReactNode = span.text;\n const marks = span.marks || [];\n\n marks.forEach((mark) => {\n if (typeof mark === 'string') {\n switch (mark) {\n case 'strong':\n content = <strong>{content}</strong>;\n break;\n case 'em':\n content = <em>{content}</em>;\n break;\n case 'code':\n content = (\n <code className=\"bg-ui-bg-subtle rounded px-1 py-0.5 font-mono text-sm\">\n {content}\n </code>\n );\n break;\n case 'underline':\n content = <u>{content}</u>;\n break;\n case 'superscript':\n content = <sup>{content}</sup>;\n break;\n case 'subscript':\n content = <sub>{content}</sub>;\n break;\n }\n }\n });\n\n // Handle marks that reference markDefs by _key\n const getMarkByKey = (key: string) => {\n return markDefs?.find((def) => def._key === key);\n };\n\n // Find link marks (both direct objects and references)\n const linkMark = marks.find((mark) => {\n if (typeof mark === 'object') {\n return mark;\n }\n if (typeof mark === 'string') {\n const markDef = getMarkByKey(mark);\n return (\n markDef &&\n (markDef._type === 'link' || markDef.__typename === 'LinkMark')\n );\n }\n return false;\n });\n\n // Find icon link marks (both direct objects and references)\n const iconLinkMark = marks.find((mark) => {\n if (typeof mark === 'object') {\n return mark;\n }\n if (typeof mark === 'string') {\n const markDef = getMarkByKey(mark);\n return (\n markDef &&\n (markDef._type === 'iconlink' ||\n markDef.__typename === 'IconLinkMark')\n );\n }\n return false;\n });\n\n // Get the actual mark object (either direct or from markDefs)\n const resolvedIconLinkMark: IconLinkMark | undefined =\n typeof iconLinkMark === 'string'\n ? (() => {\n const mark = getMarkByKey(iconLinkMark);\n return mark &&\n (mark.__typename === 'IconLinkMark' || mark._type === 'iconlink')\n ? (mark as IconLinkMark)\n : undefined;\n })()\n : iconLinkMark\n ? (iconLinkMark as IconLinkMark)\n : undefined;\n const resolvedLinkMark =\n typeof linkMark === 'string' ? getMarkByKey(linkMark) : linkMark;\n\n if (resolvedIconLinkMark) {\n return renderIconLink(resolvedIconLinkMark, content);\n }\n\n if (resolvedLinkMark) {\n return (\n <a\n href={resolvedLinkMark.href}\n target={resolvedLinkMark.target ?? ''}\n className=\"text-ui-fg-interactive hover:underline\"\n >\n {content}\n </a>\n );\n }\n\n return content;\n };\n\n const renderIconLink = (\n mark: IconLinkMark,\n children: ReactNode\n ): ReactNode => {\n const renderIcon = () => {\n switch (mark.iconType) {\n case 'class':\n return mark.iconClass ? <i className={mark.iconClass} /> : null;\n case 'component':\n switch (mark.iconComponent) {\n case 'ArrowUpRightMini':\n return (\n <ArrowUpRightMini\n fill={mark.iconFill ?? ''}\n className=\"h-4 w-4\"\n />\n );\n case 'Back':\n return <Back size={16} fill={mark.iconFill ?? ''} />;\n case 'Bancontact':\n return <Bancontact size={16} fill={mark.iconFill ?? ''} />;\n case 'ChevronDown':\n return <ChevronDown size={16} fill={mark.iconFill ?? ''} />;\n case 'Eye':\n return <Eye size={16} fill={mark.iconFill ?? ''} />;\n case 'EyeOff':\n return <EyeOff size={16} fill={mark.iconFill ?? ''} />;\n case 'FastDelivery':\n return <FastDelivery size={16} fill={mark.iconFill ?? ''} />;\n case 'Ideal':\n return <Ideal size={16} fill={mark.iconFill ?? ''} />;\n case 'MapPin':\n return <MapPin size={16} fill={mark.iconFill ?? ''} />;\n case 'Medusa':\n return <Medusa size={16} fill={mark.iconFill ?? ''} />;\n case 'NextJs':\n return <NextJs size={16} fill={mark.iconFill ?? ''} />;\n case 'Package':\n return <Package size={16} fill={mark.iconFill ?? ''} />;\n case 'PayPal':\n return <PayPal />;\n case 'PlaceholderImage':\n return <PlaceholderImage size={16} fill={mark.iconFill ?? ''} />;\n case 'Refresh':\n return <Refresh size={16} fill={mark.iconFill ?? ''} />;\n case 'Spinner':\n return <Spinner size={16} fill={mark.iconFill ?? ''} />;\n case 'Trash':\n return <Trash size={16} fill={mark.iconFill ?? ''} />;\n case 'User':\n return <User size={16} fill={mark.iconFill ?? ''} />;\n case 'X':\n return <X size={16} fill={mark.iconFill ?? ''} />;\n default:\n return null;\n }\n case 'sanity':\n return mark.iconImage?.asset?.url ? (\n <Image\n src={mark.iconImage.asset.url}\n alt={mark.iconImage.alt || 'Icon'}\n width={16}\n height={16}\n className=\"h-4 w-4\"\n />\n ) : null;\n case 'url':\n return mark.iconUrl ? (\n <Image\n src={mark.iconUrl}\n alt=\"Icon\"\n width={16}\n height={16}\n className=\"h-4 w-4\"\n />\n ) : null;\n default:\n return null;\n }\n };\n\n return (\n <a\n href={mark.href}\n target={mark.target ?? ''}\n className=\"text-ui-fg-interactive inline-flex items-center gap-1 hover:underline\"\n >\n {children}\n {renderIcon()}\n </a>\n );\n };\n\n const renderTextBlock = (block: TextBlock): ReactNode => {\n const style = block.style || 'normal';\n const children = block.children || [];\n const markDefs = block.markDefs || [];\n\n const content = children.map((child, index) => (\n <Fragment key={child._key || index}>\n {renderSpan(child, markDefs)}\n </Fragment>\n ));\n\n switch (style) {\n case 'h1':\n return <h1 className=\"mt-8 mb-6 text-4xl font-bold\">{content}</h1>;\n case 'h2':\n return (\n <Heading level=\"h2\" className=\"mt-6 mb-4 text-3xl font-semibold\">\n {content}\n </Heading>\n );\n case 'h3':\n return (\n <Heading level=\"h3\" className=\"mt-6 mb-4 text-2xl font-semibold\">\n {content}\n </Heading>\n );\n case 'h4':\n return <h4 className=\"mt-4 mb-3 text-xl font-semibold\">{content}</h4>;\n case 'h5':\n return <h5 className=\"mt-4 mb-3 text-lg font-semibold\">{content}</h5>;\n case 'h6':\n return <h6 className=\"mt-4 mb-2 text-base font-semibold\">{content}</h6>;\n case 'blockquote':\n return (\n <blockquote className=\"border-ui-border-base my-4 border-l-4 py-2 pl-4 italic\">\n <Text>{content}</Text>\n </blockquote>\n );\n default:\n return <Text className=\"mb-4 leading-relaxed\">{content}</Text>;\n }\n };\n\n const renderImage = (image: ImageBlock): ReactNode => {\n if (!image.asset?.url) return null;\n\n return (\n <div className=\"my-6\">\n <Image\n src={image.asset.url}\n alt={image.alt || ''}\n width={800}\n height={400}\n className=\"h-auto w-full rounded-lg\"\n />\n </div>\n );\n };\n\n const renderFileBlock = (file: FileBlock): ReactNode => {\n if (!file.asset?.url) return null;\n\n return (\n <div className=\"my-6\">\n <a\n href={file.asset.url}\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n className=\"border-ui-border-base text-ui-fg-interactive hover:bg-ui-bg-subtle inline-flex items-center gap-2 rounded-lg border p-4\"\n >\n <span>📎</span>\n <span>{file.asset.originalFilename || 'Download file'}</span>\n {file.asset.size && (\n <span className=\"text-ui-fg-muted text-sm\">\n ({Math.round(file.asset.size / 1024)} KB)\n </span>\n )}\n </a>\n </div>\n );\n };\n\n const renderList = (items: TextBlock[], listType: string): ReactNode => {\n const ListComponent = listType === 'bullet' ? 'ul' : 'ol';\n const listClass =\n listType === 'bullet'\n ? 'list-disc pl-6 mb-4 space-y-1'\n : 'list-decimal pl-6 mb-4 space-y-1';\n\n return (\n <ListComponent className={listClass}>\n {items.map((item) => {\n const markDefs = item.markDefs || [];\n return (\n <li key={item._key} className=\"leading-relaxed\">\n {item.children?.map((child, childIndex) => (\n <Fragment key={child._key || childIndex}>\n {renderSpan(child, markDefs)}\n </Fragment>\n ))}\n </li>\n );\n })}\n </ListComponent>\n );\n };\n\n const renderBlock = (block: RichTextBlock): ReactNode => {\n const blockType = getBlockType(block);\n\n if (\n blockType === 'block' ||\n blockType === 'textblock' ||\n blockType === 'text'\n ) {\n return renderTextBlock(block as TextBlock);\n }\n\n if (blockType === 'image' || blockType === 'imageblock') {\n return renderImage(block as ImageBlock);\n }\n\n if (blockType === 'file' || blockType === 'fileblock') {\n return renderFileBlock(block as FileBlock);\n }\n\n return null;\n };\n\n // Process blocks and group consecutive list items\n const processedContent: ReactNode[] = [];\n let currentListItems: TextBlock[] = [];\n let currentListType: string | null = null;\n\n value.forEach((block: RichTextBlock, index: number) => {\n const blockType = getBlockType(block);\n\n if (blockType === 'block' && (block as TextBlock).listItem) {\n const textBlock = block as TextBlock;\n const listItem = textBlock.listItem || null;\n if (currentListType !== listItem) {\n if (currentListItems.length > 0 && currentListType) {\n processedContent.push(\n <Fragment key={`list-${index}`}>\n {renderList(currentListItems, currentListType)}\n </Fragment>\n );\n }\n currentListItems = [textBlock];\n currentListType = listItem;\n } else {\n currentListItems.push(textBlock);\n }\n } else {\n if (currentListItems.length > 0 && currentListType) {\n processedContent.push(\n <Fragment key={`list-${index}`}>\n {renderList(currentListItems, currentListType)}\n </Fragment>\n );\n currentListItems = [];\n currentListType = null;\n }\n processedContent.push(\n <Fragment key={block._key || index}>{renderBlock(block)}</Fragment>\n );\n }\n });\n\n if (currentListItems.length > 0 && currentListType) {\n processedContent.push(\n <Fragment key=\"final-list\">\n {renderList(currentListItems, currentListType)}\n </Fragment>\n );\n }\n\n return <div className=\"prose prose-ui max-w-none\">{processedContent}</div>;\n};\n\nexport { PortableText };\n"],"mappings":"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"}
|
|
@@ -1,12 +0,0 @@
|
|
|
1
|
-
import * as react_jsx_runtime11 from "react/jsx-runtime";
|
|
2
|
-
|
|
3
|
-
//#region src/components/search-modal/index.d.ts
|
|
4
|
-
type SearchModalProps = {
|
|
5
|
-
buttonClassName?: string;
|
|
6
|
-
};
|
|
7
|
-
declare function SearchModal({
|
|
8
|
-
buttonClassName
|
|
9
|
-
}: SearchModalProps): react_jsx_runtime11.JSX.Element;
|
|
10
|
-
//#endregion
|
|
11
|
-
export { SearchModal };
|
|
12
|
-
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","names":[],"sources":["../../../src/components/search-modal/index.tsx"],"sourcesContent":[],"mappings":";;;KAkBK,gBAAA;;;AAIqD,iBAAjD,WAAA,CAJY;EAAA;AAAA,CAAA,EAIqB,gBAJrB,CAAA,EAIqC,mBAAA,CAAA,GAAA,CAAA,OAJrC"}
|
|
@@ -1,138 +0,0 @@
|
|
|
1
|
-
'use client';
|
|
2
|
-
|
|
3
|
-
import { Modal } from "../modal/index.js";
|
|
4
|
-
import { useSearch } from "../../lib/hooks/use-search.js";
|
|
5
|
-
import { useEffect, useRef, useState } from "react";
|
|
6
|
-
import { usePathname } from "next/navigation";
|
|
7
|
-
import { Fragment as Fragment$1, jsx, jsxs } from "react/jsx-runtime";
|
|
8
|
-
import { Button } from "@medusajs/ui";
|
|
9
|
-
import Image from "next/image";
|
|
10
|
-
import { PlaceholderImage } from "@gfed-medusa/sf-lib-ui/icons/placeholder-image";
|
|
11
|
-
import DOMPurify from "isomorphic-dompurify";
|
|
12
|
-
import { cn } from "@gfed-medusa/sf-lib-ui/lib/utils";
|
|
13
|
-
|
|
14
|
-
//#region src/components/search-modal/index.tsx
|
|
15
|
-
function SearchModal({ buttonClassName }) {
|
|
16
|
-
const [isOpen, setIsOpen] = useState(false);
|
|
17
|
-
const pathname = usePathname();
|
|
18
|
-
const { query, setQuery, results, loading, error, isTyping } = useSearch();
|
|
19
|
-
useEffect(() => {
|
|
20
|
-
setIsOpen(false);
|
|
21
|
-
}, [pathname]);
|
|
22
|
-
useEffect(() => {
|
|
23
|
-
if (!isOpen) setQuery("");
|
|
24
|
-
}, [isOpen, setQuery]);
|
|
25
|
-
return /* @__PURE__ */ jsxs(Fragment$1, { children: [/* @__PURE__ */ jsx("div", {
|
|
26
|
-
className: cn("small:flex hidden h-full items-center gap-x-6", buttonClassName),
|
|
27
|
-
children: /* @__PURE__ */ jsx(Button, {
|
|
28
|
-
onClick: () => setIsOpen(true),
|
|
29
|
-
variant: "transparent",
|
|
30
|
-
className: "text-small-regular hover:text-ui-fg-base px-0 hover:bg-transparent focus:!bg-transparent",
|
|
31
|
-
"data-testid": "search-button",
|
|
32
|
-
children: "Search"
|
|
33
|
-
})
|
|
34
|
-
}), /* @__PURE__ */ jsx(Modal, {
|
|
35
|
-
isOpen,
|
|
36
|
-
close: () => setIsOpen(false),
|
|
37
|
-
"aria-label": "Search modal",
|
|
38
|
-
children: /* @__PURE__ */ jsxs("div", {
|
|
39
|
-
className: "flex h-full max-h-[75vh] min-h-0 flex-col",
|
|
40
|
-
children: [/* @__PURE__ */ jsx("div", {
|
|
41
|
-
className: "shrink-0",
|
|
42
|
-
children: /* @__PURE__ */ jsx(SearchBox, {
|
|
43
|
-
query,
|
|
44
|
-
setQuery,
|
|
45
|
-
loading
|
|
46
|
-
})
|
|
47
|
-
}), /* @__PURE__ */ jsx("div", {
|
|
48
|
-
className: "mt-4 min-h-0 flex-1 overflow-y-auto",
|
|
49
|
-
children: /* @__PURE__ */ jsx(SearchResults, {
|
|
50
|
-
results,
|
|
51
|
-
loading,
|
|
52
|
-
error,
|
|
53
|
-
query,
|
|
54
|
-
isTyping
|
|
55
|
-
})
|
|
56
|
-
})]
|
|
57
|
-
})
|
|
58
|
-
})] });
|
|
59
|
-
}
|
|
60
|
-
const SearchBox = ({ query, setQuery, loading }) => {
|
|
61
|
-
const inputRef = useRef(null);
|
|
62
|
-
useEffect(() => {
|
|
63
|
-
if (inputRef.current && document.activeElement !== inputRef.current) inputRef.current.focus();
|
|
64
|
-
}, [loading]);
|
|
65
|
-
return /* @__PURE__ */ jsx("div", {
|
|
66
|
-
className: "relative w-full",
|
|
67
|
-
children: /* @__PURE__ */ jsx("input", {
|
|
68
|
-
ref: inputRef,
|
|
69
|
-
type: "text",
|
|
70
|
-
value: query,
|
|
71
|
-
onChange: (e) => setQuery(e.target.value),
|
|
72
|
-
placeholder: "Search products...",
|
|
73
|
-
className: "w-full rounded-md border border-gray-300 px-4 py-2 focus:outline-none focus-visible:outline-2 focus-visible:outline-blue-500",
|
|
74
|
-
disabled: loading,
|
|
75
|
-
autoFocus: true,
|
|
76
|
-
"data-testid": "search-input"
|
|
77
|
-
})
|
|
78
|
-
});
|
|
79
|
-
};
|
|
80
|
-
const SearchResults = ({ results, loading, error, query, isTyping }) => {
|
|
81
|
-
if (loading) return /* @__PURE__ */ jsx("div", {
|
|
82
|
-
className: "flex min-h-full items-center justify-center",
|
|
83
|
-
children: /* @__PURE__ */ jsxs("div", {
|
|
84
|
-
className: "text-center",
|
|
85
|
-
children: [/* @__PURE__ */ jsx("div", { className: "mx-auto h-8 w-8 animate-spin rounded-full border-b-2 border-blue-500" }), /* @__PURE__ */ jsx("p", {
|
|
86
|
-
className: "mt-2 text-sm text-gray-500",
|
|
87
|
-
children: "Searching..."
|
|
88
|
-
})]
|
|
89
|
-
})
|
|
90
|
-
});
|
|
91
|
-
if (error) return /* @__PURE__ */ jsx("div", {
|
|
92
|
-
className: "flex min-h-full items-center justify-center text-rose-600",
|
|
93
|
-
children: /* @__PURE__ */ jsxs("p", { children: ["Error: ", error] })
|
|
94
|
-
});
|
|
95
|
-
if (query.trim() && !isTyping && !loading && (!results || !results.items || results.items.length === 0)) return /* @__PURE__ */ jsx("div", {
|
|
96
|
-
className: "flex min-h-full items-center justify-center text-gray-500",
|
|
97
|
-
children: /* @__PURE__ */ jsx("p", { children: "No products found" })
|
|
98
|
-
});
|
|
99
|
-
if (!query.trim()) return null;
|
|
100
|
-
return /* @__PURE__ */ jsx("div", { children: results?.items?.map((hit) => /* @__PURE__ */ jsx(Hit, { hit }, hit.id)) });
|
|
101
|
-
};
|
|
102
|
-
const Hit = ({ hit }) => {
|
|
103
|
-
return /* @__PURE__ */ jsxs("div", {
|
|
104
|
-
className: "relative mt-4 flex flex-row gap-x-2",
|
|
105
|
-
"data-testid": "search-hit",
|
|
106
|
-
children: [
|
|
107
|
-
/* @__PURE__ */ jsx("div", {
|
|
108
|
-
className: "relative h-[100px] w-[100px] shrink-0 overflow-hidden border border-gray-200",
|
|
109
|
-
children: hit.thumbnail ? /* @__PURE__ */ jsx(Image, {
|
|
110
|
-
src: hit.thumbnail,
|
|
111
|
-
alt: hit.title ?? "Product Image",
|
|
112
|
-
width: 100,
|
|
113
|
-
height: 100,
|
|
114
|
-
className: "aspect-square object-cover"
|
|
115
|
-
}) : /* @__PURE__ */ jsx("div", {
|
|
116
|
-
className: "border-grey-400 flex h-[125px] w-[100px] items-center justify-center self-start border",
|
|
117
|
-
children: /* @__PURE__ */ jsx(PlaceholderImage, { size: 40 })
|
|
118
|
-
})
|
|
119
|
-
}),
|
|
120
|
-
/* @__PURE__ */ jsxs("div", {
|
|
121
|
-
className: "flex flex-col gap-y-1",
|
|
122
|
-
children: [/* @__PURE__ */ jsx("h3", { children: hit.title }), /* @__PURE__ */ jsx("p", {
|
|
123
|
-
className: "text-sm text-gray-500",
|
|
124
|
-
dangerouslySetInnerHTML: { __html: DOMPurify.sanitize(hit.description ?? "") }
|
|
125
|
-
})]
|
|
126
|
-
}),
|
|
127
|
-
/* @__PURE__ */ jsx("a", {
|
|
128
|
-
href: `/products/${hit.handle}`,
|
|
129
|
-
className: "absolute top-0 right-0 h-full w-full",
|
|
130
|
-
"aria-label": `View Product: ${hit.title}`
|
|
131
|
-
})
|
|
132
|
-
]
|
|
133
|
-
});
|
|
134
|
-
};
|
|
135
|
-
|
|
136
|
-
//#endregion
|
|
137
|
-
export { SearchModal };
|
|
138
|
-
//# sourceMappingURL=index.js.map
|