@nuskin/marketing-components 1.3.0 → 1.4.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.
@@ -0,0 +1,3 @@
1
+ export { default as useRouteReplacer } from './useRouteReplacer';
2
+ export { default as useMainContrast } from './use-toggle-font-color/useMainContrast';
3
+ export { default as useToggleFontColor } from './use-toggle-font-color/useToggleFontColor';
@@ -0,0 +1,8 @@
1
+ /**
2
+ * @returns {main:#FFFFFF, contrast:#252525} when passed true
3
+ */
4
+ declare const useMainContrast: (toggleValue?: boolean) => {
5
+ main: string;
6
+ contrast: string;
7
+ };
8
+ export default useMainContrast;
@@ -0,0 +1,8 @@
1
+ /**
2
+ * Used to fetch the appropriate theme color for primary and contrast.
3
+ * Usually black or similar, and white for contrast.
4
+ * @param toggleValue the CS toggle value between black and white font color.
5
+ * @returns hex value of the color.
6
+ */
7
+ declare const useToggleFontColor: (toggleValue?: boolean) => string;
8
+ export default useToggleFontColor;
@@ -0,0 +1,10 @@
1
+ /**
2
+ * Simply use this hook to update the region and language in the url
3
+ * Note: urlToParse should have {%region} or {%language} or {%rREGION} or {%LANGUAGE}
4
+ * @param urlToParse url to be parsed
5
+ * @returns urlToParse after conditionally replacing the region and language
6
+ */
7
+ declare const useRouteReplacer: (urlToParse?: string) => {
8
+ url?: string;
9
+ };
10
+ export default useRouteReplacer;
@@ -0,0 +1 @@
1
+ export {};
@@ -1,3 +1,4 @@
1
1
  import type { CsImageProps } from './types';
2
+ export declare const PLACEHOLDER_IMAGE_SRC: string;
2
3
  declare const CsImage: (props: CsImageProps) => import("react/jsx-runtime").JSX.Element;
3
4
  export default CsImage;
