@marvalt/shcoder 0.1.5 → 0.1.7

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.
@@ -5,9 +5,15 @@
5
5
  * Copyright (c) 2025 Vibune Pty Ltd.
6
6
  */
7
7
  import React from 'react';
8
- import type { ShortcodeAttributes } from '../types/member';
8
+ import type { Member, ShortcodeAttributes } from '../types/member';
9
9
  export interface MemberCardsGridProps extends ShortcodeAttributes {
10
10
  className?: string;
11
+ /** When set, the card (or optional button) links to this URL. */
12
+ getProfileUrl?: (member: Member) => string | undefined;
13
+ /** When set with getProfileUrl, renders a built-in button linking to the profile. */
14
+ profileButtonLabel?: string;
15
+ /** Custom card action (e.g. "View profile" button/link). Rendered in card footer. */
16
+ renderCardAction?: (member: Member) => React.ReactNode;
11
17
  }
12
18
  /**
13
19
  * MemberCardsGrid component - displays multiple members in a grid
@@ -1 +1 @@
1
- {"version":3,"file":"MemberCardsGrid.d.ts","sourceRoot":"","sources":["../../src/components/MemberCardsGrid.tsx"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,MAAM,OAAO,CAAC;AAE1B,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,iBAAiB,CAAC;AAG3D,MAAM,WAAW,oBAAqB,SAAQ,mBAAmB;IAC/D,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED;;;GAGG;AACH,eAAO,MAAM,eAAe,EAAE,KAAK,CAAC,EAAE,CAAC,oBAAoB,CA+F1D,CAAC"}
1
+ {"version":3,"file":"MemberCardsGrid.d.ts","sourceRoot":"","sources":["../../src/components/MemberCardsGrid.tsx"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,MAAM,OAAO,CAAC;AAE1B,OAAO,KAAK,EAAE,MAAM,EAAE,mBAAmB,EAAE,MAAM,iBAAiB,CAAC;AAGnE,MAAM,WAAW,oBAAqB,SAAQ,mBAAmB;IAC/D,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,iEAAiE;IACjE,aAAa,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,MAAM,GAAG,SAAS,CAAC;IACvD,qFAAqF;IACrF,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,qFAAqF;IACrF,gBAAgB,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,KAAK,CAAC,SAAS,CAAC;CACxD;AAED;;;GAGG;AACH,eAAO,MAAM,eAAe,EAAE,KAAK,CAAC,EAAE,CAAC,oBAAoB,CAuI1D,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"useMembers.d.ts","sourceRoot":"","sources":["../../src/hooks/useMembers.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAGH,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,iBAAiB,CAAC;AAC9C,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,oBAAoB,CAAC;AAS9D,wBAAgB,kBAAkB,CAAC,GAAG,EAAE,MAAM,QAE7C;AA0BD,KAAK,kBAAkB,GAAG,MAAM;IAC9B,OAAO,EAAE,GAAG,EAAE,CAAC;IACf,aAAa,EAAE,CAAC,EAAE,EAAE,MAAM,GAAG,MAAM,KAAK,GAAG,GAAG,IAAI,CAAC;IACnD,aAAa,EAAE,CAAC,OAAO,EAAE;QACvB,QAAQ,CAAC,EAAE,MAAM,CAAC;QAClB,IAAI,CAAC,EAAE,MAAM,CAAC;QACd,KAAK,CAAC,EAAE,MAAM,CAAC;QACf,OAAO,CAAC,EAAE,MAAM,CAAC;QACjB,KAAK,CAAC,EAAE,MAAM,CAAC;KAChB,KAAK,GAAG,EAAE,CAAC;CACb,CAAC;AAIF,wBAAgB,qBAAqB,CAAC,QAAQ,EAAE,kBAAkB,QAEjE;AAqCD;;GAEG;AACH,wBAAgB,UAAU,CAAC,KAAK,EAAE,mBAAmB;;;;EAwGpD;AAED;;GAEG;AACH,wBAAgB,SAAS,CAAC,EAAE,EAAE,MAAM,GAAG,MAAM;;;;EA0E5C"}
1
+ {"version":3,"file":"useMembers.d.ts","sourceRoot":"","sources":["../../src/hooks/useMembers.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAGH,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,iBAAiB,CAAC;AAC9C,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,oBAAoB,CAAC;AAS9D,wBAAgB,kBAAkB,CAAC,GAAG,EAAE,MAAM,QAE7C;AA0BD,KAAK,kBAAkB,GAAG,MAAM;IAC9B,OAAO,EAAE,GAAG,EAAE,CAAC;IACf,aAAa,EAAE,CAAC,EAAE,EAAE,MAAM,GAAG,MAAM,KAAK,GAAG,GAAG,IAAI,CAAC;IACnD,aAAa,EAAE,CAAC,OAAO,EAAE;QACvB,QAAQ,CAAC,EAAE,MAAM,CAAC;QAClB,IAAI,CAAC,EAAE,MAAM,CAAC;QACd,KAAK,CAAC,EAAE,MAAM,CAAC;QACf,OAAO,CAAC,EAAE,MAAM,CAAC;QACjB,KAAK,CAAC,EAAE,MAAM,CAAC;KAChB,KAAK,GAAG,EAAE,CAAC;CACb,CAAC;AAIF,wBAAgB,qBAAqB,CAAC,QAAQ,EAAE,kBAAkB,QAEjE;AAqCD;;GAEG;AACH,wBAAgB,UAAU,CAAC,KAAK,EAAE,mBAAmB;;;;EAsGpD;AAED;;GAEG;AACH,wBAAgB,SAAS,CAAC,EAAE,EAAE,MAAM,GAAG,MAAM;;;;EAuE5C"}
package/dist/index.cjs CHANGED
@@ -95,11 +95,11 @@ function useMembers(attrs) {
95
95
  orderby: attrs.orderby || 'date',
96
96
  order: attrs.order || 'desc',
97
97
  });
98
- // Process members to match Member interface
98
+ // Process members: preserve all keys (including ACF in member_meta); only normalize featured_image_urls
99
99
  const processedMembers = filtered.map((member) => {
100
100
  const processed = {
101
101
  ...member,
102
- member_meta: member.member_meta || {},
102
+ member_meta: member.member_meta ?? {},
103
103
  featured_image_urls: extractFeaturedImage(member),
104
104
  };
105
105
  return processed;
@@ -141,11 +141,11 @@ function useMembers(attrs) {
141
141
  throw new Error(`Failed to fetch members: ${response.statusText}`);
142
142
  }
143
143
  const data = await response.json();
144
- // Process members to extract featured images from _embedded
144
+ // Process members: preserve all keys (including ACF in member_meta); only normalize featured_image_urls
145
145
  const processedMembers = data.map((member) => {
146
146
  const processed = {
147
147
  ...member,
148
- member_meta: member.member_meta || {},
148
+ member_meta: member.member_meta ?? {},
149
149
  featured_image_urls: extractFeaturedImage(member),
150
150
  };
151
151
  return processed;
@@ -185,10 +185,10 @@ function useMember(id) {
185
185
  const provider = staticDataProvider();
186
186
  const found = provider.getMemberById(id);
187
187
  if (found) {
188
- // Process member to match Member interface
188
+ // Preserve all keys (including ACF in member_meta); only normalize featured_image_urls
189
189
  const processed = {
190
190
  ...found,
191
- member_meta: found.member_meta || {},
191
+ member_meta: found.member_meta ?? {},
192
192
  featured_image_urls: extractFeaturedImage(found),
193
193
  };
194
194
  setMember(processed);
@@ -210,10 +210,10 @@ function useMember(id) {
210
210
  throw new Error(`Failed to fetch member: ${response.statusText}`);
211
211
  }
212
212
  const data = await response.json();
213
- // Process member to extract featured image from _embedded
213
+ // Preserve all keys (including ACF in member_meta); only normalize featured_image_urls
214
214
  const processed = {
215
215
  ...data,
216
- member_meta: data.member_meta || {},
216
+ member_meta: data.member_meta ?? {},
217
217
  featured_image_urls: extractFeaturedImage(data),
218
218
  };
219
219
  setMember(processed);
@@ -1769,7 +1769,7 @@ function getCloudflareVariantUrl(url, options) {
1769
1769
  }
1770
1770
  const { width, height } = options;
1771
1771
  const base = url.endsWith('/') ? url.slice(0, -1) : url;
1772
- const variant = `w=${Math.max(1, Math.floor(width))}` + (`,h=${Math.max(1, Math.floor(height))}` );
1772
+ const variant = `w=${Math.max(1, Math.floor(width))}` + (height != null ? `,h=${Math.max(1, Math.floor(height))}` : '');
1773
1773
  return `${base}/${variant}`;
1774
1774
  }
1775
1775
 
@@ -1777,7 +1777,7 @@ function getCloudflareVariantUrl(url, options) {
1777
1777
  * MemberCardsGrid component - displays multiple members in a grid
1778
1778
  * Usage: [member_cards tax="leadership" cols="3" image="true"]
1779
1779
  */