@@ -12,8 +12,11 @@ export type NsImageProps = {
12
12
  export interface CsImageProps extends Partial<NsImageProps> {
13
13
  image_alignment?: 'left' | 'center' | 'right';
14
14
  image?: string | {
15
- image: any[];
15
+ image: CSImage[];
16
16
  };
17
+ isEditing?: boolean;
18
+ parent$?: Record<string, unknown>;
19
+ $?: Record<string, unknown>;
17
20
  }
18
21
  export type CSImage = {
19
22
  previewUrls: string[];
@@ -47,3 +50,24 @@ export type ImageFileMeta = {
47
50
  height: number | null;
48
51
  fileSize: number | null;
49
52
  };
53
+ /**
54
+ * Contentstack native asset format (fallback when Bynder image is not available)
55
+ */
56
+ export type ContentstackAsset = {
57
+ uid: string;
58
+ created_by: string;
59
+ updated_by: string;
60
+ created_at: string;
61
+ updated_at: string;
62
+ content_type: string;
63
+ file_size: string;
64
+ filename: string;
65
+ title: string;
66
+ url: string;
67
+ ACL?: Record<string, unknown>[];
68
+ _version?: number;
69
+ is_dir?: boolean;
70
+ tags?: string[];
71
+ parent_uid?: string;
72
+ $?: Record<string, unknown>;
73
+ };
package/dist/index.js CHANGED
@@ -1 +1 @@
1
- "use strict";function e(e,n,t){if(n in e){Object.defineProperty(e,n,{value:t,enumerable:true,configurable:true,writable:true})}else{e[n]=t}return e}function n(n){for(var t=1;t<arguments.length;t++){var r=arguments[t]!=null?arguments[t]:{};var i=Object.keys(r);if(typeof Object.getOwnPropertySymbols==="function"){i=i.concat(Object.getOwnPropertySymbols(r).filter(function(e){return Object.getOwnPropertyDescriptor(r,e).enumerable}))}i.forEach(function(t){e(n,t,r[t])})}return n}function t(e,n){if(e==null)return{};var t=r(e,n);var i,o;if(Object.getOwnPropertySymbols){var l=Object.getOwnPropertySymbols(e);for(o=0;o<l.length;o++){i=l[o];if(n.indexOf(i)>=0)continue;if(!Object.prototype.propertyIsEnumerable.call(e,i))continue;t[i]=e[i]}}return t}function r(e,n){if(e==null)return{};var t={};var r=Object.keys(e);var i,o;for(o=0;o<r.length;o++){i=r[o];if(n.indexOf(i)>=0)continue;t[i]=e[i]}return t}function i(e,n){if(!n){n=e.slice(0)}return Object.freeze(Object.defineProperties(e,{raw:{value:Object.freeze(n)}}))}function o(e){"@swc/helpers - typeof";return e&&typeof Symbol!=="undefined"&&e.constructor===Symbol?"symbol":typeof e}function l(){var e=i(["\n width: ",";\n background-color: ",";\n text-align: ",";\n color: ",";\n padding: 16px 32px;\n h1,\n h2,\n h3,\n h4,\n h5,\n h6 {\n font-family: 'Lora', serif;\n }\n h1 {\n font-size: 42px;\n line-height: 48px;\n }\n h2 {\n font-size: 36px;\n line-height: 42px;\n }\n h3 {\n font-size: 32px;\n line-height: 38px;\n }\n h4 {\n font-size: 26px;\n line-height: 34px;\n }\n h5 {\n font-size: 22px;\n line-height: 28px;\n }\n h6 {\n font-size: 18px;\n line-height: 24px;\n }\n p {\n margin: 0;\n padding: 0;\n }\n"]);l=function n(){return e};return e}var u=Object.create;var a=Object.defineProperty;var c=Object.getOwnPropertyDescriptor;var f=Object.getOwnPropertyNames;var d=Object.getPrototypeOf,v=Object.prototype.hasOwnProperty;var s=function(e,n){for(var t in n)a(e,t,{get:n[t],enumerable:!0})},h=function(e,n,t,r){var i=true,l=false,u=undefined;if(n&&(typeof n==="undefined"?"undefined":o(n))=="object"||typeof n=="function")try{var d=function(){var i=h.value;!v.call(e,i)&&i!==t&&a(e,i,{get:function(){return n[i]},enumerable:!(r=c(n,i))||r.enumerable})};for(var s=f(n)[Symbol.iterator](),h;!(i=(h=s.next()).done);i=true)d()}catch(e){l=true;u=e}finally{try{if(!i&&s.return!=null){s.return()}}finally{if(l){throw u}}}return e};var p=function(e,n,t){return t=e!=null?u(d(e)):{},h(n||!e||!e.__esModule?a(t,"default",{value:e,enumerable:!0}):t,e)},g=function(e){return h(a({},"__esModule",{value:!0}),e)};var m={};s(m,{CsImage:function(){return I},CsTextComponent:function(){return P}});module.exports=g(m);var b=require("react"),y=require("@nuskin/foundation-core-app/common/hooks"),x=p(require("@emotion/styled")),O=require("react/jsx-runtime"),j=function(e,n){var t=new DOMParser().parseFromString(e,"text/html");return t.querySelectorAll("a").forEach(function(e){var t;var r=(t=e.getAttribute("href"))!==null&&t!==void 0?t:"",i=n(r),o=i.url,l=o===void 0?"":o;e.setAttribute("href",l.startsWith("http")?l:"https://".concat(l))}),t.body.innerHTML},w=x.default.div(l(),function(e){var n=e.fullWidth;return n?"100%":"auto"},function(e){var n=e.bgColor;return n},function(e){var n=e.alignment;return n},function(e){var n=e.color;return n}),_=function(e){var n=e.full_width,t=n===void 0?!1:n,r=e.container_background_color,i=r===void 0?"":r,l=e.alignment,u=l===void 0?"left":l,a=e.text_editor,c=e.font_color,f=c===void 0?!1:c;var d=(0,y.useToggleFontColor)(f),v=(0,y.useRouteReplacer)(),s=function(e){var n;var t;return typeof v=="function"?{url:(t=(n=v(e))===null||n===void 0?void 0:n.url)!==null&&t!==void 0?t:""}:{url:e}},h=(0,b.useMemo)(function(){try{var e,n,t;if(i)return((t=JSON.parse(i))===null||t===void 0?void 0:(n=t.brandColor)===null||n===void 0?void 0:(e=n.colorObj)===null||e===void 0?void 0:e.light)||"transparent"}catch(e){return"transparent"}return"transparent"},[i]),p=(0,b.useMemo)(function(){return(typeof window==="undefined"?"undefined":o(window))>"u"?a:j(a,s)},[a,v]);return(0,O.jsx)(w,{color:d,fullWidth:t,bgColor:h,alignment:u,children:(0,O.jsx)("div",{dangerouslySetInnerHTML:{__html:p}})})},P=_;var S=require("@nuskin/foundation-ui-components");var C=require("@nuskin/foundation-theme"),k=(0,C.styled)("div")(function(e){var n=e.image_alignment,t=n===void 0?"center":n,r=e.width,i=e.height;return{display:"flex",justifyContent:({left:"flex-start",right:"flex-end",center:"center"})[t],"& img":{maxWidth:"fit-content",objectFit:"contain",objectPosition:"center"}}});var q=require("react/jsx-runtime"),z=["alt","className","fill","height","id","src","variant","width"],M=function(e){var r;var i=e.image_alignment,o=i===void 0?"center":i,l=e.image,u=t(e,["image_alignment","image"]),a=null,c=null;try{var f,d;var v=(d=typeof l=="string"?JSON.parse(l):l)===null||d===void 0?void 0:(f=d.image)===null||f===void 0?void 0:f[0];a=v===null||v===void 0?void 0:v.selected,c=v===null||v===void 0?void 0:v.files}catch(e){console.warn("[CsImage] Failed to parse image prop:",e)}var s,h;var p=(a===null||a===void 0?void 0:a.imageType)||"transformBaseUrl",g={src:(c===null||c===void 0?void 0:(r=c[p])===null||r===void 0?void 0:r.url)||"",alt:(a===null||a===void 0?void 0:a.altText)||"Image not available",width:(s=a===null||a===void 0?void 0:a.width)!==null&&s!==void 0?s:"100%",height:(h=a===null||a===void 0?void 0:a.height)!==null&&h!==void 0?h:"100%"};z.forEach(function(e){u[e]!==void 0&&(g[e]=u[e])});var m=(u===null||u===void 0?void 0:u.full_width)?"container !p-0":"";return(0,q.jsx)(k,{image_alignment:o,width:g.width,height:g.height,className:m,children:(0,q.jsx)(S.NsImage,n({},g))})},I=M;//# sourceMappingURL=index.js.map
1
+ "use strict";function e(e,n,r){if(n in e){Object.defineProperty(e,n,{value:r,enumerable:true,configurable:true,writable:true})}else{e[n]=r}return e}function n(n){for(var r=1;r<arguments.length;r++){var t=arguments[r]!=null?arguments[r]:{};var i=Object.keys(t);if(typeof Object.getOwnPropertySymbols==="function"){i=i.concat(Object.getOwnPropertySymbols(t).filter(function(e){return Object.getOwnPropertyDescriptor(t,e).enumerable}))}i.forEach(function(r){e(n,r,t[r])})}return n}function r(e,n){if(e==null)return{};var r=t(e,n);var i,o;if(Object.getOwnPropertySymbols){var l=Object.getOwnPropertySymbols(e);for(o=0;o<l.length;o++){i=l[o];if(n.indexOf(i)>=0)continue;if(!Object.prototype.propertyIsEnumerable.call(e,i))continue;r[i]=e[i]}}return r}function t(e,n){if(e==null)return{};var r={};var t=Object.keys(e);var i,o;for(o=0;o<t.length;o++){i=t[o];if(n.indexOf(i)>=0)continue;r[i]=e[i]}return r}function i(e,n){if(!n){n=e.slice(0)}return Object.freeze(Object.defineProperties(e,{raw:{value:Object.freeze(n)}}))}function o(e){"@swc/helpers - typeof";return e&&typeof Symbol!=="undefined"&&e.constructor===Symbol?"symbol":typeof e}function l(){var e=i(["\n width: ",";\n background-color: ",";\n text-align: ",";\n color: ",";\n padding: 16px 32px;\n\n h1,\n h2,\n h3,\n h4,\n h5,\n h6 {\n font-family: 'Lora', serif;\n }\n\n h1 {\n font-size: 42px;\n line-height: 48px;\n }\n h2 {\n font-size: 36px;\n line-height: 42px;\n }\n h3 {\n font-size: 32px;\n line-height: 38px;\n }\n h4 {\n font-size: 26px;\n line-height: 34px;\n }\n h5 {\n font-size: 22px;\n line-height: 28px;\n }\n h6 {\n font-size: 18px;\n line-height: 24px;\n }\n\n p {\n margin: 0;\n padding: 0;\n }\n"]);l=function n(){return e};return e}var a=Object.create;var u=Object.defineProperty;var d=Object.getOwnPropertyDescriptor;var f=Object.getOwnPropertyNames;var c=Object.getPrototypeOf,v=Object.prototype.hasOwnProperty;var s=function(e,n){for(var r in n)u(e,r,{get:n[r],enumerable:!0})},g=function(e,n,r,t){var i=true,l=false,a=undefined;if(n&&(typeof n==="undefined"?"undefined":o(n))=="object"||typeof n=="function")try{var c=function(){var i=g.value;!v.call(e,i)&&i!==r&&u(e,i,{get:function(){return n[i]},enumerable:!(t=d(n,i))||t.enumerable})};for(var s=f(n)[Symbol.iterator](),g;!(i=(g=s.next()).done);i=true)c()}catch(e){l=true;a=e}finally{try{if(!i&&s.return!=null){s.return()}}finally{if(l){throw a}}}return e};var h=function(e,n,r){return r=e!=null?a(c(e)):{},g(n||!e||!e.__esModule?u(r,"default",{value:e,enumerable:!0}):r,e)},p=function(e){return g(u({},"__esModule",{value:!0}),e)};var m={};s(m,{CsImage:function(){return er},CsTextComponent:function(){return K}});module.exports=p(m);var y=require("react"),b=h(require("@emotion/styled"));var w=require("react");var x="{%language}",O="{%LANGUAGE}",j="{%region}",P="{%REGION}",_=function(e){var n=arguments.length>1&&arguments[1]!==void 0?arguments[1]:{};return typeof e!="string"?"":(n.region&&(e=e.replace(j,n.region),e=e.replace(P,n.region.toUpperCase())),n.language&&(e=e.replace(x,n.language),e=e.replace(O,n.language.toUpperCase())),e)};var C=function(){if((typeof window==="undefined"?"undefined":o(window))>"u")return;var e,n;var r=new URLSearchParams(window.location.search),t=(e=r.get("region"))!==null&&e!==void 0?e:void 0,i=(n=r.get("language"))!==null&&n!==void 0?n:void 0;if(t||i)return{region:t,language:i}};var q=require("react"),k=require("@mui/material"),I=require("@nuskin/foundation-theme"),S=I.ColorUtils,M=S.getGenomeColor;var G=require("@mui/material"),L=require("@nuskin/foundation-theme"),N=require("react"),z=L.ColorUtils,E=z.getGenomeColor,U=function(){var e=arguments.length>0&&arguments[0]!==void 0?arguments[0]:!1;var n=(0,G.useTheme)();return(0,N.useMemo)(function(){return E(n,"N10",e?"light":"dark")},[e,n])},T=U;var A=require("react/jsx-runtime"),$=function(){return(0,y.useMemo)(function(){return C()},[])},W=function(e,n){return!n||!e?e:_(e,n)},D=function(e,n){if((typeof window==="undefined"?"undefined":o(window))>"u"||!e||!n)return e;var r=new DOMParser().parseFromString(e,"text/html");return r.querySelectorAll("a").forEach(function(e){var r=e.getAttribute("href");r&&e.setAttribute("href",W(r,n))}),r.body.innerHTML},F=b.default.div(l(),function(e){var n=e.fullWidth;return n?"100%":"auto"},function(e){var n=e.bgColor;return n},function(e){var n=e.alignment;return n},function(e){var n=e.color;return n}),R=function(e){var n,r;var t;var i=(t=e===null||e===void 0?void 0:(r=e.brandColor)===null||r===void 0?void 0:(n=r.colorObj)===null||n===void 0?void 0:n.light)!==null&&t!==void 0?t:e===null||e===void 0?void 0:e.color;return typeof i=="string"&&i.trim()?i:null},B=function(e){try{var n,r,t;var i=(t=JSON.parse(e))===null||t===void 0?void 0:(r=t.brandColor)===null||r===void 0?void 0:(n=r.colorObj)===null||n===void 0?void 0:n.light;return typeof i=="string"&&i.trim()?i:null}catch(e){return null}},H=function(e){if(!e)return"transparent";var n;if((typeof e==="undefined"?"undefined":o(e))=="object")return(n=R(e))!==null&&n!==void 0?n:"transparent";if(typeof e=="string"){var r=e.trim();var t;return r?r.startsWith("{")?(t=B(r))!==null&&t!==void 0?t:"transparent":r:"transparent"}return"transparent"},J=function(e){var r=e.full_width,t=r===void 0?!1:r,i=e.container_background_color,o=e.alignment,l=o===void 0?"left":o,a=e.text_editor,u=e.font_color,d=u===void 0?!1:u,f=e.$;var c=T(d),v=$(),s=(0,y.useMemo)(function(){return H(i)},[i]),g=(0,y.useMemo)(function(){return D(a,v)},[a,v]);return a?(0,A.jsx)(F,{fullWidth:t,bgColor:s,alignment:l,color:c,children:(0,A.jsx)("div",n({dangerouslySetInnerHTML:{__html:g}},f===null||f===void 0?void 0:f.text_editor))}):null},K=J;var Q=require("@nuskin/foundation-ui-components");var V=require("@nuskin/foundation-theme"),X=(0,V.styled)("div")(function(e){var n=e.image_alignment,r=n===void 0?"center":n,t=e.width,i=e.height;return{display:"flex",justifyContent:({left:"flex-start",right:"flex-end",center:"center"})[r],"& img":{maxWidth:"fit-content",objectFit:"contain",objectPosition:"center"}}});var Y=require("react/jsx-runtime"),Z="data:image/svg+xml;utf8,"+encodeURIComponent('<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 400 300" role="img" aria-label="Image not available">\n <defs>\n <linearGradient id="csImagePlaceholderGradient" x1="0" y1="0" x2="1" y2="1">\n <stop offset="0%" stop-color="#f3f4f6" />\n <stop offset="100%" stop-color="#e5e7eb" />\n </linearGradient>\n </defs>\n <rect width="400" height="300" fill="url(#csImagePlaceholderGradient)" />\n <g stroke="#d1d5db" stroke-width="4" stroke-linecap="round" stroke-linejoin="round" fill="none">\n <rect x="60" y="60" width="280" height="180" rx="12" />\n <path d="M120 200 L180 140 L230 185 L260 160 L320 210" />\n <circle cx="160" cy="120" r="20" />\n </g>\n </svg>'),ee=["alt","className","fill","height","id","src","variant","width"],en=function(e){var t=e.image_alignment,i=t===void 0?"center":t,o=e.image,l=e.parent$,a=e.isEditing,u=e.$,d=r(e,["image_alignment","image","parent$","isEditing","$"]),f=null,c=null,v=null;try{var s;var g=typeof o=="string"?JSON.parse(o):o,h=g===null||g===void 0?void 0:(s=g.image)===null||s===void 0?void 0:s[0];(h===null||h===void 0?void 0:h.selected)||(h===null||h===void 0?void 0:h.files)?(f=h===null||h===void 0?void 0:h.selected,c=h===null||h===void 0?void 0:h.files):(g===null||g===void 0?void 0:g.url)&&(v=g)}catch(e){console.warn("[CsImage] Failed to parse image prop:",e)}var p=Z,m="Image not available",y="100%",b="100%";if(f||c){var w;var x=(w=f===null||f===void 0?void 0:f.imageType)!==null&&w!==void 0?w:"transformBaseUrl",O=c===null||c===void 0?void 0:c[x];var j,P,_;(O===null||O===void 0?void 0:O.url)&&(p=O.url,m=(j=f===null||f===void 0?void 0:f.altText)!==null&&j!==void 0?j:"Image",y=(P=f===null||f===void 0?void 0:f.width)!==null&&P!==void 0?P:"100%",b=(_=f===null||f===void 0?void 0:f.height)!==null&&_!==void 0?_:"100%")}else(v===null||v===void 0?void 0:v.url)&&(p=v.url,m=v.title||v.filename||"Image");var C={src:p,alt:m,width:y,height:b};ee.forEach(function(e){d[e]!==void 0&&(C[e]=d[e])});var q=(d===null||d===void 0?void 0:d.full_width)?"container !p-0":"";return(0,Y.jsx)(X,{image_alignment:i,width:C.width,height:C.height,className:q,children:(0,Y.jsx)(Q.NsImage,n({},C,(u===null||u===void 0?void 0:u.image)||{}))})},er=en;//# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["/gitlab-runner-data/builds/ns-am/content-foundation/marketing-components/dist/index.js","../src/index.ts","../src/text/CsText.tsx","../src/image/CsImage.tsx","../src/image/CsImage.styled.tsx"],"names":["S","Object","create","g","defineProperty","T","getOwnPropertyDescriptor","N","getOwnPropertyNames","z","getPrototypeOf","R","prototype","hasOwnProperty","W","e","t","r","get","enumerable","x","o","n","call","v","__esModule","value","F","index_exports","__export","CsImage","CsImage_default","CsTextComponent","CsText_default","module","exports","__toCommonJS","import_react","require","import_hooks","import_styled","import_jsx_runtime","rewriteLinks","html","replacer","doc","DOMParser","parseFromString","querySelectorAll","forEach","link","href","getAttribute","sanitizedUrl","url","setAttribute","startsWith","body","innerHTML","Container","y","styled","div","fullWidth","bgColor","alignment","color","CsText","full_width","container_background_color","text_editor","font_color","resolvedFontColor","m","useToggleFontColor","routeReplacer","useRouteReplacer","safeRouteReplacer","backgroundColor","f","useMemo","JSON","parse","brandColor","colorObj","light","updatedHtml","window","d","jsx","children","dangerouslySetInnerHTML","__html","import_foundation_ui_components","import_foundation_theme","StyledCsImageWrapper","I","image_alignment","width","height","display","justifyContent","left","right","center","maxWidth","objectFit","objectPosition","allowedImageProps","props","fileMeta","align","image","rest","selectedImage","entry","selected","files","err","console","warn","imageType","imageProps","src","alt","altText","key","containerClassForNSImage","u","className","b","NsImage"],"mappings":"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","sourcesContent":["\"use strict\";var S=Object.create;var g=Object.defineProperty;var T=Object.getOwnPropertyDescriptor;var N=Object.getOwnPropertyNames;var z=Object.getPrototypeOf,R=Object.prototype.hasOwnProperty;var W=(e,t)=>{for(var r in t)g(e,r,{get:t[r],enumerable:!0})},x=(e,t,r,o)=>{if(t&&typeof t==\"object\"||typeof t==\"function\")for(let n of N(t))!R.call(e,n)&&n!==r&&g(e,n,{get:()=>t[n],enumerable:!(o=T(t,n))||o.enumerable});return e};var v=(e,t,r)=>(r=e!=null?S(z(e)):{},x(t||!e||!e.__esModule?g(r,\"default\",{value:e,enumerable:!0}):r,e)),F=e=>x(g({},\"__esModule\",{value:!0}),e);var L={};W(L,{CsImage:()=>P,CsTextComponent:()=>C});module.exports=F(L);var f=require(\"react\"),m=require(\"@nuskin/foundation-core-app/common/hooks\"),y=v(require(\"@emotion/styled\")),d=require(\"react/jsx-runtime\"),M=(e,t)=>{let o=new DOMParser().parseFromString(e,\"text/html\");return o.querySelectorAll(\"a\").forEach(i=>{let a=i.getAttribute(\"href\")??\"\",{url:l=\"\"}=t(a);i.setAttribute(\"href\",l.startsWith(\"http\")?l:`https://${l}`)}),o.body.innerHTML},_=y.default.div`\n width: ${({fullWidth:e})=>e?\"100%\":\"auto\"};\n background-color: ${({bgColor:e})=>e};\n text-align: ${({alignment:e})=>e};\n color: ${({color:e})=>e};\n padding: 16px 32px;\n h1,\n h2,\n h3,\n h4,\n h5,\n h6 {\n font-family: 'Lora', serif;\n }\n h1 {\n font-size: 42px;\n line-height: 48px;\n }\n h2 {\n font-size: 36px;\n line-height: 42px;\n }\n h3 {\n font-size: 32px;\n line-height: 38px;\n }\n h4 {\n font-size: 26px;\n line-height: 34px;\n }\n h5 {\n font-size: 22px;\n line-height: 28px;\n }\n h6 {\n font-size: 18px;\n line-height: 24px;\n }\n p {\n margin: 0;\n padding: 0;\n }\n`,$=({full_width:e=!1,container_background_color:t=\"\",alignment:r=\"left\",text_editor:o,font_color:n=!1})=>{let i=(0,m.useToggleFontColor)(n),a=(0,m.useRouteReplacer)(),l=s=>typeof a==\"function\"?{url:a(s)?.url??\"\"}:{url:s},p=(0,f.useMemo)(()=>{try{if(t)return JSON.parse(t)?.brandColor?.colorObj?.light||\"transparent\"}catch{return\"transparent\"}return\"transparent\"},[t]),h=(0,f.useMemo)(()=>typeof window>\"u\"?o:M(o,l),[o,a]);return(0,d.jsx)(_,{color:i,fullWidth:e,bgColor:p,alignment:r,children:(0,d.jsx)(\"div\",{dangerouslySetInnerHTML:{__html:h}})})},C=$;var b=require(\"@nuskin/foundation-ui-components\");var I=require(\"@nuskin/foundation-theme\"),w=(0,I.styled)(\"div\")(({image_alignment:e=\"center\",width:t,height:r})=>({display:\"flex\",justifyContent:{left:\"flex-start\",right:\"flex-end\",center:\"center\"}[e],\"& img\":{maxWidth:\"fit-content\",objectFit:\"contain\",objectPosition:\"center\"}}));var u=require(\"react/jsx-runtime\"),k=[\"alt\",\"className\",\"fill\",\"height\",\"id\",\"src\",\"variant\",\"width\"],E=e=>{let{image_alignment:t=\"center\",image:r,...o}=e,n=null,i=null;try{let c=(typeof r==\"string\"?JSON.parse(r):r)?.image?.[0];n=c?.selected,i=c?.files}catch(s){console.warn(\"[CsImage] Failed to parse image prop:\",s)}let a=n?.imageType||\"transformBaseUrl\",p={src:i?.[a]?.url||\"\",alt:n?.altText||\"Image not available\",width:n?.width??\"100%\",height:n?.height??\"100%\"};k.forEach(s=>{o[s]!==void 0&&(p[s]=o[s])});let h=o?.full_width?\"container !p-0\":\"\";return(0,u.jsx)(w,{image_alignment:t,width:p.width,height:p.height,className:h,children:(0,u.jsx)(b.NsImage,{...p})})},P=E;\n","export * from './text';\nexport * from './image';\n","import { ReactElement, useMemo } from 'react';\nimport { useRouteReplacer, useToggleFontColor } from '@nuskin/foundation-core-app/common/hooks';\nimport styled from '@emotion/styled';\n\ninterface CsTextProps {\n full_width?: boolean;\n container_background_color?: string;\n alignment?: 'left' | 'center' | 'right';\n text_editor: string;\n font_color?: boolean;\n}\n\nexport const rewriteLinks = (html: string, replacer: (url: string) => { url: string }): string => {\n const parser = new DOMParser();\n const doc = parser.parseFromString(html, 'text/html');\n const links = doc.querySelectorAll('a');\n\n links.forEach((link) => {\n const href = link.getAttribute('href') ?? '';\n const { url: sanitizedUrl = '' } = replacer(href);\n\n link.setAttribute('href', sanitizedUrl.startsWith('http') ? sanitizedUrl : `https://${sanitizedUrl}`);\n });\n\n return doc.body.innerHTML;\n};\n\n// Emotion styled container\nconst Container = styled.div<{ fullWidth: boolean; bgColor: string; alignment: string; color: string }>`\n width: ${({ fullWidth }) => (fullWidth ? '100%' : 'auto')};\n background-color: ${({ bgColor }) => bgColor};\n text-align: ${({ alignment }) => alignment};\n color: ${({ color }) => color};\n padding: 16px 32px;\n h1,\n h2,\n h3,\n h4,\n h5,\n h6 {\n font-family: 'Lora', serif;\n }\n h1 {\n font-size: 42px;\n line-height: 48px;\n }\n h2 {\n font-size: 36px;\n line-height: 42px;\n }\n h3 {\n font-size: 32px;\n line-height: 38px;\n }\n h4 {\n font-size: 26px;\n line-height: 34px;\n }\n h5 {\n font-size: 22px;\n line-height: 28px;\n }\n h6 {\n font-size: 18px;\n line-height: 24px;\n }\n p {\n margin: 0;\n padding: 0;\n }\n`;\n\nconst CsText = ({\n full_width = false,\n container_background_color = '',\n alignment = 'left',\n text_editor,\n font_color = false\n}: CsTextProps): ReactElement | null => {\n const resolvedFontColor = useToggleFontColor(font_color);\n const routeReplacer = useRouteReplacer() as unknown as ((url: string) => { url: string }) | undefined;\n\n const safeRouteReplacer = (url: string) => {\n if (typeof routeReplacer === 'function') {\n const result = routeReplacer(url);\n return { url: result?.url ?? '' };\n }\n return { url };\n };\n\n const backgroundColor = useMemo(() => {\n try {\n if (container_background_color) {\n const parsed = JSON.parse(container_background_color);\n return parsed?.brandColor?.colorObj?.light || 'transparent';\n }\n } catch {\n return 'transparent';\n }\n return 'transparent';\n }, [container_background_color]);\n\n const updatedHtml = useMemo(() => {\n if (typeof window === 'undefined') return text_editor;\n return rewriteLinks(text_editor, safeRouteReplacer);\n }, [text_editor, routeReplacer]);\n\n return (\n <Container color={resolvedFontColor} fullWidth={full_width} bgColor={backgroundColor} alignment={alignment}>\n <div dangerouslySetInnerHTML={{ __html: updatedHtml }} />\n </Container>\n );\n};\n\nexport default CsText;\n","import { NsImage } from '@nuskin/foundation-ui-components';\nimport { StyledCsImageWrapper } from './CsImage.styled';\nimport type { CsImageProps, NsImageProps } from './types';\n\nconst allowedImageProps: (keyof NsImageProps)[] = [\n 'alt',\n 'className',\n 'fill',\n 'height',\n 'id',\n 'src',\n 'variant',\n 'width'\n];\n\nconst CsImage = (props: CsImageProps) => {\n const { image_alignment: align = 'center', image, ...rest } = props;\n\n let selectedImage: any = null;\n let fileMeta: any = null;\n\n try {\n const parsed = typeof image === 'string' ? JSON.parse(image) : image;\n const entry = parsed?.image?.[0];\n selectedImage = entry?.selected;\n fileMeta = entry?.files;\n } catch (err) {\n console.warn('[CsImage] Failed to parse image prop:', err);\n }\n\n const imageType = selectedImage?.imageType || 'transformBaseUrl';\n const fileSource = fileMeta?.[imageType];\n\n const imageProps: NsImageProps = {\n src: fileSource?.url || '',\n alt: selectedImage?.altText || 'Image not available',\n width: selectedImage?.width ?? '100%',\n height: selectedImage?.height ?? '100%'\n };\n\n // Add any other valid props from rest\n allowedImageProps.forEach((key) => {\n if (rest[key] !== undefined) {\n (imageProps as any)[key] = rest[key];\n }\n });\n const containerClassForNSImage = rest?.full_width ? 'container !p-0' : '';\n\n return (\n <StyledCsImageWrapper\n image_alignment={align}\n width={imageProps.width}\n height={imageProps.height}\n className={containerClassForNSImage}\n >\n <NsImage {...imageProps} />\n </StyledCsImageWrapper>\n );\n};\n\nexport default CsImage;\n","import { styled } from '@nuskin/foundation-theme';\nimport type { CsImageProps } from './types';\n\nexport const StyledCsImageWrapper = styled('div')<\n Pick<CsImageProps, 'image_alignment'> & { width?: string | number; height?: string | number }\n>(({ image_alignment = 'center', width, height }) => ({\n display: 'flex',\n justifyContent: {\n left: 'flex-start',\n right: 'flex-end',\n center: 'center'\n }[image_alignment],\n '& img': {\n maxWidth: 'fit-content',\n objectFit: 'contain',\n objectPosition: 'center'\n }\n}));\n"]}
1
+ {"version":3,"sources":["/gitlab-runner-data/builds/ns-am/content-foundation/marketing-components/dist/index.js","../src/index.ts","../src/text/CsText.tsx","../src/hooks/useRouteReplacer.tsx","../src/utils/route-utils.ts","../src/hooks/use-toggle-font-color/useMainContrast.tsx","../src/hooks/use-toggle-font-color/useToggleFontColor.ts","../src/image/CsImage.tsx","../src/image/CsImage.styled.tsx"],"names":["U","Object","create","f","defineProperty","_","getOwnPropertyDescriptor","G","getOwnPropertyNames","W","getPrototypeOf","O","prototype","hasOwnProperty","$","e","n","t","get","enumerable","b","i","r","call","z","__esModule","value","j","index_exports","__export","CsImage","CsImage_default","CsTextComponent","CsText_default","module","exports","__toCommonJS","import_react","require","import_styled","languageReplaceExpression","languageReplaceExpressionUppercase","regionReplaceExpression","regionReplaceExpressionUppercase","replaceRegionAndLanguage","text","replacer","region","replace","toUpperCase","language","getRegionAndLanguageFromLocation","window","params","URLSearchParams","location","search","import_material","import_foundation_theme","A","ColorUtils","getGenomeColor","F","useToggleFontColor","toggleValue","theme","k","useTheme","E","useMemo","useToggleFontColor_default","import_jsx_runtime","useRegionLanguage","d","rewriteUrl","url","rewriteLinks","html","doc","DOMParser","parseFromString","querySelectorAll","forEach","link","href","getAttribute","setAttribute","body","innerHTML","Container","M","styled","div","fullWidth","bgColor","alignment","color","extractColorFromObject","obj","brandColor","colorObj","light","trim","parseJsonColor","jsonString","JSON","parse","resolveBackgroundColor","trimmed","startsWith","CsText","full_width","container_background_color","text_editor","font_color","fontColor","regionLang","backgroundColor","updatedHtml","R","jsx","children","dangerouslySetInnerHTML","__html","import_foundation_ui_components","StyledCsImageWrapper","P","image_alignment","width","height","display","justifyContent","left","right","center","maxWidth","objectFit","objectPosition","PLACEHOLDER_IMAGE_SRC","encodeURIComponent","allowedImageProps","props","align","image","parent$","isEditing","rest","selectedImage","fileMeta","contentstackAsset","parsed","entry","selected","files","err","console","warn","resolvedSrc","resolvedAlt","resolvedWidth","resolvedHeight","imageType","fileSource","altText","title","filename","imageProps","src","alt","key","containerClassForNSImage","w","className","v","NsImage"],"mappings":"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","sourcesContent":["\"use strict\";var U=Object.create;var f=Object.defineProperty;var _=Object.getOwnPropertyDescriptor;var G=Object.getOwnPropertyNames;var W=Object.getPrototypeOf,O=Object.prototype.hasOwnProperty;var $=(e,n)=>{for(var t in n)f(e,t,{get:n[t],enumerable:!0})},b=(e,n,t,i)=>{if(n&&typeof n==\"object\"||typeof n==\"function\")for(let r of G(n))!O.call(e,r)&&r!==t&&f(e,r,{get:()=>n[r],enumerable:!(i=_(n,r))||i.enumerable});return e};var z=(e,n,t)=>(t=e!=null?U(W(e)):{},b(n||!e||!e.__esModule?f(t,\"default\",{value:e,enumerable:!0}):t,e)),j=e=>b(f({},\"__esModule\",{value:!0}),e);var ce={};$(ce,{CsImage:()=>Q,CsTextComponent:()=>N});module.exports=j(ce);var d=require(\"react\"),M=z(require(\"@emotion/styled\"));var K=require(\"react\");var H=\"{%language}\",B=\"{%LANGUAGE}\",J=\"{%region}\",D=\"{%REGION}\",x=(e,n={})=>typeof e!=\"string\"?\"\":(n.region&&(e=e.replace(J,n.region),e=e.replace(D,n.region.toUpperCase())),n.language&&(e=e.replace(H,n.language),e=e.replace(B,n.language.toUpperCase())),e);var C=()=>{if(typeof window>\"u\")return;let e=new URLSearchParams(window.location.search),n=e.get(\"region\")??void 0,t=e.get(\"language\")??void 0;if(n||t)return{region:n,language:t}};var X=require(\"react\"),Y=require(\"@mui/material\"),A=require(\"@nuskin/foundation-theme\"),{getGenomeColor:he}=A.ColorUtils;var k=require(\"@mui/material\"),F=require(\"@nuskin/foundation-theme\"),E=require(\"react\"),{getGenomeColor:Z}=F.ColorUtils,V=(e=!1)=>{let n=(0,k.useTheme)();return(0,E.useMemo)(()=>Z(n,\"N10\",e?\"light\":\"dark\"),[e,n])},y=V;var R=require(\"react/jsx-runtime\"),q=()=>(0,d.useMemo)(()=>C(),[]),ee=(e,n)=>!n||!e?e:x(e,n),ne=(e,n)=>{if(typeof window>\"u\"||!e||!n)return e;let i=new DOMParser().parseFromString(e,\"text/html\");return i.querySelectorAll(\"a\").forEach(r=>{let l=r.getAttribute(\"href\");l&&r.setAttribute(\"href\",ee(l,n))}),i.body.innerHTML},te=M.default.div`\n width: ${({fullWidth:e})=>e?\"100%\":\"auto\"};\n background-color: ${({bgColor:e})=>e};\n text-align: ${({alignment:e})=>e};\n color: ${({color:e})=>e};\n padding: 16px 32px;\n\n h1,\n h2,\n h3,\n h4,\n h5,\n h6 {\n font-family: 'Lora', serif;\n }\n\n h1 {\n font-size: 42px;\n line-height: 48px;\n }\n h2 {\n font-size: 36px;\n line-height: 42px;\n }\n h3 {\n font-size: 32px;\n line-height: 38px;\n }\n h4 {\n font-size: 26px;\n line-height: 34px;\n }\n h5 {\n font-size: 22px;\n line-height: 28px;\n }\n h6 {\n font-size: 18px;\n line-height: 24px;\n }\n\n p {\n margin: 0;\n padding: 0;\n }\n`,re=e=>{let n=e?.brandColor?.colorObj?.light??e?.color;return typeof n==\"string\"&&n.trim()?n:null},oe=e=>{try{let t=JSON.parse(e)?.brandColor?.colorObj?.light;return typeof t==\"string\"&&t.trim()?t:null}catch{return null}},ie=e=>{if(!e)return\"transparent\";if(typeof e==\"object\")return re(e)??\"transparent\";if(typeof e==\"string\"){let n=e.trim();return n?n.startsWith(\"{\")?oe(n)??\"transparent\":n:\"transparent\"}return\"transparent\"},ae=({full_width:e=!1,container_background_color:n,alignment:t=\"left\",text_editor:i,font_color:r=!1,$:l})=>{let c=y(r),a=q(),u=(0,d.useMemo)(()=>ie(n),[n]),s=(0,d.useMemo)(()=>ne(i,a),[i,a]);return i?(0,R.jsx)(te,{fullWidth:e,bgColor:u,alignment:t,color:c,children:(0,R.jsx)(\"div\",{dangerouslySetInnerHTML:{__html:s},...l?.text_editor})}):null},N=ae;var v=require(\"@nuskin/foundation-ui-components\");var P=require(\"@nuskin/foundation-theme\"),S=(0,P.styled)(\"div\")(({image_alignment:e=\"center\",width:n,height:t})=>({display:\"flex\",justifyContent:{left:\"flex-start\",right:\"flex-end\",center:\"center\"}[e],\"& img\":{maxWidth:\"fit-content\",objectFit:\"contain\",objectPosition:\"center\"}}));var w=require(\"react/jsx-runtime\"),se=\"data:image/svg+xml;utf8,\"+encodeURIComponent(`<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 400 300\" role=\"img\" aria-label=\"Image not available\">\n <defs>\n <linearGradient id=\"csImagePlaceholderGradient\" x1=\"0\" y1=\"0\" x2=\"1\" y2=\"1\">\n <stop offset=\"0%\" stop-color=\"#f3f4f6\" />\n <stop offset=\"100%\" stop-color=\"#e5e7eb\" />\n </linearGradient>\n </defs>\n <rect width=\"400\" height=\"300\" fill=\"url(#csImagePlaceholderGradient)\" />\n <g stroke=\"#d1d5db\" stroke-width=\"4\" stroke-linecap=\"round\" stroke-linejoin=\"round\" fill=\"none\">\n <rect x=\"60\" y=\"60\" width=\"280\" height=\"180\" rx=\"12\" />\n <path d=\"M120 200 L180 140 L230 185 L260 160 L320 210\" />\n <circle cx=\"160\" cy=\"120\" r=\"20\" />\n </g>\n </svg>`),ge=[\"alt\",\"className\",\"fill\",\"height\",\"id\",\"src\",\"variant\",\"width\"],le=e=>{let{image_alignment:n=\"center\",image:t,parent$:i,isEditing:r,$:l,...c}=e,a=null,u=null,s=null;try{let o=typeof t==\"string\"?JSON.parse(t):t,g=o?.image?.[0];g?.selected||g?.files?(a=g?.selected,u=g?.files):o?.url&&(s=o)}catch(o){console.warn(\"[CsImage] Failed to parse image prop:\",o)}let m=se,h=\"Image not available\",L=\"100%\",I=\"100%\";if(a||u){let o=a?.imageType??\"transformBaseUrl\",g=u?.[o];g?.url&&(m=g.url,h=a?.altText??\"Image\",L=a?.width??\"100%\",I=a?.height??\"100%\")}else s?.url&&(m=s.url,h=s.title||s.filename||\"Image\");let p={src:m,alt:h,width:L,height:I};ge.forEach(o=>{c[o]!==void 0&&(p[o]=c[o])});let T=c?.full_width?\"container !p-0\":\"\";return(0,w.jsx)(S,{image_alignment:n,width:p.width,height:p.height,className:T,children:(0,w.jsx)(v.NsImage,{...p,...l?.image||{}})})},Q=le;\n","export * from './text';\nexport * from './image';\n","import { ReactElement, useMemo } from 'react';\nimport styled from '@emotion/styled';\nimport { useToggleFontColor } from '../hooks';\nimport { getRegionAndLanguageFromLocation, RegionLanguageQuery, replaceRegionAndLanguage } from '../utils/route-utils';\n\ninterface CsTextProps {\n full_width?: boolean;\n container_background_color?: unknown;\n alignment?: 'left' | 'center' | 'right';\n text_editor: string;\n font_color?: boolean;\n $?: {\n text_editor?: Record<string, unknown>;\n };\n}\n\n// Get region + language once\nconst useRegionLanguage = () => {\n return useMemo(() => getRegionAndLanguageFromLocation(), []);\n};\n\n// Replace region and language in a single URL\nconst rewriteUrl = (url: string, replacer?: RegionLanguageQuery): string => {\n if (!replacer || !url) return url;\n return replaceRegionAndLanguage(url, replacer);\n};\n\n// Rewrite all <a> links inside CMS HTML\nexport const rewriteLinks = (html: string, replacer?: RegionLanguageQuery): string => {\n if (typeof window === 'undefined' || !html || !replacer) return html;\n\n const parser = new DOMParser();\n const doc = parser.parseFromString(html, 'text/html');\n\n doc.querySelectorAll('a').forEach((link) => {\n const href = link.getAttribute('href');\n if (!href) return;\n link.setAttribute('href', rewriteUrl(href, replacer));\n });\n\n return doc.body.innerHTML;\n};\n\n// Styled container for CMS text\nconst Container = styled.div<{\n fullWidth: boolean;\n bgColor: string;\n alignment: string;\n color: string;\n}>`\n width: ${({ fullWidth }) => (fullWidth ? '100%' : 'auto')};\n background-color: ${({ bgColor }) => bgColor};\n text-align: ${({ alignment }) => alignment};\n color: ${({ color }) => color};\n padding: 16px 32px;\n\n h1,\n h2,\n h3,\n h4,\n h5,\n h6 {\n font-family: 'Lora', serif;\n }\n\n h1 {\n font-size: 42px;\n line-height: 48px;\n }\n h2 {\n font-size: 36px;\n line-height: 42px;\n }\n h3 {\n font-size: 32px;\n line-height: 38px;\n }\n h4 {\n font-size: 26px;\n line-height: 34px;\n }\n h5 {\n font-size: 22px;\n line-height: 28px;\n }\n h6 {\n font-size: 18px;\n line-height: 24px;\n }\n\n p {\n margin: 0;\n padding: 0;\n }\n`;\n\n// Safely resolve CMS background color\nconst extractColorFromObject = (obj: any): string | null => {\n const color = obj?.brandColor?.colorObj?.light ?? obj?.color;\n return typeof color === 'string' && color.trim() ? color : null;\n};\n\nconst parseJsonColor = (jsonString: string): string | null => {\n try {\n const parsed = JSON.parse(jsonString);\n const color = parsed?.brandColor?.colorObj?.light;\n return typeof color === 'string' && color.trim() ? color : null;\n } catch {\n return null;\n }\n};\n\nconst resolveBackgroundColor = (value: unknown): string => {\n // null, undefined, false, 0, '' → transparent\n if (!value) return 'transparent';\n\n // CMS object\n if (typeof value === 'object') {\n const color = extractColorFromObject(value);\n return color ?? 'transparent';\n }\n\n // CMS string\n if (typeof value === 'string') {\n const trimmed = value.trim();\n if (!trimmed) return 'transparent';\n\n // JSON string\n if (trimmed.startsWith('{')) {\n const color = parseJsonColor(trimmed);\n return color ?? 'transparent';\n }\n\n // Normal CSS color\n return trimmed;\n }\n\n // numbers, booleans, etc\n return 'transparent';\n};\n\nconst CsText = ({\n full_width = false,\n container_background_color,\n alignment = 'left',\n text_editor,\n font_color = false,\n $\n}: CsTextProps): ReactElement | null => {\n const fontColor = useToggleFontColor(font_color);\n const regionLang = useRegionLanguage();\n\n const backgroundColor = useMemo(\n () => resolveBackgroundColor(container_background_color),\n [container_background_color],\n );\n\n const updatedHtml = useMemo(() => rewriteLinks(text_editor, regionLang), [text_editor, regionLang]);\n\n if (!text_editor) return null;\n\n return (\n <Container fullWidth={full_width} bgColor={backgroundColor} alignment={alignment} color={fontColor}>\n <div dangerouslySetInnerHTML={{ __html: updatedHtml }} {...$?.text_editor} />\n </Container>\n );\n};\n\nexport default CsText;\n","import { useMemo } from 'react';\nimport { getRegionAndLanguageFromLocation, replaceRegionAndLanguage, RegionLanguageQuery } from '../utils/route-utils';\n\n/**\n * Simply use this hook to update the region and language in the url\n * Note: urlToParse should have {%region} or {%language} or {%rREGION} or {%LANGUAGE}\n * @param urlToParse url to be parsed\n * @returns urlToParse after conditionally replacing the region and language\n */\nconst useRouteReplacer = (urlToParse?: string): { url?: string } => {\n const replacer: RegionLanguageQuery | undefined = useMemo(() => getRegionAndLanguageFromLocation(), []);\n\n const url = useMemo(() => {\n if (!urlToParse || !replacer) return undefined;\n return replaceRegionAndLanguage(urlToParse, replacer);\n }, [urlToParse, replacer]);\n\n return { url };\n};\n\nexport default useRouteReplacer;\n","const languageReplaceExpression = '{%language}';\nconst languageReplaceExpressionUppercase = '{%LANGUAGE}';\nconst regionReplaceExpression = '{%region}';\nconst regionReplaceExpressionUppercase = '{%REGION}';\n\nexport type RegionLanguageQuery = {\n region?: string;\n language?: string;\n slug?: string;\n};\n\n/**\n * Replace {%region}, {%language} placeholders in text\n */\nexport const replaceRegionAndLanguage = (text: string, replacer: RegionLanguageQuery = {}): string => {\n if (typeof text !== 'string') {\n return '';\n }\n\n if (replacer.region) {\n text = text.replace(regionReplaceExpression, replacer.region);\n text = text.replace(regionReplaceExpressionUppercase, replacer.region.toUpperCase());\n }\n\n if (replacer.language) {\n text = text.replace(languageReplaceExpression, replacer.language);\n text = text.replace(languageReplaceExpressionUppercase, replacer.language.toUpperCase());\n }\n\n return text;\n};\n\n/**\n * Replace dynamic pathname segments like [region], [language]\n */\nexport const replacePathnameWithQueryParams = (pathname: string, queryParams: RegionLanguageQuery): string => {\n if (!pathname || typeof pathname !== 'string') {\n return '';\n }\n\n let formattedUrl = pathname;\n\n if (queryParams.region) {\n formattedUrl = formattedUrl.replace('[region]', queryParams.region);\n }\n\n if (queryParams.language) {\n formattedUrl = formattedUrl.replace('[language]', queryParams.language);\n }\n\n if (queryParams.slug) {\n formattedUrl = formattedUrl.replace('[[...slug]]', queryParams.slug);\n }\n\n return formattedUrl;\n};\n\n/**\n * Extract region & language from a query object\n */\nexport const getRegionAndLanguageFromQuery = (\n query?: Record<string, string | string[] | undefined>,\n): RegionLanguageQuery | undefined => {\n if (!query) return undefined;\n\n const region = Array.isArray(query.region) ? query.region[0] : query.region;\n\n const language = Array.isArray(query.language) ? query.language[0] : query.language;\n\n if (region || language) {\n return { region, language };\n }\n\n return undefined;\n};\n\n/**\n * ✅ Next.js Router replacement\n * Reads from browser URL safely\n */\nexport const getRegionAndLanguageFromLocation = (): RegionLanguageQuery | undefined => {\n if (typeof window === 'undefined') return undefined;\n\n const params = new URLSearchParams(window.location.search);\n\n const region = params.get('region') ?? undefined;\n const language = params.get('language') ?? undefined;\n\n if (region || language) {\n return { region, language };\n }\n\n return undefined;\n};\n","import { useMemo } from 'react';\n\nimport { useTheme } from '@mui/material';\nimport { ColorUtils } from '@nuskin/foundation-theme';\n\nconst { getGenomeColor } = ColorUtils;\n\n/**\n * @returns {main:#FFFFFF, contrast:#252525} when passed true\n */\nconst useMainContrast = (toggleValue: boolean = false): { main: string; contrast: string } => {\n const theme = useTheme();\n\n return useMemo(() => {\n const main = getGenomeColor(theme, 'N10', toggleValue ? 'light' : 'dark');\n const contrast = getGenomeColor(theme, 'N10', toggleValue ? 'dark' : 'light');\n return { main, contrast };\n }, [toggleValue, theme]);\n};\n\nexport default useMainContrast;\n","import { useTheme } from '@mui/material';\nimport { ColorUtils } from '@nuskin/foundation-theme';\nimport { useMemo } from 'react';\n\nconst { getGenomeColor } = ColorUtils;\n/**\n * Used to fetch the appropriate theme color for primary and contrast.\n * Usually black or similar, and white for contrast.\n * @param toggleValue the CS toggle value between black and white font color.\n * @returns hex value of the color.\n */\nconst useToggleFontColor = (toggleValue: boolean = false): string => {\n const theme = useTheme();\n\n return useMemo(\n () => getGenomeColor(theme, 'N10', toggleValue ? 'light' : 'dark'),\n [toggleValue, theme]\n );\n};\n\nexport default useToggleFontColor;\n","import { NsImage } from '@nuskin/foundation-ui-components';\nimport { StyledCsImageWrapper } from './CsImage.styled';\nimport type { ContentstackAsset, CsImageProps, ImageFile, ImageFileMeta, NsImageProps } from './types';\n\n// Inline SVG data URL used as a safe placeholder when the main image is unavailable\nexport const PLACEHOLDER_IMAGE_SRC =\n 'data:image/svg+xml;utf8,' +\n encodeURIComponent(\n `<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 400 300\" role=\"img\" aria-label=\"Image not available\">\n <defs>\n <linearGradient id=\"csImagePlaceholderGradient\" x1=\"0\" y1=\"0\" x2=\"1\" y2=\"1\">\n <stop offset=\"0%\" stop-color=\"#f3f4f6\" />\n <stop offset=\"100%\" stop-color=\"#e5e7eb\" />\n </linearGradient>\n </defs>\n <rect width=\"400\" height=\"300\" fill=\"url(#csImagePlaceholderGradient)\" />\n <g stroke=\"#d1d5db\" stroke-width=\"4\" stroke-linecap=\"round\" stroke-linejoin=\"round\" fill=\"none\">\n <rect x=\"60\" y=\"60\" width=\"280\" height=\"180\" rx=\"12\" />\n <path d=\"M120 200 L180 140 L230 185 L260 160 L320 210\" />\n <circle cx=\"160\" cy=\"120\" r=\"20\" />\n </g>\n </svg>`,\n );\n\nconst allowedImageProps: (keyof NsImageProps)[] = [\n 'alt',\n 'className',\n 'fill',\n 'height',\n 'id',\n 'src',\n 'variant',\n 'width'\n];\n\nconst CsImage = (props: CsImageProps) => {\n const { image_alignment: align = 'center', image, parent$, isEditing, $, ...rest } = props;\n\n let selectedImage: ImageFile | null = null;\n let fileMeta: Record<string, ImageFileMeta> | null = null;\n let contentstackAsset: ContentstackAsset | null = null;\n\n try {\n const parsed = typeof image === 'string' ? JSON.parse(image) : image;\n \n // Try Bynder format first: { image: [{ selected, files }] }\n const entry = parsed?.image?.[0];\n if (entry?.selected || entry?.files) {\n selectedImage = entry?.selected;\n fileMeta = entry?.files;\n } else if (parsed?.url) {\n // Fallback: Contentstack native asset format\n contentstackAsset = parsed;\n }\n } catch (err) {\n console.warn('[CsImage] Failed to parse image prop:', err);\n }\n\n let resolvedSrc = PLACEHOLDER_IMAGE_SRC;\n let resolvedAlt = 'Image not available';\n let resolvedWidth: number | string = '100%';\n let resolvedHeight: number | string = '100%';\n\n // Bynder format\n if (selectedImage || fileMeta) {\n const imageType = selectedImage?.imageType ?? 'transformBaseUrl';\n const fileSource = fileMeta?.[imageType];\n\n \n if (fileSource?.url) {\n resolvedSrc = fileSource.url;\n resolvedAlt = selectedImage?.altText ?? 'Image';\n resolvedWidth = selectedImage?.width ?? '100%';\n resolvedHeight = selectedImage?.height ?? '100%';\n }\n } \n // Contentstack asset fallback\n else if (contentstackAsset?.url) {\n resolvedSrc = contentstackAsset.url;\n resolvedAlt = contentstackAsset.title || contentstackAsset.filename || 'Image';\n // Contentstack assets don't provide width/height in metadata, keep defaults\n }\n\n const imageProps: NsImageProps = {\n src: resolvedSrc,\n alt: resolvedAlt,\n width: resolvedWidth,\n height: resolvedHeight\n };\n\n // Add any other valid props from rest\n allowedImageProps.forEach((key) => {\n if (rest[key] !== undefined) {\n (imageProps as Record<string, unknown>)[key] = rest[key];\n }\n });\n\n const containerClassForNSImage = rest?.full_width ? 'container !p-0' : '';\n\n return (\n <StyledCsImageWrapper\n image_alignment={align}\n width={imageProps.width}\n height={imageProps.height}\n className={containerClassForNSImage}\n >\n <NsImage {...imageProps} {...($?.image || {})} />\n </StyledCsImageWrapper>\n );\n};\n\nexport default CsImage;\n","import { styled } from '@nuskin/foundation-theme';\nimport type { CsImageProps } from './types';\n\nexport const StyledCsImageWrapper = styled('div')<\n Pick<CsImageProps, 'image_alignment'> & { width?: string | number; height?: string | number }\n>(({ image_alignment = 'center', width, height }) => ({\n display: 'flex',\n justifyContent: {\n left: 'flex-start',\n right: 'flex-end',\n center: 'center'\n }[image_alignment],\n '& img': {\n maxWidth: 'fit-content',\n objectFit: 'contain',\n objectPosition: 'center'\n }\n}));\n"]}
package/dist/index.mjs CHANGED
@@ -1 +1 @@
1
- function n(n,e,t){if(e in n){Object.defineProperty(n,e,{value:t,enumerable:true,configurable:true,writable:true})}else{n[e]=t}return n}function e(e){for(var t=1;t<arguments.length;t++){var r=arguments[t]!=null?arguments[t]:{};var i=Object.keys(r);if(typeof Object.getOwnPropertySymbols==="function"){i=i.concat(Object.getOwnPropertySymbols(r).filter(function(n){return Object.getOwnPropertyDescriptor(r,n).enumerable}))}i.forEach(function(t){n(e,t,r[t])})}return e}function t(n,e){if(n==null)return{};var t=r(n,e);var i,o;if(Object.getOwnPropertySymbols){var l=Object.getOwnPropertySymbols(n);for(o=0;o<l.length;o++){i=l[o];if(e.indexOf(i)>=0)continue;if(!Object.prototype.propertyIsEnumerable.call(n,i))continue;t[i]=n[i]}}return t}function r(n,e){if(n==null)return{};var t={};var r=Object.keys(n);var i,o;for(o=0;o<r.length;o++){i=r[o];if(e.indexOf(i)>=0)continue;t[i]=n[i]}return t}function i(n,e){if(!e){e=n.slice(0)}return Object.freeze(Object.defineProperties(n,{raw:{value:Object.freeze(e)}}))}function o(n){"@swc/helpers - typeof";return n&&typeof Symbol!=="undefined"&&n.constructor===Symbol?"symbol":typeof n}function l(){var n=i(["\n width: ",";\n background-color: ",";\n text-align: ",";\n color: ",";\n padding: 16px 32px;\n h1,\n h2,\n h3,\n h4,\n h5,\n h6 {\n font-family: 'Lora', serif;\n }\n h1 {\n font-size: 42px;\n line-height: 48px;\n }\n h2 {\n font-size: 36px;\n line-height: 42px;\n }\n h3 {\n font-size: 32px;\n line-height: 38px;\n }\n h4 {\n font-size: 26px;\n line-height: 34px;\n }\n h5 {\n font-size: 22px;\n line-height: 28px;\n }\n h6 {\n font-size: 18px;\n line-height: 24px;\n }\n p {\n margin: 0;\n padding: 0;\n }\n"]);l=function e(){return n};return n}import{useMemo as a}from"react";import{useRouteReplacer as u,useToggleFontColor as f}from"@nuskin/foundation-core-app/common/hooks";import c from"@emotion/styled";import{jsx as d}from"react/jsx-runtime";var v=function(n,e){var t=new DOMParser().parseFromString(n,"text/html");return t.querySelectorAll("a").forEach(function(n){var t;var r=(t=n.getAttribute("href"))!==null&&t!==void 0?t:"",i=e(r),o=i.url,l=o===void 0?"":o;n.setAttribute("href",l.startsWith("http")?l:"https://".concat(l))}),t.body.innerHTML},s=c.div(l(),function(n){var e=n.fullWidth;return e?"100%":"auto"},function(n){var e=n.bgColor;return e},function(n){var e=n.alignment;return e},function(n){var e=n.color;return e}),h=function(n){var e=n.full_width,t=e===void 0?!1:e,r=n.container_background_color,i=r===void 0?"":r,l=n.alignment,c=l===void 0?"left":l,h=n.text_editor,p=n.font_color,m=p===void 0?!1:p;var g=f(m),b=u(),y=function(n){var e;var t;return typeof b=="function"?{url:(t=(e=b(n))===null||e===void 0?void 0:e.url)!==null&&t!==void 0?t:""}:{url:n}},x=a(function(){try{var n,e,t;if(i)return((t=JSON.parse(i))===null||t===void 0?void 0:(e=t.brandColor)===null||e===void 0?void 0:(n=e.colorObj)===null||n===void 0?void 0:n.light)||"transparent"}catch(n){return"transparent"}return"transparent"},[i]),w=a(function(){return(typeof window==="undefined"?"undefined":o(window))>"u"?h:v(h,y)},[h,b]);return d(s,{color:g,fullWidth:t,bgColor:x,alignment:c,children:d("div",{dangerouslySetInnerHTML:{__html:w}})})},p=h;import{NsImage as m}from"@nuskin/foundation-ui-components";import{styled as g}from"@nuskin/foundation-theme";var b=g("div")(function(n){var e=n.image_alignment,t=e===void 0?"center":e,r=n.width,i=n.height;return{display:"flex",justifyContent:({left:"flex-start",right:"flex-end",center:"center"})[t],"& img":{maxWidth:"fit-content",objectFit:"contain",objectPosition:"center"}}});import{jsx as y}from"react/jsx-runtime";var x=["alt","className","fill","height","id","src","variant","width"],w=function(n){var r;var i=n.image_alignment,o=i===void 0?"center":i,l=n.image,a=t(n,["image_alignment","image"]),u=null,f=null;try{var c,d;var v=(d=typeof l=="string"?JSON.parse(l):l)===null||d===void 0?void 0:(c=d.image)===null||c===void 0?void 0:c[0];u=v===null||v===void 0?void 0:v.selected,f=v===null||v===void 0?void 0:v.files}catch(n){console.warn("[CsImage] Failed to parse image prop:",n)}var s,h;var p=(u===null||u===void 0?void 0:u.imageType)||"transformBaseUrl",g={src:(f===null||f===void 0?void 0:(r=f[p])===null||r===void 0?void 0:r.url)||"",alt:(u===null||u===void 0?void 0:u.altText)||"Image not available",width:(s=u===null||u===void 0?void 0:u.width)!==null&&s!==void 0?s:"100%",height:(h=u===null||u===void 0?void 0:u.height)!==null&&h!==void 0?h:"100%"};x.forEach(function(n){a[n]!==void 0&&(g[n]=a[n])});var w=(a===null||a===void 0?void 0:a.full_width)?"container !p-0":"";return y(b,{image_alignment:o,width:g.width,height:g.height,className:w,children:y(m,e({},g))})},O=w;export{O as CsImage,p as CsTextComponent};//# sourceMappingURL=index.mjs.map
1
+ function n(n,e,t){if(e in n){Object.defineProperty(n,e,{value:t,enumerable:true,configurable:true,writable:true})}else{n[e]=t}return n}function e(e){for(var t=1;t<arguments.length;t++){var r=arguments[t]!=null?arguments[t]:{};var i=Object.keys(r);if(typeof Object.getOwnPropertySymbols==="function"){i=i.concat(Object.getOwnPropertySymbols(r).filter(function(n){return Object.getOwnPropertyDescriptor(r,n).enumerable}))}i.forEach(function(t){n(e,t,r[t])})}return e}function t(n,e){if(n==null)return{};var t=r(n,e);var i,o;if(Object.getOwnPropertySymbols){var l=Object.getOwnPropertySymbols(n);for(o=0;o<l.length;o++){i=l[o];if(e.indexOf(i)>=0)continue;if(!Object.prototype.propertyIsEnumerable.call(n,i))continue;t[i]=n[i]}}return t}function r(n,e){if(n==null)return{};var t={};var r=Object.keys(n);var i,o;for(o=0;o<r.length;o++){i=r[o];if(e.indexOf(i)>=0)continue;t[i]=n[i]}return t}function i(n,e){if(!e){e=n.slice(0)}return Object.freeze(Object.defineProperties(n,{raw:{value:Object.freeze(e)}}))}function o(n){"@swc/helpers - typeof";return n&&typeof Symbol!=="undefined"&&n.constructor===Symbol?"symbol":typeof n}function l(){var n=i(["\n width: ",";\n background-color: ",";\n text-align: ",";\n color: ",";\n padding: 16px 32px;\n\n h1,\n h2,\n h3,\n h4,\n h5,\n h6 {\n font-family: 'Lora', serif;\n }\n\n h1 {\n font-size: 42px;\n line-height: 48px;\n }\n h2 {\n font-size: 36px;\n line-height: 42px;\n }\n h3 {\n font-size: 32px;\n line-height: 38px;\n }\n h4 {\n font-size: 26px;\n line-height: 34px;\n }\n h5 {\n font-size: 22px;\n line-height: 28px;\n }\n h6 {\n font-size: 18px;\n line-height: 24px;\n }\n\n p {\n margin: 0;\n padding: 0;\n }\n"]);l=function e(){return n};return n}import{useMemo as a}from"react";import u from"@emotion/styled";import{useMemo as d}from"react";var f="{%language}",v="{%LANGUAGE}",c="{%region}",s="{%REGION}",g=function(n){var e=arguments.length>1&&arguments[1]!==void 0?arguments[1]:{};return typeof n!="string"?"":(e.region&&(n=n.replace(c,e.region),n=n.replace(s,e.region.toUpperCase())),e.language&&(n=n.replace(f,e.language),n=n.replace(v,e.language.toUpperCase())),n)};var m=function(){if((typeof window==="undefined"?"undefined":o(window))>"u")return;var n,e;var t=new URLSearchParams(window.location.search),r=(n=t.get("region"))!==null&&n!==void 0?n:void 0,i=(e=t.get("language"))!==null&&e!==void 0?e:void 0;if(r||i)return{region:r,language:i}};import{useMemo as p}from"react";import{useTheme as h}from"@mui/material";import{ColorUtils as y}from"@nuskin/foundation-theme";var b=y.getGenomeColor;import{useTheme as x}from"@mui/material";import{ColorUtils as w}from"@nuskin/foundation-theme";import{useMemo as O}from"react";var j=w.getGenomeColor,C=function(){var n=arguments.length>0&&arguments[0]!==void 0?arguments[0]:!1;var e=x();return O(function(){return j(e,"N10",n?"light":"dark")},[n,e])},k=C;import{jsx as I}from"react/jsx-runtime";var _=function(){return a(function(){return m()},[])},P=function(n,e){return!e||!n?n:g(n,e)},S=function(n,e){if((typeof window==="undefined"?"undefined":o(window))>"u"||!n||!e)return n;var t=new DOMParser().parseFromString(n,"text/html");return t.querySelectorAll("a").forEach(function(n){var t=n.getAttribute("href");t&&n.setAttribute("href",P(t,e))}),t.body.innerHTML},G=u.div(l(),function(n){var e=n.fullWidth;return e?"100%":"auto"},function(n){var e=n.bgColor;return e},function(n){var e=n.alignment;return e},function(n){var e=n.color;return e}),L=function(n){var e,t;var r;var i=(r=n===null||n===void 0?void 0:(t=n.brandColor)===null||t===void 0?void 0:(e=t.colorObj)===null||e===void 0?void 0:e.light)!==null&&r!==void 0?r:n===null||n===void 0?void 0:n.color;return typeof i=="string"&&i.trim()?i:null},z=function(n){try{var e,t,r;var i=(r=JSON.parse(n))===null||r===void 0?void 0:(t=r.brandColor)===null||t===void 0?void 0:(e=t.colorObj)===null||e===void 0?void 0:e.light;return typeof i=="string"&&i.trim()?i:null}catch(n){return null}},E=function(n){if(!n)return"transparent";var e;if((typeof n==="undefined"?"undefined":o(n))=="object")return(e=L(n))!==null&&e!==void 0?e:"transparent";if(typeof n=="string"){var t=n.trim();var r;return t?t.startsWith("{")?(r=z(t))!==null&&r!==void 0?r:"transparent":t:"transparent"}return"transparent"},M=function(n){var t=n.full_width,r=t===void 0?!1:t,i=n.container_background_color,o=n.alignment,l=o===void 0?"left":o,u=n.text_editor,d=n.font_color,f=d===void 0?!1:d,v=n.$;var c=k(f),s=_(),g=a(function(){return E(i)},[i]),m=a(function(){return S(u,s)},[u,s]);return u?I(G,{fullWidth:r,bgColor:g,alignment:l,color:c,children:I("div",e({dangerouslySetInnerHTML:{__html:m}},v===null||v===void 0?void 0:v.text_editor))}):null},N=M;import{NsImage as U}from"@nuskin/foundation-ui-components";import{styled as T}from"@nuskin/foundation-theme";var A=T("div")(function(n){var e=n.image_alignment,t=e===void 0?"center":e,r=n.width,i=n.height;return{display:"flex",justifyContent:({left:"flex-start",right:"flex-end",center:"center"})[t],"& img":{maxWidth:"fit-content",objectFit:"contain",objectPosition:"center"}}});import{jsx as $}from"react/jsx-runtime";var W="data:image/svg+xml;utf8,"+encodeURIComponent('<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 400 300" role="img" aria-label="Image not available">\n <defs>\n <linearGradient id="csImagePlaceholderGradient" x1="0" y1="0" x2="1" y2="1">\n <stop offset="0%" stop-color="#f3f4f6" />\n <stop offset="100%" stop-color="#e5e7eb" />\n </linearGradient>\n </defs>\n <rect width="400" height="300" fill="url(#csImagePlaceholderGradient)" />\n <g stroke="#d1d5db" stroke-width="4" stroke-linecap="round" stroke-linejoin="round" fill="none">\n <rect x="60" y="60" width="280" height="180" rx="12" />\n <path d="M120 200 L180 140 L230 185 L260 160 L320 210" />\n <circle cx="160" cy="120" r="20" />\n </g>\n </svg>'),F=["alt","className","fill","height","id","src","variant","width"],H=function(n){var r=n.image_alignment,i=r===void 0?"center":r,o=n.image,l=n.parent$,a=n.isEditing,u=n.$,d=t(n,["image_alignment","image","parent$","isEditing","$"]),f=null,v=null,c=null;try{var s;var g=typeof o=="string"?JSON.parse(o):o,m=g===null||g===void 0?void 0:(s=g.image)===null||s===void 0?void 0:s[0];(m===null||m===void 0?void 0:m.selected)||(m===null||m===void 0?void 0:m.files)?(f=m===null||m===void 0?void 0:m.selected,v=m===null||m===void 0?void 0:m.files):(g===null||g===void 0?void 0:g.url)&&(c=g)}catch(n){console.warn("[CsImage] Failed to parse image prop:",n)}var p=W,h="Image not available",y="100%",b="100%";if(f||v){var x;var w=(x=f===null||f===void 0?void 0:f.imageType)!==null&&x!==void 0?x:"transformBaseUrl",O=v===null||v===void 0?void 0:v[w];var j,C,k;(O===null||O===void 0?void 0:O.url)&&(p=O.url,h=(j=f===null||f===void 0?void 0:f.altText)!==null&&j!==void 0?j:"Image",y=(C=f===null||f===void 0?void 0:f.width)!==null&&C!==void 0?C:"100%",b=(k=f===null||f===void 0?void 0:f.height)!==null&&k!==void 0?k:"100%")}else(c===null||c===void 0?void 0:c.url)&&(p=c.url,h=c.title||c.filename||"Image");var I={src:p,alt:h,width:y,height:b};F.forEach(function(n){d[n]!==void 0&&(I[n]=d[n])});var _=(d===null||d===void 0?void 0:d.full_width)?"container !p-0":"";return $(A,{image_alignment:i,width:I.width,height:I.height,className:_,children:$(U,e({},I,(u===null||u===void 0?void 0:u.image)||{}))})},R=H;export{R as CsImage,N as CsTextComponent};//# sourceMappingURL=index.mjs.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/text/CsText.tsx","../src/image/CsImage.tsx","../src/image/CsImage.styled.tsx"],"names":["useMemo","useRouteReplacer","useToggleFontColor","styled","jsx","rewriteLinks","html","replacer","doc","DOMParser","parseFromString","querySelectorAll","forEach","link","href","getAttribute","sanitizedUrl","url","setAttribute","startsWith","body","innerHTML","Container","div","fullWidth","bgColor","alignment","color","CsText","full_width","container_background_color","text_editor","font_color","resolvedFontColor","routeReplacer","safeRouteReplacer","backgroundColor","JSON","parse","brandColor","colorObj","light","updatedHtml","window","children","dangerouslySetInnerHTML","__html","CsText_default","NsImage","StyledCsImageWrapper","image_alignment","width","height","display","justifyContent","left","right","center","maxWidth","objectFit","objectPosition","allowedImageProps","CsImage","props","fileMeta","align","image","rest","selectedImage","entry","selected","files","err","console","warn","imageType","imageProps","src","alt","altText","key","containerClassForNSImage","className","CsImage_default"],"mappings":"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","sourcesContent":["import { ReactElement, useMemo } from 'react';\nimport { useRouteReplacer, useToggleFontColor } from '@nuskin/foundation-core-app/common/hooks';\nimport styled from '@emotion/styled';\n\ninterface CsTextProps {\n full_width?: boolean;\n container_background_color?: string;\n alignment?: 'left' | 'center' | 'right';\n text_editor: string;\n font_color?: boolean;\n}\n\nexport const rewriteLinks = (html: string, replacer: (url: string) => { url: string }): string => {\n const parser = new DOMParser();\n const doc = parser.parseFromString(html, 'text/html');\n const links = doc.querySelectorAll('a');\n\n links.forEach((link) => {\n const href = link.getAttribute('href') ?? '';\n const { url: sanitizedUrl = '' } = replacer(href);\n\n link.setAttribute('href', sanitizedUrl.startsWith('http') ? sanitizedUrl : `https://${sanitizedUrl}`);\n });\n\n return doc.body.innerHTML;\n};\n\n// Emotion styled container\nconst Container = styled.div<{ fullWidth: boolean; bgColor: string; alignment: string; color: string }>`\n width: ${({ fullWidth }) => (fullWidth ? '100%' : 'auto')};\n background-color: ${({ bgColor }) => bgColor};\n text-align: ${({ alignment }) => alignment};\n color: ${({ color }) => color};\n padding: 16px 32px;\n h1,\n h2,\n h3,\n h4,\n h5,\n h6 {\n font-family: 'Lora', serif;\n }\n h1 {\n font-size: 42px;\n line-height: 48px;\n }\n h2 {\n font-size: 36px;\n line-height: 42px;\n }\n h3 {\n font-size: 32px;\n line-height: 38px;\n }\n h4 {\n font-size: 26px;\n line-height: 34px;\n }\n h5 {\n font-size: 22px;\n line-height: 28px;\n }\n h6 {\n font-size: 18px;\n line-height: 24px;\n }\n p {\n margin: 0;\n padding: 0;\n }\n`;\n\nconst CsText = ({\n full_width = false,\n container_background_color = '',\n alignment = 'left',\n text_editor,\n font_color = false\n}: CsTextProps): ReactElement | null => {\n const resolvedFontColor = useToggleFontColor(font_color);\n const routeReplacer = useRouteReplacer() as unknown as ((url: string) => { url: string }) | undefined;\n\n const safeRouteReplacer = (url: string) => {\n if (typeof routeReplacer === 'function') {\n const result = routeReplacer(url);\n return { url: result?.url ?? '' };\n }\n return { url };\n };\n\n const backgroundColor = useMemo(() => {\n try {\n if (container_background_color) {\n const parsed = JSON.parse(container_background_color);\n return parsed?.brandColor?.colorObj?.light || 'transparent';\n }\n } catch {\n return 'transparent';\n }\n return 'transparent';\n }, [container_background_color]);\n\n const updatedHtml = useMemo(() => {\n if (typeof window === 'undefined') return text_editor;\n return rewriteLinks(text_editor, safeRouteReplacer);\n }, [text_editor, routeReplacer]);\n\n return (\n <Container color={resolvedFontColor} fullWidth={full_width} bgColor={backgroundColor} alignment={alignment}>\n <div dangerouslySetInnerHTML={{ __html: updatedHtml }} />\n </Container>\n );\n};\n\nexport default CsText;\n","import { NsImage } from '@nuskin/foundation-ui-components';\nimport { StyledCsImageWrapper } from './CsImage.styled';\nimport type { CsImageProps, NsImageProps } from './types';\n\nconst allowedImageProps: (keyof NsImageProps)[] = [\n 'alt',\n 'className',\n 'fill',\n 'height',\n 'id',\n 'src',\n 'variant',\n 'width'\n];\n\nconst CsImage = (props: CsImageProps) => {\n const { image_alignment: align = 'center', image, ...rest } = props;\n\n let selectedImage: any = null;\n let fileMeta: any = null;\n\n try {\n const parsed = typeof image === 'string' ? JSON.parse(image) : image;\n const entry = parsed?.image?.[0];\n selectedImage = entry?.selected;\n fileMeta = entry?.files;\n } catch (err) {\n console.warn('[CsImage] Failed to parse image prop:', err);\n }\n\n const imageType = selectedImage?.imageType || 'transformBaseUrl';\n const fileSource = fileMeta?.[imageType];\n\n const imageProps: NsImageProps = {\n src: fileSource?.url || '',\n alt: selectedImage?.altText || 'Image not available',\n width: selectedImage?.width ?? '100%',\n height: selectedImage?.height ?? '100%'\n };\n\n // Add any other valid props from rest\n allowedImageProps.forEach((key) => {\n if (rest[key] !== undefined) {\n (imageProps as any)[key] = rest[key];\n }\n });\n const containerClassForNSImage = rest?.full_width ? 'container !p-0' : '';\n\n return (\n <StyledCsImageWrapper\n image_alignment={align}\n width={imageProps.width}\n height={imageProps.height}\n className={containerClassForNSImage}\n >\n <NsImage {...imageProps} />\n </StyledCsImageWrapper>\n );\n};\n\nexport default CsImage;\n","import { styled } from '@nuskin/foundation-theme';\nimport type { CsImageProps } from './types';\n\nexport const StyledCsImageWrapper = styled('div')<\n Pick<CsImageProps, 'image_alignment'> & { width?: string | number; height?: string | number }\n>(({ image_alignment = 'center', width, height }) => ({\n display: 'flex',\n justifyContent: {\n left: 'flex-start',\n right: 'flex-end',\n center: 'center'\n }[image_alignment],\n '& img': {\n maxWidth: 'fit-content',\n objectFit: 'contain',\n objectPosition: 'center'\n }\n}));\n"]}
1
+ {"version":3,"sources":["../src/text/CsText.tsx","../src/hooks/useRouteReplacer.tsx","../src/utils/route-utils.ts","../src/hooks/use-toggle-font-color/useMainContrast.tsx","../src/hooks/use-toggle-font-color/useToggleFontColor.ts","../src/image/CsImage.tsx","../src/image/CsImage.styled.tsx"],"names":["useMemo","styled","languageReplaceExpression","languageReplaceExpressionUppercase","regionReplaceExpression","regionReplaceExpressionUppercase","replaceRegionAndLanguage","text","replacer","region","replace","toUpperCase","language","getRegionAndLanguageFromLocation","window","params","URLSearchParams","location","search","get","useTheme","ColorUtils","getGenomeColor","useToggleFontColor","toggleValue","theme","useToggleFontColor_default","jsx","useRegionLanguage","rewriteUrl","url","rewriteLinks","html","doc","DOMParser","parseFromString","querySelectorAll","forEach","link","href","getAttribute","setAttribute","body","innerHTML","Container","div","fullWidth","bgColor","alignment","color","extractColorFromObject","obj","brandColor","colorObj","light","trim","parseJsonColor","jsonString","JSON","parse","resolveBackgroundColor","value","trimmed","startsWith","CsText","full_width","container_background_color","text_editor","font_color","$","fontColor","regionLang","backgroundColor","updatedHtml","children","dangerouslySetInnerHTML","__html","CsText_default","NsImage","StyledCsImageWrapper","image_alignment","width","height","display","justifyContent","left","right","center","maxWidth","objectFit","objectPosition","PLACEHOLDER_IMAGE_SRC","encodeURIComponent","allowedImageProps","CsImage","props","align","image","parent$","isEditing","rest","selectedImage","fileMeta","contentstackAsset","parsed","entry","selected","files","err","console","warn","resolvedSrc","resolvedAlt","resolvedWidth","resolvedHeight","imageType","fileSource","altText","title","filename","imageProps","src","alt","key","containerClassForNSImage","className","CsImage_default"],"mappings":"u1DAAA,OAAuBA,WAAAA,CAAAA,KAAe,OACtC,QAAOC,MAAY,iBCDnB,QAASD,WAAAA,CAAAA,KAAe,OCAxB,CAAA,IAAME,EAA4B,cAC5BC,EAAqC,cACrCC,EAA0B,YAC1BC,EAAmC,YAW5BC,EAA2B,SAACC,OAAcC,yDAAgC,CAAC,SAChF,OAAOD,GAAS,SACT,GAGPC,CAAAA,EAASC,MAAA,EACTF,CAAAA,EAAOA,EAAKG,OAAA,CAAQN,EAAyBI,EAASC,MAAM,EAC5DF,EAAOA,EAAKG,OAAA,CAAQL,EAAkCG,EAASC,MAAA,CAAOE,WAAA,GAAa,EAGnFH,EAASI,QAAA,EACTL,CAAAA,EAAOA,EAAKG,OAAA,CAAQR,EAA2BM,EAASI,QAAQ,EAChEL,EAAOA,EAAKG,OAAA,CAAQP,EAAoCK,EAASI,QAAA,CAASD,WAAA,GAAa,EAGpFJ,CAAAA,GAmDJ,IAAMM,EAAmC,WAC5C,GAAI,CAAA,OAAOC,iCAAP,EAAOA,OAAA,EAAW,IAAa,WAIpBC,EACEA,EAHjB,IAAMA,EAAS,IAAIC,gBAAgBF,OAAOG,QAAA,CAASC,MAAM,EAEnDT,EAASM,CAAAA,EAAAA,EAAOI,GAAA,CAAI,mBAAXJ,WAAAA,EAAwB,KAAA,EACjCH,EAAWG,CAAAA,EAAAA,EAAOI,GAAA,CAAI,qBAAXJ,WAAAA,EAA0B,KAAA,EAE3C,GAAIN,GAAUG,EACV,MAAO,CAAEH,OAAAA,EAAQG,SAAAA,CAAS,CAIlC,CC7FA,QAASZ,WAAAA,CAAAA,KAAe,OAExB,QAASoB,YAAAA,CAAAA,KAAgB,eACzB,QAASC,cAAAA,CAAAA,KAAkB,0BAE3B,CAAA,IAAQC,EAAmBD,EAAnBC,cCLR,QAASF,YAAAA,CAAAA,KAAgB,eACzB,QAASC,cAAAA,CAAAA,KAAkB,0BAC3B,QAASrB,WAAAA,CAAAA,KAAe,OAExB,CAAA,IAAQsB,EAAmBD,EAAnBC,eAOFC,EAAqB,eAACC,yDAAuB,CAAA,EAC/C,IAAMC,EAAQL,IAEd,OAAOpB,EACH,kBAAMsB,EAAeG,EAAO,MAAOD,EAAc,QAAU,SAC3D,CAACA,EAAaC,EAClB,CACJ,EAEOC,EAAQH,CJ+IH,QAAAI,OAAAA,CAAAA,KAAA,mBAlJZ,CAAA,IAAMC,EAAoB,kBACf5B,EAAQ,kBAAMa,KAAoC,EAAE,GAIzDgB,EAAa,SAACC,EAAatB,SACzB,CAACA,GAAY,CAACsB,EAAYA,EACvBxB,EAAyBwB,EAAKtB,IAI5BuB,EAAe,SAACC,EAAcxB,GACvC,GAAI,CAAA,OAAOM,iCAAP,EAAOA,OAAA,EAAW,KAAe,CAACkB,GAAQ,CAACxB,EAAU,OAAOwB,EAGhE,IAAMC,EADS,IAAIC,YACAC,eAAA,CAAgBH,EAAM,aAEzC,OAAAC,EAAIG,gBAAA,CAAiB,KAAKC,OAAA,CAASC,SAAAA,GAC/B,IAAMC,EAAOD,EAAKE,YAAA,CAAa,OAC1BD,CAAAA,GACLD,EAAKG,YAAA,CAAa,OAAQZ,EAAWU,EAAM/B,GAC/C,GAEOyB,EAAIS,IAAA,CAAKC,SACpB,EAGMC,EAAY3C,EAAO4C,GAAA,KAMZ,gBAAGC,IAAAA,iBAAiBA,EAAY,OAAS,QAC9B,gBAAGC,IAAAA,eAAcA,GACvB,gBAAGC,IAAAA,iBAAgBA,GACxB,gBAAGC,IAAAA,aAAYA,IA4CtBC,EAA0BC,SAAAA,OACdA,EAAAA,MAAAA,EAAd,IAAMF,EAAQE,CAAAA,EAAAA,UAAAA,mBAAAA,EAAAA,EAAKC,UAAA,UAALD,mBAAAA,EAAAA,EAAiBE,QAAA,UAAjBF,kBAAAA,EAA2BG,KAAA,UAA3BH,WAAAA,EAAoCA,UAAAA,kBAAAA,EAAKF,KAAA,CACvD,OAAO,OAAOA,GAAU,UAAYA,EAAMM,IAAA,GAASN,EAAQ,IAC/D,EAEMO,EAAkBC,SAAAA,GACpB,GAAI,KACeC,EAAAA,EAAAA,EACf,IAAMT,GADSS,EAAAA,KAAKC,KAAA,CAAMF,YAAXC,mBAAAA,EAAAA,EACON,UAAA,UADPM,mBAAAA,EAAAA,EACmBL,QAAA,UADnBK,kBAAAA,EAC6BJ,KAAA,CAC5C,OAAO,OAAOL,GAAU,UAAYA,EAAMM,IAAA,GAASN,EAAQ,IAC/D,CAAA,QAAQ,CACJ,OAAO,IACX,CACJ,EAEMW,EAA0BC,SAAAA,GAE5B,GAAI,CAACA,EAAO,MAAO,kBAIDX,EADlB,GAAI,CAAA,OAAOW,4BAAP,EAAOA,EAAAA,GAAU,SAEjB,MADcX,CAAAA,EAAAA,EAAuBW,YAAvBX,WAAAA,EACE,cAIpB,GAAI,OAAOW,GAAU,SAAU,CAC3B,IAAMC,EAAUD,EAAMN,IAAA,OAKJC,EAJlB,OAAKM,EAGDA,EAAQC,UAAA,CAAW,KACLP,CAAAA,EAAAA,EAAeM,YAAfN,WAAAA,EACE,cAIbM,EATc,aAUzB,CAGA,MAAO,aACX,EAEME,EAAS,gBACXC,IAAAA,WAAAA,EAAAA,WAAa,CAAA,EAAbA,EACAC,IAAAA,2BACAlB,IAAAA,UAAAA,EAAAA,WAAY,OAAZA,EACAmB,IAAAA,YACAC,IAAAA,WAAAA,EAAAA,WAAa,CAAA,EAAbA,EACAC,IAAAA,EAEA,IAAMC,EAAY5C,EAAmB0C,GAC/BG,EAAa3C,IAEb4C,EAAkBxE,EACpB,kBAAM4D,EAAuBM,IAC7B,CAACA,EACL,EAEMO,EAAczE,EAAQ,kBAAM+B,EAAaoC,EAAaI,IAAa,CAACJ,EAAaI,EAAW,EAElG,OAAKJ,EAGDxC,EAACiB,EAAA,CAAUE,UAAWmB,EAAYlB,QAASyB,EAAiBxB,UAAWA,EAAWC,MAAOqB,EACrFI,SAAA/C,EAAC,MAAA,GAAIgD,wBAAyB,CAAEC,OAAQH,CAAY,GAAOJ,UAAAA,kBAAAA,EAAGF,WAAA,EAAa,GAJ1D,IAO7B,EAEOU,EAAQb,CKxKf,QAASc,WAAAA,CAAAA,KAAe,kCCAxB,QAAS7E,UAAAA,CAAAA,KAAc,0BAGhB,CAAA,IAAM8E,EAAuB9E,EAAO,OAEzC,gBAAG+E,IAAAA,gBAAAA,EAAAA,WAAkB,SAAlBA,EAA4BC,IAAAA,MAAOC,IAAAA,aAAc,CAClDC,QAAS,OACTC,eAAgB,CAAA,CACZC,KAAM,aACNC,MAAO,WACPC,OAAQ,QACZ,CAAA,CAAA,CAAEP,EAAe,CACjB,QAAS,CACLQ,SAAU,cACVC,UAAW,UACXC,eAAgB,QACpB,CACJ,GDyFY,QAAA/D,OAAAA,CAAAA,KAAA,mBArGL,CAAA,IAAMgE,EACT,2BACAC,mBACI,w0BAgBFC,EAA4C,CAC9C,MACA,YACA,OACA,SACA,KACA,MACA,UACA,QACJ,CAEMC,EAAWC,SAAAA,GACb,IAAyBC,EAA4DD,EAA7Ef,gBAAiBgB,EAAAA,WAAQ,SAARA,EAAkBC,EAA0CF,EAA1CE,MAAOC,EAAmCH,EAAnCG,QAASC,EAA0BJ,EAA1BI,UAAW9B,EAAe0B,EAAf1B,EAAM+B,IAASL,GAA7Ef,kBAAmCiB,QAAOC,UAASC,YAAW9B,MAElEgC,EAAkC,KAClCC,EAAiD,KACjDC,EAA8C,KAElD,GAAI,KAIcC,EAHd,IAAMA,EAAS,OAAOP,GAAU,SAAWvC,KAAKC,KAAA,CAAMsC,GAASA,EAGzDQ,EAAQD,UAAAA,mBAAAA,EAAAA,EAAQP,KAAA,UAARO,kBAAAA,CAAQ,CAAQ,EAAC,AAC3BC,EAAAA,UAAAA,kBAAAA,EAAOC,QAAA,IAAYD,UAAAA,kBAAAA,EAAOE,KAAA,EAC1BN,CAAAA,EAAgBI,UAAAA,kBAAAA,EAAOC,QAAA,CACvBJ,EAAWG,UAAAA,kBAAAA,EAAOE,KAAA,EACXH,CAAAA,UAAAA,kBAAAA,EAAQ1E,GAAA,GAEfyE,CAAAA,EAAoBC,CAAAA,CAE5B,CAAA,MAASI,EAAK,CACVC,QAAQC,IAAA,CAAK,wCAAyCF,EAC1D,CAEA,IAAIG,EAAcpB,EACdqB,EAAc,sBACdC,EAAiC,OACjCC,EAAkC,OAGtC,GAAIb,GAAiBC,EAAU,KACTD,EAAlB,IAAMc,EAAYd,CAAAA,EAAAA,UAAAA,kBAAAA,EAAec,SAAA,UAAfd,WAAAA,EAA4B,mBACxCe,EAAad,UAAAA,kBAAAA,CAAAA,CAAWa,EAAS,KAKrBd,EACEA,EACCA,CAJjBe,EAAAA,UAAAA,kBAAAA,EAAYtF,GAAA,GACZiF,CAAAA,EAAcK,EAAWtF,GAAA,CACzBkF,EAAcX,CAAAA,EAAAA,UAAAA,kBAAAA,EAAegB,OAAA,UAAfhB,WAAAA,EAA0B,QACxCY,EAAgBZ,CAAAA,EAAAA,UAAAA,kBAAAA,EAAepB,KAAA,UAAfoB,WAAAA,EAAwB,OACxCa,EAAiBb,CAAAA,EAAAA,UAAAA,kBAAAA,EAAenB,MAAA,UAAfmB,WAAAA,EAAyB,MAAA,CAElD,KAESE,CAAAA,UAAAA,kBAAAA,EAAmBzE,GAAA,GACxBiF,CAAAA,EAAcR,EAAkBzE,GAAA,CAChCkF,EAAcT,EAAkBe,KAAA,EAASf,EAAkBgB,QAAA,EAAY,OAAA,EAI3E,IAAMC,EAA2B,CAC7BC,IAAKV,EACLW,IAAKV,EACL/B,MAAOgC,EACP/B,OAAQgC,CACZ,EAGArB,EAAkBxD,OAAA,CAASsF,SAAAA,GACnBvB,CAAAA,CAAKuB,EAAG,GAAM,KAAA,GACbH,CAAAA,CAAAA,CAAuCG,EAAG,CAAIvB,CAAAA,CAAKuB,EAAG,CAE/D,GAEA,IAAMC,EAA2BxB,CAAAA,UAAAA,kBAAAA,EAAMnC,UAAA,EAAa,iBAAmB,GAEvE,OACItC,EAACoD,EAAA,CACGC,gBAAiBgB,EACjBf,MAAOuC,EAAWvC,KAAA,CAClBC,OAAQsC,EAAWtC,MAAA,CACnB2C,UAAWD,EAEXlD,SAAA/C,EAACmD,EAAA,KAAY0C,EAAiBnD,CAAAA,UAAAA,kBAAAA,EAAG4B,KAAA,GAAS,CAAC,GAAI,EAG3D,EAEO6B,EAAQhC,SAAAA,KAAAA,OAAAA,CAAAA,KAAAA,eAAAA","sourcesContent":["import { ReactElement, useMemo } from 'react';\nimport styled from '@emotion/styled';\nimport { useToggleFontColor } from '../hooks';\nimport { getRegionAndLanguageFromLocation, RegionLanguageQuery, replaceRegionAndLanguage } from '../utils/route-utils';\n\ninterface CsTextProps {\n full_width?: boolean;\n container_background_color?: unknown;\n alignment?: 'left' | 'center' | 'right';\n text_editor: string;\n font_color?: boolean;\n $?: {\n text_editor?: Record<string, unknown>;\n };\n}\n\n// Get region + language once\nconst useRegionLanguage = () => {\n return useMemo(() => getRegionAndLanguageFromLocation(), []);\n};\n\n// Replace region and language in a single URL\nconst rewriteUrl = (url: string, replacer?: RegionLanguageQuery): string => {\n if (!replacer || !url) return url;\n return replaceRegionAndLanguage(url, replacer);\n};\n\n// Rewrite all <a> links inside CMS HTML\nexport const rewriteLinks = (html: string, replacer?: RegionLanguageQuery): string => {\n if (typeof window === 'undefined' || !html || !replacer) return html;\n\n const parser = new DOMParser();\n const doc = parser.parseFromString(html, 'text/html');\n\n doc.querySelectorAll('a').forEach((link) => {\n const href = link.getAttribute('href');\n if (!href) return;\n link.setAttribute('href', rewriteUrl(href, replacer));\n });\n\n return doc.body.innerHTML;\n};\n\n// Styled container for CMS text\nconst Container = styled.div<{\n fullWidth: boolean;\n bgColor: string;\n alignment: string;\n color: string;\n}>`\n width: ${({ fullWidth }) => (fullWidth ? '100%' : 'auto')};\n background-color: ${({ bgColor }) => bgColor};\n text-align: ${({ alignment }) => alignment};\n color: ${({ color }) => color};\n padding: 16px 32px;\n\n h1,\n h2,\n h3,\n h4,\n h5,\n h6 {\n font-family: 'Lora', serif;\n }\n\n h1 {\n font-size: 42px;\n line-height: 48px;\n }\n h2 {\n font-size: 36px;\n line-height: 42px;\n }\n h3 {\n font-size: 32px;\n line-height: 38px;\n }\n h4 {\n font-size: 26px;\n line-height: 34px;\n }\n h5 {\n font-size: 22px;\n line-height: 28px;\n }\n h6 {\n font-size: 18px;\n line-height: 24px;\n }\n\n p {\n margin: 0;\n padding: 0;\n }\n`;\n\n// Safely resolve CMS background color\nconst extractColorFromObject = (obj: any): string | null => {\n const color = obj?.brandColor?.colorObj?.light ?? obj?.color;\n return typeof color === 'string' && color.trim() ? color : null;\n};\n\nconst parseJsonColor = (jsonString: string): string | null => {\n try {\n const parsed = JSON.parse(jsonString);\n const color = parsed?.brandColor?.colorObj?.light;\n return typeof color === 'string' && color.trim() ? color : null;\n } catch {\n return null;\n }\n};\n\nconst resolveBackgroundColor = (value: unknown): string => {\n // null, undefined, false, 0, '' → transparent\n if (!value) return 'transparent';\n\n // CMS object\n if (typeof value === 'object') {\n const color = extractColorFromObject(value);\n return color ?? 'transparent';\n }\n\n // CMS string\n if (typeof value === 'string') {\n const trimmed = value.trim();\n if (!trimmed) return 'transparent';\n\n // JSON string\n if (trimmed.startsWith('{')) {\n const color = parseJsonColor(trimmed);\n return color ?? 'transparent';\n }\n\n // Normal CSS color\n return trimmed;\n }\n\n // numbers, booleans, etc\n return 'transparent';\n};\n\nconst CsText = ({\n full_width = false,\n container_background_color,\n alignment = 'left',\n text_editor,\n font_color = false,\n $\n}: CsTextProps): ReactElement | null => {\n const fontColor = useToggleFontColor(font_color);\n const regionLang = useRegionLanguage();\n\n const backgroundColor = useMemo(\n () => resolveBackgroundColor(container_background_color),\n [container_background_color],\n );\n\n const updatedHtml = useMemo(() => rewriteLinks(text_editor, regionLang), [text_editor, regionLang]);\n\n if (!text_editor) return null;\n\n return (\n <Container fullWidth={full_width} bgColor={backgroundColor} alignment={alignment} color={fontColor}>\n <div dangerouslySetInnerHTML={{ __html: updatedHtml }} {...$?.text_editor} />\n </Container>\n );\n};\n\nexport default CsText;\n","import { useMemo } from 'react';\nimport { getRegionAndLanguageFromLocation, replaceRegionAndLanguage, RegionLanguageQuery } from '../utils/route-utils';\n\n/**\n * Simply use this hook to update the region and language in the url\n * Note: urlToParse should have {%region} or {%language} or {%rREGION} or {%LANGUAGE}\n * @param urlToParse url to be parsed\n * @returns urlToParse after conditionally replacing the region and language\n */\nconst useRouteReplacer = (urlToParse?: string): { url?: string } => {\n const replacer: RegionLanguageQuery | undefined = useMemo(() => getRegionAndLanguageFromLocation(), []);\n\n const url = useMemo(() => {\n if (!urlToParse || !replacer) return undefined;\n return replaceRegionAndLanguage(urlToParse, replacer);\n }, [urlToParse, replacer]);\n\n return { url };\n};\n\nexport default useRouteReplacer;\n","const languageReplaceExpression = '{%language}';\nconst languageReplaceExpressionUppercase = '{%LANGUAGE}';\nconst regionReplaceExpression = '{%region}';\nconst regionReplaceExpressionUppercase = '{%REGION}';\n\nexport type RegionLanguageQuery = {\n region?: string;\n language?: string;\n slug?: string;\n};\n\n/**\n * Replace {%region}, {%language} placeholders in text\n */\nexport const replaceRegionAndLanguage = (text: string, replacer: RegionLanguageQuery = {}): string => {\n if (typeof text !== 'string') {\n return '';\n }\n\n if (replacer.region) {\n text = text.replace(regionReplaceExpression, replacer.region);\n text = text.replace(regionReplaceExpressionUppercase, replacer.region.toUpperCase());\n }\n\n if (replacer.language) {\n text = text.replace(languageReplaceExpression, replacer.language);\n text = text.replace(languageReplaceExpressionUppercase, replacer.language.toUpperCase());\n }\n\n return text;\n};\n\n/**\n * Replace dynamic pathname segments like [region], [language]\n */\nexport const replacePathnameWithQueryParams = (pathname: string, queryParams: RegionLanguageQuery): string => {\n if (!pathname || typeof pathname !== 'string') {\n return '';\n }\n\n let formattedUrl = pathname;\n\n if (queryParams.region) {\n formattedUrl = formattedUrl.replace('[region]', queryParams.region);\n }\n\n if (queryParams.language) {\n formattedUrl = formattedUrl.replace('[language]', queryParams.language);\n }\n\n if (queryParams.slug) {\n formattedUrl = formattedUrl.replace('[[...slug]]', queryParams.slug);\n }\n\n return formattedUrl;\n};\n\n/**\n * Extract region & language from a query object\n */\nexport const getRegionAndLanguageFromQuery = (\n query?: Record<string, string | string[] | undefined>,\n): RegionLanguageQuery | undefined => {\n if (!query) return undefined;\n\n const region = Array.isArray(query.region) ? query.region[0] : query.region;\n\n const language = Array.isArray(query.language) ? query.language[0] : query.language;\n\n if (region || language) {\n return { region, language };\n }\n\n return undefined;\n};\n\n/**\n * ✅ Next.js Router replacement\n * Reads from browser URL safely\n */\nexport const getRegionAndLanguageFromLocation = (): RegionLanguageQuery | undefined => {\n if (typeof window === 'undefined') return undefined;\n\n const params = new URLSearchParams(window.location.search);\n\n const region = params.get('region') ?? undefined;\n const language = params.get('language') ?? undefined;\n\n if (region || language) {\n return { region, language };\n }\n\n return undefined;\n};\n","import { useMemo } from 'react';\n\nimport { useTheme } from '@mui/material';\nimport { ColorUtils } from '@nuskin/foundation-theme';\n\nconst { getGenomeColor } = ColorUtils;\n\n/**\n * @returns {main:#FFFFFF, contrast:#252525} when passed true\n */\nconst useMainContrast = (toggleValue: boolean = false): { main: string; contrast: string } => {\n const theme = useTheme();\n\n return useMemo(() => {\n const main = getGenomeColor(theme, 'N10', toggleValue ? 'light' : 'dark');\n const contrast = getGenomeColor(theme, 'N10', toggleValue ? 'dark' : 'light');\n return { main, contrast };\n }, [toggleValue, theme]);\n};\n\nexport default useMainContrast;\n","import { useTheme } from '@mui/material';\nimport { ColorUtils } from '@nuskin/foundation-theme';\nimport { useMemo } from 'react';\n\nconst { getGenomeColor } = ColorUtils;\n/**\n * Used to fetch the appropriate theme color for primary and contrast.\n * Usually black or similar, and white for contrast.\n * @param toggleValue the CS toggle value between black and white font color.\n * @returns hex value of the color.\n */\nconst useToggleFontColor = (toggleValue: boolean = false): string => {\n const theme = useTheme();\n\n return useMemo(\n () => getGenomeColor(theme, 'N10', toggleValue ? 'light' : 'dark'),\n [toggleValue, theme]\n );\n};\n\nexport default useToggleFontColor;\n","import { NsImage } from '@nuskin/foundation-ui-components';\nimport { StyledCsImageWrapper } from './CsImage.styled';\nimport type { ContentstackAsset, CsImageProps, ImageFile, ImageFileMeta, NsImageProps } from './types';\n\n// Inline SVG data URL used as a safe placeholder when the main image is unavailable\nexport const PLACEHOLDER_IMAGE_SRC =\n 'data:image/svg+xml;utf8,' +\n encodeURIComponent(\n `<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 400 300\" role=\"img\" aria-label=\"Image not available\">\n <defs>\n <linearGradient id=\"csImagePlaceholderGradient\" x1=\"0\" y1=\"0\" x2=\"1\" y2=\"1\">\n <stop offset=\"0%\" stop-color=\"#f3f4f6\" />\n <stop offset=\"100%\" stop-color=\"#e5e7eb\" />\n </linearGradient>\n </defs>\n <rect width=\"400\" height=\"300\" fill=\"url(#csImagePlaceholderGradient)\" />\n <g stroke=\"#d1d5db\" stroke-width=\"4\" stroke-linecap=\"round\" stroke-linejoin=\"round\" fill=\"none\">\n <rect x=\"60\" y=\"60\" width=\"280\" height=\"180\" rx=\"12\" />\n <path d=\"M120 200 L180 140 L230 185 L260 160 L320 210\" />\n <circle cx=\"160\" cy=\"120\" r=\"20\" />\n </g>\n </svg>`,\n );\n\nconst allowedImageProps: (keyof NsImageProps)[] = [\n 'alt',\n 'className',\n 'fill',\n 'height',\n 'id',\n 'src',\n 'variant',\n 'width'\n];\n\nconst CsImage = (props: CsImageProps) => {\n const { image_alignment: align = 'center', image, parent$, isEditing, $, ...rest } = props;\n\n let selectedImage: ImageFile | null = null;\n let fileMeta: Record<string, ImageFileMeta> | null = null;\n let contentstackAsset: ContentstackAsset | null = null;\n\n try {\n const parsed = typeof image === 'string' ? JSON.parse(image) : image;\n \n // Try Bynder format first: { image: [{ selected, files }] }\n const entry = parsed?.image?.[0];\n if (entry?.selected || entry?.files) {\n selectedImage = entry?.selected;\n fileMeta = entry?.files;\n } else if (parsed?.url) {\n // Fallback: Contentstack native asset format\n contentstackAsset = parsed;\n }\n } catch (err) {\n console.warn('[CsImage] Failed to parse image prop:', err);\n }\n\n let resolvedSrc = PLACEHOLDER_IMAGE_SRC;\n let resolvedAlt = 'Image not available';\n let resolvedWidth: number | string = '100%';\n let resolvedHeight: number | string = '100%';\n\n // Bynder format\n if (selectedImage || fileMeta) {\n const imageType = selectedImage?.imageType ?? 'transformBaseUrl';\n const fileSource = fileMeta?.[imageType];\n\n \n if (fileSource?.url) {\n resolvedSrc = fileSource.url;\n resolvedAlt = selectedImage?.altText ?? 'Image';\n resolvedWidth = selectedImage?.width ?? '100%';\n resolvedHeight = selectedImage?.height ?? '100%';\n }\n } \n // Contentstack asset fallback\n else if (contentstackAsset?.url) {\n resolvedSrc = contentstackAsset.url;\n resolvedAlt = contentstackAsset.title || contentstackAsset.filename || 'Image';\n // Contentstack assets don't provide width/height in metadata, keep defaults\n }\n\n const imageProps: NsImageProps = {\n src: resolvedSrc,\n alt: resolvedAlt,\n width: resolvedWidth,\n height: resolvedHeight\n };\n\n // Add any other valid props from rest\n allowedImageProps.forEach((key) => {\n if (rest[key] !== undefined) {\n (imageProps as Record<string, unknown>)[key] = rest[key];\n }\n });\n\n const containerClassForNSImage = rest?.full_width ? 'container !p-0' : '';\n\n return (\n <StyledCsImageWrapper\n image_alignment={align}\n width={imageProps.width}\n height={imageProps.height}\n className={containerClassForNSImage}\n >\n <NsImage {...imageProps} {...($?.image || {})} />\n </StyledCsImageWrapper>\n );\n};\n\nexport default CsImage;\n","import { styled } from '@nuskin/foundation-theme';\nimport type { CsImageProps } from './types';\n\nexport const StyledCsImageWrapper = styled('div')<\n Pick<CsImageProps, 'image_alignment'> & { width?: string | number; height?: string | number }\n>(({ image_alignment = 'center', width, height }) => ({\n display: 'flex',\n justifyContent: {\n left: 'flex-start',\n right: 'flex-end',\n center: 'center'\n }[image_alignment],\n '& img': {\n maxWidth: 'fit-content',\n objectFit: 'contain',\n objectPosition: 'center'\n }\n}));\n"]}
@@ -1,13 +1,15 @@
1
1
  import { ReactElement } from 'react';
2
+ import { RegionLanguageQuery } from '../utils/route-utils';
2
3
  interface CsTextProps {
3
4
  full_width?: boolean;
4
- container_background_color?: string;
5
+ container_background_color?: unknown;
5
6
  alignment?: 'left' | 'center' | 'right';
6
7
  text_editor: string;
7
8
  font_color?: boolean;
9
+ $?: {
10
+ text_editor?: Record<string, unknown>;
11
+ };
8
12
  }
9
- export declare const rewriteLinks: (html: string, replacer: (url: string) => {
10
- url: string;
11
- }) => string;
12
- declare const CsText: ({ full_width, container_background_color, alignment, text_editor, font_color }: CsTextProps) => ReactElement | null;
13
+ export declare const rewriteLinks: (html: string, replacer?: RegionLanguageQuery) => string;
14
+ declare const CsText: ({ full_width, container_background_color, alignment, text_editor, font_color, $ }: CsTextProps) => ReactElement | null;
13
15
  export default CsText;
@@ -1,9 +1,7 @@
1
1
  import type { Meta, StoryObj } from '@storybook/react-webpack5';
2
2
  import CsText from './CsText';
3
+ import 'react-quill/dist/quill.snow.css';
3
4
  declare const meta: Meta<typeof CsText>;
4
5
  export default meta;
5
6
  type Story = StoryObj<typeof CsText>;
6
- export declare const Default: Story;
7
- export declare const CenterAligned: Story;
8
- export declare const WithBackground: Story;
9
- export declare const DarkFont: Story;
7
+ export declare const CMSForm: Story;
@@ -0,0 +1,22 @@
1
+ export type RegionLanguageQuery = {
2
+ region?: string;
3
+ language?: string;
4
+ slug?: string;
5
+ };
6
+ /**
7
+ * Replace {%region}, {%language} placeholders in text
8
+ */
9
+ export declare const replaceRegionAndLanguage: (text: string, replacer?: RegionLanguageQuery) => string;
10
+ /**
11
+ * Replace dynamic pathname segments like [region], [language]
12
+ */
13
+ export declare const replacePathnameWithQueryParams: (pathname: string, queryParams: RegionLanguageQuery) => string;
14
+ /**
15
+ * Extract region & language from a query object
16
+ */
17
+ export declare const getRegionAndLanguageFromQuery: (query?: Record<string, string | string[] | undefined>) => RegionLanguageQuery | undefined;
18
+ /**
19
+ * ✅ Next.js Router replacement
20
+ * Reads from browser URL safely
21
+ */
22
+ export declare const getRegionAndLanguageFromLocation: () => RegionLanguageQuery | undefined;
@@ -0,0 +1 @@
1
+ export {};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@nuskin/marketing-components",
3
- "version": "1.3.0",
3
+ "version": "1.4.0",
4
4
  "description": "A React based component library for marketing components to use with content stack pagebuilding",
5
5
  "types": "dist/index.d.ts",
6
6
  "main": "dist/index.js",
@@ -25,7 +25,6 @@
25
25
  "build:package": "tsup",
26
26
  "build-dev": "yarn build-storybook",
27
27
  "build-test": "yarn build-storybook",
28
- "build-prod": "yarn build-storybook --mode=production",
29
28
  "lint": "eslint src",
30
29
  "test": "jest --coverage",
31
30
  "test:watch": "jest --watch",
@@ -36,19 +35,18 @@
36
35
  "storybook": "storybook dev -p 6006",
37
36
  "build-storybook": "storybook build -o dist"
38
37
  },
39
- "dependencies": {
40
- "@nuskin/foundation-core-app": "^1.16.1",
41
- "@types/react": "^18.2.0",
42
- "@types/react-dom": "^18.2.0",
43
- "react-circular-progressbar": "^2.1.0",
44
- "react-dom": "^18.2.0",
45
- "react-icons": "^4.0.0"
46
- },
47
38
  "devDependencies": {
48
39
  "@babel/core": "^7.23.2",
40
+ "@babel/helpers": "^7.23.0",
49
41
  "@babel/preset-env": "^7.23.2",
50
42
  "@babel/preset-react": "^7.22.15",
51
43
  "@babel/preset-typescript": "^7.23.2",
44
+ "@nuskin/foundation-core-app": "1.17.3",
45
+ "@jest/core": "29.7.0",
46
+ "@jest/test-sequencer": "29.7.0",
47
+ "@mui/icons-material": "^5.15.0",
48
+ "@mui/material": "^5.15.0",
49
+ "@mui/system": "^5.15.0",
52
50
  "@nuskin/eslint-config": "^1.0.0-setup.1",
53
51
  "@nuskin/foundation-ui-components": "2.0.0",
54
52
  "@storybook/addon-a11y": "^10.0.13",
@@ -80,24 +78,31 @@
80
78
  "eslint-plugin-spellcheck": "^0.0.20",
81
79
  "eslint-plugin-storybook": "^10.0.13",
82
80
  "eslint-plugin-unused-imports": "^4.1.4",
83
- "jest": "^29.7.0",
81
+ "jest": "29.7.0",
82
+ "jest-cli": "29.7.0",
83
+ "jest-config": "29.7.0",
84
84
  "jest-environment-jsdom": "^29.7.0",
85
85
  "prettier": "^3.5.3",
86
86
  "react": "^18.2.0",
87
+ "react-quill": "2.0.0",
87
88
  "storybook": "^10.0.13",
88
89
  "tsup": "8.3.6",
89
90
  "typescript": "^5.4.2"
90
91
  },
91
92
  "peerDependencies": {
93
+ "@mui/icons-material": "^5.0.0",
94
+ "@mui/material": "^5.0.0",
95
+ "@mui/system": "^5.0.0",
92
96
  "@nuskin/foundation-ui-components": "2.0.0",
97
+ "@nuskin/foundation-core-app": "1.x",
93
98
  "react": "^18.2.0",
94
99
  "typescript": "^5.4.2"
95
100
  },
96
101
  "resolutions": {
97
102
  "@nuskin/foundation-theme": "1.7.0",
98
103
  "esbuild": "0.25.0",
99
- "@babel/runtime": "7.26.10",
100
- "@babel/helpers": "7.26.10"
104
+ "@babel/runtime": "^7.28.4",
105
+ "@babel/helpers": "^7.28.4"
101
106
  },
102
107
  "files": [
103
108
  "dist",