1780
- const MemberCardsGrid = ({ tax, category, role, cols = '3', image = 'true', limit, orderby, order, className = '', }) => {
1780
+ const MemberCardsGrid = ({ tax, category, role, cols = '3', image = 'true', limit, orderby, order, className = '', getProfileUrl, profileButtonLabel, renderCardAction, }) => {
1781
1781
  const { members, loading, error } = useMembers({
1782
1782
  tax: tax || category,
1783
1783
  role,
@@ -1805,18 +1805,28 @@ const MemberCardsGrid = ({ tax, category, role, cols = '3', image = 'true', limi
1805
1805
  }[colsNum] || 'grid-cols-1 md:grid-cols-2 lg:grid-cols-3';
1806
1806
  return (jsxRuntimeExports.jsx("div", { className: `member-cards-grid grid ${gridCols} gap-6 ${className}`, children: members.map((member) => {
1807
1807
  const meta = member.member_meta || {};
1808
- const rawImageUrl = showImage
1809
- ? (member.featured_image_urls?.medium?.url || member.featured_image_urls?.full?.url)
1808
+ // Prefer Cloudflare URL from static generator enrichment (featured_media_cloudflare_url), then featured_image_urls
1809
+ const cfFromEnrichment = showImage && typeof member.featured_media_cloudflare_url === 'string'
1810
+ ? member.featured_media_cloudflare_url
1810
1811
  : null;
1811
- // Prefer Cloudflare URLs with 9:16 @ 720x1280, but fall back to any URL so images still render
1812
- const imageUrl = rawImageUrl
1813
- ? (isCloudflareImageUrl(rawImageUrl)
1814
- ? getCloudflareVariantUrl(rawImageUrl, { width: 720, height: 1280 })
1815
- : rawImageUrl)
1812
+ const rawImageUrl = showImage && !cfFromEnrichment
1813
+ ? (member.featured_image_urls?.medium?.url || member.featured_image_urls?.full?.url)
1816
1814
  : null;
1815
+ const imageUrl = cfFromEnrichment
1816
+ ? getCloudflareVariantUrl(cfFromEnrichment, { width: 720, height: 1280 })
1817
+ : rawImageUrl
1818
+ ? (isCloudflareImageUrl(rawImageUrl)
1819
+ ? getCloudflareVariantUrl(rawImageUrl, { width: 720, height: 1280 })
1820
+ : rawImageUrl)
1821
+ : null;
1817
1822
  const fullName = [meta.members_firstname, meta.members_last_name].filter(Boolean).join(' ')
1818
1823
  || member.title.rendered;
1819
- return (jsxRuntimeExports.jsxs("div", { className: "member-card bg-white rounded-lg shadow-md overflow-hidden", children: [imageUrl && (jsxRuntimeExports.jsx("div", { className: "member-card-image aspect-[9/16] w-full overflow-hidden bg-slate-100", children: jsxRuntimeExports.jsx("img", { src: imageUrl, alt: fullName, className: "h-full w-full object-cover" }) })), jsxRuntimeExports.jsxs("div", { className: "member-card-content p-6", children: [jsxRuntimeExports.jsx("h3", { className: "member-card-name text-xl font-bold mb-2", children: fullName }), meta.member_role && (jsxRuntimeExports.jsx("p", { className: "member-card-role text-gray-600 mb-2", children: meta.member_role })), meta.business_name && (jsxRuntimeExports.jsx("p", { className: "member-card-company text-sm text-gray-500 mb-2", children: meta.business_name })), meta.tagline && (jsxRuntimeExports.jsx("p", { className: "member-card-tagline text-sm italic mb-3", children: meta.tagline })), meta.member_pitch && (jsxRuntimeExports.jsx("p", { className: "member-card-pitch text-sm mb-3 line-clamp-3", children: meta.member_pitch })), meta.website && (jsxRuntimeExports.jsx("a", { href: meta.website, target: "_blank", rel: "noopener noreferrer", className: "member-card-website text-blue-600 hover:underline text-sm", children: "Visit Website \u2192" }))] })] }, member.id));
1824
+ const profileUrl = getProfileUrl?.(member);
1825
+ const hasExplicitAction = !!(profileButtonLabel || renderCardAction);
1826
+ const wrapCardInLink = profileUrl && !hasExplicitAction;
1827
+ const cardContent = (jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [imageUrl && (jsxRuntimeExports.jsx("div", { className: "member-card-image aspect-[9/16] w-full overflow-hidden bg-slate-100", children: jsxRuntimeExports.jsx("img", { src: imageUrl, alt: fullName, className: "h-full w-full object-cover" }) })), jsxRuntimeExports.jsxs("div", { className: "member-card-content p-6", children: [jsxRuntimeExports.jsx("h3", { className: "member-card-name text-xl font-bold mb-2", children: fullName }), meta.member_role && (jsxRuntimeExports.jsx("p", { className: "member-card-role text-gray-600 mb-2", children: meta.member_role })), meta.business_name && (jsxRuntimeExports.jsx("p", { className: "member-card-company text-sm text-gray-500 mb-2", children: meta.business_name })), meta.tagline && (jsxRuntimeExports.jsx("p", { className: "member-card-tagline text-sm italic mb-3", children: meta.tagline })), meta.member_pitch && (jsxRuntimeExports.jsx("p", { className: "member-card-pitch text-sm mb-3 line-clamp-3", children: meta.member_pitch })), meta.website && (jsxRuntimeExports.jsx("a", { href: meta.website, target: "_blank", rel: "noopener noreferrer", className: "member-card-website text-blue-600 hover:underline text-sm", children: "Visit Website \u2192" })), hasExplicitAction && (jsxRuntimeExports.jsx("div", { className: "member-card-actions mt-4", children: renderCardAction ? (renderCardAction(member)) : profileUrl && profileButtonLabel ? (jsxRuntimeExports.jsx("a", { href: profileUrl, className: "member-card-profile-button inline-block px-4 py-2 text-sm font-medium text-white bg-blue-600 rounded-md hover:bg-blue-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-blue-500", children: profileButtonLabel })) : null }))] })] }));
1828
+ const cardInner = wrapCardInLink ? (jsxRuntimeExports.jsx("a", { href: profileUrl, className: "member-card-link block h-full text-inherit no-underline hover:opacity-95 focus:outline-none focus:ring-2 focus:ring-inset focus:ring-blue-500 rounded-lg", children: cardContent })) : (cardContent);
1829
+ return (jsxRuntimeExports.jsx("div", { className: "member-card bg-white rounded-lg shadow-md overflow-hidden", children: cardInner }, member.id));
1820
1830
  }) }));
1821
1831
  };
1822
1832